|
Post the function you are most proud of.
Last post 06-01-2007 4:23 PM by kupior. 116 replies.
-
05-14-2007 10:11 PM
|
|
-
Dark Shikari


- Joined on 04-25-2007
- Posts 97
|
Post the function you are most proud of.
Its not long until the deadline, so I figure we might as well start the inevitable.
Post the function or code snippet you are most proud of: the one that more than any other truly demonstrates your program's WTFery. Mine is the division function:
float DoDiv(float op1, float op2, int *isErr) { unsigned int result[FLOAT_ARRAY_SIZE]; if(*isErr == INIT_ZERO & mantissa2 == INIT_ZERO & exponent2 == INIT_ZERO) { *isErr = CONST_ONE; return op1;} result[SIGN_INDEX] = INIT_ZERO; result[MANTISSA_INDEX] = div(bitshift(add(mantissa1, MANT_CUTOFF), DIV_SCALING_FACTOR), add(mantissa2, MANT_CUTOFF), CONST_ONE); result[EXP_INDEX] = add(sub(exponent1, sub(exponent2, EXP_OFFSET)), sub(MANTISSA_SIZE, DIV_SCALING_FACTOR)); while(greaterThan(result[MANTISSA_INDEX], bitshift(MANT_CUTOFF, CONST_ONE))){ result[EXP_INDEX] = add(result[EXP_INDEX], CONST_ONE); result[MANTISSA_INDEX] = bitshift(result[MANTISSA_INDEX], sub(INIT_ZERO, CONST_ONE));} while(lessThan(result[MANTISSA_INDEX],MANT_CUTOFF) & (result[MANTISSA_INDEX] != INIT_ZERO) & ((result[MANTISSA_INDEX] & MANT_CUTOFF) == INIT_ZERO)){ result[MANTISSA_INDEX] = bitshift(result[MANTISSA_INDEX], CONST_ONE); result[EXP_INDEX] = sub(result[EXP_INDEX], CONST_ONE);} if(logicalNot(exponent1) == INIT_ZERO & logicalNot(exponent2) == INIT_ZERO) result[MANTISSA_INDEX] = sub(result[MANTISSA_INDEX], MANT_CUTOFF); int resultvar = add(add(bitshift(result[EXP_INDEX], MANTISSA_SIZE), result[MANTISSA_INDEX]), bitshift(result[SIGN_INDEX], add(MANTISSA_SIZE, EXP_SIZE))); if(lessThan(*isErr, NUM_ITERATIONS)){ result[MANTISSA_INDEX] = div(bitshift(add(mantissa1, MANT_CUTOFF), DIV_SCALING_FACTOR), add(mantissa2, MANT_CUTOFF), INIT_ZERO); if(result[MANTISSA_INDEX] != INIT_ZERO){ result[EXP_INDEX] = add(sub(exponent1, sub(exponent2, EXP_OFFSET)), sub(MANTISSA_SIZE, DIV_SCALING_FACTOR)); while(greaterThan(result[MANTISSA_INDEX], bitshift(MANT_CUTOFF, CONST_ONE))){ result[EXP_INDEX] = add(result[EXP_INDEX], CONST_ONE); result[MANTISSA_INDEX] = bitshift(result[MANTISSA_INDEX], sub(INIT_ZERO, CONST_ONE));} while(lessThan(result[MANTISSA_INDEX], MANT_CUTOFF) & (result[MANTISSA_INDEX] != INIT_ZERO) & ((result[MANTISSA_INDEX] & MANT_CUTOFF) == INIT_ZERO)){ result[MANTISSA_INDEX] = bitshift(result[MANTISSA_INDEX], CONST_ONE); result[EXP_INDEX] = sub(result[EXP_INDEX], CONST_ONE);} if(logicalNot(exponent1) == INIT_ZERO & logicalNot(exponent2) == INIT_ZERO) result[MANTISSA_INDEX] = sub(result[MANTISSA_INDEX], MANT_CUTOFF); int resultvar2 = add(add(bitshift(result[EXP_INDEX], MANTISSA_SIZE), result[MANTISSA_INDEX]), bitshift(result[SIGN_INDEX], add(MANTISSA_SIZE, EXP_SIZE))); *isErr = add(*isErr, CONST_ONE); float remainderDiv = convertTofloat(add(MANT_CUTOFF, mantissa2)); return DoAdd(DoDiv((*(float *) &resultvar2), remainderDiv, isErr), (*(float *) &resultvar));} else{ *isErr = INIT_ZERO; return (*(float *) &resultvar);}} else{ *isErr = INIT_ZERO; return (*(float *) &resultvar);} } It has a few interesting properties. 1. It works by splitting up a floating point number and doing integer operations on it. Yes, and it can return a fractional answer. 2. Each division uses 32 bits of precision, but the numbers are 24 bits, giving only 8 bits of precision for the actual result. How do I get more bits? Recursion. AGHHHHHHHHHHH 3. The "mantissa1", "exponent2", and so on are NOT global variables. They are #defines, like #define mantissa1 splitfloat(op1, MANTISSA_INDEX). 4. It uses no operations other than bitwise and, bitwise not, ==, !=, and = (assignment). The details to this mostly lie in the functions it calls, not the original function, however. 5. It takes 5 seconds to run, fully optimized, on a Core 2 Duo 2Ghz. It contains no intentional delay loops. 6. As far as I know, it works for all positive floating point numbers, even those beyond 2^32.
|
|
-
-
JCM


- Joined on 03-16-2006
- Posts 23
|
Re: Post the function you are most proud of.
Well, crap. If that's what the judges are looking for, I guess I'm just SOL. :) My entry was *much* easier to read and understand. It had comments and everything. I didn't think that the goal was obfusticated code nearly as much as just something that made the judges shake their heads.
|
|
-
-
dsharp


- Joined on 05-10-2007
- Posts 9
|
Re: Post the function you are most proud of.
Since we're not really aiming for obfuscation here, I chose to go down the "... well you *could* do that, but it's not a good idea." route.
Storeable* ServiceManager::getService(const std::string &serviceName) { Storeable* rc = NULL; map<string,Storeable*>::iterator i = services.find(serviceName); if (i != services.end()) { rc = i->second; } else { //oops! didn't find the service, calculate the soundex, //and see if the programmer has just misspelled it. string soundex = getSoundex(serviceName); map<string,string>::iterator j = soundices.find(soundex); if (j != soundices.end()) { i = services.find(j->second); rc = i->second; } } return rc; }
|
|
-
-
Dark Shikari


- Joined on 04-25-2007
- Posts 97
|
Re: Post the function you are most proud of.
JCM:Well, crap. If that's what the judges are looking for, I guess I'm just SOL. :) My entry was *much* easier to read and understand. It had comments and everything. I didn't think that the goal was obfusticated code nearly as much as just something that made the judges shake their heads.
I omitted the comments in the copy-paste of the code.
|
|
-
-
stolen_username


- Joined on 05-08-2007
- East Lansing, MI
- Posts 64
|
Re: Post the function you are most proud of.
Eh. From what I've seen here, most people were more creative than I was and actually managed to come up with solutions that function as calculators. I probably don't have too much to lose.
DWORD WINAPI Calculation_thread(LPVOID lpParam)
{
LARGE_INTEGER last_expr_file_time;
SYSTEMTIME system_time;
FILETIME converted_system_time;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &converted_system_time);
last_expr_file_time.HighPart = converted_system_time.dwHighDateTime;
last_expr_file_time.LowPart = converted_system_time.dwLowDateTime;
while (IsWindow(calc_window))
{
WIN32_FIND_DATA find_data;
HANDLE find_handle = FindFirstFile("expr-*.xml", &find_data);
if (find_handle)
{
BOOL found_file = TRUE;
while (found_file)
{
LARGE_INTEGER test_time;
test_time.HighPart = find_data.ftCreationTime.dwHighDateTime;
test_time.LowPart = find_data.ftCreationTime.dwLowDateTime;
if (test_time.QuadPart > last_expr_file_time.QuadPart)
{
Do_calculation(find_data.cFileName);
last_expr_file_time = test_time;
break;
}
found_file = FindNextFile(find_handle, &find_data);
}
FindClose(find_handle);
}
}
return 0;
}
Comments removed because it's just more fun without them.
|
|
-
-
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.
Ok, all entered and confirmed! I can't really post a single function that I'm proud of, because they're all very basic, fairly short functions. Well, methods, really -- I took a very object-oriented approach. In fact, I built what I consider to be a very well thought out, very well designed, and ultimately very useless C++ class library. I call my submission the VICE: Virtual Integrated Circuit Engine. I'm rather proud of that backronym. ;) Basically, I took the concept of the Virtual Machine to its reductio ad absurdum: Virtual Transistors. Rather than compute values with the CPU, I built Virtual AND gates, Virtual OR gates, virtual flipflops, virtual registers, and virtual computation units, all composed (ultimately) of Virtual Transistors. Well, the VirtualFlipFlop wasn't -- flipflops are based on a feedback loop, and that would have caused infinite recursion, and I actually wanted to *pass* the tests. :) My goal was a Turing complete VirtualCPU, complete with 4 MB of VirtualRAM, a full set of registers, and a subset of the x86 instruction set, but I ran out of time. In fact, I never got to floating point computation, so Dark Shakiri has me beat in that department. I do, however, have flawless cross-platform 32-bit integer addition, subtraction, and multiplication. Despite being insanely complex, VICE is pretty performant. Wasteful, yes, but performant thanks to fast processors. Hmm... I wonder if it would be as fast as a JVM or .NET? Maybe I'll keep working on it...
Agile Team-Oriented Waterfall-Centric Cowboy Coder.
|
|
-
-
Einsidler


