??? 06/10/07 04:38 Modified: 06/10/07 04:53 Read: times |
#140498 - Sunday Quiz - Bit Flipper in C |
Jan's weekend quiz from a couple of weeks ago involved an 8051 assembly language program that counted the number of 1 bits in a byte. That reminded me of a similar small problem--that of reversing the bits in a byte. I was thinking that a contest to write the fastest such program would be fun, but then I realized that a simple table lookup would be the hands down winner, and not very interesting at that. Then this nonsense started, and I thought that maybe reversing the bits in a byte would be a good exercise for a one-line C contest. So that's what this is.
The program in main(), below compares, for all possible input values, the output of the known-good (I hope!) bit reversal function GoodFlip() against that of the similar function TestFlip(). If the results are identical, main() prints "Pass". Otherwise it prints out the offending pairs of mismatched results. Your job is to replace the entire body of TestFlip() with your own version. Your goal is to reduce the size of the source code to the absolute minimum. This means you should use one-character names for everything, no comments, no unnecessary spaces, and every trick you can think of to make your program short. As noted in the comment below, the supplied body of TestFlip() contains 63 bytes. Based on some playing around I did a couple of days ago, I bet somebody will be able to get it close to 50. Anything near 40 would be truly amazing. Just so we're all singing the same song, a few rules are in probably in order: 1. Your TestFlip() must produce the same results as GoodFlip(). In other words, main() must report "Pass". 2. As clever as the idea might seem, TestFlip() may not call GoodFlip(). 3. If you need a variable with a type other than unsigned char, you may #define and use a 2-character abbreviation for the type name, as I have done already for unsigned char. The #define can be outside TestFlip(), and doesn't count towards the size of your program. However, as in the supplied example, the use of the abbreviation must be within TestFlip() and does count as part of the program. 4. Other rules TBD if questions arise. This seems to me like a fairly straightforward problem, with somewhat limited opportunity for fancy tricks. But I may be wrong about that. In any case, once we get the kinks worked out, the overall structure of the challenge should apply as well to more interesting coding problems. Have fun! -- Russ #include <stdio.h> /* //////////////////////////////////////////////////////////////////////////// Data Type Abbreviations //////////////////////////////////////////////////////////////////////////// */ #define UC unsigned char /* //////////////////////////////////////////////////////////////////////////// Function Prototypes //////////////////////////////////////////////////////////////////////////// */ UC GoodFlip(UC); UC TestFlip(UC); /* //////////////////////////////////////////////////////////////////////////// main() //////////////////////////////////////////////////////////////////////////// */ void main() { int in; // Input value counter int allTestsMatch; // Flag: all tests match allTestsMatch = 1; // Assume success for (in=0; in<256; in++) { // For all input values if (GoodFlip((UC)in) != TestFlip((UC)in)) { // Mismatch printf("Mismatch: %02X vs. " // Report the details "%02X\n", GoodFlip((UC)in), TestFlip((UC)in)); allTestsMatch = 0; // Note that we had a mismatch } // End 'mismatch' } // End 'for all input values' printf(allTestsMatch ? "Pass\n" : "Fail\n");// Report overall result } // End main() /* //////////////////////////////////////////////////////////////////////////// GoodFlip() //////////////////////////////////////////////////////////////////////////// */ UC GoodFlip(UC c) { UC result; // Build result here result = 0; // Construct the mirror image if (c & 0x01) result |= 0x80; // of the input byte, one bit if (c & 0x02) result |= 0x40; // at a time in the most if (c & 0x04) result |= 0x20; // straightforward way if (c & 0x08) result |= 0x10; // imaginable. if (c & 0x10) result |= 0x08; if (c & 0x20) result |= 0x04; if (c & 0x40) result |= 0x02; if (c & 0x80) result |= 0x01; return result; } // End GoodFlip() /* //////////////////////////////////////////////////////////////////////////// TestFlip() //////////////////////////////////////////////////////////////////////////// */ UC TestFlip(UC c) { UC r,i;r=0;for(i=0;i<8;i++){if(c&(1<<i))r|=(0x80>>i);}return r; /* 63 bytes */ } |