Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: Sort of trivial code challenge - may be interesting to you anyway Date: Wed, 11 Mar 2026 08:23:12 -0700 Organization: A noiseless patient Spider Lines: 115 Message-ID: <86v7f28k67.fsf@linuxsc.com> References: <10n80sc$3soe4$1@dont-email.me> <86v7feei2e.fsf@linuxsc.com> <10o53k6$1i0ef$2@dont-email.me> <86ms0peby6.fsf@linuxsc.com> <10ockdh$3qpk6$1@dont-email.me> <10ocrjn$3qpk6$2@dont-email.me> <10od64s$3qpk6$4@dont-email.me> <86ikb9bmtw.fsf@linuxsc.com> <10oem5t$n5hk$1@dont-email.me> <86o6kz9zng.fsf@linuxsc.com> <10oi72k$1rss6$1@dont-email.me> <20260308003557.00000754@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Wed, 11 Mar 2026 15:23:16 +0000 (UTC) Injection-Info: dont-email.me; posting-host="5f44bcdbc02769ce6998caa4a4cb2206"; logging-data="1172321"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19VV78YjrGOtbVarhdjBFPYW6kWxsahV9E=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:Ffm9a5JhKS6t+LTpCrmC5QdO9Fg= sha1:2wY4OrkvwoeNaX0p/cAoJ4+DlpQ= Xref: csiph.com comp.lang.c:396906 Michael S writes: > On Sat, 7 Mar 2026 16:58:48 -0500 > DFS wrote: > >> A nit you may have forgotten: you earlier said main() was not allowed: > > You misunderstood. > Having main() is allowed and necessary. Calling main() in your code is > forbidden. Right. > If calling main() recursively was allowed then possible solution could > be just uglier than previos counter-challenge, but would not require > any different ideas. It may not require different ideas, but IMO it benefits from adopting an approach similar to the posted setjmp version. Here is a revision of the code I posted, changed so that it does not use setjmp()/longjmp() but instead calls main() recursively. I think using recursive calls to main to simulate having multiple functions would make the code more difficult to understand, not easier. Note by the way that all calls to main() below are tail calls, and are optimized away, so there is no stack depth penalty for this method, unlike using recursive calls to main to simulate having other functions available. #include #include #include typedef size_t Z; typedef _Bool B; static Z k, h, w, c; static int d; #define GO(x) return main( (x), argv ) #define NUMBERISH(p) ((p) && *(p) && (p)[ strspn((p),"0123456789") ] == 0) enum { START, // the initial state; must be zero NADA = -99, // make the following values all be negative AFU, USAGE, // give suitable message and exit ROOT, DRAT, // find ceiling( sqrt( cutoff ) ); possible no joy exit HWC, // display H*W values with cutoff C FIN, // exit program }; int main( int argc, char *argv[] ){ switch( argc < 0 ? argc : 0 ){ case START: { B usage = argc < 2 || argc > 4; B g1 = argc > 1 && NUMBERISH( argv[1] ); B g2 = argc > 2 && NUMBERISH( argv[2] ); B g3 = argc > 3 && NUMBERISH( argv[3] ); Z a1 = g1 ? strtoul( argv[1], 0, 10 ) : 0; Z a2 = g2 ? strtoul( argv[2], 0, 10 ) : 0; Z a3 = g3 ? strtoul( argv[3], 0, 10 ) : 0; B square = argc == 2 && g1; B hw = argc == 3 && g1&&g2 && a1&&a2; B hwc = argc == 4 && g1&&g2 && a1&&a2 && g3; k = 0; h = hw || hwc ? a1 : a1/4 + !a1; // note: initial value(h) > 0 w = hw || hwc ? a2 : h; c = square ? a1 : !hwc ? h*w : a3 > h*w ? h*w : a3; d = snprintf( 0, 0, "%zu", c ); GO( usage ?USAGE : square ?ROOT : (hw||hwc) && a1&&a2 ?HWC : AFU ); } case AFU: printf( " urk... bad arguments\n" ); GO( USAGE ); case USAGE: printf( " usage:\n" ); printf( " %s cutoff {{for square}}\n", argv[0] ); printf( " %s rows columns [cutoff]\n", argv[0] ); GO( FIN ); case ROOT: { h = c < 2 ? 1 : c < 5 ? 2 : (h + c/h) / 2; h += h*h < c; w = h; B done = c < 2 || h*h < c+2*h && c <= h*h; B good = c < 2 || h*h < c+h && c <= h*h; GO( !done ?ROOT : good ?HWC : DRAT ); } case DRAT: printf( " square with cutoff %zu - no joy\n", c ); GO( FIN ); case HWC: { B eol = k/h + 1 == w; B end = k+1 + (h>c ? h-c : 0) >= h*w; Z nextk = eol ? k - (w-1)*h + 1 : k+h; printf( k < c ? " %*zu" : "", d, k+1 ); printf( c > 0 && eol ? "\n" : "" ); GO( end ?(printf( "------\n" ), FIN) : (k = nextk, HWC) ); } } }