- Joined on 11-15-2006
- Posts 99
|
Re: Post the function you are most proud of.
Here's the code snippet for my bubble sort, completely necessary to my algorithm but doesn't actually do anything. By pure coincedence every test case can do without it, but some operations return strange results. int strlength = strlen(op1); bool move_made = true; char temp; for (int a = 0; a < strlength - 1 && move_made; a++) { move_made = false; for (int b = a + 1; b < strlength; b++) if (ToInt(&op1[a]) < ToInt(&op1[b])) { temp = op1[b]; op1[b] = op1[a]; op1[a] = temp; move_made = true; } } In this case all calls to ToInt return 0. oh, and the only comment in there explains that it is just a "standard bubble sort."
Download my OMGWTF entry, Romanorum Computus
|
|
-
-
Massimo


- Joined on 04-24-2007
- Posts 84
|
Re: Post the function you are most proud of.
Ok, you asked for it ;-)
First: // Magic method #1 // --------------- // This one makes possible to change on-the-fly the // actual class being pointed by a generic Operation* // pointer void* Operation::operator new(size_t,Operation* op) { return(op); }
Second: // Magic method #2 // --------------- // This one changes the actual class it belongs to, // destroying it and creating in place a new one of // the correct type void Operation::ChooseOperation(char op) { this->~Operation();
switch(op) { case '+': new(this) Sum(); break; case '-': new(this) Sub(); break; case '*': new(this) Mul(); break; case '/': new(this) Div(); break; default: new(this) Dummy(); }
return; }
What do they to?
Well, they're pare of a quite peculiar implementation of the "polymorphism" concept ;-)
|
|
-
-
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.
Massimo -- that is.... insane! WTF?
Agile Team-Oriented Waterfall-Centric Cowboy Coder.
|
|
-
-
ashelly


- Joined on 05-15-2007
- Posts 2
|
Re: Post the function you are most proud of.
I am _least_ proud of my hack to pass the test cases without implementing long division: Number* operator/(Number& other) { if (other.multidigit()) return new Six; return *(this) * *((new One) / other);
}
|
|
-
-
Einsidler


