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++;
}
}