Kind of goes without saying the solution should handle any row x$ cc /version
column input:
input 1 1
input 2 20$ mcr []rowcol 2 20
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
Simple enough. But the following 2 requirements take it from trivialSure, sure... if you're a professional C programmer with a BS and 5+
to less trivial!
input = 5 5 23 (cutoff at 23)
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19
5 10 15 20
input = 1 10 (no cutoff)$ mcr []rowcol 1 10
1 2 3 4 5 6 7 8 9 10
input = 1 10 3 (cutoff at 3)$ mcr []rowcol 1 10 3
1 2 3
--------------------------------------------------------------------@compile rowcol.c
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' --------------------------------------------------------------------
input = 1 (1 row and 1 column includes 1)
1
input = 2@rowcol 2
not possible to output 1-2 where rows=columns
input = 4 (2 rows and 2 columns includes 4)@rowcol 4
1 3
2 4
input = 5@rowcol 5
not possible to output 1-5 where rows=columns
input = 6$ cc /define=DEBUG=1 rowcol.c
not possible to output 1-6 where rows=columns
input = 9@rowcol 9
1 4 7
2 5 8
3 6 9
input = 10 11 or 12@rowcol 11
not possible to output 1-10/11/12 where rows=columns
input = 25@rowcol 25
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
* Extra Credit if you determine a formula for this requirement. I kindI can't see any. There's probably a better way to do this by putting the col/rows counter stuff in a function but now that I have it working I
of brute-forced it with 2 loops. As you can see, N = prime isn't
enough to know if it can be done.
My code is below.I have not looked until I posted this. Obviously very different. I have
DFS <nospam@dfs.com> writes:
Kind of goes without saying the solution should handle any row x
column input:
Simple enough. But the following 2 requirements take it from trivialSure, sure... if you're a professional C programmer with a BS and 5+
to less trivial!
years experience.
This was a bit above where I am but once I started it
I had to finish it so here I am.
* Extra Credit if you determine a formula for this requirement. I kindI can't see any. There's probably a better way to do this by putting the col/rows counter stuff in a function but now that I have it working I
of brute-forced it with 2 loops. As you can see, N = prime isn't
enough to know if it can be done.
don't want to mess with it.
Glad to be done with this!
@logout
Good afternoon, JAYJWA ...
End of TOPS20:<SYSTEM>LOGOUT.CMD.1
Killed Job 12, User JAYJWA, TTY121 ATR2:/dev/pts/14, at 25-Feb-2026 15:46:17
Used 0:00:00 in 0:52:08
Challenge is to output sequential numbers by column then row:[snip]
Kind of goes without saying the solution should handle any row x column input:[snip]
input rows columns
--------------------------------------------------------------------[snip]
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' --------------------------------------------------------------------
* Extra Credit if you determine a formula for this requirement. I kind
of brute-forced it with 2 loops. As you can see, N = prime isn't
enough to know if it can be done. -----------------------------------------------------------------------
On Thu, 19 Feb 2026 16:55:25 -0500, DFS wrote:
Challenge is to output sequential numbers by column then row:[snip]
Kind of goes without saying the solution should handle any row x column[snip]
input:
input rows columns
--------------------------------------------------------------------[snip]
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'
--------------------------------------------------------------------
* Extra Credit if you determine a formula for this requirement. I kind
of brute-forced it with 2 loops. As you can see, N = prime isn't
enough to know if it can be done.
-----------------------------------------------------------------------
Reasonably trivial. Took me about 20 minutes to get it working.
Hint for the "Extra Credit" part: given the requirement that, when
only "cut-off" specified, rows must equal columns, then the
number of rows and columns are related to the square root of the
cut-off value. And, the partial column can only have between 1
and n_rows values in it. So, invalid cut-off values are easy enough
to compute by using some simple math.
I write more Python than anything (then duplicate the .py programs inPython's great. I did some Java then got distracted by Python then got distracted by C. Since (almost) all of the systems I use have C, C it is
C for exercise).
FYI: your code compiled cleanly 1st time on gccAfter I tested it on Linux, I see it did. Before, when I was building
I notice you stopped at 30x30, I guess because of your monitor?I wanted it to run on TOPS-20, which is headless. That terminal is set
Your name is close to my home state of Jawja.It was my login name in computer class in highschool. It just stuck over
Hint for the "Extra Credit" part: given the requirement that, whenI'm not seeing it. You can cleanly take the square root of 1, 4, and 9
only "cut-off" specified, rows must equal columns, then the
number of rows and columns are related to the square root of the
cut-off value. And, the partial column can only have between 1
and n_rows values in it. So, invalid cut-off values are easy enough
to compute by using some simple math.
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
Hint for the "Extra Credit" part: given the requirement that, whenI'm not seeing it. You can cleanly take the square root of 1, 4, and 9
only "cut-off" specified, rows must equal columns, then the
number of rows and columns are related to the square root of the
cut-off value. And, the partial column can only have between 1
and n_rows values in it. So, invalid cut-off values are easy enough
to compute by using some simple math.
but 6 and 7 yield floats around 2.x. 7 works for the puzzle but 6 does
not.
@rowcol 4
1 3
2 4
@rowcol 5
Not possible to output 1-5 where rows=columns.
@rowcol 6
Not possible to output 1-6 where rows=columns.
@rowcol 7
1 4 7
2 5
3 6
@rowcol 9
1 4 7
2 5 8
3 6 9
@rowcol 1
1
@
On Thu, 26 Feb 2026 13:33:40 -0500, jayjwa wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
Hint for the "Extra Credit" part: given the requirement that, whenI'm not seeing it. You can cleanly take the square root of 1, 4, and 9
only "cut-off" specified, rows must equal columns, then the
number of rows and columns are related to the square root of the
cut-off value. And, the partial column can only have between 1
and n_rows values in it. So, invalid cut-off values are easy enough
to compute by using some simple math.
but 6 and 7 yield floats around 2.x. 7 works for the puzzle but 6 does
not.
@rowcol 4
1 3
2 4
@rowcol 5
Not possible to output 1-5 where rows=columns.
@rowcol 6
Not possible to output 1-6 where rows=columns.
@rowcol 7
1 4 7
2 5
3 6
@rowcol 9
1 4 7
2 5 8
3 6 9
@rowcol 1
1
@
unsigned int n_rows, n_cols, cut_off;
/* ... */
/* handle standalone "cut_off" value */
n_rows = n_cols = ceil(sqrt(cut_off));
if ( (cut_off < (n_rows * (n_cols-1)) + 1) || (cut_off > (n_rows * n_cols)) )
{
fprintf(stderr,"Cut off value %u not possible where rows=cols\n",cut_off);
/* error handling as required */
}
On Thu, 26 Feb 2026 18:49:41 +0000, Lew Pitcher wrote:[snip]
On Thu, 26 Feb 2026 13:33:40 -0500, jayjwa wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
Hint for the "Extra Credit" part: given the requirement that, whenI'm not seeing it. You can cleanly take the square root of 1, 4, and 9
only "cut-off" specified, rows must equal columns, then the
number of rows and columns are related to the square root of the
cut-off value. And, the partial column can only have between 1
and n_rows values in it. So, invalid cut-off values are easy enough
to compute by using some simple math.
but 6 and 7 yield floats around 2.x. 7 works for the puzzle but 6 does
not.
@rowcol 4
1 3
2 4
@rowcol 5
Not possible to output 1-5 where rows=columns.
@rowcol 6
Not possible to output 1-6 where rows=columns.
@rowcol 7
1 4 7
2 5
3 6
@rowcol 9
1 4 7
2 5 8
3 6 9
@rowcol 1
1
@
unsigned int n_rows, n_cols, cut_off;
/* ... */
/* handle standalone "cut_off" value */
n_rows = n_cols = ceil(sqrt(cut_off));
if ( (cut_off < (n_rows * (n_cols-1)) + 1) || (cut_off > (n_rows * n_cols)) )
{
fprintf(stderr,"Cut off value %u not possible where rows=cols\n",cut_off);
/* error handling as required */
}
13:53:54 $ cat cutoff.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void)
{
unsigned int n_rows, n_cols, cut_off;
for (cut_off = 1 ; cut_off < 32; ++cut_off)
{
n_rows = n_cols = ceil(sqrt(cut_off));
if ( (cut_off < (n_rows * (n_cols-1)) + 1) || (cut_off > (n_rows * n_cols)) )
printf("Cut off value %u not possible where rows=cols\n",cut_off);
else
printf("Cut off = %u, Rows = %u, Cols = %u\n",cut_off,n_rows,n_cols);
}
return 0;
}
On Thu, 26 Feb 2026 17:06:53 +0000, Lew Pitcher wrote:
On Thu, 19 Feb 2026 16:55:25 -0500, DFS wrote:
Challenge is to output sequential numbers by column then row:[snip]
Kind of goes without saying the solution should handle any row x column[snip]
input:
input rows columns
--------------------------------------------------------------------[snip]
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'
--------------------------------------------------------------------
* Extra Credit if you determine a formula for this requirement. I kind
of brute-forced it with 2 loops. As you can see, N = prime isn't
enough to know if it can be done.
-----------------------------------------------------------------------
Reasonably trivial. Took me about 20 minutes to get it working.
Hint for the "Extra Credit" part: given the requirement that, when
only "cut-off" specified, rows must equal columns, then the
number of rows and columns are related to the square root of the
cut-off value.
And, the partial column can only have between 1
and n_rows values in it. So, invalid cut-off values are easy enough
to compute by using some simple math.
Script done on Thu 26 Feb 2026 12:25:33 PM EST
On Thu, 19 Feb 2026 16:55:25 -0500, DFS wrote:
Challenge is to output sequential numbers by column then row:[snip]
Kind of goes without saying the solution should handle any row x column[snip]
input:
input rows columns
--------------------------------------------------------------------[snip]
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'
--------------------------------------------------------------------
* Extra Credit if you determine a formula for this requirement. I kind
of brute-forced it with 2 loops. As you can see, N = prime isn't
enough to know if it can be done.
-----------------------------------------------------------------------
Reasonably trivial. Took me about 20 minutes to get it working.
Hint for the "Extra Credit" part: given the requirement that, when
only "cut-off" specified, rows must equal columns, then the
number of rows and columns are related to the square root of the
cut-off value. And, the partial column can only have between 1
and n_rows values in it. So, invalid cut-off values are easy enough
to compute by using some simple math.
On Thu, 26 Feb 2026 17:06:53 +0000, Lew Pitcher wrote:
On Thu, 19 Feb 2026 16:55:25 -0500, DFS wrote:
Challenge is to output sequential numbers by column then row:[snip]
Kind of goes without saying the solution should handle any row x column >>> input:[snip]
input rows columns
--------------------------------------------------------------------[snip]
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'
--------------------------------------------------------------------
* Extra Credit if you determine a formula for this requirement. I kind
of brute-forced it with 2 loops. As you can see, N = prime isn't
enough to know if it can be done.
-----------------------------------------------------------------------
Reasonably trivial. Took me about 20 minutes to get it working.
Hint for the "Extra Credit" part: given the requirement that, when
only "cut-off" specified, rows must equal columns, then the
number of rows and columns are related to the square root of the
cut-off value. And, the partial column can only have between 1
and n_rows values in it. So, invalid cut-off values are easy enough
to compute by using some simple math.
/*
** From: DFS <nospam@dfs.com>
** Newsgroups: comp.lang.c
** Subject: Sort of trivial code challenge - may be interesting to you anyway ** Date: Thu, 19 Feb 2026 16:55:25 -0500
** Message-ID: <10n80sc$3soe4$1@dont-email.me>
**
** Challenge is to output sequential numbers by column then row:
** Kind of goes without saying the solution should handle any row x column ** input:
**
** input rows 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'
** --------------------------------------------------------------------
**
** * Extra Credit if you determine a formula for this requirement. I kind
** of brute-forced it with 2 loops. As you can see, N = prime isn't
** enough to know if it can be done.
** -----------------------------------------------------------------------
**
** Solution by Lew Pitcher 2026-02-26
** cc -o rowcol -mtune=native -Wall -std=c99 -pedantic -lm rowcol.c
**
** NB: uses ceil(), sqrt(), and log10() calls from math lib
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
static int StrUint(const char *string, unsigned int *valu);
static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off);
int main(int argc, char *argv[])
{
int status = EXIT_FAILURE,
args_ok = 1;
unsigned int n_rows = 0,
n_cols = 0,
cut_off = 0;
switch (argc)
{
case 4: /* rowcol #rows #cols cutoff */
if ((StrUint(argv[3],&cut_off) == 0) || (cut_off == 0))
{
fprintf(stderr,"Invalid value for cut-off (\"%s\")\n",argv[3]);
args_ok = 0;
}
case 3: /* rowcol #rows #cols */
if ((StrUint(argv[1],&n_rows) == 0) || (n_rows == 0))
{
fprintf(stderr,"Invalid value for # rows (\"%s\")\n",argv[1]);
args_ok = 0;
}
if ((StrUint(argv[2],&n_cols) == 0) || (n_cols == 0))
{
fprintf(stderr,"Invalid value for # columns (\"%s\")\n",argv[2]);
args_ok = 0;
}
break;
case 2: /* rowcol cutoff */
if ((StrUint(argv[1],&cut_off) == 0) || (cut_off == 0))
{
fprintf(stderr,"Invalid value for cut off (\"%s\")\n",argv[1]);
args_ok = 0;
}
else
{
n_rows = n_cols = ceil(sqrt(cut_off));
if ( (cut_off < (n_rows * (n_cols-1)) + 1) )
{
fprintf(stderr,"Cut off value %u not possible where rows=cols\n",cut_off);
args_ok = 0;
}
}
break;
default:
args_ok = 0; /* default error msg is usage message */
break;
}
if (args_ok)
{
dosquare(n_rows,n_cols,cut_off);
status = EXIT_SUCCESS;
}
else fprintf(stderr,"Usage:\t%s #_rows #_cols [ cut-off ]\nor\t%s cut-off\n",argv[0],argv[0]);
return status;
}
/*
** StrUint() parse string for numeric decimal integer value
** returns 0 on failure,
** 1, valu updated on success
*/
static int StrUint(const char *string, unsigned int *valu)
{
int status = 0;
char *eptr;
unsigned long int result;
result = strtoul(string,&eptr,10);
if ((eptr !=string) && (*eptr == 0) && (result <= UINT_MAX))
{
*valu = result;
status = 1;
}
return status;
}
/*
** dosquare() prints out the specified square, with numbers
** ascending in columns
** Notes:
** 1) square printed with equal field_width, so that all cols
** have same width
** 2) function does not return a value
*/
static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
{
unsigned int field_width; /* for equal spacing of output data */
if (cut_off == 0) cut_off = n_rows * n_cols;
field_width = ceil(log10(cut_off)) + 1;
for (unsigned int row = 0; row < n_rows; ++row)
{
for (unsigned int col = 0; col < n_cols; ++col)
{
unsigned int valu = 1 + row + (col * n_rows);
if (valu <= cut_off)
printf("%-*u",field_width,valu);
}
puts("");
}
}
Challenge is to output sequential numbers by column then row:
input = 25
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
input = 26
not possible to output 1-26 where rows=columns
input = 27
not possible to output 1-27 where rows=columns
etc
* Extra Credit if you determine a formula for this requirement. I kind
˙ of brute-forced it with 2 loops.˙ As you can see, N = prime isn't
˙ enough to know if it can be done. -----------------------------------------------------------------------
My code is below.
Look for 'core routine' to see the master output algorithm
Requirement 1 is part of the core routine
Requirement 2 is the function "calc_rows_columns()"
If you try this, don't feel obligated to output the column headers as I
did.˙ It's a nice-to-have.
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
Simple enough. But the following 2 requirements take it from trivial
to less trivial!
--------------------------------------------------------------------
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' --------------------------------------------------------------------
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from
trivial to less trivial!
--------------------------------------------------------------------
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' --------------------------------------------------------------------
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
On Mon, 02 Mar 2026 00:44:57 -0800
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from
trivial to less trivial!
--------------------------------------------------------------------
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'
--------------------------------------------------------------------
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Does 'etc' include function calls?
I guess that the answer is 'yes', but would like it confirmed.
Another counter challenge could have been to commpletely avoid
loops/goto. But given the hint above it would not be interesting.
Michael S <already5chosen@yahoo.com> writes:
On Mon, 02 Mar 2026 00:44:57 -0800
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from
trivial to less trivial!
--------------------------------------------------------------------
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'
--------------------------------------------------------------------
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Does 'etc' include function calls?
I guess that the answer is 'yes', but would like it confirmed.
I don't think of function calls as being in the same category
as control flow statements. I guess the point of your question
is one loop could be in a function called from within another
loop. The "don't use nested loops" is meant to include dynamic
nesting as well as static nesting. In other words one loop
running, by any means, during the time another loop is in
progress, is disallowed. So a call to a function where the call
is inside a loop, and where the called function effects a loop
in some way, is not allowed any more than 'for(...) for(...)'
would be. Is that specific and well-defined enough to answer
your question? There is no prohibition against function calls
per se; the relevant condition is about loops, including
simulated loops that don't use for() or while() or do/while().
Another counter challenge could have been to commpletely avoid
loops/goto. But given the hint above it would not be interesting.
I am confident it wouldn't be challenging for someone with your
level of experience, but it could be interesting for some other
folks.
The version of this program that I wrote has no for()'s,
while()'s, do/while()'s, or switch() statements, and also has
no nested loops,
and also does not have recursive
function calls.
DFS <nospam@dfs.com> writes:
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
On 3/2/2026 3:44 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Done.
Does everything in my original challenge, but with no loops:
no for.. while.. do.. goto.. or recursion.
On 02/03/2026 14:35, Tim Rentsch wrote:
Michael S <already5chosen@yahoo.com> writes:
On Mon, 02 Mar 2026 00:44:57 -0800
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from
trivial to less trivial!
-------------------------------------------------------------------- >>>>> 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'
--------------------------------------------------------------------
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Does 'etc' include function calls?
I guess that the answer is 'yes', but would like it confirmed.
I don't think of function calls as being in the same category
as control flow statements. I guess the point of your question
is one loop could be in a function called from within another
loop. The "don't use nested loops" is meant to include dynamic
nesting as well as static nesting. In other words one loop
running, by any means, during the time another loop is in
progress, is disallowed. So a call to a function where the call
is inside a loop, and where the called function effects a loop
in some way, is not allowed any more than 'for(...) for(...)'
would be. Is that specific and well-defined enough to answer
your question? There is no prohibition against function calls
per se; the relevant condition is about loops, including
simulated loops that don't use for() or while() or do/while().
Another counter challenge could have been to commpletely avoid
loops/goto. But given the hint above it would not be interesting.
I am confident it wouldn't be challenging for someone with your
level of experience, but it could be interesting for some other
folks.
The version of this program that I wrote has no for()'s,
while()'s, do/while()'s, or switch() statements, and also has
no nested loops,
Doesn't the prior condition preclude that? Since if there are zero
loops, it's hard to make them nested!
DFS <nospam@dfs.com> writes:
On 3/2/2026 3:44 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Done.
Does everything in my original challenge, but with no loops:
no for.. while.. do.. goto.. or recursion.
Unfortunately the two functions generate() and validate() are
mutually recursive.
They may be optimized to use tail-call
elimination, but at the source level they are recursive.
The latest challenge, which I just got through doing, is to
disallow if, for, while, goto, return, and to forbid functions
and function calls except for calls to C standard library
functions.
Also no math library. :)
The program is a bit on the long side because of argument
processing but the matrix print code is less than 20 lines,
including 5 blank lines.
On 3/3/2026 12:09 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
On 3/2/2026 3:44 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Done.
Recursion means the function calls itself.
[...]
The latest challenge, which I just got through doing, is to
disallow if, for, while, goto, return, and to forbid functions
and function calls except for calls to C standard library
functions.
Yikes!
Is main() OK?
How about the use of variables?
What written languages are allowed?
nested ternaries? How deep?
Also no math library. :)
Using math.h allowed me to easily create a one-line formula.
But I could probably now do it in 3-4 lines without math.h.
The program is a bit on the long side because of argument
processing but the matrix print code is less than 20 lines,
including 5 blank lines.
I'll have to bow out for now, but would like to see your latest code.
I note that the no-loops challenge was a worthwhile pursuit I never
even considered.
I think a recursive function could be really short and sweet, so I'm
going to try that.
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from trivial
to less trivial!
--------------------------------------------------------------------
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'
--------------------------------------------------------------------
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
I think it's better to do that in C++ and not in C:
#include <iostream>
#include <thread>
#include <sstream>
#include <iomanip>
using namespace std;
static size_t parse( string_view str );
int main( int argc, char **argv )
{
˙˙˙˙if( argc < 3 )
˙˙˙˙˙˙˙ return EXIT_FAILURE;
˙˙˙˙size_t
˙˙˙˙˙˙˙ rows = parse( argv[1] ),
˙˙˙˙˙˙˙ cols = parse( argv[2] ),
˙˙˙˙˙˙˙ clip = rows * cols;
˙˙˙˙if( argc >= 4 )
˙˙˙˙˙˙˙ clip = parse( argv[3] );
˙˙˙˙if( (ptrdiff_t)rows < 0 || (ptrdiff_t)cols < 0 || (ptrdiff_t)clip <
0 )
˙˙˙˙˙˙˙ return EXIT_FAILURE;
˙˙˙˙unsigned width = [&]
˙˙˙˙˙˙˙ {
˙˙˙˙˙˙˙˙˙˙˙ ostringstream oss;
˙˙˙˙˙˙˙˙˙˙˙ oss << clip;
˙˙˙˙˙˙˙˙˙˙˙ return oss.str().length();
˙˙˙˙˙˙˙ }();
˙˙˙˙for( size_t row = 0; row < rows; ++row )
˙˙˙˙{
˙˙˙˙˙˙˙ for( size_t col = 0; col < cols; ++col )
˙˙˙˙˙˙˙˙˙˙˙ if( size_t value = col * cols + row; value <= clip )
˙˙˙˙˙˙˙˙˙˙˙ {
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ cout << right << setw( width ) << col * cols + row;
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ if( value < clip && col < cols - 1 )
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ cout << ", ";
˙˙˙˙˙˙˙˙˙˙˙ }
˙˙˙˙˙˙˙˙˙˙˙ else
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ break;
˙˙˙˙˙˙˙ cout << endl;
˙˙˙˙}
}
static size_t parse( string_view str )
{
˙˙˙˙istringstream iss( (string( str )) );
˙˙˙˙size_t ret;
˙˙˙˙iss >> ret;
˙˙˙˙return iss && iss.eof() ? ret : -1;
}
I think it's better to do that in C++ and not in C:
Bonita Montero <Bonita.Montero@gmail.com> writes:
I think it's better to do that in C++ and not in C:
The only difference is that you're using the
really awful C++ input and output streams. Horrible stuff.
The C version is far more readable.
Bart <bc@freeuk.com> writes:
On 02/03/2026 14:35, Tim Rentsch wrote:
Michael S <already5chosen@yahoo.com> writes:
On Mon, 02 Mar 2026 00:44:57 -0800
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from[...]
trivial to less trivial!
-------------------------------------------------------------------- >>>>>> 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 tryA straightfoward exercise. Here is a counter challenge to make
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'
-------------------------------------------------------------------- >>>>>
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Does 'etc' include function calls?
I guess that the answer is 'yes', but would like it confirmed.
I don't think of function calls as being in the same category
as control flow statements. I guess the point of your question
is one loop could be in a function called from within another
loop. The "don't use nested loops" is meant to include dynamic
nesting as well as static nesting. In other words one loop
running, by any means, during the time another loop is in
progress, is disallowed. So a call to a function where the call
is inside a loop, and where the called function effects a loop
in some way, is not allowed any more than 'for(...) for(...)'
would be. Is that specific and well-defined enough to answer
your question? There is no prohibition against function calls
per se; the relevant condition is about loops, including
simulated loops that don't use for() or while() or do/while().
Another counter challenge could have been to commpletely avoid
loops/goto. But given the hint above it would not be interesting.
I am confident it wouldn't be challenging for someone with your
level of experience, but it could be interesting for some other
folks.
The version of this program that I wrote has no for()'s,
while()'s, do/while()'s, or switch() statements, and also has
no nested loops,
Doesn't the prior condition preclude that? Since if there are zero
loops, it's hard to make them nested!
I see no reason to answer your questions since you seem to have
no interest in writing C code.
On 03/03/2026 05:15, Tim Rentsch wrote:
[...]
This kind of challenge can be done in any language. My algorithm
can be trivially converted to C if needed; it is clear enough.
[...]
My rule is not to post my own code until others have made a good
faith effort on the challenge.
On Tue, 03 Mar 2026 06:20:33 -0800
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
My rule is not to post my own code until others have made a good
faith effort on the challenge.
One question before I start thinking: is setjmp/longjmp also diallowed?
On Mon, 02 Mar 2026 00:44:57 -0800, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from trivial
to less trivial!
--------------------------------------------------------------------
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'
--------------------------------------------------------------------
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
So, instead of my
for (unsigned int row = 0; row < n_rows; ++row)
{
for (unsigned int col = 0; col < n_cols; ++col)
{
unsigned int valu = 1 + row + (col * n_rows);
if (valu <= cut_off)
printf(" %*u",field_width,valu);
}
putchar('\n');
}
use...
int max = n_rows * n_cols;
for (unsigned int count = 0; count < max; ++count)
{
unsigned int row, col, valu;
col = count % n_cols;
row = count / n_cols;
valu = 1 + row + (col * n_rows);
if (valu <= cut_off) printf(" %*u",field_width,valu);
if (col == n_cols-1) putchar('\n');
}
I think it's better to do that in C++ and not in C:
Bonita Montero <Bonita.Montero@gmail.com> writes:
I think it's better to do that in C++ and not in C:
Then your response should be posted in comp.lang.c++
and not in comp.lang.c.
On 2026-03-03 21:48, Bart wrote:
On 03/03/2026 05:15, Tim Rentsch wrote:
[...]
This kind of challenge can be done in any language. My algorithm
can be trivially converted to C if needed; it is clear enough.
Sure. But let's have a closer look...
It's debatable whether the algorithm is the challenge or whether
writing actual "C" code is the challenge, say, because "C" may
be so convoluted or just inappropriate for such tasks that it's
difficult to solve such challenges with the "C" language. - But
obviously this challenge is not challenging the "C" language in
any way; it's an ordinary ("C", or other) programming task.[*]
So I basically agree with you.[**]
Though, with the subsequent refinements, to abstain from certain
types of language constructs, i.e. programming with one arm tied
behind your back, the question is not as clearly to answer; it's
just easier to compare the various variants and code evolutions
if you have a common language base (and here in CLC that's "C").
On 03/03/2026 22:47, Janis Papanagnou wrote:
On 2026-03-03 21:48, Bart wrote:
On 03/03/2026 05:15, Tim Rentsch wrote:Sure. But let's have a closer look...
[...]
This kind of challenge can be done in any language. My algorithm
can be trivially converted to C if needed; it is clear enough.
It's debatable whether the algorithm is the challenge or whether
writing actual "C" code is the challenge, say, because "C" may
be so convoluted or just inappropriate for such tasks that it's
difficult to solve such challenges with the "C" language. - But
obviously this challenge is not challenging the "C" language in
any way; it's an ordinary ("C", or other) programming task.[*]
So I basically agree with you.[**]
Though, with the subsequent refinements, to abstain from certain
types of language constructs, i.e. programming with one arm tied
behind your back, the question is not as clearly to answer; it's
just easier to compare the various variants and code evolutions
if you have a common language base (and here in CLC that's "C").
The original challenge is a C coding challenge, because it is posted
in a C language group. But it seems entirely reasonable to code it
first in a different language to get a feel for it, and see what the
output is. After all, if you were to ask regulars in this group to
write code for this task without any restrictions on the language, a
fair proportion would reach for languages other than C (I'd expect
mostly Python, but some C++ and some other languages).
As for the later challenges, these are not C programming
challenges. There are just a set of arbitrary silly limitations. A C
coding challenge asks for C code, and any restrictions should come
from the C world. For example, you could ban the use of dynamic
memory because some C programming environments ban that. You could
ban recursive functions, because some C programming environments ban
that. Ban "for" and "while", and you are not programming in C. If
people find that sort of thing fun, that's fine - but don't expect
anyone else to be impressed by it.
In light of this, Tim's reply to Bart is not only childish, petty and unhelpful, but it was also hypocritical. He is no longer talking
about programming in C himself.
Michael S <already5chosen@yahoo.com> writes:
On Tue, 03 Mar 2026 06:20:33 -0800
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
My rule is not to post my own code until others have made a good
faith effort on the challenge.
One question before I start thinking: is setjmp/longjmp also
diallowed?
setjmp and longjmp are both part of the standard C library,
so yes calling them is allowed. (The C standard calls setjmp
a macro, but the Synopsis describes it using a function
interface, so it seems natural to count it as a function.)
David Brown <david.brown@hesbynett.no> writes:
On 03/03/2026 22:47, Janis Papanagnou wrote:
On 2026-03-03 21:48, Bart wrote:
On 03/03/2026 05:15, Tim Rentsch wrote:Sure. But let's have a closer look...
[...]
This kind of challenge can be done in any language. My algorithm
can be trivially converted to C if needed; it is clear enough.
It's debatable whether the algorithm is the challenge or whether
writing actual "C" code is the challenge, say, because "C" may
be so convoluted or just inappropriate for such tasks that it's
difficult to solve such challenges with the "C" language. - But
obviously this challenge is not challenging the "C" language in
any way; it's an ordinary ("C", or other) programming task.[*]
So I basically agree with you.[**]
Though, with the subsequent refinements, to abstain from certain
types of language constructs, i.e. programming with one arm tied
behind your back, the question is not as clearly to answer; it's
just easier to compare the various variants and code evolutions
if you have a common language base (and here in CLC that's "C").
The original challenge is a C coding challenge, because it is posted
in a C language group. But it seems entirely reasonable to code it
first in a different language to get a feel for it, and see what the
output is. After all, if you were to ask regulars in this group to
write code for this task without any restrictions on the language, a
fair proportion would reach for languages other than C (I'd expect
mostly Python, but some C++ and some other languages).
As for the later challenges, these are not C programming
challenges. There are just a set of arbitrary silly limitations. A
C coding challenge asks for C code, and any restrictions should come
from the C world. For example, you could ban the use of dynamic
memory because some C programming environments ban that. You could
ban recursive functions, because some C programming environments ban
that. Ban "for" and "while", and you are not programming in C. If
people find that sort of thing fun, that's fine - but don't expect
anyone else to be impressed by it.
In light of this, Tim's reply to Bart is not only childish, petty
and unhelpful, but it was also hypocritical. He is no longer
talking about programming in C himself.
I disagree. Banning "for" and "while" is an arbitrary restriction,
but a C program with no "for" or "while" is still a C program.
If you're not interested in such a challenge, perhaps because
you think the restriction is silly, that's fine, but this is still comp.lang.c. Showing how to accomplish something in C without "for"
and "while" may or may not be of interest to you, but it's topical.
Posting a solution in C++ or some other language, with or without
"for" and "while", would be inappropriate.
(Starting with some
other language, treating it as pseudo-code, and then translating
the solution to C might be appropriate, but I don't think anyone
here has done that.)
David Brown <david.brown@hesbynett.no> writes:
As for the later challenges, these are not C programming
challenges. There are just a set of arbitrary silly limitations. A C
coding challenge asks for C code, and any restrictions should come
from the C world. For example, you could ban the use of dynamic
memory because some C programming environments ban that. You could
ban recursive functions, because some C programming environments ban
that. Ban "for" and "while", and you are not programming in C. If
people find that sort of thing fun, that's fine - but don't expect
anyone else to be impressed by it.
I disagree. Banning "for" and "while" is an arbitrary restriction,
but a C program with no "for" or "while" is still a C program.
If you're not interested in such a challenge, perhaps because
you think the restriction is silly, that's fine, but this is still comp.lang.c. Showing how to accomplish something in C without "for"
and "while" may or may not be of interest to you, but it's topical.
Posting a solution in C++ or some other language, with or without
"for" and "while", would be inappropriate. (Starting with some
other language, treating it as pseudo-code, and then translating
the solution to C might be appropriate, but I don't think anyone
here has done that.)
On 2026-03-03 21:48, Bart wrote:
On 03/03/2026 05:15, Tim Rentsch wrote:
[...]
This kind of challenge can be done in any language. My algorithm
can be trivially converted to C if needed; it is clear enough.
Sure. But let's have a closer look...
It's debatable whether the algorithm is the challenge or whether
writing actual "C" code is the challenge, say, because "C" may
be so convoluted or just inappropriate for such tasks that it's
difficult to solve such challenges with the "C" language. - But
obviously this challenge is not challenging the "C" language in
any way; it's an ordinary ("C", or other) programming task.[*]
So I basically agree with you.[**]
Though, with the subsequent refinements, to abstain from certain
types of language constructs, i.e. programming with one arm tied
behind your back, the question is not as clearly to answer; it's
just easier to compare the various variants and code evolutions
if you have a common language base (and here in CLC that's "C").
Janis
[...]
[*] A task that other folks might have solved by using existing
tools instead of explicit and longish error-prone programming.
[**] Not everyone here might appreciate code in other languages
as you know.[***]
[***] Though I, personally, would be interested to see other
languages' solutions *if* you could do such things easier with
some specific other language; this would then has a drift to a
comparison of "C" design with other languages' designs, which
I'd then perceive as an interesting topical question.[****]
[****] But for *that* your language would not qualify because,
as you said, it can be "trivially converted to C".
DFS <nospam@dfs.com> writes:
On 3/3/2026 12:09 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
On 3/2/2026 3:44 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Done.
I should have added, I appreciate your taking on the challenge.
Recursion means the function calls itself.
What you're describing is called direct recursion. The word
recursion by itself, without the adjective, includes the case
of mutually recursive functions.
[...]
The latest challenge, which I just got through doing, is to
disallow if, for, while, goto, return, and to forbid functions
and function calls except for calls to C standard library
functions.
Yikes!
Is main() OK?
Yes, sorry, not mentioning main() was an oversight on my part.
(Still not okay to call it.)
How about the use of variables?
Sure.
What written languages are allowed?
Standard ISO C. Okay not to be strictly conforming. :)
nested ternaries? How deep?
Sure. As deep as you can stand, within reason. My own code
sometimes used ?: at the end of another ?: but not in the middle
(ie, ... ? ... ? ... : ... : ... never appeared).
Also no math library. :)
Using math.h allowed me to easily create a one-line formula.
But I could probably now do it in 3-4 lines without math.h.
Yes it isn't hard.
The program is a bit on the long side because of argument
processing but the matrix print code is less than 20 lines,
including 5 blank lines.
I'll have to bow out for now, but would like to see your latest code.
My rule is not to post my own code until others have made a good
faith effort on the challenge.
I note that the no-loops challenge was a worthwhile pursuit I never
even considered.
Yes, no loops is fun. Once you get used to it, using tail-recursive functions in place of loops often seems like a better choice.
I think a recursive function could be really short and sweet, so I'm
going to try that.
By all means. The version I first wrote had two tail-recursive
functions, one to find the appropriate number of rows and columns
for a given cutoff, and one to show the matrix of values.
On 03/03/2026 05:15, Tim Rentsch wrote:
I see no reason to answer your questions since you seem to have >> no interest in writing C code.
This kind of challenge can be done in any language. My algorithm can be trivially converted to C if needed; it is clear enough.
Anwway, when I submitted my version, the last post in the thread was by
the OP, and it contained some Python code. So likely some here might
also be prototyping in a soft language first.
On 3/3/2026 3:48 PM, Bart wrote:
On 03/03/2026 05:15, Tim Rentsch wrote:
I see no reason to answer your questions since you seem to have >> no
interest in writing C code.
This kind of challenge can be done in any language. My algorithm can
be trivially converted to C if needed; it is clear enough.
Anwway, when I submitted my version, the last post in the thread was
by the OP, and it contained some Python code. So likely some here
might also be prototyping in a soft language first.
I never posted any python code in this thread.
incredible.
I spent at least 20 minutes just trying to make nested loops work:
for i in range(rows):
for j in range(cols):
I was trapped in my mind by the idea the code had to start like that,
with consecutive loops statements.
On Tue, 03 Mar 2026 15:51:08 -0800
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
On Tue, 03 Mar 2026 06:20:33 -0800
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
My rule is not to post my own code until others have made a good
faith effort on the challenge.
One question before I start thinking: is setjmp/longjmp also
diallowed?
setjmp and longjmp are both part of the standard C library,
so yes calling them is allowed. (The C standard calls setjmp
a macro, but the Synopsis describes it using a function
interface, so it seems natural to count it as a function.)
If setjmp/longjmp allowed then it's not interesting.
No thinking required, just tedious work and attention to details.
At least, that's how it looks to me without actually trying.
On 04/03/2026 13:30, DFS wrote:
On 3/3/2026 3:48 PM, Bart wrote:
On 03/03/2026 05:15, Tim Rentsch wrote:
I see no reason to answer your questions since you seem to have >>
no interest in writing C code.
This kind of challenge can be done in any language. My algorithm can
be trivially converted to C if needed; it is clear enough.
Anwway, when I submitted my version, the last post in the thread was
by the OP, and it contained some Python code. So likely some here
might also be prototyping in a soft language first.
I never posted any python code in this thread.
I was refering to this:
On 26/02/2026 19:31, DFS wrote:
incredible.
I spent at least 20 minutes just trying to make nested loops work:
for i in range(rows):
˙˙˙˙˙ for j in range(cols):
I was trapped in my mind by the idea the code had to start like that,
with consecutive loops statements.
for.. and while.. loops are more intuitive (because we likely spent many years using them), but once I got it working without them it felt sort
of freeing.
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
On Mon, 02 Mar 2026 00:44:57 -0800, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from trivial
to less trivial!
--------------------------------------------------------------------
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'
--------------------------------------------------------------------
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
So, instead of my
for (unsigned int row = 0; row < n_rows; ++row)
{
for (unsigned int col = 0; col < n_cols; ++col)
{
unsigned int valu = 1 + row + (col * n_rows);
if (valu <= cut_off)
printf(" %*u",field_width,valu);
}
putchar('\n');
}
use...
int max = n_rows * n_cols;
for (unsigned int count = 0; count < max; ++count)
{
unsigned int row, col, valu;
col = count % n_cols;
row = count / n_cols;
valu = 1 + row + (col * n_rows);
if (valu <= cut_off) printf(" %*u",field_width,valu);
if (col == n_cols-1) putchar('\n');
}
Right. Except for minor differences in spacing, this code
gives the same output as your original.
One glitch: when the cutoff is less than the number of
rows, this code behaves differently than what DFS prescribes,
as can be seen by an example in his original posting. (The
original code also.)
On 3/3/2026 9:20 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
On 3/3/2026 12:09 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
On 3/2/2026 3:44 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
Done.
I should have added, I appreciate your taking on the challenge.
Absolutely. It was actually interesting to get it done without loops.
Recursion means the function calls itself.
What you're describing is called direct recursion. The word
recursion by itself, without the adjective, includes the case
of mutually recursive functions.
I see.
I didn't realize there were so many types of recursion:
direct: tail, head, tree, nested
indirect (or mutual), linear, multiple, structural, generative.
[...]
The latest challenge, which I just got through doing, is to
disallow if, for, while, goto, return, and to forbid functions
and function calls except for calls to C standard library
functions.
Yikes!
Is main() OK?
Yes, sorry, not mentioning main() was an oversight on my part.
(Still not okay to call it.)
I was actually kidding, but I see online you can do some trickery to
make a standalone C program work without main().
[...]
I note that the no-loops challenge was a worthwhile pursuit I never
even considered.
Yes, no loops is fun. Once you get used to it, using tail-recursive
functions in place of loops often seems like a better choice.
Yes.
for.. and while.. loops are more intuitive (because we likely spent
many years using them), but once I got it working without them it felt
sort of freeing.
I think a recursive function could be really short and sweet, so I'm
going to try that.
By all means. The version I first wrote had two tail-recursive
functions, one to find the appropriate number of rows and columns
for a given cutoff, and one to show the matrix of values.
I recently thought of a new approach: fill an array with 1 to the
cutoff (min(cutoff, rows*cols) anyway), and just print the whole array
col by row. Then there's never a need to check each value as you're
printing it.
For me a for.. loop is easiest to fill an array.
but if loops are banned you could do it recursively.
but if recursion is banned you could do it?
To my eye, printing sequential numbers or names by column-row looks
better than by row-column.
On Tue, 03 Mar 2026 16:23:54 -0800, Tim Rentsch wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
On Mon, 02 Mar 2026 00:44:57 -0800, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
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
[...]
Simple enough. But the following 2 requirements take it from trivial >>>>> to less trivial!
-------------------------------------------------------------------- >>>>> 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' >>>>> --------------------------------------------------------------------
A straightfoward exercise. Here is a counter challenge to make
things more interesting: as above, but don't use nested loops
(or goto's, etc).
So, instead of my
for (unsigned int row = 0; row < n_rows; ++row)
{
for (unsigned int col = 0; col < n_cols; ++col)
{
unsigned int valu = 1 + row + (col * n_rows);
if (valu <= cut_off)
printf(" %*u",field_width,valu);
}
putchar('\n');
}
use...
int max = n_rows * n_cols;
for (unsigned int count = 0; count < max; ++count)
{
unsigned int row, col, valu;
col = count % n_cols;
row = count / n_cols;
valu = 1 + row + (col * n_rows);
if (valu <= cut_off) printf(" %*u",field_width,valu);
if (col == n_cols-1) putchar('\n');
}
Right. Except for minor differences in spacing, this code
gives the same output as your original.
True enough. I've been fiddling with the column alignment;
the code I originally posted kept DFS' example left alignment,
but I prefer right alignment of numbers in columnar format.
The minor differences in spacing come from me not remembering
which version I posted. Mea culpa.
One glitch: when the cutoff is less than the number of
rows, this code behaves differently than what DFS prescribes,
as can be seen by an example in his original posting. (The
original code also.)
Right. I noticed that as well, but too late. I've modified my
code to conform to the "no blank lines" rule. However, I have
mutated the code from the original that I presented here,
what with conditional compilation and all, and will post it later.
My current code does not satisfy the later counter-challenge of
avoiding for()/do/do while()/goto/ and recursion. That's a
challenge that I have to think on ;-)
Actually, I would not mind demonstration of how it can be done in C++[...]
On 3/3/2026 9:20 AM, Tim Rentsch wrote:[...]
DFS <nospam@dfs.com> writes:
Is main() OK?Yes, sorry, not mentioning main() was an oversight on my part.
(Still not okay to call it.)
I was actually kidding, but I see online you can do some trickery to
make a standalone C program work without main().
Why? Just for s's and giggles?
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
(...)
Now it fits:
#include <iostream>
#include <thread>
#include <sstream>
#include <iomanip>
#include <optional>
using namespace std;
static optional<size_t> parse( const char *str );
int main( int argc, char **argv )
{
˙˙˙˙if( argc < 3 )
˙˙˙˙˙˙˙ return EXIT_FAILURE;
˙˙˙˙optional<size_t>
˙˙˙˙˙˙˙ rows = parse( argv[1] ),
˙˙˙˙˙˙˙ cols = parse( argv[2] );
˙˙˙˙if( !rows || !cols )
˙˙˙˙˙˙˙ return EXIT_FAILURE;
˙˙˙˙size_t clip = *rows * *cols - 1;
˙˙˙˙if( argc >= 4 )
˙˙˙˙˙˙˙ if( optional<size_t> pClip = parse( argv[3] ); pClip )
˙˙˙˙˙˙˙˙˙˙˙ clip = *pClip <= clip ? *pClip : clip;
˙˙˙˙˙˙˙ else
˙˙˙˙˙˙˙˙˙˙˙ return EXIT_FAILURE;
˙˙˙˙unsigned width = [&]
˙˙˙˙˙˙˙ {
˙˙˙˙˙˙˙˙˙˙˙ ostringstream oss;
˙˙˙˙˙˙˙˙˙˙˙ oss << clip;
˙˙˙˙˙˙˙˙˙˙˙ return (unsigned)oss.str().length();
˙˙˙˙˙˙˙ }();
˙˙˙˙if( clip < rows )
˙˙˙˙˙˙˙ rows = clip + 1;
˙˙˙˙for( size_t row = 0; row < rows; ++row )
˙˙˙˙{
˙˙˙˙˙˙˙ for( size_t col = 0, value; col < *cols; ++col )
˙˙˙˙˙˙˙˙˙˙˙ if( size_t value = col * *rows + row; value <= clip )
˙˙˙˙˙˙˙˙˙˙˙ {
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ cout << right << setw( width ) << value;
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ if( value < clip && col < *cols - 1 )
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ cout << ", ";
˙˙˙˙˙˙˙˙˙˙˙ }
˙˙˙˙˙˙˙˙˙˙˙ else
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ break;
˙˙˙˙˙˙˙ cout << endl;
˙˙˙˙}
}
static optional<size_t> parse( const char *str )
{
˙˙˙˙istringstream iss( str );
˙˙˙˙size_t ret;
˙˙˙˙iss >> ret;
˙˙˙˙if( !iss || !iss.eof() )
˙˙˙˙˙˙˙ return nullopt;
˙˙˙˙return ret;
}
The detection of parsing errors is much more comfortable with that
since the parse function returns a nullopt wenn the value could not
been parsed.
That's C++: less and more readable code.
On 3/4/2026 5:44 AM, Bonita Montero wrote:
<code below>
Your first code compiled fine
$ g++ rc-montero1.cpp -o rc
$
but this one tossed out a lot of errors.
$ g++ rc-montero2.cpp -o rc[277 lines deleted]
rc-montero2.cpp:13:1: error: extended character ˙ is not valid in an identifier
13 | ˙˙˙˙if( argc < 3 )
| ^
On 3/4/2026 5:44 AM, Bonita Montero wrote:
<code below>
Your first code compiled fine
$ g++ rc-montero1.cpp -o rc
$
but this one tossed out a lot of errors.
$ g++ rc-montero2.cpp -o rc
rc-montero2.cpp:13:1: error: extended character ˙ is not valid in an >identifier
13 | ˙˙˙˙if( argc < 3 )
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:[277 lines deleted]
<code below>
Your first code compiled fine
$ g++ rc-montero1.cpp -o rc
$
but this one tossed out a lot of errors.
$ g++ rc-montero2.cpp -o rc
rc-montero2.cpp:13:1: error: extended character ˙ is not valid in an
identifier
13 | ˙˙˙˙if( argc < 3 )
| ^
Apparently the code you compiled contained NO-BREAK-SPACE (U+00a0) characters, and your compiler didn't tolerate them.
You really really didn't need to post hundreds of lines of error
messages to make that point -- especially since the code was C++
and should never have been posted to comp.lang.c in the first place.
It was thunderbird which made a NBSP-row out of my tabs.
˙˙˙ unsigned width = [&]
˙˙˙˙˙˙˙ {
˙˙˙˙˙˙˙˙˙˙˙ ostringstream oss;
˙˙˙˙˙˙˙˙˙˙˙ oss << clip - 1;
˙˙˙˙˙˙˙˙˙˙˙ return (unsigned)oss.str().length();
˙˙˙˙˙˙˙ }();
Now it fits:
That's C++: less and more readable code.
On 3/4/2026 5:44 AM, Bonita Montero wrote:
Now it fits:
Almost.
With no stop you print 0 to input-1
$./rc 1 3
0, 1, 2
With stop you print 0 to stop
$ ./rc 5 1 3
0
1
2
3
Both inputs should print 3 numbers.
That's C++: less and more readable code.
<53 lines of almost unreadable C++ snipped>
-------------------------------------------------------------------
My 29 lines of C that matches the functionality of your 53 lines -------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
˙˙˙˙if (argc < 3 || argc > 4) {
˙˙˙˙˙˙˙ printf("Enter 2 or 3 arguments:\n$./prog rows columns [stop]\n");
˙˙˙˙˙˙˙ return 0;
˙˙˙˙}
˙˙˙˙int rows = atoi(argv[1]);
˙˙˙˙int cols = atoi(argv[2]);
˙˙˙˙int max = (argc == 4) ? atoi(argv[3]) : rows * cols ;
˙˙˙˙char cw[6];
˙˙˙˙int colwidth = sprintf(cw,"%d",max) + 1;
˙˙˙˙for (int r = 1; r <= rows; r++) {
˙˙˙˙˙˙˙ if (r <= max) {
˙˙˙˙˙˙˙˙˙˙˙ int nbr = r;
˙˙˙˙˙˙˙˙˙˙˙ printf("%*d",colwidth,nbr);
˙˙˙˙˙˙˙˙˙˙˙ for (int i = 0; i < cols-1; i++) {
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ nbr += rows;
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ (nbr <= max) ? printf("%*d",colwidth,nbr) : 0 ;
˙˙˙˙˙˙˙˙˙˙˙ }
˙˙˙˙˙˙˙˙˙˙˙ printf("\n");
˙˙˙˙˙˙˙ }
˙˙˙˙˙˙˙ else
˙˙˙˙˙˙˙ {
˙˙˙˙˙˙˙˙˙ break;
˙˙˙˙˙˙˙ }
˙˙˙˙}
˙˙˙˙return 0;
}
----------------------------------------------------------
Now it's even shorter - and still *with* error handling:
#include <iostream>
And *still* in the wrong group.I'm impressed about how far your reading goes.
Am 05.03.2026 um 08:24 schrieb DFS:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
Now it fits:
Almost.
With no stop you print 0 to input-1
$./rc 1 3
0, 1, 2
With stop you print 0 to stop
$ ./rc 5 1 3
0
1
2
3
Both inputs should print 3 numbers.
That's C++: less and more readable code.
<53 lines of almost unreadable C++ snipped>
-------------------------------------------------------------------
My 29 lines of C that matches the functionality of your 53 lines
-------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
˙˙˙˙˙if (argc < 3 || argc > 4) {
˙˙˙˙˙˙˙˙ printf("Enter 2 or 3 arguments:\n$./prog rows columns
[stop]\n");
˙˙˙˙˙˙˙˙ return 0;
˙˙˙˙˙}
˙˙˙˙˙int rows = atoi(argv[1]);
˙˙˙˙˙int cols = atoi(argv[2]);
˙˙˙˙˙int max = (argc == 4) ? atoi(argv[3]) : rows * cols ;
˙˙˙˙˙char cw[6];
˙˙˙˙˙int colwidth = sprintf(cw,"%d",max) + 1;
˙˙˙˙˙for (int r = 1; r <= rows; r++) {
˙˙˙˙˙˙˙˙ if (r <= max) {
˙˙˙˙˙˙˙˙˙˙˙˙ int nbr = r;
˙˙˙˙˙˙˙˙˙˙˙˙ printf("%*d",colwidth,nbr);
˙˙˙˙˙˙˙˙˙˙˙˙ for (int i = 0; i < cols-1; i++) {
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ nbr += rows;
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ (nbr <= max) ? printf("%*d",colwidth,nbr) : 0 ;
˙˙˙˙˙˙˙˙˙˙˙˙ }
˙˙˙˙˙˙˙˙˙˙˙˙ printf("\n");
˙˙˙˙˙˙˙˙ }
˙˙˙˙˙˙˙˙ else
˙˙˙˙˙˙˙˙ {
˙˙˙˙˙˙˙˙˙˙ break;
˙˙˙˙˙˙˙˙ }
˙˙˙˙˙}
˙˙˙˙˙return 0;
}
----------------------------------------------------------
This is more readable
and *with* error handling while parsing the
parameters. You don't have that.
#include <iostream>
#include <thread>
#include <sstream>
#include <iomanip>
#include <optional>
#include <algorithm>
using namespace std;
static optional<size_t> parse( const char *str );
int main( int argc, char **argv )
{
˙˙˙˙if( argc < 3 )
˙˙˙˙˙˙˙ return EXIT_FAILURE;
˙˙˙˙optional<size_t>
˙˙˙˙˙˙˙ rows = parse( argv[1] ),
˙˙˙˙˙˙˙ cols = parse( argv[2] );
˙˙˙˙if( !rows || !*rows || !cols || !*cols )
˙˙˙˙˙˙˙ return EXIT_FAILURE;
˙˙˙˙size_t clip = *rows * *cols;
˙˙˙˙if( argc >= 4 )
˙˙˙˙˙˙˙ if( optional<size_t> psClip = parse( argv[3] ); psClip &&
*psClip )
˙˙˙˙˙˙˙˙˙˙˙ clip = (*psClip <= clip ? *psClip : clip) + 1;
˙˙˙˙˙˙˙ else
˙˙˙˙˙˙˙˙˙˙˙ return EXIT_FAILURE;
˙˙˙˙size_t nMtx = *rows * *cols;
˙˙˙˙clip = clip <= nMtx ? clip : nMtx;
˙˙˙˙unsigned width = (unsigned)(ostringstream() << clip - 1).str().length();
˙˙˙˙for( size_t row = 0; row < min( *rows, clip ); ++row )
˙˙˙˙{
˙˙˙˙˙˙˙ bool head = true;
˙˙˙˙˙˙˙ for( size_t value = row; value < min( nMtx, clip ); value +=
*rows, head = false )
˙˙˙˙˙˙˙˙˙˙˙ cout << " "sv.substr( head, !head ) << right << setw( width
) << value;
˙˙˙˙˙˙˙ cout << endl;
˙˙˙˙}
}
static optional<size_t> parse( const char *str )
{
˙˙˙˙istringstream iss( str );
˙˙˙˙size_t ret;
˙˙˙˙iss >> ret;
˙˙˙˙if( !iss || !iss.eof() )
˙˙˙˙˙˙˙ return nullopt;
˙˙˙˙return ret;
}
Definitely not.˙ But if you indented correctly it would be easier to read. Win for C either way.
| Sysop: | Tetrazocine |
|---|---|
| Location: | Melbourne, VIC, Australia |
| Users: | 15 |
| Nodes: | 8 (0 / 8) |
| Uptime: | 238:00:02 |
| Calls: | 207 |
| Files: | 21,502 |
| Messages: | 83,256 |