- Joined on 11-15-2006
- Posts 99
|
Re: Post the function you are most proud of.
ashelly:I am _least_ proud of my hack to pass the test cases without implementing long division: Number* operator/(Number& other) { if (other.multidigit()) return new Six; return *(this) * *((new One) / other);
}
Reminds me of my "if (op2 > 5) return 6; // bug fix " :( Funny thing is, I didn't need it in debugging, but it crashed spectacularly when run from a compiled copy.
Download my OMGWTF entry, Romanorum Computus
|
|
-
-
kvigor


- Joined on 05-11-2007
- Posts 6
|
Re: Post the function you are most proud of.
Placement new of this?! I bow to the master; that is sick, sick and disturbing. For myself, I'm kinda proud of this macro: #define IS(x,y,z,a) \ template <> \ const char *saymyname(const x, const y, const z) \ { \ static a _crap; \ return _crap.name(); \ };
yes, it's a macro that generates a specialization of a template function that ignores all its parameters, and yes, it's important. I banged the whole mess out in about an hour this morning (22 svn commits!) so I didn't get a chance to fully wtfify it, but on the other hand, it's perverse code I wrote in a hurry.
|
|
-
-
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.
Ok, I changed my mind. Here is the code for the VirtualTransistor:
VirtualTransistor.h
#pragma once #include "VirtualComponent.h" #include "VirtualConnection.h"
namespace VICE { namespace Component { // The VirtualTransistor is the heart of the VICE system. Although itself // a VirtualComponent, nearly all other VirtualComponents are built from a // VirtualTransistor or from other VirtualComponents that (at some point) // utilize a VirtualTransistor. // // A VirtualTransistor models an NPN transistor which is, essentially, a // switch. It sends current through its output (typically called // an "Emitter" on NPN transistors), only if it both receives current from // its input ("Collector") and receives a small amount of current from // its switch input ("Base"). // // Because both current and voltage have been abstracted away for Virtual // Integrated Circuits, the difference between NPN and PNP transistors // (essentially a matter of current direction and whether a connected base // adds to or subtracts from the current flowing through the transistor) // becomes moot. In a VirtualTransistor, "current" flows from the Collector // to the Emitter. class VirtualTransistor : public VirtualComponent { public: ///////////////// //// Methods //// /////////////////
// default constructor VirtualTransistor(); // Causes the VirtualTransistor to update its output based // on its inputs. void Update();
//////////////////////////// //// Inputs and Outputs //// ////////////////////////////
//*****************************************************// //** Collector -- simulates a transistor's collector **// //** or "power input" **// //** Defaults to VirtualConnection::AlwaysOff **// //*****************************************************// private: const VirtualConnection * Collector; public: const VirtualConnection * Get_Collector(); void Set_Collector(const VirtualConnection * collector);
//************************************************// //** Base -- Simulates a transistor's base **// //** or "switch input" **// //** Defaults to VirtualConnection::AlwaysOff **// //************************************************// private: const VirtualConnection * Base; public: const VirtualConnection * Get_Base(); void Set_Base(const VirtualConnection * base);
//*************************************************// //** Emitter -- Simulates a transistor's emitter **// //** or "result output" **// //** Defaults to VirtualConnection::AlwaysOff **// //*************************************************// private: VirtualConnection Emitter; public: const VirtualConnection * Get_Emitter(); }; } }
VirtualTransistor.cpp
#include "StdAfx.h" #include "VirtualTransistor.h" #include <stdexcept>
using namespace VICE::Component;
VirtualTransistor::VirtualTransistor() : Collector(&VirtualConnection::AlwaysOff), Base(&VirtualConnection::AlwaysOff)
{}
void VirtualTransistor::Update()
{
if(Collector->On && Base->On)
{
Emitter.On = true;
}
else
{
Emitter.On = false;
}
}
//*************//
//** Emitter **//
//*************//
const VirtualConnection * VirtualTransistor::Get_Emitter()
{
return &Emitter;
}
//***************//
//** Collector **//
//***************//
const VirtualConnection * VirtualTransistor::Get_Collector()
{
return Collector;
}
void VirtualTransistor::Set_Collector(const VirtualConnection * collector)
{
if(collector == NULL)
{
throw std::invalid_argument("collector cannot be null");
}
Collector = collector;
}
//**********//
//** Base **//
//**********//
const VirtualConnection * VirtualTransistor::Get_Base()
{
return Base;
}
void VirtualTransistor::Set_Base(const VirtualConnection * base)
{
if(base == NULL)
{
throw std::invalid_argument("base cannot be null");
}
Base = base;
}
Agile Team-Oriented Waterfall-Centric Cowboy Coder.
|
|
-
-
macavenger


- Joined on 05-15-2007
- Fairbanks, AK
- Posts 7
|
Re: Post the function you are most proud of.
Well proud definitely isn't the right word, but my subtraction function:
void SubtractChars (char* op1, char* op2, bool borrow, char pos) { char length= ( strlen(op1)>strlen(op2) ) ?strlen(op1)+'0' : strlen(op2)+'0'; bool newBorrow=FALSE; if(pos==length-'0') { if(borrow) { strcpy(result, ShiftRight(result, length+'\001')); result['\0']='-'; return; } else return; } pos=pos+'\001'; char num1=( (int)strlen(op1)-pos<'\0' ) ? '0' : op1[strlen(op1)-pos]; if(borrow) num1=num1-'\001'; char num2=( (int)strlen(op2)-pos<'\0' ) ? '0' : op2[strlen(op2)-pos]; if (num2>num1) if(length-pos>'0') { num1=num1+'\n'; newBorrow=TRUE; } char diff=(num1-num2)+'0'; if (diff<'0') { //This is a fun line :) Could this be simplified? perhaps. Dunno. Don't care. It works. diff=(':'-(diff+'\n'))+'0'; newBorrow=TRUE; } result[length-pos-'0']=diff; SubtractChars(op1,op2,newBorrow,pos); }
It's a little buggy, but it seems to work, at least for the test cases. My apologies to the testers for the UI- on the EXTREMELY slim chance that I win, I'll send you guys a very large bottle of aspirin :)
Aluminum iMac 20" C2D 2.4 GHz/300 GB/3 GB
|
|
-
-
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.
This is one of my finer moments in my entry. It's actually two functions. Two sides of a coin, if you will. Ok, here it goes: First, a struct definition: struct do_next_stack_s { uint32_t lvl; // stack depth uint32_t r; // return point pointer struct do_next_stack_s *n; // next point down... }; typedef struct do_next_stack_s dn_stack_t; Next, the first function: #define XYZZY 0x02 void push(void) { uint32_t stack[1]; dn_stack_t *s; int i = 1;
s = new dn_stack_t; s->r = *(stack+XYZZY); // save the calling location s->n = dn_stack; dn_stack = s;
i = 1; while (s) { if (i >= 0x50) { assert(0 && "PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON."); } s->lvl = i++; s = s->n; }
return; }
Finally, the second function: void pop(void) { uint32_t stack[1]; dn_stack_t *s = dn_stack; dn_stack_t *t = dn_stack; int i = 1;
if (resuming >= 0x50) { assert(0 && "ENCOUNTERED PLEASE RESUME(0x50), GIVING UP."); }
while (s && s->lvl != resuming) s = s->n;
if (!s) { assert(0 && "TRYING TO RESUME BEYOND THE STACK, GIVING UP."); }
// You are not expected to understand this. See SOLUTION File. *(stack+XYZZY) = s->r;
dn_stack = s->n; s->n = NULL; s = t; while (s) { t = s; s = s->n; delete t; }
s = dn_stack;
while (s) { if (i >= 0x50) { assert(0 && "PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON."); } s->lvl = i++; s = s->n; }
return; } push() and pop() are then entered into a couple #defines, and used all over the place. Also, there is a 'forget' function which kills things from the top of the call stack.
Googling a couple of the more flamboyant error messages will give you a dark hint as to the horrors I've conjured from out of the depths.
All men are frauds. The only difference between them is that some admit it. I myself deny it. -- H. L. Mencken
|
|
-
-
waggy


- Joined on 05-15-2007
- Posts 1
|
Re: Post the function you are most proud of.
signed short fq_multiply_bs( NETWORK_VALUE_TYPE o1, MULTIPLY_BS_TYPE bs, BS_TYPE bsl ) { BS_TYPE abs_bs; unsigned short abs_prod; if( (o1==0) || (bs==0) ){return( (signed short) 0);} if( bs<0 ){ abs_bs = (BS_TYPE) (-bs); } else { abs_bs = (BS_TYPE) bs ; }
if( o1<0 ){ abs_prod = (unsigned short) (-o1); } else { abs_prod = (unsigned short) o1 ; } abs_prod<<=bsl; switch(abs_bs) { case 0: return( (signed short) 0 ); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: abs_prod>>=( 8 - abs_bs ); break; case 8: break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: abs_bs-=8; abs_prod<<= abs_bs; break; default: abs_prod = (unsigned short) SHRT_MAX; } if( ( (o1<=0) && (bs<=0) ) || ( (o1>=0) && (bs>=0) ) ){ return( (signed short) abs_prod ); } else{ return( (signed short) (-abs_prod) ); } }
My apologies if I mangled it when removing the comments, as is the convention in this thread. (FYI 'fq' is mnemonic for 'finger-quotes' and 'bs' is mnemonic for 'bit-shift'.) Admittedly, this function isn't much to look at, though with all the casting you might think I enjoy fishing. I like it because it works surprisingly well for weighting the inputs and applying the IIR filter coefficients to the nodes in a neural network.* Unfortunately I started late (just a few days ago) and did not have time to implement the genetic algorithm needed to develop a network trainable to respond properly (on a virtual 7-segment display) to the test cases. An IIR network with random weights and coefficients does behave rather well, even limited as it is to using 8-bit signed char arrays; the segments seem to flicker with a deep desire to learn the proper response.
*After I had worked out the idea of selecting power-of-two coefficients for a neural network of IIR filters using a genetic algorithm, I found it was far from original: http://www.vu.union.edu/~robleec/capstone/documentation/project_ANNIE_conference.doc
|
|
-
-
SamP


- Joined on 05-05-2007
- Posts 25
|
Re: Post the function you are most proud of.
Whiskey Tango Foxtrot? Over.:Ok, all entered and confirmed! I can't really post a single function that I'm proud of, because they're all very basic, fairly short functions. Well, methods, really -- I took a very object-oriented approach. In fact, I built what I consider to be a very well thought out, very well designed, and ultimately very useless C++ class library. I call my submission the VICE: Virtual Integrated Circuit Engine. I'm rather proud of that backronym. ;) Basically, I took the concept of the Virtual Machine to its reductio ad absurdum: Virtual Transistors. Rather than compute values with the CPU, I built Virtual AND gates, Virtual OR gates, virtual flipflops, virtual registers, and virtual computation units, all composed (ultimately) of Virtual Transistors. Well, the VirtualFlipFlop wasn't -- flipflops are based on a feedback loop, and that would have caused infinite recursion, and I actually wanted to *pass* the tests. :) My goal was a Turing complete VirtualCPU, complete with 4 MB of VirtualRAM, a full set of registers, and a subset of the x86 instruction set, but I ran out of time. In fact, I never got to floating point computation, so Dark Shakiri has me beat in that department. I do, however, have flawless cross-platform 32-bit integer addition, subtraction, and multiplication. Despite being insanely complex, VICE is pretty performant. Wasteful, yes, but performant thanks to fast processors. Hmm... I wonder if it would be as fast as a JVM or .NET? Maybe I'll keep working on it...
What you did can be totally not a WTF. Finish your program, throw up a proper GUI, and you got an excellent learner toolkit for beginner programmers and engineers. Allow students to explore how a basic, conceptual CPU works. Even the calculator would be useful, to visually show all the steps it takes for a basic arithmetic operation to be performed. We're not even talking assembly here. We're talking microcode -- individual control units within the processor itself. I sure wish I had something like that when I studied CPUs. You could even sell the thing if you see it through.
|
|
-
-
Zor


- Joined on 05-14-2007
- Posts 7
|
Re: Post the function you are most proud of.
Not the most exciting function, but I'm proud of it because it was a huge pain, and it looks cool...

I had to post a screenshot, because I couldnt get the formatting to come out right. Pretend that it extends to the right another 900 characters or so
|
|
-
-
kint


- Joined on 05-15-2007
- Posts 1
|
Re: Post the function you are most proud of.
This function does the bulk of the heavy lifting char *CalcInterface::Execute(char* szResult) { ShowWindow(CalcHandle::Instance().getCalcWnd(), SW_SHOWNORMAL); //preamble -- prepare to take over control BlockInput(true); POINT mousePoint; GetCursorPos(&mousePoint); BringWindowToTop(CalcHandle::Instance().getCalcWnd());
//clear Calculator's answer field Clear();
//prep calc for decimal input INPUT Input[1]; memset(Input, 0, sizeof(INPUT)); Input[0].type = INPUT_KEYBOARD; Input[0].ki.wVk = VK_F6; SendInput(1, Input, sizeof(INPUT)); Input[0].ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, Input, sizeof(INPUT));
//iterate through the command string (e.g. "421-325=") and click the button for each character DebugSpew("CommandProcessor::Execute(%s)", str().c_str()); for (size_t i = 0; i< str().length(); ++i) DoClick(str().at(i));
//postamble -- return control to the user BlockInput(false); SetCursorPos(mousePoint.x, mousePoint.y); BringWindowToTop(gCalcWnd);
return GetAnswer(szResult); }
|
|
-
-
msntfs


- Joined on 12-02-2006
- Posts 32
|
Re: Post the function you are most proud of.
My calcalutor was Enterprise powered, but had a shitty client. See how it parses number(i think it is not actually used there). int t_c(char* t){ int delka=zj_dlk(t)-2; unsigned long int cislice[50]; cislice[for_array(1)]=*((char*)(((int)t)+(delka-0))); switch(cislice[for_array(1)]){ case '0': cislice[for_array(1)]=0; break; case '1': cislice[for_array(1)]=1; break; case '2': cislice[for_array(1)]=2; break; case '3': cislice[for_array(1)]=3; break; case '4': cislice[for_array(1)]=4; break; case '5': cislice[for_array(1)]=5; break; case '6': cislice[for_array(1)]=6; break; case '7': cislice[for_array(1)]=7; break; case '8': cislice[for_array(1)]=8; break; case '9': cislice[for_array(1)]=9; break; } cislice[for_array(2)]=*((char*)(((int)t)+(delka-1))); switch(cislice[for_array(2)]){ case '0': cislice[for_array(2)]=0; break; case '1': cislice[for_array(2)]=1; break; case '2': cislice[for_array(2)]=2; break; case '3': cislice[for_array(2)]=3; break; case'4': cislice[for_array(2)]=4; break; case '5': cislice[for_array(2)]=5; break; case '6': cislice[for_array(2)]=6; break; case '7': cislice[for_array(2)]=7; break; case '8': cislice[for_array(2)]=8; break; case '9': cislice[for_array(2)]=9; break; } ______________SNIP TO 50 ______________
for(int i=delka+2;i<=50;i++){ cislice[for_array(i)]=0; } unsigned long int cislo=cislice[for_array(1)]; cislo=cislo+cislice[for_array(2)]*mocnina(10,2); cislo=cislo+cislice[for_array(3)]*mocnina(10,3); cislo=cislo+cislice[for_array(4)]*mocnina(10,4); cislo=cislo+cislice[for_array(5)]*mocnina(10,5); cislo=cislo+cislice[for_array(6)]*mocnina(10,6); cislo=cislo+cislice[for_array(7)]*mocnina(10,7); cislo=cislo+cislice[for_array(8)]*mocnina(10,8); cislo=cislo+cislice[for_array(9)]*mocnina(10,9); cislo=cislo+cislice[for_array(10)]*mocnina(10,10); cislo=cislo+cislice[for_array(11)]*mocnina(10,11); cislo=cislo+cislice[for_array(12)]*mocnina(10,12); cislo=cislo+cislice[for_array(13)]*mocnina(10,13); cislo=cislo+cislice[for_array(14)]*mocnina(10,14); cislo=cislo+cislice[for_array(15)]*mocnina(10,15); cislo=cislo+cislice[for_array(16)]*mocnina(10,16); cislo=cislo+cislice[for_array(16)]*mocnina(10,16); cislo=cislo+cislice[for_array(18)]*mocnina(10,18); cislo=cislo+cislice[for_array(19)]*mocnina(10,19); cislo=cislo+cislice[for_array(20)]*mocnina(10,20); cislo=cislo+cislice[for_array(21)]*mocnina(10,21); cislo=cislo+cislice[for_array(22)]*mocnina(10,22); cislo=cislo+cislice[for_array(23)]*mocnina(10,23); cislo=cislo+cislice[for_array(24)]*mocnina(10,24); cislo=cislo+cislice[for_array(25)]*mocnina(10,25); cislo=cislo+cislice[for_array(26)]*mocnina(10,26); cislo=cislo+cislice[for_array(27)]*mocnina(10,27); cislo=cislo+cislice[for_array(28)]*mocnina(10,28); cislo=cislo+cislice[for_array(29)]*mocnina(10,29); cislo=cislo+cislice[for_array(30)]*mocnina(10,30); cislo=cislo+cislice[for_array(31)]*mocnina(10,31); cislo=cislo+cislice[for_array(32)]*mocnina(10,32); cislo=cislo+cislice[for_array(33)]*mocnina(10,33); cislo=cislo+cislice[for_array(34)]*mocnina(10,34); cislo=cislo+cislice[for_array(35)]*mocnina(10,35); cislo=cislo+cislice[for_array(36)]*mocnina(10,36); cislo=cislo+cislice[for_array(37)]*mocnina(10,37); cislo=cislo+cislice[for_array(38)]*mocnina(10,38); cislo=cislo+cislice[for_array(39)]*mocnina(10,39); cislo=cislo+cislice[for_array(40)]*mocnina(10,40); cislo=cislo+cislice[for_array(41)]*mocnina(10,41); cislo=cislo+cislice[for_array(42)]*mocnina(10,42); cislo=cislo+cislice[for_array(43)]*mocnina(10,43); cislo=cislo+cislice[for_array(44)]*mocnina(10,44); cislo=cislo+cislice[for_array(45)]*mocnina(10,45); cislo=cislo+cislice[for_array(46)]*mocnina(10,46); cislo=cislo+cislice[for_array(47)]*mocnina(10,47); cislo=cislo+cislice[for_array(48)]*mocnina(10,48); cislo=cislo+cislice[for_array(49)]*mocnina(10,49); cislo=cislo+cislice[for_array(50)]*mocnina(10,50); return cislo; }
But that dividing function is best. It is really smart.
|
|
-
-
Massimo


- Joined on 04-24-2007
- Posts 84
|
Re: Post the function you are most proud of.
Whiskey Tango Foxtrot? Over.:Massimo -- that is.... insane! WTF?
That's exactly what I'm hoping the judges will shout upon reading it ;-)
|
|
-
-
msntfs


- Joined on 12-02-2006
- Posts 32
|
Re: Post the function you are most proud of.
Seems to me that it could be done with unix utility banner :)
|
|
-
-
Massimo


