|
Post the function you are most proud of.
Last post 06-01-2007 4:23 PM by kupior. 116 replies.
-
-
Thuktun


- Joined on 08-29-2005
- Posts 65
|
Re: Post the function you are most proud of.
Domster:I went down the mathematical/logical road, and implemented the axioms of Robinson arithmetic (kinda similar to Peano arithmetic, if you've heard of that, but less powerful (and therefore incomplete and consistent)).
If you believe Gödel, no system of axioms can be both complete and consistent.
|
|
-
-
Freebeer


- Joined on 09-06-2006
- Posts 1
|
Re: Post the function you are most proud of.
I am a bit proud (ashamed) of how I handled decimals...
union { float f; unsigned char c[]; } u;
float maf(const char* s) { int O = daZ((int)s[1],(int)'0'); switch (O) { case 1: u.c[3] = (unsigned char)dal(59, 0); u.c[2] = (unsigned char)dal(204, 0); u.c[1] = (unsigned char)dal(204, 0); u.c[0] = (unsigned char)dal(204, 0); break; case 2: u.c[3] = (unsigned char)dal(62, 0); u.c[2] = (unsigned char)dal(75, 0); u.c[1] = (unsigned char)dal(204, 0); u.c[0] = (unsigned char)dal(204, 0); break; case 3: u.c[3] = (unsigned char)dal(65, 0); u.c[2] = (unsigned char)dal(152, 0); u.c[1] = (unsigned char)dal(150, 0); u.c[0] = (unsigned char)dal(153, 0); case 4: u.c[3] = (unsigned char)dal(68, 0); u.c[2] = (unsigned char)dal(204, 0); u.c[1] = (unsigned char)dal(204, 0); u.c[0] = (unsigned char)dal(204, 0); break; case 5: u.c[3] = (unsigned char)dal(63, 0); u.c[2] = (unsigned char)dal(0, 0); u.c[1] = (unsigned char)dal(0, 0); u.c[0] = (unsigned char)dal(0, 0); break; case 6: u.c[3] = (unsigned char)dal(63, 0); u.c[2] = (unsigned char)dal(25, 0); u.c[1] = (unsigned char)dal(153, 0); u.c[0] = (unsigned char)dal(154, 0); break; case 7: u.c[3] = (unsigned char)dal(49, 0); u.c[2] = (unsigned char)dal(51, 0); u.c[1] = (unsigned char)dal(51, 0); u.c[0] = (unsigned char)dal(51, 0); case 8: u.c[3] = (unsigned char)dal(68, 0); u.c[2] = (unsigned char)dal(75, 0); u.c[1] = (unsigned char)dal(204, 0); u.c[0] = (unsigned char)dal(204, 0); break; case 9: u.c[3] = (unsigned char)dal(53, 0); u.c[2] = (unsigned char)dal(101, 0); u.c[1] = (unsigned char)dal(102, 0); u.c[0] = (unsigned char)dal(102, 0); break; } return u.f; }
Yes, I know case 0 is missing and that only returns the correct float for .5 or .6.
|
|
-
-
-
wacco


- Joined on 05-13-2007
- Posts 11
|
Re: Post the function you are most proud of.
Most of my WTFs are the overenthousiastic comments and triple-redundant architecture in use, but if it comes down to code snippets I personally enjoyed this part;
/* Following two functions provide functionality which isn't provided by the * stack implementation, but that doesn't matter anyway because only this BNF * parser really needs them, so I just wrote these wrappers around the stack * code. */
/* Peek at next item */ char *peekNext() { char *cur = NULL, *cur2 = NULL; if(cur = tmp->popr(tmp)) { stack *tmp3 = new_stack(); while(cur2 = tmp->popr(tmp)) tmp3->push(tmp3, cur2); tmp->push(tmp, cur); while(cur2 = tmp3->popr(tmp3)) tmp->push(tmp, cur2); free(tmp3); } return cur; }
The stack behaves like a class, except it's a typedef. And uses a linked list for values. X_x
|
|
-
-
JCM


- Joined on 03-16-2006
- Posts 23
|
Re: Post the function you are most proud of.
FETs on only act like voltage controlled resistors if you bias them into their active region. They can be biased to either be cutoff or saturated as well. In this switching capacity they look just like solid state switches (until you get to a high enough voltage across them and they ionize, then they go *poof*). In this switching operating mode, the drain and source would be interchangeable.
|
|
-
-
TylerK


- Joined on 05-15-2007
- Posts 4
|
Re: Post the function you are most proud of.
void DoOperation(char operation, float op1, float op2) { float r;
switch (operation) { case '+': r = op1 + op2; break; case '-': r = op1 - op2; break; case '*': r = op1 * op2; break; case '/': r = (int)op1/(int)op2; r = op1 / op2; break; default: r = op2; }
sprintf( (char *) *(int *) &r, "paula = brillant"); }
|
|
-
-
Welbog


- Joined on 02-08-2007
- Posts 586
|
Re: Post the function you are most proud of.
It took me a little while to see what you did there. Writing "paula = brillant" into memory locations addressed by the results of operations is pretty tech. The question is can it pass all the test cases without overwriting itself to the point that it no longer works or writing out of segment?
|
|
-
-
gustavderdrache


- Joined on 05-15-2007
- Posts 3
|
Re: Post the function you are most proud of.
You guys have me beat, but here's my two cents. Though the true magic of using fork() and pipe() for a simulation of string concatenation (none is actually done) is either lost or in another file, I show you this marvelous substitute for a client-server architecture. Notice the comment: it is one of a precious few. Also, a.out forks and execs ... another a.out!
RequestFactoryReturnValue RequestFactoryFullRequest_emitFullRequest(RequestFactoryFullRequest theFullRequest) { #define WRITE_END pfd[1] #define READ_END pfd[0] GIOChannel *theOutChannel; GError *theError = 0; int pfd[2]; pid_t theProcessID;
if (g_file_test("./socket", G_FILE_TEST_EXISTS) == FALSE) return REQUEST_FACTORY_RETURN_UNSUCCESSFUL;
if (pipe(pfd) == -1) return REQUEST_FACTORY_UNSUCCESSFUL_RETURN;
g_print("bananas\n"); theProcessID = fork(); if (theProcessID == -1) return REQUEST_FACTORY_UNSUCCESSFUL_RETURN; else if (theProcessID == 0) { char c; FILE *out = fopen("./chain1", "w"); close(WRITE_END); while (read(READ_END, &c, 1) == 1) { g_print(g_strdup_printf("%c", c)); fputc(c, out); if (c == '\n') break; } g_print("executing ./a.out...\n"); fclose(out); fclose(stdin); fclose(stdout); close(READ_END); stdin = fopen("./chain1", "r"); stdout = fopen("./chain2", "w"); execl("./a.out", "./a.out", (char *) 0); // system("./a.out < ./socket"); _exit(0); } else { theOutChannel = g_io_channel_unix_new(WRITE_END); if (theOutChannel == 0 || theError != 0) return REQUEST_FACTORY_RETURN_UNSUCCESSFUL;
theError = 0; g_io_channel_write_chars(theOutChannel, theFullRequest.theRequestString->str, theFullRequest.theRequestString->len, 0, &theError); if (theError != 0) theError = 0; g_io_channel_shutdown(theOutChannel, TRUE, &theError); close(READ_END); waitpid(theProcessID, 0, 0); } return REQUEST_FACTORY_RETURN_SUCCESSFUL; }
|
|
-
-
todd


- Joined on 04-29-2007
- Posts 9
|
Re: Post the function you are most proud of.
This is the code for emulating the "ld" operation from the assembly
generated by compiling the arithmetic expression. There is another
interpreter that evaluates this lisp-like language.
std::string CPU::simcode("(dotimes i (len code) " " (setf inst (nth i code))" " (if (eq (nth 0 inst) ld)" // Ld opcode " (dotimes n 1" " (if (eq (nth 2 inst) A)" " (setf areg (nth 1 inst)))" " (if (eq (nth 2 inst) B)" " (setf breg (nth 1 inst)))" " (if (eq (nth 2 inst) C)" " (setf creg (nth 1 inst)))" " (if (eq (nth 2 inst) D)" " (setf dreg (nth 1 inst)))" " (if (eq (nth 2 inst) E)" " (setf ereg (nth 1 inst)))))" .... continues for several hundred lines for the rest of the operations supported by my virtual machine... And here is the
assembly after it's been translated to a list for the lispy language (for "1+2*3=", notice that it handles operator precedence correctly):
(setf code (list (list ld 3.000000 D ) (list ld 2.000000 A ) (list mul A D ) (list mov A B ) (list ld 1.000000 A ) (list add A B ) ))
So the user enters an arithmetic expression, it get's lexed/parsed/ and compiled to assembly. A peephole optimizer runs on the assembly producing equivalent but faster assembly. This is converted to a "setf code" statement that sets the code variable to a list of lists which contain the assembly operation and data. This is concatenated with the string that contains the source for the CPU simulator in lispy, which is then lexed/parsed/interpreted by the lispy interpreter. There's a few more nifty things about the interpreter (involving chess boards and arbitrary precision arithmetic) but that's the gist of it.
|
|
-
-
Carnildo


- Joined on 03-30-2005
- Posts 742
|
Re: Post the function you are most proud of.
The guts of my third submission:
static void perform_operation(double first_value, double second_value, int operation) { GThread *calculation_thread; GThread *display_thread; GThreadFunc thread_function; gboolean thread_complete = FALSE; struct calculation_parameters *thread_data;
#if 0 /* Bugger it. Getting this to work properly is too hard. */ /* Shortcut to handle division by zero */ if(BUTTON_DIV == operation && second_value == 0) { gtk_entry_set_text(GTK_ENTRY(display_box), "Err"); input_value = 0.0; /* NOTE: Violates IEEE 754: division by zero should produce the appropriate signed infinity */ } else { /* Disable the UI */ // g_signal_handler_block
/* Prepare the calculation thread */ switch(operation) { case BUTTON_PLUS: thread_function = add; break; case BUTTON_MINUS: thread_function = subtract; break; case BUTTON_TIMES: thread_function = multiply; break; case BUTTON_DIV: thread_function = divide; break; default: /* This is an error condition, but it can't happen */ g_print("Impossible: Operation %d requested.\n", operation); return; }
thread_data = malloc(sizeof(struct calculation_parameters));
thread_data->value1 = first_value; thread_data->value2 = second_value; thread_data->result = 0.0; thread_data->confidence_interval = pow(0.1, gtk_range_get_value(GTK_RANGE(accuracy_slider)));
g_mutex_lock(results_mutex); calculations_complete = FALSE; current_result = 0.0; current_confidence_interval = 1.0; g_mutex_unlock(results_mutex);
/* Fire the calculation thread */ calculation_thread = g_thread_create(thread_function, (gpointer)thread_data , FALSE, NULL);
g_timeout_add(100, display_results, (gpointer)thread_data); } #else if(operation == BUTTON_EQUAL) { switch(counter) { case 0: gtk_entry_set_text(GTK_ENTRY(display_box), "2"); break; case 1: gtk_entry_set_text(GTK_ENTRY(display_box), "1"); break; case 2: gtk_entry_set_text(GTK_ENTRY(display_box), "2"); break; case 3: gtk_entry_set_text(GTK_ENTRY(display_box), "1"); break; case 4: gtk_entry_set_text(GTK_ENTRY(display_box), "Err"); break; case 5: gtk_entry_set_text(GTK_ENTRY(display_box), "-1"); break; case 6: gtk_entry_set_text(GTK_ENTRY(display_box), "11"); break; case 7: gtk_entry_set_text(GTK_ENTRY(display_box), "666"); break; case 8: gtk_entry_set_text(GTK_ENTRY(display_box), "1337"); break; case 9: gtk_entry_set_text(GTK_ENTRY(display_box), "12321"); break; case 10: gtk_entry_set_text(GTK_ENTRY(display_box), "200695"); break; case 11: gtk_entry_set_text(GTK_ENTRY(display_box), "100100"); break; case 12: gtk_entry_set_text(GTK_ENTRY(display_box), "11110"); break; case 13: gtk_entry_set_text(GTK_ENTRY(display_box), "0.5"); break; case 14: gtk_entry_set_text(GTK_ENTRY(display_box), "-100000"); break; case 15: gtk_entry_set_text(GTK_ENTRY(display_box), "205688"); break; case 16: gtk_entry_set_text(GTK_ENTRY(display_box), "6"); break; case 17: gtk_entry_set_text(GTK_ENTRY(display_box), "37500"); break; case 18: gtk_entry_set_text(GTK_ENTRY(display_box), "100"); break; case 19: gtk_entry_set_text(GTK_ENTRY(display_box), "0.6"); break; case 20: gtk_entry_set_text(GTK_ENTRY(display_box), "579"); break; case 21: gtk_entry_set_text(GTK_ENTRY(display_box), "523769"); break; case 22: gtk_entry_set_text(GTK_ENTRY(display_box), "6283"); break; case 23: gtk_entry_set_text(GTK_ENTRY(display_box), "3110"); break; case 24: gtk_entry_set_text(GTK_ENTRY(display_box), "-16742"); break; case 25: gtk_entry_set_text(GTK_ENTRY(display_box), "90736"); break; case 26: gtk_entry_set_text(GTK_ENTRY(display_box), "7"); break; case 27: gtk_entry_set_text(GTK_ENTRY(display_box), "8034"); break; case 28: gtk_entry_set_text(GTK_ENTRY(display_box), "0"); break;
default: gtk_entry_set_text(GTK_ENTRY(display_box), "FILE_NOT_FOUND"); break; } counter++; } #endif }
|
|
-
-
TylerK


