2010-12-16 debianforum.de is a place I like much, but most because of the little programming questions that can often be solved with the standard tools (sed, wc, awk, tr, etc) in nice ways. I love to find cool and short and shorter solutions, just for fun. For me, these threads start to become really interesting when the origi- nal question is solved and the ``but I have a sorter solution'' game starts. :-) Yesterday exactly such a thread came up. [0] Although I have few time currently, I couldn't resist to go to find even shorter solutions. The question had been: Produce all numbers from ``00 00 00 00 00 00'' to ``FF FF FF FF FF FF'', in this format, one per line. The problem itself is not hard to solve, but with how few charac- ters could one solve it? I do like to use awk for such kinds of problems. The first version I posted (75 chars): awk 'BEGIN{for(i=0;i<2^48;i++)printf("%012X\n",i)}'|sed 's,..,& ,g;s, $,,' The second version (70 chars): awk 'BEGIN{while(i<2^48)printf("%012X\n",i++)}'|sed 's,.., &,g;s,.,,' I did not need to initialize the variable because all get ini- tialized to 0 (or "") on first use. Using for or while loops does not matter, they need the same amout of chars. In sed: In- stead of appending the space to the pairs, I prepended it, then I could remove the anchor because the dot would match the first char. The third version (68 chars): id|awk '{while(i<2^48)printf("%012X\n",i++)}'|sed 's,.., &,g;s,.,,' I posted the second version together with the third one because the latter is very ugly, only to remove two more chars. Then I realized that awk's integers are 32 bit unsigned. No number larger than 2^32-1 was generated. I knew that bc(1) had no such limits, hence I wrote a new version that would produce correct results. The fourth version (94 chars): echo 'obase=16;while(i<2^48)i++'|bc|awk '{printf("%0*d",12-length,0)}1'|sed 's,.., &,g;s,.,,' Bc has, AFAIR, no possibility to format the output, thus the awk post processor. When someone came up with a C++ approach, I converted it into C: #include int main(void) { unsigned long long i=1LL<<24; while (i<1LL<<48) { printf("%012llX\n",i++); } return 0; } This should be valid C99 code. Of course this is quite wordy, hence I stripped everything the compiler does not need so much: long long i;main(){while(i<1LL<<48)printf("%012llX\n",i++);} For the IOCCC I now would need to start using the preprocessor. ;-) This program produces only the numbers, the sed script needs to be appended. Hence surely no better. An approach in Python3 by dimi is better: python3 -c "for i in range(2**48): print('%012X'%i)" (It does not run with Python 2.) As in the C program, the sed script is still needed. Then, with 75 chars, it's less than the bc version: python3 -c "for i in range(2**48): print('%012X'%i)"|sed 's,.., &,g;s,.,,' Maybe one could shorten the Python part further more; I don't know Python well. Later in the thread the original had been extended to the wish to filter out all numbers with three equal hex-bytes next to each other. This addition to the problem, unfortunately, hadn't been described exact enough, thus some corner-cases are unsure. My solution therefore is: grep -v '\(..\) \1 \1' Comments of any kind are welcome! [0] http://debianforum.de/forum/viewtopic.php?f=28&t=125571 http://marmaro.de/lue/ markus schnalke