- Joined on 04-24-2007
- Posts 84
|
Re: Post the function you are most proud of.
kvigor:Placement new of this?! I bow to the master; that is sick, sick and disturbing.
Want to know The Real WTF(TM)?
I got the idea from a real thread on comp.lang.c++ where a guy was asking if this could be a proper program design for a real application... people there were quite shocked.
|
|
-
-
Worf


- Joined on 05-15-2007
- Posts 14
|
Re: Post the function you are most proud of.
My turn. Since I normally only do command line apps (in Linux, but I do Windows as well), I decided to learn Win32 GUI. Just FYI, this was in a DLL module I wrote as part of a grander WTF entry. I've got more... Comments removed to make it more interesting.
CalcErrorCode WINAPI DoCalc(CalcOperationCode op, Operand *op1, Operand *op2, Operand *ans)
{
HWND hCalc;
HWND hCalcEdit;
TCHAR result[RESULT_LEN];
TCHAR calc_exe[10];
POINT pEdit;
while (hCalc = FindWindow(NULL, TEXT("Calculator")))
{
SendMessage(hCalc, WM_CLOSE, 0, 0);
}
memset(calc_exe, 0, sizeof(calc_exe));
_tcscpy(calc_exe, TEXT("calc.exe"));
if (!CreateProcess(NULL, calc_exe, NULL, NULL, FALSE, 0, NULL, NULL, &siCalc, &piCalc))
{
MessageBox(NULL, TEXT("Could not start up calc.exe"), TEXT("Error"), MB_OK | MB_ICONERROR);
return CALC_NOT_SUPPORTED;
}
WaitForInputIdle(piCalc.hProcess, INFINITE);
hCalc = FindWindow(NULL, TEXT("Calculator"));
pEdit.x = 8;
pEdit.y = 8;
hCalcEdit = ChildWindowFromPoint(hCalc, pEdit);
SendAKey(VK_DELETE);
memset(result, 0, sizeof(result));
SendMessage(hCalcEdit, WM_GETTEXT, RESULT_LEN - 1, (LPARAM) result);
if (result[0] == TEXT('0'))
{
decimal = result[1];
}
else
{
decimal = TEXT('.');
}
SetForegroundWindow(hCalc);
Sleep(100);
WaitForInputIdle(piCalc.hProcess, INFINITE);
SendString(op1->ops);
SendAKey(TCharToVKey((TCHAR) op));
SendString(op2->ops);
SendAKey(TCharToVKey(TEXT('=')));
Sleep(100);
WaitForInputIdle(piCalc.hProcess, INFINITE);
SendMessage(hCalcEdit, WM_GETTEXT, RESULT_LEN - 1, (LPARAM) result);
ans->resultIsFloat = FALSE;
SendMessage(hCalc, WM_CLOSE, 0, 0);
if (TranslateResults(result) == 1)
{
return CALC_ERROR;
}
else
{
_tcscpy(ans->ops, result);
return CALC_NO_ERROR;
}
}
Oh, BTW, the bulk of my Win32 programming came from Windows CE BSP development. Hence the Unicode.
|
|
-
-
Drahflow


- Joined on 11-12-2006
- Posts 3
|
Re: Post the function you are most proud of.
inline float DoSub2(float op1, float op2, char reserved, const long reserved2) { register ostringstream out; out << DoSub(op1, op2, reserved, reserved); #if __UNDEFINED__ cout << "DoSub2 received: " << out.str() << endl; #endif of commented section if(out.str().c_str() == "-0") return DoSub2(op2, op1, reserved, reserved); middle: if(out.str().c_str() == string("-0")) return -DoSub(op2, op1, reserved, reserved);
if(istringstream(out.str()) >> f) return f; }
|
|
-
-
Domster


- Joined on 06-29-2006
- Posts 5
|
Re: Post the function you are most proud of.
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)).
float DoMul(float op1, float op2) { /* Swap the operands (multiplication is symmetrical) so op2 is smaller */ if (op2 > op1) { float op3 = op1; op1 = op2; op2 = op3; } ostringstream s;
s << Unary(op1);
s << "*";
s << Unary(op2);
Theorem theorem = Theorem(s.str().c_str());
s.str(""); /* This time, we get to apply four different axioms! Neat. */
int i = 0;
while (theorem.ApplyAxiomSeven()) {
i++;
if (i % Theorem::CleanMultiplicationMagic == 0) {
theorem.Clean();
}
} theorem.ApplyAxiomSix(); while (theorem.ApplyAxiomFive()) {
i++;
if (i % Theorem::CleanAdditionMagic == 0) {
theorem.Clean();
}
} while (theorem.ApplyAxiomFour()) {
i++;
if (i % Theorem::CleanAdditionMagic == 0) {
theorem.Clean();
}
} theorem.Clean(); s << theorem;
Unary result = Unary(s.str().c_str());
return Unary::ConstructFloat(result, Unary("0"), false);
}
|
|
-
-
asuffield


- Joined on 05-31-2006
- Posts 2,137
|
Re: Post the function you are most proud of.
Whiskey Tango Foxtrot? Over.:Massimo -- that is.... insane! WTF?
It's a really strange way to write a type-punning cast. It should compile into pretty much the same thing as reinterpret_cast would give you, if I'm reading it right.
|
|
-
-
wotnarg