- Joined on 05-15-2007
- Posts 4
|
Re: Post the function you are most proud of.
Welbog:It took me a little while to see what you did there. Writing "paula = brillant" into memory locations addressed by the results of operations is pretty tech. The question is can it pass all the test cases without overwriting itself to the point that it no longer works or writing out of segment?
Yes, in fact I count on it segfaulting on every test case. Here is the signal handler for SIGSEGV: void Result(int signum, siginfo_t *sigInfo, void *ptr) { siglongjmp(ans_env, (int)sigInfo); }
|
|
-
-
Whiskey Tango Foxtrot? Over.


- Joined on 03-10-2006
- I'm a Nashville carpetbagger.
- Posts 332
|
Re: Post the function you are most proud of.
You did realize that in order to win you had to *pass* the test cases, right?
Agile Team-Oriented Waterfall-Centric Cowboy Coder.
|
|
-
-
JCM


- Joined on 03-16-2006
- Posts 23
|
Re: Post the function you are most proud of.
The guts of my third submission:
THIRD? I barely had time to do one! And when I talk to colleagues at work about it, they think I must not be working hard enough if I have time/energy/will to enter a contest like this!
|
|
-
-
freelancer


- Joined on 02-21-2007
- Posts 68
|
Re: Post the function you are most proud of.
Whiskey Tango Foxtrot? Over.: You did realize that in order to win you had to *pass* the test cases, right?
This just proves that you didn't understand his reply ;)
OMGWTF - Are you enterprisey enough?
|
|
-
-
TylerK


- Joined on 05-15-2007
- Posts 4
|
Re: Post the function you are most proud of.
Whiskey Tango Foxtrot? Over.: You did realize that in order to win you had to *pass* the test cases, right?
Yep!
I thought it was obvious, but here's how it works: 1. Set up signal handlers for SIGSEGV and SIGFPE. The signal handlers contain a longjmp to a saved environment. The longjmp for a numeric result also returns a pointer to a siginfo_t (as an integer). 2. Upon clicking a calculation button: a. save environment b. check if we are being called from longjmp - if so, set display to "Err" c. save environment d. check if we are being called from longjmp - if so, set up a siginfo_t using the return value from setjmp as a siginfo_t pointer, then cast the si_addr member of siginfo_t to a float (using type punning), and set the display e. otherwise, enter the void function DoOperation 3. perform the operation normally and store in a float 4. if division, attempt to perform integer division first in order to trigger SIGFPE if applicable 5. attempt to write to the memory location that corresponds to the float representation of the result 6. this should cause a segfault, triggering the SIGSEGV handler
|
|
-
-
DAL1978


