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: Sun, 15 Mar 2026 15:09:26 -0700 Organization: A noiseless patient Spider Lines: 103 Message-ID: <86pl5468yx.fsf@linuxsc.com> References: <10n80sc$3soe4$1@dont-email.me> <20260314104246.0000613e@tin.it> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Sun, 15 Mar 2026 22:09:31 +0000 (UTC) Injection-Info: dont-email.me; posting-host="37fbd2bc0a39a2e0da8dcfefffa00bf6"; logging-data="1460169"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19EWrDWpQggIaBrZ0IltwScXe0Ps/W5seE=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:Q9MymanR0yUhsUAj34grxb8ltwM= sha1:cnnQs+p+LfTd7mKdU/ZNXWpU45w= Xref: csiph.com comp.lang.c:397008 peter writes: [some white space added] > On Thu, 19 Feb 2026 16:55:25 -0500 > DFS wrote: > >> Challenge is to output sequential numbers by column then row: >> >> 1 6 11 16 21 >> 2 7 12 17 22 >> 3 8 13 18 23 >> 4 9 14 19 24 >> 5 10 15 20 25 >> >> -------------------------------------------------------------------- >> 1) must be able to cut the output off at any arbitrary value >> lower than rows x columns >> -------------------------------------------------------------------- >> >> -------------------------------------------------------------------- >> 2) if you don't specify rows and columns, your solution must try >> to calculate them to form a square (same # of rows and columns) >> that includes only 1 to N. >> >> If rows=columns can't be calculated, return message 'not possible' >> -------------------------------------------------------------------- > > Here is another version! > This has two alternative implementation techniques: > > - It uses a state machine with computed goto instead of loops Commentary on that below > - It creates a string in memory and outputs that at the end The code outputs values in the same order as they would be if printf() were used. Given the existence of a buffer, it seems like it would be easier to add the output values in simple ascending value order. To say that another way, it doesn't look like building the string in memory, the way it is done here, buys anything. > computed gotos is a gcc extension (also supported by clang). > > Here is the code [...] > void SM(unsigned int rows, unsigned int cols, unsigned int cut ) { > > const static void* jmp_table[2][2] = { > {&&print, &&out,}, > {&&newline, &&out,}, > }; > > unsigned int N=rows*cols; > unsigned int col=0; > unsigned int row=0; > unsigned int nr=1; > unsigned int w=dwidth(cut)+2; > unsigned int pos=0; > char *str=malloc(cut*w+rows*2+16); > > // start of the state machine > > newline: // emit a newline > // then fall tru to print > str[pos++]=10; > col=0; > row++; > > print: // print out number > nr=col*rows+row; > pos = nr<=cut ? addnr(nr, str, pos, w) : pos ; > col++; > goto *jmp_table[col==cols][nr==N]; > > out: // exit the SM > str[pos++]=10; > type(str, pos); > return; > > } //SM This function is a lot more complicated than it needs to be. The code below uses stdio rather than in-memory string buffering, but it would be easy to change that if desired. void show_board( unsigned height, unsigned width, unsigned cutoff ){ const int D = digits_width( cutoff ); const unsigned R = cutoff < height ? cutoff : height; unsigned r = 0, c = 0; while( r < R ){ unsigned v = r + c*height; if( v < cutoff ) printf( " %*u", D, v+1 ); if( ++c >= width ) putchar( '\n' ), c = 0, r++; } }