- Joined on 04-25-2007
- Posts 2
|
Re: Post the function you are most proud of.
I don't really have a function that is concise to enough to exemplify my program, but I'll post two things: First, a snippet of my output logs: <xml><xml><xml><id>13</id></xml><xml><xml><id>13</id></xml><xml><mime>application/xml</mime></xml><xml><xml><id>13</id></xml><xml><mime>application/xml</mime></xml><xml><version>version=1.0 encoding=UTF-8</version></xml><xml><xml><id>13</id></xml><xml><mime>application/xml</mime></xml><xml><version>version=1.0 encoding=UTF-8</version></xml><xml><datap>136304952</datap></xml><xml><xml><id>13</id></xml><xml><mime>application/xml</mime></xml><xml><version>version=1.0 encoding=UTF-8</version></xml><xml><datap>136304952</datap></xml><xml><type>tryte</type></xml>
And part of my header analizar_syntactica.h: #define mientras while #define si if #define cierto true #define falso false #define clase class typedef std::string cadena; #define plantilla template #define devuelvan return #define hagan do typedef void vacio; typedef int entero; typedef char caracter; typedef class XMLExceptionNode NoduloDeExcepcionXML; #define molde_reinterpretado reinterpret_cast #define para for #define tiponombre typename #define caso case #define cambien switch #define nueva new #define rompanse break #define tiren throw #define intenten try #define cojan catch #define CERO 0 #define publico public typedef float fraccion; #define lingual_cast reinterpret_cast #define defecto default #define corrienteDeCadenas stringstream
I'll let you think about what went on ;) Final note: it involved ternary logic and COMEFROM.
|
|
-
-
Worf


- Joined on 05-15-2007
- Posts 14
|
Re: Post the function you are most proud of.
Bonus. Same submission, different DLL. This is nearly the entire DLL source verbatim. Just FYI, the main calculator event loop (it's similar to the SkeletonSolution) is *NOT* the same event loop we start here. In fact, the context this code is running in is handling the windows message. So great fun can happen because we're starting to process messages again, in a different window unrelated to the first window originally created, with no link back ot the first window other than the stack.
// Defines
#define EDIT_CONTROL 101
#define BUTTON_ANSWER 102
#define BUTTON_SKIP 103
#define BUTTON_ERROR 104
#define STATIC_CONTROL 105
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
{
ProcessLoop = FALSE; // Stop processing loop and return.
}
break;
case WM_CREATE:
{
HFONT hfDefault = NULL;
HWND hStatic;
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE, 0, 120, 400, 25, hwnd, (HMENU) EDIT_CONTROL, GetModuleHandle(NULL), NULL);
if (hEdit == NULL)
{
MessageBox(hwnd, TEXT("Could not create edit box"), TEXT("Error"), MB_OK | MB_ICONERROR);
}
SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));
SendMessage(hEdit, EM_LIMITTEXT, (WPARAM) (MAX_OPERAND_LEN - 1), 0);
hStatic = CreateWindowEx(WS_EX_LEFT, TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | ES_READONLY | ES_MULTILINE, 0, 0, 400, 120, hwnd, (HMENU)STATIC_CONTROL, GetModuleHandle(NULL), NULL);
if (hStatic == NULL)
{
MessageBox(hwnd, TEXT("Could not create static text"), TEXT("Error"), MB_OK | MB_ICONERROR);
}
SendMessage(hStatic, WM_SETTEXT, 0, (LPARAM) g_szMathQuestion);
hButtonAnswer = CreateWindowEx(WS_EX_LEFT, TEXT("BUTTON"), TEXT("Submit Answer"), WS_CHILD | WS_VISIBLE | BS_TEXT | BS_DEFPUSHBUTTON, 0, 150, 120, 60, hwnd, (HMENU)BUTTON_ANSWER, GetModuleHandle(NULL), NULL);
hButtonSkip = CreateWindowEx(WS_EX_LEFT, TEXT("BUTTON"), TEXT("Skip Question"), WS_CHILD | WS_VISIBLE | BS_TEXT, 123, 150, 120, 60, hwnd, (HMENU)BUTTON_SKIP, GetModuleHandle(NULL), NULL);
hButtonError = CreateWindowEx(WS_EX_LEFT, TEXT("BUTTON"), TEXT("Answer Undefined"), WS_CHILD | WS_VISIBLE | BS_TEXT, 246, 150, 154, 60, hwnd, (HMENU)BUTTON_ERROR, GetModuleHandle(NULL), NULL);
if ((hButtonAnswer == NULL) || (hButtonSkip == NULL) || (hButtonError == NULL))
{
MessageBox(hwnd, TEXT("Could not create buttons"), TEXT("Error"), MB_OK | MB_ICONERROR);
error_code = CALC_NOT_SUPPORTED;
ProcessLoop = FALSE;
}
SetFocus(hEdit);
}
break;
case WM_COMMAND:
{
if (HIWORD(wParam) == BN_CLICKED)
{
SendMessage(hEdit, WM_GETTEXT, 256, (LPARAM) g_szAnswer);
if (LOWORD(wParam) == BUTTON_ANSWER)
{
error_code = CALC_NO_ERROR;
}
else if (LOWORD(wParam) == BUTTON_SKIP)
{
error_code = CALC_NOT_SUPPORTED;
}
else if (LOWORD(wParam) == BUTTON_ERROR)
{
error_code = CALC_ERROR;
}
SendMessage(hwnd, WM_CLOSE, 0, 0);
}
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
CalcErrorCode WINAPI DoCalc(CalcOperationCode op, Operand *op1, Operand *op2, Operand *ans)
{
HWND hwnd;
MSG Msg;
_stprintf(g_szMathQuestion,
TEXT("What is %s %c %s?\r\n")
TEXT("Enter your answer and click \"Submit Answer\" below.\r\n")
TEXT("If you do not wish to answer, click \"Skip Question\".\r\n")
TEXT("Or click \"Answer Undefined\" if there is no answer, like dividing by zero.\r\n"),
op1->ops, (TCHAR) op, op2->ops);
ans->resultIsFloat = FALSE;
// Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
TEXT("Math Pop Quiz!"),
WS_OVERLAPPEDWINDOW | WS_DLGFRAME,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 240,
NULL, NULL, g_hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"),
MB_ICONEXCLAMATION | MB_OK);
return CALC_NOT_SUPPORTED;
}
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while ((GetMessage(&Msg, NULL, 0, 0) > 0) && (ProcessLoop))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
_tcscpy(ans->ops, g_szAnswer);
return error_code;
}
|
|
-
-
asuffield


- Joined on 05-31-2006
- Posts 2,137
|
Re: Post the function you are most proud of.
Whiskey Tango Foxtrot? Over.:Basically, I took the concept of the Virtual Machine to its reductio ad absurdum: Virtual Transistors.
Actually, looking at the code you posted, what you have here is a kind of virtual relay. Transistors do something quite different (which makes the construction of digital logic quite subtle but is vital to the construction of really fast digital logic). Relay-based logic is much simpler - we just don't normally use it, because relays tend to catch fire if you run them at the speeds we need for modern electronics. Rather than compute values with the CPU, I built Virtual AND gates, Virtual OR gates, virtual flipflops, virtual registers, and virtual computation units, all composed (ultimately) of Virtual Transistors.
You should really have built a virtual NAND gate and then built all the others from assemblies of NAND gates - you know, the way they teach it in undergrad courses (because it's easier than explaining how to build them all from real transistors). The transistor count goes way up when you do that. Well, the VirtualFlipFlop wasn't -- flipflops are based on a feedback loop, and that would have caused infinite recursion, and I actually wanted to *pass* the tests. :)
It's actually possible to model this, by constructing an event timeline and running it forwards until you have determined whether it is stable or astable (compare the new state to every prior state; if it's the same as the immediately previous state, the outcome is stable, and if it's the same as any other state, the outcome is astable). Your virtual "transistor" is quantized so it would always resolve into one or the other within n! steps for n connections. Alternatively you can just clock the thing and hook it up directly to the display field: as the values change, so does the displayed number, and the user is required to judge for themselves when the computation is finished by waiting for the display to stop changing. That would probably have been even more insane than what you did.
|
|
-
-
sagakan