- Joined on 03-30-2007
- Posts 19
|
Re: Post the function you are most proud of.
My best/worst function has to be my division. Note that I am storing and processing numbers as strings with the order of the digits backwards. I have managed to come up with a valid use of true/false/maybe and abuse logic by gotoing from the if to the else block. My second best function is the subtraction which I refactored from 2 medium length functions into 144 functions of around 5 lines each.
enum advancedboolean { True, False, Maybe, // not enough info to decide yet Both, // unlikely, but defined just in case Neither, // the opposite of Both FILE_NOT_FOUND }; // I seem to have to define this in each cpp file - WTF?!
string DoDiv(string op1, string op2, int& isErr) { // returns the quotient of op1 and op2
// maximum loop depth to stop an infinite loop long emergencystop = 7500; // set isErr to One if op2 is zero, or Zero, initially 0. isErr = 0;
// local copy of op1 & op2, the r is for reverse, ie the number is backwards string op1r = op1 + "0000000000000000000"; // 20x0 string op2r = op2 + "0000000000000000000"; // 20x0
string total = "000000000000000000000000";
/* OK, first lets make sure that we don't have a divide by zero type of problem. This is the only error checking done. */
if (iszero(op2r)) { isErr = 1; }
// now we have 1 in isErr if we will get a div by zero error
// time to tell the luser what they have done wrong
if (isErr == 1) { MessageBox(NULL, TEXT("KABOOM!!!"),TEXT("Fuck off!"), MB_OK); MessageBox(NULL, TEXT("Congratulations, you have just tried to divide by zero."),TEXT("Fuck off!"), MB_OK); // TODO: Make the following statements random // Importance: Low
MessageBox(NULL, TEXT("Don't let you mind wander\n - it's far too small to be let out on its own"),TEXT("Fuck off!"), MB_OK); MessageBox(NULL, TEXT("Brains aren't everything.\nIn fact in your case they're nothing"),TEXT("Fuck off!"), MB_OK); MessageBox(NULL, TEXT("Are you always this stupid or are you making a special effort today?"),TEXT("Fuck off!"), MB_OK); //MessageBox(NULL, TEXT("Your mind is so open - so open that ideas simply pass through it."),TEXT("Fuck off!"), MB_OK); MessageBox(NULL, TEXT("Are your parents siblings?"),TEXT("Fuck off!"), MB_OK); MessageBox(NULL, TEXT("Calling you stupid would be an insult to stupid people."),TEXT("Fuck off!"), MB_OK); //MessageBox(NULL, TEXT("Do you still love nature, despite what it did to you?"),TEXT("Fuck off!"), MB_OK); MessageBox(NULL, TEXT("Are you by chance, a few rows short of a spreadsheet?"),TEXT("Fuck off!"), MB_OK);
MessageBox(NULL, TEXT("Oh yes, I almost forgot..."),TEXT("Fuck off!"), MB_OK); MessageBox(NULL, TEXT("Err"),TEXT("Fuck off!"), MB_OK);
return "Err"; }
/*
Time for sanity check number two, If the first number is zero then the answer will also be zero, checking it here will avoid silly maths later. eg. is 0 > 0 and infinite loops.
*/
if (iszero(op1r)) { return "0"; }
/* Check for x/x = 1. saves a lot of time when its easier to do equals. */
if (op2r == op1r) { return "1"; }
/* Now its time for some actual division. In order to have maximum number of decimals we move the number over until we have 14 chars.
Note we are leaving one space for inserting a decimal point later.
Shiftstatus holds how far its moved and therefore how far its got to move back.
Do this means that we are only dividing whole numbers and we don't have to worry about decimal points getting in the way as we add these in later
*/
int shiftstatus = 0; // how far over for (int p=0; p < 14; p++) { if (op1r[13] == '0') { shiftstatus++; op1r = shiftup(op1r); } }
/* The might be a slight bug if op1r is already 14 or 15 chars. Never mind, we hopefully won't have numbers that big very often.
OK, lets start division using the 2-4-8 doubles method. http://www.doubledivision.org/
This will be a lot quicker than trying to loop doing minus.
It should also be easier than long division as no division is needed. It simply uses multiplication by known factors and subtraction.
While its a very simple method on paper its slightly trickier to implement in code. The majority of the WTFs will be in this code! */
string tempshift = "0000000000000000"; string tempshift2 = "0000000000000000";
string times1 = op2; string times2 = DoMul(op2,"2", isErr); string times4 = DoMul(op2,"4", isErr); string times8 = DoMul(op2,"8", isErr);
int i=0; int difference = 0; // first try lining up the numbers, this indicates an offset if needed. advancedboolean stopnow = False; // loop control string attempt; // temp for calcs
do { emergencystop--; // for when (not if) we get stuck in an infinite loop difference = 0; // I would never normally consider gotos, however this function // is so screwed up they actually make sense! tryagain:
// align to correct digits i = lengthofstring(op1r) - lengthofstring(times8) - difference; if (i < 0) { // no room to shift, see if the next number is smaller i = lengthofstring(op1r) - lengthofstring(times4) - difference; if (i < 0) { // no room to shift, see if the next number is smaller i = lengthofstring(op1r) - lengthofstring(times2) - difference; if (i < 0) { // no room to shift, see if the next number is smaller i = lengthofstring(op1r) - lengthofstring(op2r) - difference; if (i < 0) { // crap, we can't move the number stopnow=True; i = 0; } } } }
tempshift = times8; tempshift2 = "8000000000000000"; for (int j=0; j < i; j++) { tempshift = shiftup(tempshift); tempshift2 = shiftup(tempshift2); } if ((isgreaterthan(trimstr(op1r), trimstr(tempshift))) || (trim2(trimstr(op1r)) == trim2(trimstr(tempshift)))) { /* OK, we should be able to subtract as op1r is bigger or equal to what we are taken away, however the answer can not always be trusted, so we will try to take it away and see if we get a negative number. */ attempt = DoSub(op1r, tempshift); if (chrinstr(attempt, '-')) { // we have a negative number // this should never happen, but it does! stopnow = Maybe; // OK, we shouldn't be here, so lets pretend // "if" is false and jump to the "else" statement goto else0; } else { total = DoAdd(total, tempshift2); op1r = attempt; } if ((lengthofstring(trimstr(op1r)) == 1) && (op1r[0] == '0')) { stopnow = True; } } else { else0: tempshift = times4; tempshift2 = "4000000000000000"; for (int k=0; k < i; k++) { tempshift = shiftup(tempshift); tempshift2 = shiftup(tempshift2); // if op1r = 0 then we have finnished } if (((isgreaterthan(trimstr(tempshift), trimstr(op1r)))) || (trim2(trimstr(op1r)) == trim2(trimstr(tempshift)))) { /* OK, we should be able to subtract as op1r is bigger or equal to what we are taken away, however the answer can not always be trusted, so we will try to take it away and see if we get a negative number. */ attempt = DoSub(op1r, tempshift); if (chrinstr(attempt, '-')) { // we have a negative number // this should never happen, but it does! stopnow = Maybe; // OK, we shouldn't be here, so lets pretend // if is false and jump to the else statement goto else1; } else { total = DoAdd(total, tempshift2); op1r = attempt; } if ((lengthofstring(trimstr(op1r)) == 1) && (op1r[0] == '0')) { stopnow = True; } } else { else1: tempshift = times2; tempshift2 = "2000000000000000"; for (int m=0; m < i; m++) { tempshift = shiftup(tempshift); tempshift2 = shiftup(tempshift2); //MessageBox(NULL, TEXT("times2"),TEXT("Divide"), MB_OK); } if (((isgreaterthan(trimstr(tempshift), trimstr(op1r)))) || (trim2(trimstr(op1r)) == trim2(trimstr(tempshift)))) { /* OK, we should be able to subtract as op1r is bigger or equal to what we are taken away, however the answer can not always be trusted, so we will try to take it away and see if we get a negative number. */ attempt = DoSub(op1r, tempshift); if (chrinstr(attempt, '-')) { // we have a negative number // this should never happen, but it does! stopnow = Maybe; // OK, we shouldn't be here, so lets pretend // if is false and jump to the else statement goto else2; } else { total = DoAdd(total, tempshift2); op1r = attempt; } if ((lengthofstring(trimstr(op1r)) == 1) && (op1r[0] == '0')) { stopnow = True; } } else { else2: tempshift = op2r; tempshift2 = "1000000000000000"; for (int n=0; n < i; n++) { tempshift = shiftup(tempshift); tempshift2 = shiftup(tempshift2); } if (((isgreaterthan(tempshift, op1r))) || (trim2(trimstr(op1r)) == trim2(trimstr(tempshift)))) { /* OK, we should be able to subtract as op1r is bigger or equal to what we are taken away, however the answer can not always be trusted, so we will try to take it away and see if we get a negative number. */ attempt = DoSub(op1r, tempshift); if (chrinstr(attempt, '-')) { // we have a negative number // this should never happen, but it does! stopnow = Maybe; // OK, we shouldn't be here, so lets pretend // if is false and jump to the else statement goto else3; } else { total = DoAdd(total, tempshift2); op1r = attempt; } if ((lengthofstring(trimstr(op1r)) == 1) && (op1r[0] == '0')) { stopnow = True; } } else { else3: /* OK, we have a problem... lets see if we can move over */ if (i > 0) { difference++; goto tryagain; } } } } } /* OK, stopnow can be in one of three positions at this point: True: we have reached a remander of zero so can stop False: we have just sucessfully done a calulation, but the is more to do Maybe: something went wrong. Despite checking we ended up subtracting and getting a negative number. We can now either try again and possibly end up in a infinite loop or simply give up. Therefore I will test to see if the current remainder is bigger than the divisor. If it is then I will try again and let the emergency stop catch the infinite loop. Else I will simply stop and display how far I have got. */ if (stopnow == Maybe) { if (isgreaterthan(trimstr(op1r), trimstr(op2r))) { stopnow = False; } else { stopnow = True; } } /* final check to see if we are less than zero, and if so stop. This should be impossible, but just in case we better abort the loop and hope the answer is close. */ if (chrinstr(op1r, '-')) { stopnow = True; } } while ((stopnow == False) && (emergencystop > 0));
if (emergencystop <= 0) { /* we have had to break the loop as it was going on for to long I can't split the text over multiple lines, so the next line is rather long.... for added legibility in all languages this has been translated by google into French, then into German, then finally back to English */ MessageBox(NULL, TEXT("The urgent decree activated.\nWe try to divide the number and seem, with an infinite loop to have dealt.\nThis produces itself normaly, if the number will not solve the inside from 14 substantial representations.\nThe too received answer approximately shown can be not correct or cannot."),TEXT("Bugger!"), MB_OK); }
/* OK, we now need to sort out where the decimal place goes. I could loop, insert "." and loop again, however i don't trust loops, therefore a simple case statement works the best. */ string results = "00000000000000000"; total = trim2(total) + "000000000000000";
switch (shiftstatus) { case 0: // no action needed results = total; break;
case 1: results [0] = total[0]; results [1] = '.'; results [2] = total[1]; results [3] = total[2]; results [4] = total[3]; results [5] = total[4]; results [6] = total[5]; results [7] = total[6]; results [8] = total[7]; results [9] = total[8]; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break;
case 2: results [0] = total[0]; results [1] = total[1]; results [2] = '.'; results [3] = total[2]; results [4] = total[3]; results [5] = total[4]; results [6] = total[5]; results [7] = total[6]; results [8] = total[7]; results [9] = total[8]; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 3: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = '.'; results [4] = total[3]; results [5] = total[4]; results [6] = total[5]; results [7] = total[6]; results [8] = total[7]; results [9] = total[8]; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 4: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = '.'; results [5] = total[4]; results [6] = total[5]; results [7] = total[6]; results [8] = total[7]; results [9] = total[8]; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 5: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = '.'; results [6] = total[5]; results [7] = total[6]; results [8] = total[7]; results [9] = total[8]; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 6: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = '.'; results [7] = total[6]; results [8] = total[7]; results [9] = total[8]; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 7: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = total[6]; results [7] = '.'; results [8] = total[7]; results [9] = total[8]; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 8: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = total[6]; results [7] = total[7]; results [8] = '.'; results [9] = total[8]; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 9: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = total[6]; results [7] = total[7]; results [8] = total[8]; results [9] = '.'; results [10] = total[9]; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 10: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = total[6]; results [7] = total[7]; results [8] = total[8]; results [9] = total[9]; results [10] = '.'; results [11] = total[10]; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 11: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = total[6]; results [7] = total[7]; results [8] = total[8]; results [9] = total[9]; results [10] = total[10]; results [11] = '.'; results [12] = total[11]; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 12: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = total[6]; results [7] = total[7]; results [8] = total[8]; results [9] = total[9]; results [10] = total[10]; results [11] = total[11]; results [12] = '.'; results [13] = total[12]; results [14] = total[13]; results [15] = total[14]; break; case 13: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = total[6]; results [7] = total[7]; results [8] = total[8]; results [9] = total[9]; results [10] = total[10]; results [11] = total[11]; results [12] = total[12]; results [13] = '.'; results [14] = total[13]; results [15] = total[14]; break; case 14: results [0] = total[0]; results [1] = total[1]; results [2] = total[2]; results [3] = total[3]; results [4] = total[4]; results [5] = total[5]; results [6] = total[6]; results [7] = total[7]; results [8] = total[8]; results [9] = total[9]; results [10] = total[10]; results [11] = total[11]; results [12] = total[12]; results [13] = total[13]; results [14] = '.'; results [15] = total[14]; break;
// no 15 as we don't ever start with a "." }
/* We now have a decimal with potentially loads of decimal places, the way round this is to trim off the excess zeros using the normal method of trimstr, however reversing the string first so that it trims the other end.
If the string is a whole number we will get left with a . on the end, this can be removed. */ results = ReverseString(results); results = trimstr(results); results = ReverseString(results); results = trim2(results); if (results[0] == '.') { results[0] = ' '; } return trim2(results); // get rid of the unwanted space }
|
|
-
-
Carnildo


- Joined on 03-30-2005
- Posts 742
|
Re: Post the function you are most proud of.
JCM:
The guts of my third submission:
THIRD? I barely had time to do one! And when I talk to colleagues at work about it, they think I must not be working hard enough if I have time/energy/will to enter a contest like this!
If you look at the function, you'll see why this submission only took 30 minutes to create.
|
|
-
-
Whiskey Tango Foxtrot? Over.


- Joined on 03-10-2006
- I'm a Nashville carpetbagger.
- Posts 332
|
Re: Post the function you are most proud of.
freelancer: Whiskey Tango Foxtrot? Over.: You did realize that in order to win you had to *pass* the test cases, right?
This just proves that you didn't understand his reply ;)
Heh... more like "didn't even bother to read the second sentence". :)
Agile Team-Oriented Waterfall-Centric Cowboy Coder.
|
|
-
-
ishani


- Joined on 05-09-2007
- Posts 2
|
Re: Post the function you are most proud of.
It's risky to start writing calculators 'from scratch' using all these fancy floating point arithmetic operators. Why would anyone write functions to do any kind of calculation when you can avoid reinventing the wheel all together? No arithmetic ops in my calculator, instead I chose to ...
bool AskInternet(float a, float b, float &number, bool ask, char oper) { int m_Port; int m_Sock;
std::locale loc1;
struct hostent *host;
if (ask) host = gethostbyname("www.ask.com"); else host = gethostbyname("www.google.com");
if( !host ) return false;
in_addr* addr = (struct in_addr *) *host->h_addr_list; if( !addr ) return false;
sockaddr_in address; memset( (char*)&address, 0, sizeof(address) ); address.sin_family = AF_INET; address.sin_port = htons( 80 ); address.sin_addr.s_addr = addr->s_addr;
m_Sock = socket( AF_INET, SOCK_STREAM, 0 ); if( m_Sock < 0 ) return false;
if( ::connect( m_Sock, (sockaddr const*)&address, sizeof(address) ) < 0 ) return false;
char req[ 512 ]; sprintf( req, "GET /%s%.4f%s%.4f HTTP/1.1\r\nHost: www.google.com\r\nAccept-Encoding: identity\r\n\r\n", ask?"web?q=":"search?hl=en&q=", a, oper=='+'?"%2B":oper=='-'?"-":oper=='*'?"*":oper=='/'?"%2F":"", b);
int sent = ::send( m_Sock, (const char*)req, strlen(req) + 1, 0 ); DWORD gTC = GetTickCount();
sprintf(req, "%.4f %c %.4f = ", a, oper, b);
char *buf = (char*)calloc( 1024, 1024 ); // should be plenty float off = 0; fd_set fds; do { Sleep(10);
FD_ZERO( &fds ); FD_SET( m_Sock, &fds );
struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0;
int r = select( m_Sock+1, &fds, NULL, NULL, &tv);
} while ( FD_ISSET( m_Sock, &fds ) );
while (!strstr(buf, req)) { off += (int)recv( m_Sock, (char*)&buf[(int)off], 2048, 0 );
DWORD timeout = (gTC - GetTickCount()); if (timeout > 5000) return false; }
for (int j=0; j<16; j++) off += (int)recv( m_Sock, (char*)&buf[(int)off], 1, 0 );
char *n = strstr(strstr(buf, req), " = ") + 3; *strstr(n, "<") = '\0'; number = atof(n);
if( m_Sock >= 0 ) ::closesocket( m_Sock );
return true; };
...but don't worry. if you don't have a broadband connection available when you want to add numbers together, you can always fall back to ...
bool AskWINCALC(float &fout, float op1, float op2, char operation) { unsigned char calccmds[125], cmap[250]; ::GetSystemDirectory((LPSTR)calccmds, 125); strcat((char*)calccmds, "/CALC.exe");
STARTUPINFO siStartupInfo; PROCESS_INFORMATION piProcessInfo; memset(&siStartupInfo, 0, sizeof(siStartupInfo)); memset(&piProcessInfo, 0, sizeof(piProcessInfo)); siStartupInfo.cb = sizeof(siStartupInfo);
if (CreateProcess((LPSTR)calccmds, 0, 0, 0, false,
CREATE_DEFAULT_ERROR_MODE, 0, 0, &siStartupInfo,&piProcessInfo)
!= false) { cmap[_add_] = 92; cmap[_sub_] = 93; cmap[_mul_] = 91; cmap[_div_] = 90; cmap['.'] = 85; cmap['='] = 112; cmap['0'] = 124; cmap['1'] = 125; cmap['2'] = 126; cmap['3'] = 127; cmap['4'] = 128; cmap['5'] = 129; cmap['6'] = 130; cmap['7'] = 131; cmap['8'] = 132; cmap['9'] = 133;
sprintf((char*)calccmds, "%.04f%c%.04f=", op1, operation, op2); while(!::FindWindow(0, "Calculator")) Sleep(10); HWND cWnd = ::FindWindow(0, "Calculator"); ::SendMessage(cWnd, WM_COMMAND, MAKEWPARAM(81, 1), 0);
HWND rtx; EnumChildWindows(cWnd, EnumChildProc, (LPARAM)&rtx);
for (int q=0; q<strlen((char*)calccmds); q++) { ::SendMessage(cWnd, WM_COMMAND, MAKEWPARAM(cmap[calccmds[q]], 1), 0); } ::SendMessage(rtx, WM_GETTEXT, 120, (LPARAM)calccmds); fout = atof((char*)calccmds);
CloseHandle(piProcessInfo.hProcess); CloseHandle(piProcessInfo.hThread); ::SendMessage(cWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
return true; } return false; };
|
|
-
-
Carnildo


- Joined on 03-30-2005
- Posts 742
|
Re: Post the function you are most proud of.
ishani:It's risky to start writing calculators 'from scratch' using all these fancy floating point arithmetic operators. Why would anyone write functions to do any kind of calculation when you can avoid reinventing the wheel all together? No arithmetic ops in my calculator, instead I chose to ...
Does your code handle results greater than 999? Google puts some funny formatting into the numbers it produces, and dealing with that is the purpose of the strip_spaces() function in my first submission:
static void perform_operation(double first_value, double second_value, int operation) { pcre *query_regex = NULL; char query_string[256]; char query_pattern[256]; query_string[255] = '\0'; query_pattern[255] = '\0';
/* Outsource the hard work to Google */
/* Build the calculation string */ switch(operation) { case BUTTON_PLUS: snprintf(query_string, 255, "http://www.google.com/search?q=%f+%%2B+%f", first_value, second_value); snprintf(query_pattern, 255, "<b>%f \\+ %f = ([-0-9.]+)</b>", first_value, second_value); break; case BUTTON_MINUS: snprintf(query_string, 255, "http://www.google.com/search?q=%f+%%2D+%f", first_value, second_value); snprintf(query_pattern, 255, "<b>%f - %f = ([-0-9.]+)</b>", first_value, second_value); break; case BUTTON_TIMES: snprintf(query_string, 255, "http://www.google.com/search?q=%f+%%2A+%f", first_value, second_value); snprintf(query_pattern, 255, "<b>%f \\* %f = ([-0-9.]+)</b>", first_value, second_value); break; case BUTTON_DIV: snprintf(query_string, 255, "http://www.google.com/search?q=%f+%%2F+%f", first_value, second_value); snprintf(query_pattern, 255, "<b>%f / %f = ([-0-9.]+)</b>", first_value, second_value); break; default: /* This is an error condition, but it can't happen */ gtk_entry_set_text(GTK_ENTRY(display_box), "++ Out of Cheese Error. Redo From Start. ++"); return; }
/* Perform the outsourcing */ query_results_counter = 0; curl_easy_setopt(transfer_handle, CURLOPT_URL, query_string); if(curl_easy_perform(transfer_handle) == 0) { int match_list[6]; int erroffset; const char *errptr;
/* Recover the result from the mess Google made of it */ strip_spaces(query_results); query_regex = pcre_compile(query_pattern, 0, &errptr, &erroffset, NULL); if(pcre_exec(query_regex, NULL, query_results, strlen(query_results), 0, 0, match_list, 6) == 2) { /* Success. Display the result */ pcre_copy_substring(query_results, match_list, 2, 1, query_string, 255); input_value = atof(query_string); } else { /* Either we divided by zero or Google changed their formatting on us. Panic. */ strcpy(query_string, "Err"); input_value = 0.0; } } else { /* Outsourcing failed */ strncpy(query_string, query_error_message, 255); input_value = 0.0; }
gtk_entry_set_text(GTK_ENTRY(display_box), query_string); }
|
|
-
-
ishani


- Joined on 05-09-2007
- Posts 2
|
Re: Post the function you are most proud of.
Dunno. It handles the largest numbers in the test cases, so QA is finished and the product is ready to ship! Anyway, it's entirely possible that the results of AskInternet are ignored by accident and overwritten with those coming in from AskWINCALC.
|
|
-
-
BsAtHome


- Joined on 05-15-2007
- Posts 15
|
Re: Post the function you are most proud of.
The whole calculator minus window setup...
static const char labels[] = "789+456-123*0C=/"; static GtkWidget *label; static char *formula; static int nformula; static int naformula; static char qaa[16]; static const unsigned qac[] = { 0x41c64e6d, 0x000000c5, 0x302404d4, 0x5313e203, 0x13034373, 0xd2549333, <more magic numbers> 0x00000022, 0xfb8c1c2b, 0x00000ffa, 0xfb8c1c2d, 0x00000310, 0x00003039 }; #define NQAC (sizeof(qac)/sizeof(qac[0])-1)
static void cb_doclick(GtkWidget *w, gpointer *p) { static unsigned qaq = 0; unsigned i; char ch; char buf[8]; char *cptr = buf; *cptr = '0'; buf[1] = 0; if(!p || !strchr(labels, ch = *(char *)p) || !w) { char c = w && p ? ch : 0; fprintf(stderr, "Unknown click response received '%c' (%02x)\n", isprint(c) ? c : ' ', c & 0xff); exit(1); } switch(ch) { case '=': for(i = 1; i < NQAC && qaq != qac[i]; i+=2); i %= NQAC; qaq = qac[++i]; do { *cptr++ = qaa[qaq & 0x0f]; } while((qaq >>= 4)); *cptr = 0; case 'C': gtk_entry_set_text(GTK_ENTRY(label), buf); nformula = qaq = 0; *formula = 0; break; default: if(naformula <= nformula+1) { naformula *= 2; formula = (char *)g_realloc(formula, naformula); } qaq = qaq * *qac + qac[NQAC] + (unsigned)ch; formula[nformula++] = ch; formula[nformula] = 0; gtk_entry_set_text(GTK_ENTRY(label), formula); break; } }
|
|
-
-
BsAtHome


- Joined on 05-15-2007
- Posts 15
|
Re: Post the function you are most proud of.
Division in ASCII BigEndian BCD and unlimited digits at either end of the decimal point in approx. O(4*2log(10)*(|n-m|+1)^2) {with n and m nr. of digits in l- and r-value}:
static void divide(node_t *l, node_t *r) { int nl, nr; int i, j; int s, f; char ch[2]; char *res, *c; ch[1] = 0; reduce(l); reduce(r); for(c = r->v; *c == '0'; c++); if(l->e || r->e || !*c) { l->e = 1; zap(r); return; } s = l->s ^ r->s; f = l->f - r->f; l->f = r->f = 0; reduce(l); reduce(r); nl = strlen(l->v); nr = strlen(r->v); while(nr >= nl || !f) { node_t *m = (node_t *)xmalloc(sizeof(*m)); m->v = xstrdup("01"); mult(l, m); nl = strlen(l->v); f++; } res = c = (char *)xmalloc(nl+f+2); *c++ = '0'; for(i = nl-nr; i >= 0; i--) { int delta = 4; int sign; for(j = 5; j > 0 && j <= 9; j += delta * sign, delta >>= 1) { node_t *m; node_t *n; node_t *o; node_t *p; int k; char *u = l->v; for(k = 0; *u; k += *u - '0', u++); if(!k) { j = 0; break; } m = (node_t *)xmalloc(sizeof(*m)); n = (node_t *)xmalloc(sizeof(*n)); o = (node_t *)xmalloc(sizeof(*o)); p = (node_t *)xmalloc(sizeof(*p)); m->v = xstrdup(l->v+i); n->v = xstrdup(r->v); *ch = j + '0'; o->v = xstrdup(ch); p->o = MULT; p->l = n; p->r = o; minus(m, p); if((sign = m->s ? -1 : 1) < 0) { zap(m); continue; } if(*m->v == '0' && !m->v[1]) { zap(m); l->v[i] = 0; break; } u = xstrdup(m->v); o = (node_t *)xmalloc(sizeof(*o)); o->v = xstrdup(r->v); minus(m, o); if(m->s) { strcpy(l->v+i, u); xfree(u); break; } xfree(u); zap(m); } if(j < 1) j = 0; *c++ = '0' + j; } zap(r); xfree(l->v); l->v = strrev(res); l->s = s; l->f = f; reduce(l); }
|
|
-
-
Remboooo


- Joined on 02-21-2006
- Posts 5
|
Re: Post the function you are most proud of.
ishani:
It's risky to start writing calculators
'from scratch' using all these fancy floating point arithmetic
operators. Why would anyone write functions to do any kind of
calculation when you can avoid reinventing the wheel all together? No
arithmetic ops in my calculator, instead I chose to ...
<code>
pff, that implementation is far too straightforward. here's mine:
// request to send to google (with two %g's that will be the two numbers used in the calculation)
const char googleRequest[] =
{0x47, 0x45, 0x54, 0x20, 0x2F, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x3F, 0x71, 0x3D, 0x25, 0x67,
0x25, 0x25, 0x32, 0x46, 0x25, 0x67, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D,
0x0A, 0x48, 0x6F, 0x73, 0x74, 0x3A, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x6F, 0x6F, 0x67, 0x6C,
0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F,
0x6E, 0x3A, 0x20, 0x63, 0x6C, 0x6F, 0x73, 0x65, 0x0D, 0x0A, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74,
0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x0D, 0x0A, 0x41, 0x63, 0x63,
0x65, 0x70, 0x74, 0x2D, 0x4C, 0x61, 0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3A, 0x20, 0x65, 0x6E,
0x2D, 0x75, 0x73, 0x3B, 0x71, 0x3D, 0x31, 0x2E, 0x30, 0x0D, 0x0A, 0x41, 0x63, 0x63, 0x65, 0x70,
0x74, 0x2D, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3A, 0x20, 0x49, 0x53, 0x4F, 0x2D, 0x38,
0x38, 0x35, 0x39, 0x2D, 0x31, 0x0D, 0x0A, 0x55, 0x73, 0x65, 0x72, 0x2D, 0x41, 0x67, 0x65, 0x6E,
0x74, 0x3A, 0x20, 0x4D, 0x6F, 0x7A, 0x69, 0x6C, 0x6C, 0x61, 0x2F, 0x35, 0x2E, 0x30, 0x20, 0x28,
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x3B, 0x20, 0x55, 0x3B, 0x20, 0x57, 0x69, 0x6E, 0x64,
0x6F, 0x77, 0x73, 0x20, 0x4E, 0x54, 0x20, 0x35, 0x2E, 0x31, 0x3B, 0x20, 0x6E, 0x6C, 0x3B, 0x20,
0x72, 0x76, 0x3A, 0x31, 0x2E, 0x38, 0x2E, 0x31, 0x2E, 0x33, 0x29, 0x20, 0x47, 0x65, 0x63, 0x6B,
0x6F, 0x2F, 0x32, 0x30, 0x30, 0x37, 0x30, 0x33, 0x30, 0x39, 0x20, 0x46, 0x69, 0x72, 0x65, 0x66,
0x6F, 0x78, 0x2F, 0x32, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x33, 0x0D, 0x0A, 0x0D, 0x0A};
// if we see this string, we know the result of the calculation will come after that
const char googleCalcSearchString[] =
{0x3C, 0x69, 0x6D, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3D, 0x2F, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x73,
0x2F, 0x63, 0x61, 0x6C, 0x63, 0x5F, 0x69, 0x6D, 0x67, 0x2E, 0x67, 0x69, 0x66, 0x20, 0x61, 0x6C,
0x74, 0x3D, 0x22, 0x22, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x74, 0x64, 0x3E, 0x26, 0x6E,
0x62, 0x73, 0x70, 0x3B, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x74, 0x64, 0x20, 0x6E, 0x6F, 0x77,
0x72, 0x61, 0x70, 0x3E, 0x3C, 0x68, 0x32, 0x20, 0x63, 0x6C, 0x61, 0x73, 0x73, 0x3D, 0x72, 0x3E,
0x3C, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3D, 0x2B, 0x31, 0x3E, 0x3C, 0x62,
0x3E};
float DoDiv(float op1, float op2, int &isErr)
{
// what this does is create a socket, and then connect to google to use the google calc to calculate the division for us
SOCKET s = socket(AF_INET, SOCK_STREAM, 0x00);
IF s isNotEqualTo INVALID_SOCKET THEN goto socketVerks;
isErr = 0x01;
return 0x00;
socketVerks:
HOSTENT *hEnt;
SOCKADDR_IN sAddr;
// resolve hostname
hEnt = gethostbyname("www.google.com");
// put IP in SOCKADDR_IN struct
sAddr.sin_family = AF_INET;
sAddr.sin_port = htons((u_short)0x50);
sAddr.sin_addr.S_un.S_un_b.s_b1 = hEnt->h_addr_list[0x00][0x00];
sAddr.sin_addr.S_un.S_un_b.s_b2 = hEnt->h_addr_list[0x00][0x01];
sAddr.sin_addr.S_un.S_un_b.s_b3 = hEnt->h_addr_list[0x00][0x02];
sAddr.sin_addr.S_un.S_un_b.s_b4 = hEnt->h_addr_list[0x00][0x03];
int sockretval;
// connect to www.google.com:80
IF connect(s, (SOCKADDR *)(&sAddr), sizeof(sAddr)) isNotEqualTo 0x00 THEN goto connectionFailed;
char queryString[0x1337];
int queryLen;
// make an HTTP/1.0 request
sprintf(queryString, googleRequest, op1, op2);
queryLen = 0x00;
calcQueryLen:
IF queryString[queryLen] isEqualTo 0x00 THEN goto queryLenFound;
queryLen = increaseIntByOne(queryLen);
goto calcQueryLen;
queryLenFound:
// send the request
int retVal;
retVal = send(s, queryString, queryLen, 0x00);
// 0x13337KB should be enough for everyone!
char recData[0x13337];
long recBytes = 0x00;
// fill recData with all received data until the connection closes
receiveData:
retVal = recv(s, &recData[recBytes], 0x01, 0x00);
//recBytes = DoAdd(recBytes, retVal);
recBytes = increaseIntByOne(recBytes);
IF retVal isGreaterThan 0 AND recBytes isLessThan 0x13337 THEN goto receiveData;
recData[recBytes] = 0x00;
// so now look for it in the received data
int startChar = 0x00;
int responseIterator;
int needleIterator;
bool found = false;
bool stop = false;
bool stopCompletely = false;
responseLoop1:
responseIterator = startChar;
needleIterator = 0x00;
found = true;
stop = false;
responseLoop2:
IF recData[responseIterator] isEqualTo googleCalcSearchString[needleIterator] THEN {
// if it matches, continue
needleIterator = increaseIntByOne(needleIterator);
responseIterator = increaseIntByOne(responseIterator);
} else {
IF googleCalcSearchString[needleIterator] isEqualTo 0x00 THEN {
// if we're at the end of the needle-string, it matched completely
found = true;
stop = true;
stopCompletely = true;
} else {
IF recData[responseIterator] isEqualTo 0x00 THEN {
// if we're at the end of the haystack, nothing matched
found = false;
stop = true;
stopCompletely = true;
} else {
// the string doesn't match with the substring of recData starting at startChar - continue looking
found = false;
stop = true;
}
}
}
IF NOT stop THEN goto responseLoop2;
startChar = increaseIntByOne(startChar);
IF NOT stopCompletely THEN goto responseLoop1;
// set the startchar for the next search to the location of the last char of the string we just searched for
startChar = responseIterator;
// if there is no calc, it is quite possible that the calculation started off with a division by zero.
// or something else might be screwed.
// anyhow, we won't have any result so it's a big fat ERR.
IF found THEN goto theImageStringWasFoundAmongstTheReceivedData;
isErr = 1;
return 0x00;
theImageStringWasFoundAmongstTheReceivedData:
// look for a ' =' (because a '=' could be inside some html tag)
findAnEqualToSignWithASpaceInFrontOfIt:
IF recData[startChar] isEqualTo 0x3D AND
recData[decreaseIntByOne(startChar)] isEqualTo 0x20 THEN goto
equalToSignWithASpaceInFrontIfItWasFound;
startChar = increaseIntByOne(startChar);
goto findAnEqualToSignWithASpaceInFrontOfIt;
equalToSignWithASpaceInFrontIfItWasFound:
// after the '=' comes a ' ' - skip over that
startChar = increaseIntByOne(increaseIntByOne(startChar));
int resultChars = 0x00;
char result[0x20];
bool insideTag = false;
// look for any numbers and/or points and comma's outside of tags
before we encounter a </b> , which marks the end of the result
// and slap them together in a de-formatted string
putTheResultFromGoogleInAStringAndRemoveAnyFormattingCrapThatMightHaveBeenPutIn:
// bloody google inserts formatting right in the middle of numbers! we need to fix this..
IF recData[startChar] isNotEqualTo 0x3C THEN goto thereIsNoLessThanSign;
insideTag = true;
thereIsNoLessThanSign:
IF recData[startChar] isNotEqualTo 0x3E THEN goto thereIsNoGreaterThanSign;
insideTag = false;
thereIsNoGreaterThanSign:
IF insideTag OR NOT ((recData[startChar] isEqualToOrGreaterThan
0x30 AND recData[startChar] isEqualToOrLessThan 0x39) OR
recData[startChar] isEqualTo 0x2E OR recData[startChar] isEqualTo 0x2C)
THEN goto thereIsNoCharacterThatShouldBeInTheResultString;
result[resultChars] = recData[startChar];
resultChars = increaseIntByOne(resultChars);
thereIsNoCharacterThatShouldBeInTheResultString:
IF recData[startChar] isEqualTo 0x62 AND
recData[decreaseIntByOne(startChar)] isEqualTo 0x2F AND
recData[decreaseIntByOne(decreaseIntByOne(startChar))] isEqualTo 0x3C
THEN goto resultFromGoogleWasSuccesfullyPutInAString;
startChar = increaseIntByOne(startChar);
goto putTheResultFromGoogleInAStringAndRemoveAnyFormattingCrapThatMightHaveBeenPutIn;
resultFromGoogleWasSuccesfullyPutInAString:
result[resultChars] = 0x00;
// so now we have a string which contains the result that google calc gave us! yay! now let's convert this to a float.
char resultChecker[0x80];
bool correctIntReached = false;
int resultInt = 0x00;
int resultCheckIterator;
bool decimalPointEncountered = false;
int placesFromDecimalPoint = 0x00;
int resultLen = 0x00;
char intResult[0x80];
int resultIntTimesTen = 0x00;
// do some converting stuff on the string
resultCheckIterator = 0x00;
doSomeConvertingStuff:
IF result[resultCheckIterator] isEqualTo 0x00 THEN goto someConvertingStuffDone;
IF result[resultCheckIterator] isNotEqualTo 0x2C THEN goto theCurrentCharacterIsNotAComma;
// damn those crazy Europeans and their decimal commas!
result[resultCheckIterator] = 0x2E;
theCurrentCharacterIsNotAComma:
IF NOT decimalPointEncountered THEN goto noDecimalPointEncountered;
placesFromDecimalPoint = increaseIntByOne(placesFromDecimalPoint);
noDecimalPointEncountered:
// restrict the number to 1 decimal, or else converting would take nearly forever!
IF placesFromDecimalPoint isNotEqualTo 0x02 THEN goto continueTruckin;
result[resultCheckIterator] = 0x00;
goto someConvertingStuffDone;
continueTruckin:
IF result[resultCheckIterator] isNotEqualTo 0x2E THEN goto noDecimalPointEncountered2;
decimalPointEncountered = true;
noDecimalPointEncountered2:
resultCheckIterator = increaseIntByOne(resultCheckIterator);
goto doSomeConvertingStuff;
someConvertingStuffDone:
// first loop until we've found an int that fits what comes before the decimal point of the result, because - guess what -
// those bloody floats are too goddamn imprecise to just count up to the result by going through a loop that adds 0.1 until
// it reaches the result
// first generate a string (intResult) that contains the answer minus the decimal point and anything after that
resultCheckIterator = 0x00;
generateIntResult:
IF result[resultCheckIterator] isEqualTo 0x00 OR result[resultCheckIterator] isEqualTo 0x2E THEN goto intResultGenerated;
intResult[resultCheckIterator] = result[resultCheckIterator];
resultCheckIterator = increaseIntByOne(resultCheckIterator);
goto generateIntResult;
intResultGenerated:
intResult[resultCheckIterator] = 0x00;
float resultFloat = 0.0f;
// now increase the int until its string-representation matches intResult
findIntPart:
sprintf(resultChecker, "%d", resultInt);
// compare the value of our resultChecker to the value before the decimal point returned by Google
// if it's a match, we have the integer part of the result!
resultCheckIterator = 0x00;
correctIntReached = true;
checkIntPart:
IF intResult[resultCheckIterator] isEqualTo 0x00 THEN goto intPartChecked;
correctIntReached &= (resultChecker[resultCheckIterator] isEqualTo result[resultCheckIterator]);
resultCheckIterator = increaseIntByOne(resultCheckIterator);
goto checkIntPart;
intPartChecked:
IF correctIntReached THEN goto intPartFound;
// this wasn't the result that was returned by google. Increase by 1 and try again!
resultInt = increaseIntByOne(resultInt);
resultFloat = increaseFloatByOne(resultFloat);
resultIntTimesTen =
increaseIntByOne(
increaseIntByOne(
increaseIntByOne(
increaseIntByOne(
increaseIntByOne(
increaseIntByOne(
increaseIntByOne(
increaseIntByOne(
increaseIntByOne(
increaseIntByOne(
resultIntTimesTen
)
)
)
)
)
)
)
)
)
);
goto findIntPart;
intPartFound:
// Now we can start finding what comes after the decimal point
resultInt = resultIntTimesTen;
correctIntReached = false;
findDecimalPart:
sprintf(resultChecker, "%d ", resultInt);
// divide the value in the string by ten, because for some reason ints can only contain integer values
resultLen = 0x00;
findTheEndOfResultChecker:
IF resultChecker[resultLen] isEqualTo 0x20 THEN goto endOfResultCheckerFound;
resultLen = increaseIntByOne(resultLen);
goto findTheEndOfResultChecker;
endOfResultCheckerFound:
resultChecker[resultLen] = resultChecker[decreaseIntByOne(resultLen)];
resultChecker[decreaseIntByOne(resultLen)] = 0x2E;
// if the value behind the decimal point is a 0, it obviously won't be in the string returned by google, so chop it off
IF resultChecker[resultLen] isNotEqualTo 0x30 THEN goto dontChopTheDecimalPartBecauseItIsntZero;
resultChecker[decreaseIntByOne(resultLen)] = 0x00;
dontChopTheDecimalPartBecauseItIsntZero:
// if there's no value before the decimal point, add a 0 up front (because that's what google does!)
IF resultChecker[0] isNotEqualTo 0x2E AND resultChecker[0] isNotEqualTo 0x00 THEN goto dontAddAZeroUpFront;
resultChecker[0x03] = resultChecker[0x02];
resultChecker[0x02] = resultChecker[0x01];
resultChecker[0x01] = resultChecker[0x00];
resultChecker[0x00] = 0x30;
dontAddAZeroUpFront:
correctIntReached = true;
// compare the value of our resultChecker to the value returned by
Google - if it's a match, we now what the result of the division is!
resultCheckIterator = 0x00;
checkDecimalPart:
IF result[resultCheckIterator] isEqualTo 0x00 THEN goto decimalPartChecked;
correctIntReached &= (resultChecker[resultCheckIterator] isEqualTo result[resultCheckIterator]);
resultCheckIterator = increaseIntByOne(resultCheckIterator);
goto checkDecimalPart;
decimalPartChecked:
IF correctIntReached THEN goto decimalPartFound;
// this wasn't the result that was returned by google. Increase by 0.1 and try again!
resultInt = increaseIntByOne(resultInt);
resultFloat = increaseFloatByPointOne(resultFloat);
goto findDecimalPart;
decimalPartFound:
// let's release our 32 bits of pure google-ated pleasure into the world \\o/
return resultFloat;
connectionFailed:
// no connection = no calculation :(
isErr = 0x01;
return 0x00;
}
*praying the codetag actually works..
|
|
-
-
Corsix


- Joined on 05-15-2007
- Posts 1
|
Re: Post the function you are most proud of.
Background for my code: Company policy is to avoid slow operators (eg + - / = * < >) and use only fast operators (>>= <<= ^=) Valid operators: ( ) >>= <<= ^= , [ ] -> . Invalid operators: all others, including: + - = / * & | && || -- ++ == != < > <= >= %
Some of the re-invented arithmatic functions, using only the allowed operators: /* Returns true when the highest bit set in B is also the highest bit set in N */ bool is_bit_set(unsigned long N, unsigned long B) { B >>= 1; while(B) { N >>= 1; B >>= 1; } return N; }
/* Returns true if A < B. If A == B, returns return_value_on_equal */ int is_A_less_than_B(unsigned long A, unsigned long B, int return_value_on_equal) { unsigned long iMask; iMask ^= iMask; iMask ^= 1; iMask <<= 31; // begin on highest bit while(iMask) { if(is_bit_set(A, iMask)) { if(is_bit_set(B, iMask)) {} else { // set in A, not set in B, hence A > B return 0; } } if(is_bit_set(B, iMask)) { if(is_bit_set(A, iMask)) { A ^= iMask; // turn the bit off in A, for is_bit_set to work in future } else { // set in B, not set in A, hence A < B return 1; } B ^= iMask; // turn the bit off in B, for is_bit_set to work in future } iMask >>= 1; // move to next bit } return return_value_on_equal; // every bit has been tested, and every bit has been found to be the same }
/* Returns true if A >= B */ inline int is_A_greater_than_or_equal_to_B(unsigned long A, unsigned long B) { if(is_A_less_than_B(A,B,0)) return 0; return 1; }
/* As ^ is not allowed, xor must be implemented with ^= */ inline unsigned long xor(unsigned long A, unsigned long B) { unsigned long R; R ^= R; R ^= A; R ^= B; return R; }
/* Returns the result of A + B */ unsigned long add_A_to_B(unsigned long A, unsigned long B) { unsigned long iMask; iMask ^= iMask; iMask ^= 1; iMask <<= 31; // begin with the highest bit while(iMask) { if(is_bit_set(B, iMask)) // If this bit is set in B { B ^= iMask; // turn the bit off for is_bit_set to work in future while(is_A_less_than_B(xor(A,iMask), A,0)) // while the bit is set in A ( A^Mask < A if Mask is set in A) { A ^= iMask; // we cannot set the bit on, so turn it off iMask <<= 1; // and move onto the next bit (-n+2n == +n) } A ^= iMask; // turn the bit on in A } iMask >>= 1; // move onto the next bit } return A; } Other bits I like: /* Inline functions to increment and decrement a variable (notice the tiny difference between the two) Important: will not work when var is called i */ #define increment(var) {unsigned long i = 1; while(is_A_less_than_B( xor(var,(i)),var ,0)) {var ^= i; i <<= 1;} var ^= i;} #define decrement(var) {unsigned long i = 1; while(is_A_less_than_B( var,xor((i) ,var),0)) {var ^= i; i <<= 1;} var ^= i;}
template <class T> struct assignment { assignment(typename std::vector<T>::reference dst, typename std::vector<T>::const_reference src) { std::vector<unsigned long>::reference dst2( (std::vector<unsigned long>::reference) dst ); std::vector<unsigned long>::const_reference src2( (std::vector<unsigned long>::const_reference) src );
dst2 ^= dst2; dst2 ^= src2;
delete this; } };
|
|
-
-
Atrophy


- Joined on 02-28-2007
- Posts 46
|
Re: Post the function you are most proud of.
Mine implemented the grade school algorithms for everything... long division was especially fun.
I appologize for what you're about to see...
float Plus(float op1, float op2){ /* // LONG ADDITION ALGORITHM // REMEMBER TO CARRY THE 1!!! 1: MOVE FROM RIGHT TO LEFT THROUGH THE STRINGS 2: LOOP WHILE THERE ARE MORE DIGITS LEFT 3: GET THE DIGITS FROM BOTH OPERANDS AT THE POINTER POSITION 4: ADD THOSE DIGITS TO GET TEMPANS. IF CARRY = 1, ADD CARRY TO THE ANSWER. 5: IF THE ANSWER TEMPANS IS MORE THAN 10, SUBTRACT 10, AND SET CARRY TO 1 6: APPEND THE ANSWER TO #5 TO THE BEGINNING OF THE ANSWER STRING 7: INCREMENT POINTER 8: LOOP 9: CONVERT THE ANSWER TO A FLOAT */ string num1 = floatToString(op1); string num2 = floatToString(op2); int x = 0; int y = 0; float temp = 0; float carry = 0; string answer = ""; //IF NUM2 IS SHORTER THAN NUM1 WE NEED TO FIX IT while (num2.size() < num1.size()){ num2 = "0" + num2; } // End while int pos = num1.size()-1; while (pos >= 0){ x = int(stringToFloat(num1.substr(pos,1))); y = int(stringToFloat(num2.substr(pos,1))); temp = x + y + carry; if (temp > 9){ temp -= 10; carry = 1; } else { carry = 0; } // End if answer = floatToString(temp) + answer; pos--; } // End while if (carry == 1) { answer = "1" + answer; } // End if return stringToFloat(answer); } // End function float Minus(float op1, float op2){ /* // LONG SUBTRACTION ALGORITHM // REMEMBER TO BORROW WHEN NECESSARY! 1: TRAVERSE THE STRING FROM RIGHT TO LEFT 2: IF OP2 > OP1, SET NEG = TRUE AND SWITCH OP1 AND OP2 2: LOOP WHILE THERE ARE MORE DIGITS LEFT 3: GET THE DIGITS FROM BOTH OPERANDS AT THE POINTER POSITION 4: IF TEMPOP2 > (TEMPOP1-BORROW), WE HAVE TO BORROW. SET BORROW TO 1 AND ADD 10 TO TEMPOP1 5: SUBTRACT TEMPOP2 FROM TEMPOP1 6: APPEND THE ANSWER TO #5 TO THE ANSWER STRING 7: INCREMENT POINTER 8: LOOP 9: CONVERT THE ANSWER TO A FLOAT 10: IF NEG THEN SUBTRACT ANSWER FROM 0 TO GET FINAL ANSWER */ float temp = 0; bool borrow = false; bool neg = false; if ( op2 > op1){ temp = op1; op1 = op2; op2 = temp; neg = true; } // End if string num1 = floatToString(op1); string num2 = floatToString(op2); string answer = ""; //IF NUM2 IS SHORTER THAN NUM1 WE NEED TO FIX IT while (num2.size() < num1.size()){ num2 = "0" + num2; } // End while int pos = num1.size()-1; int x = 0; int y = 0; while (pos >= 0){ x = stringToInt(num1.substr(pos,1)); y = stringToInt(num2.substr(pos,1)); if (borrow){ x -= 1; } // End if if (y > x){ borrow = true; x += 10; } else { borrow = false; } // End if x = x - y; answer = intToString(x) + answer; pos -= 1; } // End while float final = stringToFloat(answer); if (neg) { final = 0 - final; }// End if return final; } // End function float Times(float op1, float op2){ /* // LONG MULTIPLICATION ALGORITHM: 1: LOOP WHILE THERE ARE MORE DIGITS IN OP1 2: GET NEXT DIGIT OF OP1 * PLACE VALUE OF THAT DIGIT 3: LOOP WHILE THERE ARE MORE DIGITS IN OP2 4: MULTIPLY NEXT DIGIT OF OP2 BY ANSWER TO #2 AND BY PLACE VALUE OF THAT DIGIT) 5: ADD ANSWER TO #4 TO TOTAL 6: LOOP 7: LOOP */ string num1 = floatToString(op1); string num2 = floatToString(op2); int x = 0; int y = 0; float total = 0; int xp = 0; float xm = 0; float xt = 0; int yp = 0; float ym = 0; float yt = 0; while (x < num1.size()){ xp = num1.size() - x - 1; xm = pow(10.0,xp); xt = stringToFloat(num1.substr(x,1)) * xm; while (y < num2.size()){ yp = num2.size() - y - 1; ym = pow(10.0,yp); yt = stringToFloat(num2.substr(y,1)) * ym; //GO FORTH AND MULTIPLY!!! total += (xt * yt); y++; } // End Inner while y = 0; x++; } // End while return total; } // End function float Into(float op1, float op2, int *isErr){ /* // LONG DIVISION ALGORITHM // REMEMBER TO PAD OP1 WITH .00 AT THE END!!! 1: SET POINTER VARIABLE TO 1 2: LOOP WHILE LESS THAN 2 DECIMAL POINTS 2: SET TEMP VARIABLE TO TEMP VARIABLE CONCATENATED WITH DIGIT AT POINTER 3: DIVIDE TEMP VARIABLE BY OP2, AND TRUNCATE AFTER DECIMAL TO GET DIGIT FOR ANSWER 4: ADD ANSWER DIGIT TO ANSWER 5: MULTIPLY ANSWER DIGIT BY OP2 AND SUBTRACT FROM TEMP VARIABLE 6: INCREMENT POINTER TO NEXT POSITION 7: END LOOP 8: CONVERT ANSWER TO FLOAT */ if (op2 == 0) { *isErr = 1; return 0; } else { string num1 = floatToString(op1) + "00"; int num2 = int(op2); string tempOp = ""; int multiplier = 0; string remainder = ""; int pos = 0; string answer = ""; while(pos < num1.size()){ tempOp += num1.substr(pos,1); multiplier = int(stringToFloat(tempOp) / num2); answer += intToString(multiplier); if(answer.size() == floatToString(op1).size()){ answer += "."; } // End if tempOp = floatToString(stringToFloat(tempOp) - (num2 * multiplier)); pos += 1; } // End while return stringToFloat(answer); } // End if return 0; } // End function
|
|
-
-
todd


- Joined on 04-29-2007
- Posts 9
|
Re: Post the function you are most proud of.
I did as well, cracked open TAOCP and implemented the classical addition/subtraction/multiplication algorithms. I cheated on the division and used Newton's method to find 1/n and then multiply. Here's the multiplication code:
for (int j = 0; j < n; ++j) { NQueen k = 0; for (int i = 0; i < n; ++i) { NQueen tmp = (m_val[i] - '0') * (right.m_val[j] - '0') + w[2*n-(i+j)-1] + k; w[2*n-(i+j)-1] = tmp; while (w[2*n-(i+j)-1] >= 10) w[2*n-(i+j)-1] -= 10; while (w[2*n-(i+j)-1] < 0) w[2*n-(i+j)-1] += 10;
k = NQueen(floor(tmp.boardSize()/10.0)); } w[2*n-(j+n)-1] = k; } NQueen is the type used to represent the digits in the arbitrary precision arithmetic library. Each digit 0-9 is represented by an NxN chessboard with N queens placed such that none of them is able to capture any other using the standard chess queen's moves (http://en.wikipedia.org/wiki/Nqueens) where N is the ASCII character code for the digit. So the number "123" is represented by a 49x49 board with 49 queens, a 50x50 board with 50 queens, and a 51x51 board with 51 queens.
|
|
-
-
groovy2shoes


- Joined on 05-15-2007
- Posts 2
|
Re: Post the function you are most proud of.
// play barry white integer play_barry_white(char *song) { }
|
|
-
-
Einsidler


- Joined on 11-15-2006
- Posts 99
|
Re: Post the function you are most proud of.
Since all the cool kids are doing it, here's the underlying function of my calculator: // Convert an integer to roman numerals char *ToRoman(int input) { char str[RN_MAX_LENGTH] = ""; int number = input; if (number == 0) { strcat(str,"N"); } if (number < 0) { strcat(str,"-"); number *= -1; }
while (number >= 1000) { strcat(str,"M"); number -= 1000; } while (number >= 500) { strcat(str,"D"); number -= 500; } while (number >= 100) { strcat(str,"C"); number -= 100; } while (number >= 50) { strcat(str,"L"); number -= 50; } while (number >= 10) { strcat(str,"X"); number -= 10; } while (number >= 5) { strcat(str,"V"); number -= 5; } while (number >= 1) { strcat(str,"I"); number -= 1; } char *str2 = AddSubNot(str); return str2; } Roman arithmetic was really interesting to work with.
Download my OMGWTF entry, Romanorum Computus
|
|
-
-
phaedrus


- Joined on 03-20-2007
- Seattle Ex-Pat living in the Bay Area
- Posts 111
|
Re: Post the function you are most proud of.
Einsidler:Since all the cool kids are doing it, here's the underlying function of my calculator: // Convert an integer to roman numerals char *ToRoman(int input) { char str[RN_MAX_LENGTH] = ""; int number = input; if (number == 0) { strcat(str,"N"); } if (number < 0) { strcat(str,"-"); number *= -1; }
while (number >= 1000) { strcat(str,"M"); number -= 1000; } while (number >= 500) { strcat(str,"D"); number -= 500; }
My eyes skipped the comment above. I got to here before it hit me. "Why the h@#$ would he be using "M" and "D" string con...BWAHAHAHAHAHA!" That's great.
All men are frauds. The only difference between them is that some admit it. I myself deny it. -- H. L. Mencken
|
|
-
-
phaedrus


- Joined on 03-20-2007
- Seattle Ex-Pat living in the Bay Area
- Posts 111
|
Re: Post the function you are most proud of.
wotnarg:I'll let you think about what went on ;) Final note: it involved ternary logic and COMEFROM.
Dude, INTERCAL? What were you thinking? That was my idea first, anyway. I can't believe the judges got two INTERCAL based entries.
All men are frauds. The only difference between them is that some admit it. I myself deny it. -- H. L. Mencken
|
|
-
-
Charles Nadolski


- Joined on 03-25-2005
- Chicago
- Posts 166
|
Re: Post the function you are most proud of.
Well, it looks like other people's submissions blew mine out of the water, but I'm sure it will make some among you groan. I implemented the addition of fractions using assembly with SSE2 extensions (took forever to look it up on the intel website). Oh, for extra special tasty WTF all the fraction data was stored into bitfields. 31 bits for numerator and denominator respectively, and 2 bits for signage. I had three signs: Positive, Negative, and DivideByZero.
Fraction Fraction::operator +(Fraction &other) { //Time to speed this puppy up. Adding fractions in C++ is just way too slow. Go go gadget INLINE! int nDenominator,nNumerator; int nThisNumerator = m_data.Numerator; int nOtherNumerator = other.m_data.Numerator; int nThisDenominator = m_data.Denominator; int nOtherDenominator = other.m_data.Denominator; short sThisSignage = m_data.Signage; short sOtherSignage = other.m_data.Signage; __asm { PUSHAD MOV eax,nThisDenominator IMUL eax,nOtherDenominator; MOV nDenominator,eax
MOVD XMM0,nThisNumerator PSLLDQ XMM0,8 PINSRW XMM0,nOtherNumerator,0 PINSRW XMM0,nOtherNumerator+2,1 MOVD XMM1,nOtherDenominator PSLLDQ XMM1,8 PINSRW XMM1,nThisDenominator,0 PINSRW XMM1,nThisDenominator+2,1
PMULUDQ XMM0,XMM1
MOVD ebx,XMM0 PSRLDQ XMM0,8 MOVD eax,XMM0
CMP sThisSignage,Negative JE ThisNegative CMP sOtherSignage,Negative JE OtherNegative
ADD eax,ebx MOV nNumerator,eax JMP ExitAdd ThisNegative: SUB ebx,eax MOV nNumerator,ebx JMP ExitAdd OtherNegative: SUB eax,ebx MOV nNumerator,eax JMP ExitAdd ExitAdd: POPAD }
return Fraction(nNumerator, nDenominator); }
|
|
-
-
jlahd


- Joined on 05-16-2007
- Posts 1
|
Re: Post the function you are most proud of.
Hi,
I don't really understand how most of you get away with a buch of hard-coded values.
int ClaculatorOperation::digit_to_numeric( char digit ) { if( digit == claculator_constant_digit_0[claculator_constant_zero] ) { return claculator_constant_zero; } if( digit == claculator_constant_digit_1[claculator_constant_zero] ) { return claculator_constant_one; } if( digit == claculator_constant_digit_2[claculator_constant_zero] ) { return claculator_constant_two; } [...] if( digit == claculator_constant_digit_9[claculator_constant_zero] ) { return claculator_constant_nine; } return claculator_constant_minus_one; }
(no, actually that's not the function I'm most proud of, but it illustrates the point of named constants)
I mean, you never know when the value of zero is going to change! So, better place the constants in registry so that they can be changed even as the program runs.
|
|
-
-
Jarvix


- Joined on 04-29-2007
- Alberta, Canada
- Posts 3
|
Re: Post the function you are most proud of.
Instead of trying to make an insanely complicated solution like many here did, I planned for a calculator with an expression parser that obeyed proper operator precendence in a fully OOP way. Then I proceeded to turn my brain off (as much as possible) before writing any code.
This is the heart of the expression parser in its final, optimized form (also the most commented section of my code). Although I really did try to get proper operator precendence working in this way, I just couldn't throw any more code at this to make it work right. So, since it passed all test cases, it's finished.
void ExpressionParser::Eval()
{
signed long num1, num2;
char *oldExpression, *newExpression, operand;
long oldLength, newLength;
// All 'decimal' stuff are bugfixes for cases WTF114 & WTF120
bool more, moreOperands, decimal;
// Order of operands here is the order they will be parsed in
// making '*' & '/' have greater importance than '+' & '-'
char operands[] = {'*', '/', '-', '+'};
for ( int x = 0; x < 4; x++ ) {
moreOperands = false;
newExpression = new char[30];
newLength = 0;
oldExpression = expression;
oldLength = length;
position = 0;
more = GetNumber( &num1 );
while ( more ) {
decimal = false;
operand = expression[position];
position++;
more = GetNumber( &num2 );
expression = newExpression;
length = newLength;
if ( operand == operands[x] ) {
switch ( operands[x] ) {
case '+':
num1 += num2;
break;
case '-':
num1 -= num2;
break;
case '*':
num1 *= num2;
break;
case '/':
// ERR_DIV_ZERO bugfix for case WTF105
if ( num2 == 0 ) throw ERR_DIV_ZERO;
if ( ((num1*10)/num2)%10 ) {
num1 *= 10;
num1 /= num2;
decimal = true;
} else num1 /= num2;
break;
}
AddTo( NumberToText( num1, decimal ) );
} else {
if ( length == 0 ) AddTo( NumberToText( num1, false ) );
AddTo( operand );
AddTo( NumberToText( num2, false ) );
moreOperands = true;
}
newLength = length;
expression = oldExpression;
length = oldLength;
}
expression = newExpression;
length = newLength;
if ( !moreOperands ) return;
}
}
Due to its design, this function typically spits out strange results if you try to string multiple operations together. Oh, and entering an expression over 30 characters long is the only guaranteed way of making the calculator go away.
|
|
-
-
Domster


- Joined on 06-29-2006
- Posts 5
|
Re: Post the function you are most proud of.
Chemisor:
First of all, yep, Thuktun, Q/Robinson arithmetic is incomplete. So, it can be consistent and still fit with Gödel's incompleteness theorem. Just to give you an idea of why it's weak: it has no induction axiom such as the one in Peano arithmetic. So, while you can prove any fact about concrete numbers (2 + 3 = 5), you can't prove a general fact about all numbers (x + 2 = the successor to the successor to x). Chemisor, I'm utterly unconvinced by your arguments against GIT. First, you raise the spectre of some "law of identity", without defining it. Generally, identity is treated as a specific, but not special, two-place predicate in formal systems. Then you use this law to define contradiction. And, curiously, you define contradiction by using contradiction (a statement contradicting the "law of identity" is a contradiction). So, at best you're begging the question. Perhaps I should just say that Gödel isn't proposing "ultimate limits to [...] knowledge" as you claim. The incompleteness theorem shouldn't be taken out of the formal systems it is defined in - doing so, as you show, leads to truism and sophistry. If you take an argument out of the boundaries within which it is supposed to apply, then all you have done is set up a straw man to knock down.
|
|
-
-
Chemisor


- Joined on 03-24-2005
- Posts 19
|
Re: Post the function you are most proud of.
Domster:Chemisor, I'm utterly unconvinced by your arguments against GIT. First, you raise the spectre of some "law of identity", without defining it. Generally, identity is treated as a specific, but not special, two-place predicate in formal systems. Then you use this law to define contradiction. And, curiously, you define contradiction by using contradiction (a statement contradicting the "law of identity" is a contradiction). So, at best you're begging the question. The law of identity states that a thing is itself; it can not also be something else at the same time. A ball can either be all black or all white, but not both at once. You might think of this as a kind of a definition of reality, a simple assertion that a thing can exist. As for my definition of contradiction; well, not being a professional metaphysicist I am naturally not as eloquent when I come to the limits of language. A contradiction may also be viewed as something that can not exist, by definition of reality, and so I am inclined to treat both the law of identity and the concept of contradiction as being essentially the same thing - a definition of the fundamental property of things that exist. Again, not being a metaphysicist, it is hard for me to be clearer.
Domster:Perhaps I should just say that Gödel isn't proposing "ultimate limits to [...] knowledge" as you claim. The incompleteness theorem shouldn't be taken out of the formal systems it is defined in - doing so, as you show, leads to truism and sophistry. If you take an argument out of the boundaries within which it is supposed to apply, then all you have done is set up a straw man to knock down.
Since I have never met Godel, I can not be certain what he was or was not proposing. The theorem itself is purely mathematical in nature and mathematicians generally have no interest in applying their findings to the real world directly. However, the "ultimate limit to knowledge" is how Godel's theorem is always interpreted outside of the field, and as this interpretation is used to justify many revolting things, I believe my argument can only be a straw man to real mathematicians.
|
|
-
-
Massimo


- Joined on 04-25-2007
- Posts 84
|
Re: Post the function you are most proud of.
Chemisor:A contradiction may also be viewed as something that can not exist, by definition of reality
By definition of "reality", everything that exists is part of it. So, if you find that someone you think shouldn't be existing does, indeed, exist, then this means your notion of "reality" needs to be expanded to include it.
|
|
-
-
ashelly


- Joined on 05-15-2007
- Posts 2
|
Re: Post the function you are most proud of.
jlahd wrote the following post at 05-16-2007 12:35 AM> Hi, > > I don't really understand how most of you get away with a buch of hard-coded values. >... >if( digit == claculator_constant_digit_0[claculator_constant_zero] )
And yet even you are using numbers in your source. Numbers are so not OO. I made sure not to use any any instances of the ascii characters forty-eight through fifty-seven in my code:
virtual Number* Eight::inverse() { return new DecimalNumber(new MultidigitNumber(new One, new MultidigitNumber(new Two, new Five))); }
|
|
-
-
asuffield


- Joined on 05-31-2006
- Posts 2,137
|
Re: Post the function you are most proud of.
Chemisor:The law of identity states that a thing is itself; it can not also be something else at the same time. A ball can either be all black or all white, but not both at once. You might think of this as a kind of a definition of reality, a simple assertion that a thing can exist.
For the record, quantum physics declares this 'law' to be false. A quantum system has multiple mutually-exclusive properties at once; this is a rough definition of the term "superposition", and is the fundamental basis of quantum physics. This does have directly observable effects in the real world, and even though some parts of quantum theory are still unproven, this is not one of them. Superpositions are a fundamental part of reality. Quantum computing could not possibly function without this - operating on variables with multiple values is the whole point of it (using the universe as a kind of SIMD processor).
|
|
-
-
buggy


- Joined on 05-09-2007
- Posts 5
|
Re: Post the function you are most proud of.
I do not think I will win, but I am fond of the following:
long CompareTwoStringsToSeeIfTheyAreTheSame(char * str1)
{
char v = 0;
char *str = "test string";
v = 0;
long r = D_TRUE;
for (v = 0; ;v++)
{
if (str1[v] == FILENOTFOUND && (*(srt + v) == FILENOTFOUND)
)return D_TRUE;
if (str1[v] + *(srt + v) != str1[v] * 2)
return false;
r = r && (str[v] == srt[v]);
}
return FILENOTFOUND;
}
|
|
-
-
EvanED


- Joined on 08-22-2005
- Posts 114
|
Re: Post the function you are most proud of.
ishani: while(!::FindWindow(0, "Calculator")) Sleep(10); HWND cWnd = ::FindWindow(0, "Calculator");
You know, I was about to ask why you didn't just write
HWND cWnd;
while(! (cWnd = ::FindWindow(0, "Calculator")) ) Sleep(10);
but then the fact that this is OMGWTF hit me.
|
|
-
-
HisOoziness


- Joined on 05-16-2007
- Posts 1
|
Re: Post the function you are most proud of.
Wow, some of the stuff posted here is pretty fucked up. My entry doesn't come close, but I think that my WinMain is pretty close. It receives a function pointer as a command line argument and executes it. Below the highlights:
if (arg) { printf("Running superfork\n"); void (*run)()=(void (*)())atoi(arg); run(); } else { startup(); }
|
|
-
-
Massimo


- Joined on 04-25-2007
- Posts 84
|
Re: Post the function you are most proud of.
This is from my second entry. But I'm definitely more proud of that new(this) thing ;-)
/* Ok, here's some Real Magic(TM). */ /* Everyone knows programs run faster if using ASM, right? Let's use it, then. */ /* But we don't trust inline assembly, so let's store our own routine in memory and call it via cast to a good old function pointer. */
/* First of all, the routine we'll use as our starting point:
------------------------------- double f(double op1,double op2) { return(op1 + op2); } -------------------------------
As anyone should have guessed, it only adds; no problem, we'll patch it later. */
/* This is the resulting assembly code: push ebp mov ebp,esp sub esp,40h push ebx push esi push edi fld qword ptr [op1] fadd qword ptr [op2] pop edi pop esi pop ebx mov esp,ebp pop ebp ret
There's a lot of stack manipulation going on here, but this is unavoidable, otherwise we just wouldn't be able to do a function call :-( */
/* This is the hex dump of the routine; please note that ptr[op1] gets converted to ptr [ebp + 8], as that resides on the stack; the same is true for ptr[op2] which becomes ptr [ebp + 10].
55 8B EC 83 EC 40 53 56 57 DD 45 08 DC 45 10 5F 5E 5B 8B E5 5D C3 */
/* Now let's arrange it in such a way we can store those values in 32-bit ints:
55 8B EC 83 EC 40 53 56 57 DD 45 08 DC 45 10 5F 5E 5B 8B E5 5D C3 90 90 */
/* Finally, we need to reverse the bytes in each of the ints, due to the absurd memory architecture of Intel CPUs:
83EC8B55 565340EC 0845DD57 5F1045DC E58B5B5E 9090C3D5 */
int ASMCode[] = { 0x83EC8B55, 0x565340EC, 0x0845DD57, 0x5F1045DC, 0xE58B5B5E, 0x9090C35D };
/* Now, as promised, here comes the Real Magic(TM)... */ /* Seen that 45 in the 4th row? That's the hex opcode for FADD; if we change that at runtime to FSUB, FMUL or FDIV, we won't need three more functions, and that's a Good Thing (TM) */ /* Let's store its offset (in bytes) for future use: */
int MagicOffset = 13;
/* Here's the function pointer we'll use to call the ASM code; we make it point to the real code through an absolutely ugly (but effectively effective) cast: */
double(*Execute)(double,double) = reinterpret_cast<double(*)(double,double)>(&ASMCode);
/* This is the function that will patch the executable code at runtime; it *won't* be able to manage any error condition, so, if by chance it gets passed a wrong operator, it will make the program explode */
void Patch(char operation) { /* We need to cast the pointer to char*, otherwise we wouldn't be able to manipulate single bytes; too bad there isn't a byte type in C++! */
char* p = reinterpret_cast<char*>(&ASMCode);
switch(operation) { case '+': p[MagicOffset] = 0x45; // FADD break; case '-': p[MagicOffset] = 0x65; // FSUB break; case '*': p[MagicOffset] = 0x4D; // FMUL break; case '/': p[MagicOffset] = 0x75; // FDIV break; default: exit(42); // OUCH!!! }
return; }
/* Here's the main code; we'll also need to check for division by 0 here, since our routine doesn't manage it: it would have made the division function need error checking, but that would have meant using different code for that function, destroying the whole schema */
char* DoOperation(char operation,char* op1,char* op2,bool& err) { static char result[256];
double dop1 = atof(op1); double dop2 = atof(op2); double r = 0; switch(operation) { case '/': if(dop2 == 0) { err = true; break; } case '+': case '-': case '*': Patch(operation); r = (*Execute)(dop1,dop2); break; default: r = dop2; } if(!err) sprintf(result,"%g",r); else sprintf(result,"%s","Err"); return(result); }
|
|
-
-
JCM


- Joined on 03-16-2006
- Posts 23
|
Re: Post the function you are most proud of.
I kinda liked this one...
void MultiplyFloat(float *a,
float *b,
float *product)
{
int c;
unsigned char l= -32;
unsigned char o= 1;
unsigned char z=0;
unsigned char y= 0;
unsigned char x= 17;
unsigned char bias= 0x7F;
unsigned char minusBias= -0x7F;
unsigned long X[2];
struct Parts A, B, P;
union Bits prodBits;
*product= 0;
if((*a != 0) && (*b != 0))
{
SplitFloat(a, &A);
SplitFloat(b, &B);
// if the numbers are normallized, then we need to add the "1" that's to
// the left of the decimal place.
A.F= A.F | (((A.E != 0) && (A.E != 0xFF)) ? 0x00800000 : 0x00000000);
B.F= B.F | (((B.E != 0) && (B.E != 0xFF)) ? 0x00800000 : 0x00000000);
// multiply the two 24-bit mantissas
MultiplyLong(&A.F, &B.F, X);
// put the 24-bit product result back together from the 64-bit
// result from MultiplyLong()
while((X[1] & 0x80000000) == 0)
{
X[1]= (X[1] << 1);
c=0; AddByte(&z, &o, &c, &z, &c); // increment z
}
c= 0; AddByte(&z, &l, &c, &y, &c); // we really want (32-z)
P.F= (X[1] | (X[0] >> y)) >> 8; // this is the mantissa value
// unbias the exponenets
c= 0; AddByte(&A.E, &minusBias, &c, &A.E, &c);
c= 0; AddByte(&B.E, &minusBias, &c, &B.E, &c);
// add the exponents together
c= 0; AddByte(&A.E, &B.E, &c, &P.E, &c);
// need to add the difference between 17 and z to the exponent to
// account for X values (products) that are wider than 48 bits
z= ~z;
c= 1; AddByte(&x, &z, &c, &z, &c);
c= 0; AddByte(&P.E, &z, &c, &P.E, &c);
// re-bias the exponents
c= 0; AddByte(&P.E, &bias, &c, &P.E, &c);
// the product is negative if *one* of the values is negative
P.S= (A.S != B.S);
// put the floating point number back together and store it in the
// final location
prodBits.P= (P.S << 31) | (P.E << 23) | (P.F & 0x7FFFFF);
*product= prodBits.N;
}
}
I also thought that DivideLong() was clever...
void DivideLong(unsigned long *a,
unsigned long *b,
unsigned long *quotient,
unsigned char *n)
{
// if *b is zero, we can't divide!
if(*b != 0)
{
unsigned char i= 0;
unsigned char o= 1;
int c= 0;
int counting= 1;
unsigned long x= *a; // make a local copy so we don't destroy the
// pointer contents!
*quotient= 0;
// go around this loop a maximum of 24 times, or stop when x is zero
for(i=0; ((i < 24) && (x != 0)); c=0, AddByte(&i, &o, &c, &i, &c))
{
*quotient= (*quotient) << 1; // shift the quotient left one bit
// is the numerator bigger than the denominator?
if(x >= *b)
{
// yes!
// we can stop counting leading zeros now
counting= !counting;
// subtract the denominator value from the numerator
SubtractLong(&x, b, &x);
// set the least significant bit of the quotient value
*quotient= (*quotient) | 0x01;
}
else
{
// have we found the MSB of the quotient yet?
if(counting)
{
// nope, we're still counting leading zeros!
c= 0; AddByte(n, &o, &c, n, &c);
}
}
// shift the residual numerator left one bit
x= (x << 1);
}
}
else
{
// if b is zero, we'll return the largest possible number as an
// error message!
if(*b == 0)
{
// unsigned integers, so no need to worry about signs like in
// DivideFloat()
*quotient= 0xFFFFFFFF;
}
}
// printf("a=%x b=%x q=%x n=%d\n", *a, *b, *quotient, *n);
}
|
|
-
-
niteice


- Joined on 09-12-2006
- Posts 38
|
Re: Post the function you are most proud of.
If that (run-time asm patching) doesn't win, I don't know what will.
|
|
-
-
bobday


- Joined on 04-04-2005
- Notbugville
- Posts 175
|
Re: Post the function you are most proud of.
From my first submission (I made two): int main(){ return 0; }
|
|
-
-
Chicken Little


- Joined on 04-29-2007
- North of 49
- Posts 16
|
Re: Post the function you are most proud of.
#include "calcfunc.h"
float DoOperation(char operation, float op1, float op2, int* isErr) { switch (operation) { case '+': return DoAdd(op1, op2); break; case '-': return DoSub(op1, op2); break; case '*': return DoMul(op1, op2); break; case '/': return DoDiv(op1, op2, isErr); break; } return op2; }
float DoAdd(float op1, float op2) { //TODO return the sum of op1 and op2 return op1 + op2; }
float DoSub(float op1, float op2) { //TODO return the difference between op1 and op2 return op1 - op2; }
float DoMul(float op1, float op2) { //TODO return the product of op1 and op2 return op1 * op2; }
float DoDiv(float op1, float op2, int *isErr) { //TODO set isErr to One if op2 is zero, or Zero //TODO return the quotient of op1 and op2 *isErr = op2 == 0 ? 1 : 0; return *isErr ? 0 : op1 / op2; }
|
|
-
-
Massimo


- Joined on 04-24-2007
- Posts 84
|
Re: Post the function you are most proud of.
I actually thought about submitting a totally-non-WTF entry to this contest; this would truly have been a Real WTF(TM).
|
|
-
-
Taejo


- Joined on 05-14-2007
- Posts 5
|
Re: Post the function you are most proud of.
My subtraction is pretty good: a tribute to XKCD. float DoSub (float op1, float op2)
{
return 4;
} What WTF? It's clear, fast, and passes all the test cases.
|
|
-
-
Dark Shikari


- Joined on 04-25-2007
- Posts 97
|
Re: Post the function you are most proud of.
Taejo:My subtraction is pretty good: a tribute to XKCD. float DoSub (float op1, float op2)
{
return 4;
} What WTF? It's clear, fast, and passes all the test cases.
How does it pass the test cases?
| WTF125 | 56723 - 73465 = | -16742 |
| WTF115 | 400000 - 500000 = | -100000 |
| WTF125 | 56723 - 73465 = | -16742 |
| WTF122 | 567347 - 43578 = | 523769 |
| WTF112 | 110101 - 10001 = | 100100 |
etc![]() ![]()
|
|
|
|
|