- Joined on 05-14-2007
- Posts 1
|
Re: Post the function you are most proud of.
typedef
L(LET,
L(
/*
Greatest common divisor
*/
L(Gcd,
L(LAMBDA, L(a, b),
L(IF, L(EQ, b, I<0>),
a,
L(Gcd, b, L(MOD, a, b))))),
/*
Lest common multiple
*/
L(Lcm,
L(LAMBDA, L(a, b),
L(DIV, L(MULT, a, b), L(Gcd, a, b)))),
/*
EnterDigit
*/
L(EnterDigit,
L(LAMBDA, L(fracnum, digit),
L(FracAdd,
L(FracMult, fracnum, L(MakeFrac, I<10>, I<1>)),
L(MakeFrac, digit, I<1>)))),
/*
MakeFrac
*/
L(MakeFrac,
L(LAMBDA, L(a, b),
L(CONS, a, b))),
/*
FracIsNegative
*/
L(FracIsNegative,
L(LAMBDA, L(fracnum),
L(LT, L(CAR, fracnum), I<0>))),
/*
FracNormalizeSign
*/
L(FracNormalizeSign,
L(LAMBDA, L(fracnum),
L(IF, L(LT, L(CDR, fracnum), I<0>),
L(CONS, L(MULT, L(CAR, fracnum), I<-1>), L(MULT, L(CDR, fracnum), I<-1>)),
fracnum))),
/*
Normalize
*/
L(FracNormalize,
L(LAMBDA, L(fracnum),
L(FracNormalizeSign, L(LET,
L(
L(a, L(CAR, fracnum)),
L(b, L(CDR, fracnum))),
L(LET, L( L(gcd, L(Gcd, a, b)) ), L(CONS, L(DIV, a, gcd), L(DIV, b, gcd))))))),
|
|
-
-
IMil


- Joined on 05-26-2006
- Posts 30
|
Re: Post the function you are most proud of.
My functions are too innocent to be published here, I'll show a part of config file instead: ===================================================== Three is either a part of circle 11 to 6 a part of circle 12 to 7 6 of first joins 12 of second or a long horizontal line a slash line a part of circle 11 to 7 right of first joins top of second bottom of second joins 11 of third
=====================================================
|
|
-
-
Massimo


- Joined on 04-24-2007
- Posts 84
|
Re: Post the function you are most proud of.
asuffield: Whiskey Tango Foxtrot? Over.:Massimo -- that is.... insane! WTF?
It's a really strange way to write a type-punning cast. It should compile into pretty much the same thing as reinterpret_cast would give you, if I'm reading it right.
Oh no, it's definitely not a cast. The object has suicidal tendencies, to its just delets itself (by calling its own destructor) and creates a new one in the same memory by calling its constructor; of course, this is not particularly relevant as these objects only have (virtual) methods and no member variables, but this has the added bonus of making everything explode if you add some without really knowing what's going on.
This could have been done from outside the object by deleting a pointer and allocating a new object where it points to, but it's definitely more fun to delete "this" ;-)
|
|
-
-
Dark Shikari


- Joined on 04-25-2007
- Posts 97
|
Re: Post the function you are most proud of.
IMil:My functions are too innocent to be published here, I'll show a part of config file instead: ===================================================== Three is either a part of circle 11 to 6 a part of circle 12 to 7 6 of first joins 12 of second or a long horizontal line a slash line a part of circle 11 to 7 right of first joins top of second bottom of second joins 11 of third
=====================================================
Oh my god.
|
|
-
-
jtxx000


- Joined on 12-01-2006
- Posts 3
|
Re: Post the function you are most proud of.
Integer division in only 143 pixels of code!

(enlarged 8x)
|
|
-
-
Welbog


- Joined on 02-08-2007
- Posts 586
|
Re: Post the function you are most proud of.
That's terrifying. How's it work?
|
|
-
-
th0mas


- Joined on 05-05-2007
- Posts 19
|
Re: Post the function you are most proud of.
Here's a snippet of my configuration file (For the calculator, at least): <Application>
<!-- Pre and Post code -->
<Variable Name="PreCode" Type="String">
<Value>
#include <string.h>
#include <stdlib.h>
char buf[255];
char *stripZero(char *str)
{
char *p;
int hasDecimal = 0;
while (*str == '0' &&
*(str+1) != 0 && *(str+1) != '.') {
str++;
} (... bunch of code ...) </Value>
</Variable>
<Variable Name="PostCode" Type="String">
<Value>
return 0;
}
</Value>
</Variable> <TextBox>
<Variable Name="Name" Type="String" Value="Display" />
<Variable Name="Value" Type="String" Value="0" />
<Variable Name="Row" Type="Number" Value="0" />
<Variable Name="Column" Type="Number" Value="0" />
<Variable Name="Length" Type="Number" Value="4" />
<Variable Name="Height" Type="Number" Value="1" />
<Variable Name="Editable" Type="Number" Value="0" />
</TextBox>
<Button>
<Variable Name="Name" Type="String" Value="Button1" />
<Variable Name="Label" Type="String" Value="1" />
<Variable Name="Row" Type="Number" Value="3" />
<Variable Name="Column" Type="Number" Value="0" />
<Variable Name="Code" Type="String"
Value="if (ClearScreen == 1) { Display="1";
ClearScreen=0; } else { Display =
stripZero(appendString(Display,"1")); }" />
</Button>
<Button>
<Variable Name="Name" Type="String" Value="Button2" />
<Variable Name="Label" Type="String" Value="2" />
<Variable Name="Row" Type="Number" Value="3" />
<Variable Name="Column" Type="Number" Value="1" />
<Variable Name="Code" Type="String"
Value="if (ClearScreen == 1) { Display="2";
ClearScreen=0; } else { Display =
stripZero(appendString(Display,"2")); }" />
</Button> (...) Oh, and those escaped characters? That's not the forum, thats a requirement since the C code is in XML...
|
|
-
-
jtxx000


- Joined on 12-01-2006
- Posts 3
|
Re: Post the function you are most proud of.
Welbog:That's terrifying. How's it work?
Function inputs come from the top of the screen and outputs go out the bottom. There are three predefined operations: increment (green), decrement (red) and conditional (blue). The conditional operation checks the value coming in the top, and outputs the left input if it's greater than 0 and outputs or the right one if it's not. The black pixels represent wires and the grey pixels represent connected wires. The dark yellow pixel is subtraction, which is defined in another image. The purple pixel is the division function itself. So the division function basically works like this:
div(a, b) = if (a-b)>0 return div(a-b, b) + 1; else return (b-b)+1;
|
|
-
-
sleeping


- Joined on 04-25-2007
- Posts 8
|
Re: Post the function you are most proud of.
I am rather proud of 2 parts in my code. The first one is a single-line number swapper which raises warnings in some compilers, but I've never seen the runtime fail me :
int a = 5 ; int b = 9 ; a ^= b ^= a ^= b ; // a is now 9 and b is 5
I also quite like the comment part which introduces the "addition" section of my code :
// I've learned in my electronics course how CPU makers use NAND gates, // short for Not-AND, in order to add two bits. In order to optimize // the operations, I will implement the addition as the CPU does it // under the hood. That will minimize transformations done by the // compiler. Doing stuff in "machine language" is a common type of // optimization. // // Here's a small diagram to explain what goes on : // // +-------------#### 2 +-----------------#### 7 // | #####o---+ | #####o---+ // bit_1 ----+ +--#### | | +--#### | // | | | | | | // +--#### 1 | +--#### 4 | | | // #####o--+ #####o--+-----#### 5 | +--#### 8 // +--#### | +--#### #####o---+ #####o---- result // | | | +--#### | +--#### // bit_2 ----+ +--#### 3 | | | | // | | #####o---+ | | | // +----------|--#### | | | // | | +--#### 6 | // | | | #####o---+ // carry_in ------------|-------------------------+-----------|--#### // | | // | | // | +-----#### 9 // | #####o---------- carry_out // +-------------------------------------------#### // // // LEGEND : ----- : wire // // #### // #####o : NAND gate // #### //
(I'll let you imagine the implementation).
BTW, I hope you all covered your behinds by either not providing your real name in the source file, or by putting a comment section explaining that the thing is bad on purpose... Would be awful to have a future employer google your name, find the source, and hold it against you...
|
|
-
-
-
asuffield


- Joined on 05-31-2006
- Posts 2,137
|
Re: Post the function you are most proud of.
JCM:// Because both current and voltage have been abstracted away for Virtual // Integrated Circuits, the difference between NPN and PNP transistors // (essentially a matter of current direction and whether a connected base // adds to or subtracts from the current flowing through the transistor) // becomes moot. In a VirtualTransistor, "current" flows from the Collector // to the Emitter
So what you're saying is that it's like a JFET, not a BJT?
FETs still behave like electronically controlled variable resistors, they just use a different equation. As far as I'm aware, the only similar device with a strictly quantized on/off nature is the relay. Just because you can use a transistor to build an electronically controlled switch does not mean that a transistor actually is a switch - it isn't, and it's not even close. It just happens to be the most complicated component involved (typically you use one or more transistors and two or more resistors, but there are many variations).
|
|
-
-
Welbog


- Joined on 02-08-2007
- Posts 586
|
Re: Post the function you are most proud of.
I don't actually have my code handy, so I can't post the code itself, but I'm most proud of invoking my operations. The basic flow is as follows:
// Multiply 5 and 6 Number * op1 = new Number("5"); Number * op2 = new Number("6"); VECTOR v; v.push_back(op1); v.push_back(op2); Operation * op = new Multiplication(); unsigned int product; try { op->operate(v); } catch (string * result) { product = atoi(result->cstr()); } // product now stores the number 30.
And that had to be done for every operation, including simple loop counter incrementing. VECTOR is a #define for vector<Number *>. Thirteen lines of code for any one operation, and all operations (including Addition) call other operations, in most cases many, many times.
|
|
-
-
freelancer


- Joined on 02-21-2007
- Posts 68
|
Re: Post the function you are most proud of.
This gets called a lot: void noop() { //do nothing } Also, I really like my DoDiv: void DoDiv() { setGlobalVariable("divResult", getGlobalVariable("divOp1") / getGlobalVariable("divOp2")); setGlobalVariable("moreOp1", getGlobalVariable("divResult")); setGlobalVariable("moreOp2", ninehundredandninetyninethousandninehundredandninetynine); more(); switch ((int)getGlobalVariable("moreResult")) { // We're not supposed to get results this high. Assume divideByZero. case 1: setGlobalVariable("divResult", (ninehundredandninetyninethousandninehundredandninetynine)); setGlobalVariable("isErr", 1); throw true; throw false; break; case 0: setGlobalVariable("isErr", (zero)); break; } setGlobalVariable("divI", (zero)); setGlobalVariable("divOldI", (zero)); try { loop: setGlobalVariable("equalOp1", getGlobalVariable("divI") * getGlobalVariable("divOp2")); setGlobalVariable("equalOp2", getGlobalVariable("divOp1")); equal(); switch ((int)getGlobalVariable("equalResult")) { case 1: setGlobalVariable("divResult", getGlobalVariable("divI")); throw 'a'; break; case 0: noop(); break; } setGlobalVariable("moreOp1", getGlobalVariable("divI") * getGlobalVariable("divOp2")); setGlobalVariable("moreOp2", getGlobalVariable("divOp1")); more(); switch ((int)getGlobalVariable("moreResult")) { case 1: setGlobalVariable("divI", getGlobalVariable("divOldI")); throw 'b'; break; case 0: noop(); break; } setGlobalVariable("divOldI", getGlobalVariable("divI")); setGlobalVariable("divI", getGlobalVariable("divI") + one); goto loop; } catch (char a) { switch (a) { case 'bn': try { tooMuch: setGlobalVariable("equalOp1", getGlobalVariable("divI") * getGlobalVariable("divOp2")); setGlobalVariable("equalOp2", getGlobalVariable("divOp1")); equal(); switch ((int)getGlobalVariable("equalResult")) { case 1: setGlobalVariable("divResult", getGlobalVariable("divI")); throw 'a'; break; case 0: noop(); break; } setGlobalVariable("moreOp1", getGlobalVariable("divI") * getGlobalVariable("divOp2")); setGlobalVariable("moreOp2", getGlobalVariable("divOp1")); more(); switch ((int)getGlobalVariable("moreResult")) { case 1: setGlobalVariable("divResult", getGlobalVariable("divI")); throw 'a'; break; case 0: noop(); break; } setGlobalVariable("divOldI", getGlobalVariable("divI")); setGlobalVariable("divI", getGlobalVariable("divI") + zeropointone); goto tooMuch; } catch (char a) { } break; } } noop(); }
OMGWTF - Are you enterprisey enough?
|
|
-
-
Chemisor


- Joined on 03-24-2005
- Posts 19
|
Re: Post the function you are most proud of.
I'm sure the mathematicians here would get the hint ;) And gasp in horror. And yes, that really is the minimum hash table (within a week, anyway). Supports command chars, regular number keys, and the keypad with and without numlock on. void CCalc::OnKey (GdkEventKey* pev) { static const char bhash[] = "7 09159362 =./ -*+ 67452301Q C89 ./C-*+ 67452301 =Q=89 48 "; int v = (int)(char)(short)(pev->keyval); // (short) converts from unsigned, (char) truncates to table value, (int) expands hash value range. k = (v ^ 6) + ((v >> 3) ^ 7); // generated by eigenhash OnButton (NULL, (gpointer)&bhash[k%(VectorSize(bhash)-1)]); // Well, yeah, I could look up the button pointer by label, but that's too much work... }
|
|
-
-
DoggettCK


- Joined on 05-15-2007
- Posts 2
|
Re: Post the function you are most proud of.
sleeping wrote the following post at 05-15-2007 7:23 AM:
I
am rather proud of 2 parts in my code. The first one is a single-line
number swapper which raises warnings in some compilers, but I've never
seen the runtime fail me :
int a = 5 ; int b = 9 ; a ^= b ^= a ^= b ; // a is now 9 and b is 5 I did the same thing in my in-place string reversal function: void revstr(char *str) { if(*str == '\0') { return; } char *start = str; char *end = start + strlen(str) - 1; while(start < end) { *start ^= *end ^= *start++ ^= *end--; // Fancy } } I'm also proud of my palindrome function, which may or may not actually be used: bool isAlphaNumeric(char c) { return (iswalpha(c) || iswdigit(c)); }
// Determine if a string is a palindrome, ignoring any non-alphanumeric characters. bool isPalindrome(char *str) { // "A man, a plan, Anal Panama!" if(*str == '\0') { return false; } int len = strlen(str); if(len <= 1) return true; char *start = str; char *end = start + len - 1; while(start < end) { if(!isAlphaNumeric(*start)) { *start++; continue; } if(!isAlphaNumeric(*end)) { *end--; continue; } if(towlower(*start) != towlower(*end)) return false; *start++; *end--; } return true; }
|
|
-
-
Einsidler


- Joined on 11-15-2006
- Posts 99
|
Re: Post the function you are most proud of.
Does setGlobalVariable and getGlobalVariable use files, the registry or something even worse?
Download my OMGWTF entry, Romanorum Computus
|
|
-
-
freelancer


- Joined on 02-21-2007
- Posts 68
|
Re: Post the function you are most proud of.
Einsidler:Does setGlobalVariable and getGlobalVariable use files, the registry or something even worse?
Nope, they actually use......*drums*.......global variables! But not arrays, that's overrated. Instead, I have fifty or so globally defined variable pairs called global1name, global1value, global2name, global2value, etc..... Just because you asked, here's setGlobalVariable: void setGlobalVariable(char* name, float value) { int i = zero; int iAdd = one; try { loop: i = i + iAdd; if (i == one) { if (strcmp(global1name, name) == (zero)) { global1value = value; throw 'a'; } } if (i == (two)) { if (strcmp(global2name, name) == (zero)) { global2value = value; throw 'a'; } } if (i == (three)) { if (strcmp(global3name, name) == (zero)) { global3value = value; throw 'a'; } } if (i == (four)) { if (strcmp(global4name, name) == (zero)) { global4value = value; throw 'a'; } } if (i == (five)) { if (strcmp(global5name, name) == (zero)) { global5value = value; throw 'a'; } } if (i == (six)) { if (strcmp(global6name, name) == (zero)) { global6value = value; throw 'a'; } } if (i == (seven)) { if (strcmp(global7name, name) == (zero)) { global7value = value; throw 'a'; } } if (i == (eight)) { if (strcmp(global8name, name) == (zero)) { global8value = value; throw 'a'; } } if (i == (nine)) { if (strcmp(global9name, name) == (zero)) { global9value = value; throw 'a'; } } if (i == (ten)) { if (strcmp(global10name, name) == (zero)) { global10value = value; throw 'a'; } } if (i == (eleven)) { if (strcmp(global11name, name) == (zero)) { global11value = value; throw 'a'; } } if (i == (twelve)) { if (strcmp(global12name, name) == (zero)) { global12value = value; throw 'a'; } } if (i == (thirteen)) { if (strcmp(global13name, name) == (zero)) { global13value = value; throw 'a'; } } if (i == (forteen)) { if (strcmp(global14name, name) == (zero)) { global14value = value; throw 'a'; } } if (i == (fifteen)) { if (strcmp(global15name, name) == (zero)) { global15value = value; throw 'a'; } } if (i == (sixteen)) { if (strcmp(global16name, name) == (zero)) { global16value = value; throw 'a'; } } if (i == (seventeen)) { if (strcmp(global17name, name) == (zero)) { global17value = value; throw 'a'; } } if (i == (eighteen)) { if (strcmp(global18name, name) == (zero)) { global18value = value; throw 'a'; } } if (i == (nineteen)) { if (strcmp(global19name, name) == (zero)) { global19value = value; throw 'a'; } } if (i == (twenty)) { if (strcmp(global20name, name) == (zero)) { global20value = value; throw 'a'; } } if (usingExtendedVariables) { if (i == (twentyone)) { if (strcmp(global21name, name) == (zero)) { global21value = value; throw 'a'; } } if (i == (twentytwo)) { if (strcmp(global22name, name) == (zero)) { global22value = value; throw 'a'; } } if (i == (twentythree)) { if (strcmp(global23name, name) == (zero)) { global23value = value; throw 'a'; } } if (i == (twentyfour)) { if (strcmp(global24name, name) == (zero)) { global24value = value; throw 'a'; } } if (i == (twentyfive)) { if (strcmp(global25name, name) == (zero)) { global25value = value; throw 'a'; } } if (i == (twentysix)) { if (strcmp(global26name, name) == (zero)) { global26value = value; throw 'a'; } } if (i == (twentyseven)) { if (strcmp(global27name, name) == (zero)) { global27value = value; throw 'a'; } } if (i == (twentyeight)) { if (strcmp(global28name, name) == (zero)) { global28value = value; throw 'a'; } } if (i == (twentynine)) { if (strcmp(global29name, name) == (zero)) { global29value = value; throw 'a'; } } if (i == (thirty)) { if (strcmp(global30name, name) == (zero)) { global30value = value; throw 'a'; } } if (i == (thirtyone)) { if (strcmp(global31name, name) == (zero)) { global31value = value; throw 'a'; } } if (i == (thirtytwo)) { if (strcmp(global32name, name) == (zero)) { global32value = value; throw 'a'; } } if (i == (thirtythree)) { if (strcmp(global33name, name) == (zero)) { global33value = value; throw 'a'; } } if (i == (thirtyfour)) { if (strcmp(global34name, name) == (zero)) { global34value = value; throw 'a'; } } if (i == (thirtyfive)) { if (strcmp(global35name, name) == (zero)) { global35value = value; throw 'a'; } } if (i == (thirtysix)) { if (strcmp(global36name, name) == (zero)) { global36value = value; throw 'a'; } } if (i == (thirtyseven)) { if (strcmp(global37name, name) == (zero)) { global37value = value; throw 'a'; } } } if (usingExtraVariables) { if (i == (thirtyeight)) { if (strcmp(global38name, name) == (zero)) { global38value = value; throw 'a'; } } if (i == (thirtynine)) { if (strcmp(global39name, name) == (zero)) { global39value = value; throw 'a'; } } if (i == (forty)) { if (strcmp(global40name, name) == (zero)) { global40value = value; throw 'a'; } } } if (i == (fortyone)) { //not found, check for empty i = (zero); innerLoop: i = i + iAdd; if (i == (one)) { try { isStringEmpty(global1name); } catch (char* exception) { strcpy(global1name, name); global1value = value; throw 'a'; } } if (i == (two)) { try { isStringEmpty(global2name); } catch (char* exception) { strcpy(global2name, name); global2value = value; throw 'a'; } } if (i == (three)) { try { isStringEmpty(global3name); } catch (char* exception) { strcpy(global3name, name); global3value = value; throw 'a'; } } if (i == (four)) { try { isStringEmpty(global4name); } catch (char* exception) { strcpy(global4name, name); global4value = value; throw 'a'; } } if (i == (five)) { try { isStringEmpty(global5name); } catch (char* exception) { strcpy(global5name, name); global5value = value; throw 'a'; } } if (i == (six)) { try { isStringEmpty(global6name); } catch (char* exception) { strcpy(global6name, name); global6value = value; throw 'a'; } } if (i == (seven)) { try { isStringEmpty(global7name); } catch (char* exception) { strcpy(global7name, name); global7value = value; throw 'a'; } } if (i == (eight)) { try { isStringEmpty(global8name); } catch (char* exception) { strcpy(global8name, name); global8value = value; throw 'a'; } } if (i == (nine)) { try { isStringEmpty(global9name); } catch (char* exception) { strcpy(global9name, name); global9value = value; throw 'a'; } } if (i == (ten)) { try { isStringEmpty(global10name); } catch (char* exception) { strcpy(global10name, name); global10value = value; throw 'a'; } } if (i == (eleven)) { try { isStringEmpty(global11name); } catch (char* exception) { strcpy(global11name, name); global11value = value; throw 'a'; } } if (i == (twelve)) { try { isStringEmpty(global12name); } catch (char* exception) { strcpy(global12name, name); global12value = value; throw 'a'; } } if (i == (thirteen)) { try { isStringEmpty(global13name); } catch (char* exception) { strcpy(global13name, name);; global13value = value; throw 'a'; } } if (i == (forteen)) { try { isStringEmpty(global14name); } catch (char* exception) { strcpy(global14name, name); global14value = value; throw 'a'; } } if (i == (fifteen)) { try { isStringEmpty(global15name); } catch (char* exception) { strcpy(global15name, name); global15value = value; throw 'a'; } } if (i == (sixteen)) { try { isStringEmpty(global16name); } catch (char* exception) { strcpy(global16name, name); global16value = value; throw 'a'; } } if (i == (seventeen)) { try { isStringEmpty(global17name); } catch (char* exception) { strcpy(global17name, name); global17value = value; throw 'a'; } } if (i == (eighteen)) { try { isStringEmpty(global18name); } catch (char* exception) { strcpy(global18name, name); global18value = value; throw 'a'; } } if (i == (nineteen)) { try { isStringEmpty(global19name); } catch (char* exception) { strcpy(global19name, name); global19value = value; throw 'a'; } } if (i == (twenty)) { try { isStringEmpty(global20name); } catch (char* exception) { strcpy(global20name, name); global20value = value; throw 'a'; } } if (i == (twentyone)) { try { isStringEmpty(global21name); } catch (char* exception) { strcpy(global21name, name); global21value = value; throw 'a'; } } if (i == (twentytwo)) { try { isStringEmpty(global22name); } catch (char* exception) { strcpy(global22name, name); global22value = value; throw 'a'; } } if (i == (twentythree)) { try { isStringEmpty(global23name); } catch (char* exception) { strcpy(global23name, name); global23value = value; throw 'a'; } } if (i == (twentyfour)) { try { isStringEmpty(global24name); } catch (char* exception) { strcpy(global24name, name); global24value = value; throw 'a'; } } if (i == (twentyfive)) { try { isStringEmpty(global25name); } catch (char* exception) { strcpy(global25name, name); global25value = value; throw 'a'; } } if (i == (twentysix)) { try { isStringEmpty(global26name); } catch (char* exception) { strcpy(global26name, name); global26value = value; throw 'a'; } } if (i == (twentyseven)) { try { isStringEmpty(global27name); } catch (char* exception) { strcpy(global27name, name); global27value = value; throw 'a'; } } if (i == (twentyeight)) { try { isStringEmpty(global28name); } catch (char* exception) { strcpy(global28name, name); global28value = value; throw 'a'; } } if (i == (twentynine)) { try { isStringEmpty(global29name); } catch (char* exception) { strcpy(global29name, name); global29value = value; throw 'a'; } } if (i == (thirty)) { try { isStringEmpty(global30name); } catch (char* exception) { strcpy(global30name, name); global30value = value; throw 'a'; } } if (i == (thirtyone)) { try { isStringEmpty(global31name); } catch (char* exception) { strcpy(global31name, name); global31value = value; throw 'a'; } } if (i == (thirtytwo)) { try { isStringEmpty(global32name); } catch (char* exception) { strcpy(global32name, name); global32value = value; throw 'a'; } } if (i == (thirtythree)) { try { isStringEmpty(global33name); } catch (char* exception) { strcpy(global33name, name); global33value = value; throw 'a'; } } if (i == (thirtyfour)) { try { isStringEmpty(global34name); } catch (char* exception) { strcpy(global34name, name); global34value = value; throw 'a'; } } if (i == (thirtyfive)) { try { isStringEmpty(global35name); } catch (char* exception) { strcpy(global35name, name); global35value = value; throw 'a'; } } if (i == (thirtysix)) { try { isStringEmpty(global36name); } catch (char* exception) { strcpy(global36name, name); global36value = value; throw 'a'; } } if (i == (thirtyseven)) { try { isStringEmpty(global37name); } catch (char* exception) { strcpy(global37name, name); global37value = value; throw 'a'; } } if (i == (thirtyeight)) { try { isStringEmpty(global38name); } catch (char* exception) { strcpy(global38name, name); global38value = value; throw 'a'; } } if (i == (thirtynine)) { try { isStringEmpty(global39name); } catch (char* exception) { strcpy(global39name, name); global39value = value; throw 'a'; } } if (i == (forty)) { try { isStringEmpty(global40name); } catch (char* exception) { strcpy(global40name, name); global40value = value; throw 'a'; } } if (i == (fortyone)) { generateException(); throw generatedException; throw 'a'; } goto innerLoop; } goto loop; } catch (char a) { } noop(); }
OMGWTF - Are you enterprisey enough?
|
|
-
-
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.
asuffield:Actually, looking at the code you posted, what you have here is a kind of virtual relay. Transistors do something quite different (which makes the construction of digital logic quite subtle but is vital to the construction of really fast digital logic). Relay-based logic is much simpler - we just don't normally use it, because relays tend to catch fire if you run them at the speeds we need for modern electronics.
Very true, and I remember the basic theories of electronics, or at least I've re-remembered most of them as a result of this project. I discussed some of how the VirtualTransistor (or VirtualRelay, if you like) differs from a real transistor in my comments. I could have attempted to simulate wire-level current, but chose not to for simplicity. If I had, I might have been able to build a NAND gate from VirtualTransistors and build all my components from that, but because I chose "on" or "off" for my current, I had to go with AND/Inverter instead.
Agile Team-Oriented Waterfall-Centric Cowboy Coder.
|
|
-
-
TheFeshy


- Joined on 05-04-2007
- Posts 12
|
Re: Post the function you are most proud of.
This gets called a lot: void noop() { //do nothing }
I have a function like that too, but mine is a little different: void operator delete(void* address){}; It goes well with my global new replacement: void* operator new (size_t sz){return (void*)&(mBlocks[mFreeIndex++]);}; mBlocks is a static array of 16k byte blocks. Heap allocation in only two ops! How's that for optimization?
|
|
-
-
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.
SamP:What you did can be totally not a WTF. Finish your program, throw up a proper GUI, and you got an excellent learner toolkit for beginner programmers and engineers. Allow students to explore how a basic, conceptual CPU works. Even the calculator would be useful, to visually show all the steps it takes for a basic arithmetic operation to be performed. We're not even talking assembly here. We're talking microcode -- individual control units within the processor itself. I sure wish I had something like that when I studied CPUs. You could even sell the thing if you see it through.
When I explained how I was doing things, and how much fun I was having re-reading my digitial electronics texts, my wife said something similar. While I doubt I'll ever actually build a product out of VICE that I can sell, either for real use or for learning purposes, I think that if I ever end up teaching digital electronics I'll use at least the basic components of VICE (the VirtualConnection and the AND, OR, NAND, NOR, XOR gates) and require my students to build and test working digital circuits with them.
Agile Team-Oriented Waterfall-Centric Cowboy Coder.
|
|
|
|
|