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.
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
On 3/5/26 09:52, Bonita Montero wrote:
Now it's even shorter - and still *with* error handling:
#include <iostream>
And *still* in the wrong group.
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
using ciel(log10(rows*columns)) performs better than snprintf
in this application.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
DFS <nospam@dfs.com> writes:
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?
I'm curious what you're referring to. It's not possible to have a
working *portable* C program (for a hosted implementation) without
a main function. There might be some compiler-specific tricks for
using or specifying an entry point with a different name.
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
using ciel(log10(rows*columns)) performs better than snprintf
in this application.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
On Wed, 4 Mar 2026 10:02:02 -0500
DFS <nospam@dfs.com> wrote:
To my eye, printing sequential numbers or names by column-row looks
better than by row-column.
Were you programming in Fortran in your youth?
On 3/4/2026 12:27 PM, Michael S wrote:
On Wed, 4 Mar 2026 10:02:02 -0500
DFS <nospam@dfs.com> wrote:
To my eye, printing sequential numbers or names by column-row looks
better than by row-column.
Were you programming in Fortran in your youth?
Nah. Never looked at it.
Is column-row output an option in Fortran?
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.
Am 05.03.2026 um 11:06 schrieb DFS:
Definitely not.ÿ But if you indented correctly it would be easier to
read.
Win for C either way.
Absolutely not.
It's the typical C code which is prone to buffer-over-
flows (sprintf)
and there's no checking of the validity of the command-
line-parameters.
But usually C++ is about five times less code
since there are no built
-in complex containers like a map<> or an unordered_map in C. If you
want to to that in C you have to stick with external libraries which
do the polymorphic behaviour with callbacks (slower).
That's the most popular reason C++ is mostly much less code, but there a few further.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Don't do that with 64 bit integrals and a FPU which has 53 bits mantissa.
On 3/5/26 19:46, Bonita Montero wrote:
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Don't do that with 64 bit integrals and a FPU which has 53 bits
mantissa.
Why ?
On 3/4/2026 2:25 PM, Keith Thompson wrote:
DFS <nospam@dfs.com> writes:
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?
I'm curious what you're referring to.ÿ It's not possible to have a
working *portable* C program (for a hosted implementation) without
a main function.ÿ There might be some compiler-specific tricks for
using or specifying an entry point with a different name.
Correct, per Google AI Overview (for "c program without main function")
"While the C standard requires a main() function for programs running in
a standard "hosted" environment, it is technically possible to create an executable program without explicitly defining main() using non-
standard, implementation-specific methods.
These methods often fall into two main categories:
1. Using Preprocessor Directives (Macros)
2. Modifying the Entry Point (Linker Options)"
Rentsch's motivation seems to be doing something way outside the box.
All will be revealed when he releases his double-secret code.
On 3/4/2026 12:27 PM, Michael S wrote:
On Wed, 4 Mar 2026 10:02:02 -0500
DFS <nospam@dfs.com> wrote:
To my eye, printing sequential numbers or names by column-row looks
better than by row-column.
Were you programming in Fortran in your youth?
Nah.ÿ Never looked at it.
Is column-row output an option in Fortran?
I programmed internal business software my entire IT career.
Lotus-1-2-3 macros
dBase, clipper and Paradox (DOS)
ObjectPAL (an offshoot of Delphi used in Borland Paradox for Windows
desktop database)
small amts of Rexx and perl and Java
T-SQL and Oracle PL/SQL
tons of VB and VBA
hobby coding
PowerBuilder
first C program May 2014
first Python early 2016
I like C for raw performance and strictness of code.
I like python for ease of use and productivity.
Where else but Python can you get meaningful Usenet stats in 22 lines?
-------------------------------------------------------
import sys as y,nntplib as t
On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
[snip]
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. :)
Inventive, aren't you :-)
I've got a working matrix print that (I think) satisfies your
requirements, but have not started on the argument processing
logic yet. I may, yet again, revise my approach, as the solution
I'm using is quite tedious to code.
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.
20 lines, including 4 blank lines, but I can reduce it a bit.
I should be able to match (or at least approximate) your line
count.
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
using ciel(log10(rows*columns)) performs better than snprintf
in this application.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
On Wed, 4 Mar 2026 10:02:02 -0500
DFS <nospam@dfs.com> wrote:
To my eye, printing sequential numbers or names by column-row looks
better than by row-column.
Were you programming in Fortran in your youth?
On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
[snip]
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. :)
Inventive, aren't you :-)
I've got a working matrix print that (I think) satisfies your
requirements, but have not started on the argument processing
logic yet. I may, yet again, revise my approach, as the solution
I'm using is quite tedious to code.
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.
20 lines, including 4 blank lines, but I can reduce it a bit.
I should be able to match (or at least approximate) your line
count.
On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:
On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
[snip]
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. :)
Inventive, aren't you :-)
I've got a working matrix print that (I think) satisfies your
requirements, but have not started on the argument processing
logic yet. I may, yet again, revise my approach, as the solution
I'm using is quite tedious to code.
OK, so the "no if statements" is a bit of a bother, but not
insurmountable. It's just a case of switching things around.
And, perhaps there's a third option as well.
As I said, the alternatives are just tedious to code.
But, I now need to find a replacement for sqrt() that doesn't take
a lot of space. Back to first principles for me, then.
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:
On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
[snip]
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. :)
Inventive, aren't you :-)
I've got a working matrix print that (I think) satisfies your
requirements, but have not started on the argument processing
logic yet. I may, yet again, revise my approach, as the solution
I'm using is quite tedious to code.
OK, so the "no if statements" is a bit of a bother, but not
insurmountable. It's just a case of switching things around.
And, perhaps there's a third option as well.
As I said, the alternatives are just tedious to code.
I did manage to find some tricks to make things simpler, but
probably the most important is ?: is your friend.
But, I now need to find a replacement for sqrt() that doesn't take
a lot of space. Back to first principles for me, then.
There is an easy way to do this, if not especially elegant: start a
counter at 0 and count it up until counter*counter >= cutoff. Then
there is a straightword arithmetic test to see if counter is good or
bad.
On Thu, 05 Mar 2026 14:12:19 -0800, Tim Rentsch wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:
On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
[snip]
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. :)
Inventive, aren't you :-)
I've got a working matrix print that (I think) satisfies your
requirements, but have not started on the argument processing
logic yet. I may, yet again, revise my approach, as the solution
I'm using is quite tedious to code.
OK, so the "no if statements" is a bit of a bother, but not
insurmountable. It's just a case of switching things around.
And, perhaps there's a third option as well.
As I said, the alternatives are just tedious to code.
I did manage to find some tricks to make things simpler, but
probably the most important is ?: is your friend.
that, and switch()/case, which is a nice substitute for if ()
statements with complex bodies, or if () / else statements.
But, I now need to find a replacement for sqrt() that doesn't take
a lot of space. Back to first principles for me, then.
There is an easy way to do this, if not especially elegant: start a counter at 0 and count it up until counter*counter >= cutoff. Then
there is a straightword arithmetic test to see if counter is good or
bad.
I was playing with the Heron's method of approximation, but was
getting anomalous numbers when coded to the restrictions of the
challenge.
I don't mind burning cycles, and might go for the straightforward
way, but I'm still thinking on it
On Thu, 05 Mar 2026 14:12:19 -0800, Tim Rentsch wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:
On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
[snip]
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. :)
Inventive, aren't you :-)
I've got a working matrix print that (I think) satisfies your
requirements, but have not started on the argument processing
logic yet. I may, yet again, revise my approach, as the solution
I'm using is quite tedious to code.
OK, so the "no if statements" is a bit of a bother, but not
insurmountable. It's just a case of switching things around.
And, perhaps there's a third option as well.
As I said, the alternatives are just tedious to code.
I did manage to find some tricks to make things simpler, but
probably the most important is ?: is your friend.
that, and switch()/case, which is a nice substitute for if () statements
with complex bodies, or if () / else statements.
But, I now need to find a replacement for sqrt() that doesn't take
a lot of space. Back to first principles for me, then.
There is an easy way to do this, if not especially elegant: start a
counter at 0 and count it up until counter*counter >= cutoff. Then
there is a straightword arithmetic test to see if counter is good or
bad.
I was playing with the Heron's method of approximation, but was
getting anomalous numbers when coded to the restrictions of the
challenge.
I don't mind burning cycles, and might go for the straightforward
way, but I'm still thinking on it
On Thu, 5 Mar 2026 22:24:53 -0000 (UTC)
Lew Pitcher <lew.pitcher@digitalfreehold.ca> wrote:
On Thu, 05 Mar 2026 14:12:19 -0800, Tim Rentsch wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:
On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
[snip]
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. :)
Inventive, aren't you :-)
I've got a working matrix print that (I think) satisfies your
requirements, but have not started on the argument processing
logic yet. I may, yet again, revise my approach, as the solution
I'm using is quite tedious to code.
OK, so the "no if statements" is a bit of a bother, but not
insurmountable. It's just a case of switching things around.
And, perhaps there's a third option as well.
As I said, the alternatives are just tedious to code.
I did manage to find some tricks to make things simpler, but
probably the most important is ?: is your friend.
that, and switch()/case, which is a nice substitute for if ()
statements with complex bodies, or if () / else statements.
My impression was that switch is omitted from the list of disallowed constructs by mistake.
On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:[...]
But, I now need to find a replacement for sqrt() that doesn't take
a lot of space. Back to first principles for me, then.
OK, it's not pretty, but here it is
/*
** 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
** --------------------------------------------------------------------
** 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'
** --------------------------------------------------------------------
**
** * 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.
** -----------------------------------------------------------------------
**
** From: Tim Rentsch <tr.17687@z991.linuxsc.com>
** Newsgroups: comp.lang.c
** Subject: Re: Sort of trivial code challenge - may be interesting to you anyway
** Date: Mon, 02 Mar 2026 21:09:21 -0800
** Message-ID: <86ms0peby6.fsf@linuxsc.com>
**
** 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. :)
**
** ========================================================================== **
** Tim Rentsch counter-counter-challenge; solution by Lew Pitcher 2026-03-05 ** cc -o rowcol_TR2 -mtune=native -Wall -std=c99 -pedantic -w rowcol_TR2.c
**
** Note: -w to suppress warnings relating to using switch() to evaluate
** a boolean value
**
** This code released into the public domain. Lew Pitcher, 2026-03-04
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <setjmp.h>
#include <math.h>
On 05/03/2026 18:49, DFS wrote:
On 3/4/2026 12:27 PM, Michael S wrote:
Where else but Python can you get meaningful Usenet stats in 22 lines?
-------------------------------------------------------
import sys as y,nntplib as t
How many lines would it be without using 'nntplib'?
Most of Python's usefulness is due to the availability of lots of
different libraries. It is an actual scripting language.
(However when I ran your script, it was missing 'nntplib'.)
scott@slp53.sl.home (Scott Lurndal) writes:
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
using ciel(log10(rows*columns)) performs better than snprintf
in this application.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Using snprintf() is more correct and also more obviously correct.
It's the typical C code which is prone to buffer-over-
flows (sprintf)
s/typical/untested
But usually C++ is about five times less code
since there are no built
-in complex containers like a map<> or an unordered_map in C. If you
want to to that in C you have to stick with external libraries which
do the polymorphic behaviour with callbacks (slower).
External library not necessary.ÿ It's a little bit of code, such as: https://www.geeksforgeeks.org/dsa/implementation-on-map-or-dictionary- data-structure-in-c/
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
using ciel(log10(rows*columns)) performs better than snprintf
in this application.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Using snprintf() is more correct and also more obviously correct.
Yes, I had assumed the first row, first column would be zero, not one.
OK, it's not pretty, but here it is
On 3/5/26 19:46, Bonita Montero wrote:
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Don't do that with 64 bit integrals and a FPU which has 53 bits mantissa.
ÿÿ Why ?
Am 05.03.2026 um 20:50 schrieb tTh:
On 3/5/26 19:46, Bonita Montero wrote:
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Don't do that with 64 bit integrals and a FPU which has 53 bits
mantissa.
?? Why ?
Because the 53 bits may mistakenly represent a power of ten because
the lower bits were dropped.
The formula is incorrect, regardless.
With correct formula, i.e. floor(..)+1, imprecision become harmless.
For numbers like 9999999999999979 you get one unnecessary space.
Not a big deal.
Am 06.03.2026 um 10:49 schrieb Michael S:
The formula is incorrect, regardless.
With correct formula, i.e. floor(..)+1, imprecision become harmless.
For numbers like 9999999999999979 you get one unnecessary space.
Not a big deal.
Then better count characters.
There's more than one way to skin a cat.
Ogh, sorry. I mean, more than one to post a picture of kitten.
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
OK, it's not pretty, but here it is
No worries - being pretty is not on the list of requested properties. :)
Congratulations on being the first to post an answer.
Two problems related to how setjmp()/longjmp() are used:
1. Any local variable changed between a setjmp() and the longjmp()
that goes back to it must be declared 'volatile' to avoid problems
with indeterminate values. (Minor.)
2. A pattern like 'x = setjmp( jbuf );' is not one of the officially
approved forms in the C standard for setjmp(). More specifically,
any such usage has undefined behavior. (More serious.)
If you look in the C standard for setjmp(), there is a subsection
titled 'Environmental limits' that explains which forms are approved
for use. Personally I think it's regrettable that 'x = setjmp( jbuf );'
is not one of them, but I feel obliged to observe that limitation and
follow what the standard prescribes for using setjmp().
scott@slp53.sl.home (Scott Lurndal) writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
using ciel(log10(rows*columns)) performs better than snprintf
in this application.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Using snprintf() is more correct and also more obviously correct.
Yes, I had assumed the first row, first column would be zero, not one.
The value for 10 is also wrong. And 100. And 1000. etc...
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
using ciel(log10(rows*columns)) performs better than snprintf
in this application.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Using snprintf() is more correct and also more obviously correct.
Yes, I had assumed the first row, first column would be zero, not
one.
The value for 10 is also wrong. And 100. And 1000. etc...
No, 10*10 yields 100 values from 0 to 99.
DFS <nospam@dfs.com> writes:
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.
Hmmm. Well I give you points for originality. ;)
If both of those hints aren't enough, ask again and I'll try to get
you closer to the goal.
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("");
}
}
OK, it's not pretty, but here it is
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
DFS <nospam@dfs.com> writes:
On 3/4/2026 5:44 AM, Bonita Montero wrote:
int colwidth = sprintf(cw,"%d",max) + 1;
using ciel(log10(rows*columns)) performs better than snprintf
in this application.
$ printf '%f\n' $(( ceil(log10( 8*8)) ))
2.000000
Using snprintf() is more correct and also more obviously correct.
Yes, I had assumed the first row, first column would be zero, not one.
The value for 10 is also wrong. And 100. And 1000. etc...
No, 10*10 yields 100 values from 0 to 99.
On 3/4/2026 11:09 AM, Tim Rentsch wrote:
DFS <nospam@dfs.com> writes:
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.
Hmmm. Well I give you points for originality. ;)
I'm sensing sarcasm.
I pursued the array approach (a little differently than I described
above), but in the end it was useless and a waste of time.
example: 4x4 array looked like this:
position: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
initial : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
filled : 1 5 9 13 0 2 6 10 14 0 3 7 11 15 0 4 8 12 16
printed :
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
When you come to a 0 you do newline.
Worked great with no cutoffs, but couldn't quite get the printing
right when there were cutoff values. And it ended up being about 50%
MORE code than my original algorithm. And it used an unnecessary
array object.
Altogether a fail.
If both of those hints aren't enough, ask again and I'll try to get
you closer to the goal.
I'll wait until you post your majestic code.
On Thu, 05 Mar 2026 20:31:39 -0800, Tim Rentsch wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
OK, it's not pretty, but here it is
No worries - being pretty is not on the list of requested properties. :)
Congratulations on being the first to post an answer.
Two problems related to how setjmp()/longjmp() are used:
1. Any local variable changed between a setjmp() and the longjmp()
that goes back to it must be declared 'volatile' to avoid problems
with indeterminate values. (Minor.)
2. A pattern like 'x = setjmp( jbuf );' is not one of the officially
approved forms in the C standard for setjmp(). More specifically,
any such usage has undefined behavior. (More serious.)
If you look in the C standard for setjmp(), there is a subsection
titled 'Environmental limits' that explains which forms are approved
for use. Personally I think it's regrettable that 'x = setjmp( jbuf );'
is not one of them, but I feel obliged to observe that limitation and
follow what the standard prescribes for using setjmp().
yah.
As you can tell, I haven't used setjmp()/longjmp() much, and am
unfamiliar with the caveats surrounding them.
I'll look at revising my code, in the light of your comments, and
repost with a more "legal" version.
Thanks for the observations. I look forward to seeing /your/ code :-)
I assume it works according to the spec, where I admit I don't fully understand the conditions. So input of '10 10 90' is fine (prints 1-90 within 10x10 matrix) omits final column), but input of '90' fails, even though it's the same square matrix.
On 2/26/2026 2:34 PM, Lew Pitcher wrote:
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("");
}
}
I found a nit:[snip]
with 1-column inputs like 10 1 3 or 100 1 25, your program prints (row
- cutoff) blank lines after the cutoff.
On Fri, 06 Mar 2026 10:36:19 -0500, DFS wrote:
On 2/26/2026 2:34 PM, Lew Pitcher wrote:[snip]
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("");
}
}
I found a nit:
with 1-column inputs like 10 1 3 or 100 1 25, your program prints (row
- cutoff) blank lines after the cutoff.
Yes, I'm aware :-)
I fixed it in a later version, which I have not posted yet.
On 3/6/2026 11:02 AM, Bart wrote:
I assume it works according to the spec, where I admit I don't fully
understand the conditions. So input of '10 10 90' is fine (prints 1-90
within 10x10 matrix) omits final column), but input of '90' fails,
even though it's the same square matrix.
The condition is "Can a square matrix contain only 1-N?"
Only a non-square matrix of 10x9 or 9x10 can contain 1-90.
Only a square matrix of 10x10 can contain 1-91.
On 3/6/2026 12:11 PM, DFS wrote:
1) only a non-square matrix of 10x9 or 9x10 can contain only 1-90.
2) only a square matrix of 10x10 can contain only 1-91
------------------------------
ÿ 1ÿ 2ÿ 3ÿ 4ÿ 5ÿ 6ÿ 7ÿ 8ÿ 9 10
------------------------------
ÿ 1 11 21 31 41 51 61 71 81 91
ÿ 2 12 22 32 42 52 62 72 82
ÿ 3 13 23 33 43 53 63 73 83
ÿ 4 14 24 34 44 54 64 74 84
ÿ 5 15 25 35 45 55 65 75 85
ÿ 6 16 26 36 46 56 66 76 86
ÿ 7 17 27 37 47 57 67 77 87
ÿ 8 18 28 38 48 58 68 78 88
ÿ 9 19 29 39 49 59 69 79 89
ÿ10 20 30 40 50 60 70 80 90
On 3/6/2026 11:02 AM, Bart wrote:
I assume it works according to the spec, where I admit I don't fully
understand the conditions. So input of '10 10 90' is fine (prints 1-90
within 10x10 matrix) omits final column), but input of '90' fails,
even though it's the same square matrix.
The condition is "Can a square matrix contain only 1-N?"
Only a non-square matrix of 10x9 or 9x10 can contain 1-90.
Only a square matrix of 10x10 can contain 1-91.
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
Thanks for the observations. I look forward to seeing /your/ code :-)
I'm eager to post it.
I'm still hoping DFS will at least post an attempt.
I'm happy to give a hint if someone asks. Let's say I
will wait another day or so and can post after that whether or
not DFS has come forward.
On 3/6/2026 11:53 AM, Tim Rentsch wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
Thanks for the observations. I look forward to seeing /your/ code :-)
I'm eager to post it.
It's time!
I'm still hoping DFS will at least post an attempt.
You're an optimist. You'd make a good lion tamer.
"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."
would probably take me 3 days solid to research and write
I did deliver a "no fors, whiles, gotos, or returns" version.
Then I bowed out.
On 06/03/2026 17:11, DFS wrote:
On 3/6/2026 11:02 AM, Bart wrote:
I assume it works according to the spec, where I admit I don't fully
understand the conditions. So input of '10 10 90' is fine (prints
1-90 within 10x10 matrix) omits final column), but input of '90'
fails, even though it's the same square matrix.
The condition is "Can a square matrix contain only 1-N?"
Only a non-square matrix of 10x9 or 9x10 can contain 1-90.
Only a square matrix of 10x10 can contain 1-91.
I still don't get it. Doesn't an input of '10 10 90' specify a square matrix? But it still prints the numbers 1-90:
ÿc:\cx>t 10 10 90ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ # run LP's program
ÿ1ÿ 11 21 31 41 51 61 71 81
ÿ2ÿ 12 22 32 42 52 62 72 82
ÿ3ÿ 13 23 33 43 53 63 73 83
ÿ4ÿ 14 24 34 44 54 64 74 84
ÿ5ÿ 15 25 35 45 55 65 75 85
ÿ6ÿ 16 26 36 46 56 66 76 86
ÿ7ÿ 17 27 37 47 57 67 77 87
ÿ8ÿ 18 28 38 48 58 68 78 88
ÿ9ÿ 19 29 39 49 59 69 79 89
ÿ10 20 30 40 50 60 70 80 90
But this fails:
ÿc:\cx>t 90
ÿCut off value 90 not possible where rows=cols
ÿUsage:ÿ t #_rows #_cols [ cut-off ]
ÿorÿÿÿÿÿ t cut-off
This second invocation couldn't print 1-90 within a 10x10 matrix, but
the first one could. Or is that first one not considered square; it's a rectangle where height and width happen to be the same?
[...]
For another view:
Inputÿÿ Sqr Matrix?ÿÿÿ sqrt(Input)
----------------------------------
ÿÿ 1ÿÿÿ possibleÿÿÿÿÿÿÿ 1.00
ÿÿ 2ÿÿÿ not possibleÿÿÿ 1.41
ÿÿ 3ÿÿÿ possibleÿÿÿÿÿÿÿ 1.73
ÿÿ 4ÿÿÿ possibleÿÿÿÿÿÿÿ 2.00
ÿÿ 5ÿÿÿ not possibleÿÿÿ 2.24
ÿÿ 6ÿÿÿ not possibleÿÿÿ 2.45
ÿÿ 7ÿÿÿ possibleÿÿÿÿÿÿÿ 2.65
ÿÿ 8ÿÿÿ possibleÿÿÿÿÿÿÿ 2.83
ÿÿ 9ÿÿÿ possibleÿÿÿÿÿÿÿ 3.00
ÿ 10ÿÿÿ not possibleÿÿÿ 3.16
ÿ 11ÿÿÿ not possibleÿÿÿ 3.32
ÿ 12ÿÿÿ not possibleÿÿÿ 3.46
ÿ 13ÿÿÿ possibleÿÿÿÿÿÿÿ 3.61
ÿ 14ÿÿÿ possibleÿÿÿÿÿÿÿ 3.74
ÿ 15ÿÿÿ possibleÿÿÿÿÿÿÿ 3.87
ÿ 16ÿÿÿ possibleÿÿÿÿÿÿÿ 4.00
ÿ 17ÿÿÿ not possibleÿÿÿ 4.12
ÿ 18ÿÿÿ not possibleÿÿÿ 4.24
ÿ 19ÿÿÿ not possibleÿÿÿ 4.36
ÿ 20ÿÿÿ not possibleÿÿÿ 4.47
ÿ 21ÿÿÿ possibleÿÿÿÿÿÿÿ 4.58
ÿ 22ÿÿÿ possibleÿÿÿÿÿÿÿ 4.69
ÿ 23ÿÿÿ possibleÿÿÿÿÿÿÿ 4.80
ÿ 24ÿÿÿ possibleÿÿÿÿÿÿÿ 4.90
ÿ 25ÿÿÿ possibleÿÿÿÿÿÿÿ 5.00
ÿ 26ÿÿÿ not possibleÿÿÿ 5.10
ÿ 27ÿÿÿ not possibleÿÿÿ 5.20
ÿ 28ÿÿÿ not possibleÿÿÿ 5.29
ÿ 29ÿÿÿ not possibleÿÿÿ 5.39
ÿ 30ÿÿÿ not possibleÿÿÿ 5.48
ÿ 31ÿÿÿ possibleÿÿÿÿÿÿÿ 5.57
ÿ 32ÿÿÿ possibleÿÿÿÿÿÿÿ 5.66
ÿ 33ÿÿÿ possibleÿÿÿÿÿÿÿ 5.74
ÿ 34ÿÿÿ possibleÿÿÿÿÿÿÿ 5.83
ÿ 35ÿÿÿ possibleÿÿÿÿÿÿÿ 5.92
ÿ 36ÿÿÿ possibleÿÿÿÿÿÿÿ 6.00
ÿ 37ÿÿÿ not possibleÿÿÿ 6.08
ÿ 38ÿÿÿ not possibleÿÿÿ 6.16
ÿ 39ÿÿÿ not possibleÿÿÿ 6.24
ÿ 40ÿÿÿ not possibleÿÿÿ 6.32
ÿ 41ÿÿÿ not possibleÿÿÿ 6.40
ÿ 42ÿÿÿ not possibleÿÿÿ 6.48
ÿ 43ÿÿÿ possibleÿÿÿÿÿÿÿ 6.56
ÿ 44ÿÿÿ possibleÿÿÿÿÿÿÿ 6.63
ÿ 45ÿÿÿ possibleÿÿÿÿÿÿÿ 6.71
ÿ 46ÿÿÿ possibleÿÿÿÿÿÿÿ 6.78
ÿ 47ÿÿÿ possibleÿÿÿÿÿÿÿ 6.86
ÿ 48ÿÿÿ possibleÿÿÿÿÿÿÿ 6.93
ÿ 49ÿÿÿ possibleÿÿÿÿÿÿÿ 7.00
ÿ 50ÿÿÿ not possibleÿÿÿ 7.07
ÿ 51ÿÿÿ not possibleÿÿÿ 7.14
ÿ 52ÿÿÿ not possibleÿÿÿ 7.21
ÿ 53ÿÿÿ not possibleÿÿÿ 7.28
ÿ 54ÿÿÿ not possibleÿÿÿ 7.35
ÿ 55ÿÿÿ not possibleÿÿÿ 7.42
ÿ 56ÿÿÿ not possibleÿÿÿ 7.48
ÿ 57ÿÿÿ possibleÿÿÿÿÿÿÿ 7.55
ÿ 58ÿÿÿ possibleÿÿÿÿÿÿÿ 7.62
ÿ 59ÿÿÿ possibleÿÿÿÿÿÿÿ 7.68
ÿ 60ÿÿÿ possibleÿÿÿÿÿÿÿ 7.75
ÿ 61ÿÿÿ possibleÿÿÿÿÿÿÿ 7.81
ÿ 62ÿÿÿ possibleÿÿÿÿÿÿÿ 7.87
ÿ 63ÿÿÿ possibleÿÿÿÿÿÿÿ 7.94
ÿ 64ÿÿÿ possibleÿÿÿÿÿÿÿ 8.00
ÿ 65ÿÿÿ not possibleÿÿÿ 8.06
ÿ 66ÿÿÿ not possibleÿÿÿ 8.12
ÿ 67ÿÿÿ not possibleÿÿÿ 8.19
ÿ 68ÿÿÿ not possibleÿÿÿ 8.25
ÿ 69ÿÿÿ not possibleÿÿÿ 8.31
ÿ 70ÿÿÿ not possibleÿÿÿ 8.37
ÿ 71ÿÿÿ not possibleÿÿÿ 8.43
ÿ 72ÿÿÿ not possibleÿÿÿ 8.49
ÿ 73ÿÿÿ possibleÿÿÿÿÿÿÿ 8.54
ÿ 74ÿÿÿ possibleÿÿÿÿÿÿÿ 8.60
ÿ 75ÿÿÿ possibleÿÿÿÿÿÿÿ 8.66
ÿ 76ÿÿÿ possibleÿÿÿÿÿÿÿ 8.72
ÿ 77ÿÿÿ possibleÿÿÿÿÿÿÿ 8.77
ÿ 78ÿÿÿ possibleÿÿÿÿÿÿÿ 8.83
ÿ 79ÿÿÿ possibleÿÿÿÿÿÿÿ 8.89
ÿ 80ÿÿÿ possibleÿÿÿÿÿÿÿ 8.94
ÿ 81ÿÿÿ possibleÿÿÿÿÿÿÿ 9.00
ÿ 82ÿÿÿ not possibleÿÿÿ 9.06
ÿ 83ÿÿÿ not possibleÿÿÿ 9.11
ÿ 84ÿÿÿ not possibleÿÿÿ 9.17
ÿ 85ÿÿÿ not possibleÿÿÿ 9.22
ÿ 86ÿÿÿ not possibleÿÿÿ 9.27
ÿ 87ÿÿÿ not possibleÿÿÿ 9.33
ÿ 88ÿÿÿ not possibleÿÿÿ 9.38
ÿ 89ÿÿÿ not possibleÿÿÿ 9.43
ÿ 90ÿÿÿ not possibleÿÿÿ 9.49
ÿ 91ÿÿÿ possibleÿÿÿÿÿÿÿ 9.54
ÿ 92ÿÿÿ possibleÿÿÿÿÿÿÿ 9.59
ÿ 93ÿÿÿ possibleÿÿÿÿÿÿÿ 9.64
ÿ 94ÿÿÿ possibleÿÿÿÿÿÿÿ 9.70
ÿ 95ÿÿÿ possibleÿÿÿÿÿÿÿ 9.75
ÿ 96ÿÿÿ possibleÿÿÿÿÿÿÿ 9.80
ÿ 97ÿÿÿ possibleÿÿÿÿÿÿÿ 9.85
ÿ 98ÿÿÿ possibleÿÿÿÿÿÿÿ 9.90
ÿ 99ÿÿÿ possibleÿÿÿÿÿÿÿ 9.95
ÿ100ÿÿÿ possibleÿÿÿÿÿÿÿ 10.00
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
On 3/6/2026 4:53 PM, Bart wrote:
On 06/03/2026 17:11, DFS wrote:
On 3/6/2026 11:02 AM, Bart wrote:
I assume it works according to the spec, where I admit I don't fully
understand the conditions. So input of '10 10 90' is fine (prints
1-90 within 10x10 matrix) omits final column), but input of '90'
fails, even though it's the same square matrix.
The condition is "Can a square matrix contain only 1-N?"
Only a non-square matrix of 10x9 or 9x10 can contain 1-90.
Only a square matrix of 10x10 can contain 1-91.
I still don't get it. Doesn't an input of '10 10 90' specify a square
matrix? But it still prints the numbers 1-90:
ÿÿc:\cx>t 10 10 90ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ # run LP's program
ÿÿ1ÿ 11 21 31 41 51 61 71 81
ÿÿ2ÿ 12 22 32 42 52 62 72 82
ÿÿ3ÿ 13 23 33 43 53 63 73 83
ÿÿ4ÿ 14 24 34 44 54 64 74 84
ÿÿ5ÿ 15 25 35 45 55 65 75 85
ÿÿ6ÿ 16 26 36 46 56 66 76 86
ÿÿ7ÿ 17 27 37 47 57 67 77 87
ÿÿ8ÿ 18 28 38 48 58 68 78 88
ÿÿ9ÿ 19 29 39 49 59 69 79 89
ÿÿ10 20 30 40 50 60 70 80 90
That's a 10x9 matrix.
ÿ 89ÿÿÿ not possibleÿÿÿ 9.43
ÿ 90ÿÿÿ not possibleÿÿÿ 9.49
ÿ 91ÿÿÿ possibleÿÿÿÿÿÿÿ 9.54
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
On 07/03/2026 03:14, DFS wrote:
On 3/6/2026 4:53 PM, Bart wrote:
On 06/03/2026 17:11, DFS wrote:
On 3/6/2026 11:02 AM, Bart wrote:
I assume it works according to the spec, where I admit I don't
fully understand the conditions. So input of '10 10 90' is fine
(prints 1-90 within 10x10 matrix) omits final column), but input of >>>>> '90' fails, even though it's the same square matrix.
The condition is "Can a square matrix contain only 1-N?"
Only a non-square matrix of 10x9 or 9x10 can contain 1-90.
Only a square matrix of 10x10 can contain 1-91.
I still don't get it. Doesn't an input of '10 10 90' specify a square
matrix? But it still prints the numbers 1-90:
ÿÿc:\cx>t 10 10 90ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ # run LP's program
ÿÿ1ÿ 11 21 31 41 51 61 71 81
ÿÿ2ÿ 12 22 32 42 52 62 72 82
ÿÿ3ÿ 13 23 33 43 53 63 73 83
ÿÿ4ÿ 14 24 34 44 54 64 74 84
ÿÿ5ÿ 15 25 35 45 55 65 75 85
ÿÿ6ÿ 16 26 36 46 56 66 76 86
ÿÿ7ÿ 17 27 37 47 57 67 77 87
ÿÿ8ÿ 18 28 38 48 58 68 78 88
ÿÿ9ÿ 19 29 39 49 59 69 79 89
ÿÿ10 20 30 40 50 60 70 80 90
That's a 10x9 matrix.
But the request is for a 10x10 matrix with a cut-off of 90.
What's the difference between that, and a specifying only the cut-off of
90, where the numbers need to be within a square matrix for the smallest square that can display 90 numbers? That would be 10x10 too.
The difference not only appears to be very subtle, but I don't
understand why it is important.
If I disable that restriction for my version that only does cut-offs
within a square matrix, and show "-" where there is no output, then this output for N=4-7:
ÿinput = 4
ÿ1 3
ÿ2 4
ÿinput = 5
ÿnot possible to output 1-5 where rows=columns
ÿinput = 6
ÿnot possible to output 1-6 where rows=columns
ÿinput = 7
ÿ1 4 7
ÿ2 5
ÿ3 6
becomes instead:
ÿinput = 4
ÿ1 3
ÿ2 4
ÿinput = 5
ÿ1 4 -
ÿ2 5 -
ÿ3 - -
ÿinput = 6
ÿ1 4 -
ÿ2 5 -
ÿ3 6 -
ÿinput = 7
ÿ1 4 7
ÿ2 5 -
ÿ3 6 -
What exactly is the problem? That "input = 6" version (minus the hypens)
is also what I get with Lew's program with inputs of "3 3 6". I asked
for 3 columns, and got only two.
ÿÿ 89ÿÿÿ not possibleÿÿÿ 9.43
ÿÿ 90ÿÿÿ not possibleÿÿÿ 9.49
ÿÿ 91ÿÿÿ possibleÿÿÿÿÿÿÿ 9.54
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
I've looked, but can't see a pattern!
On 07/03/2026 03:14, DFS wrote:
On 3/6/2026 4:53 PM, Bart wrote:
On 06/03/2026 17:11, DFS wrote:
On 3/6/2026 11:02 AM, Bart wrote:
I assume it works according to the spec, where I admit I don't
fully understand the conditions. So input of '10 10 90' is fine
(prints 1-90 within 10x10 matrix) omits final column), but input of >>>>> '90' fails, even though it's the same square matrix.
The condition is "Can a square matrix contain only 1-N?"
Only a non-square matrix of 10x9 or 9x10 can contain 1-90.
Only a square matrix of 10x10 can contain 1-91.
I still don't get it. Doesn't an input of '10 10 90' specify a square
matrix? But it still prints the numbers 1-90:
ÿÿc:\cx>t 10 10 90ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ # run LP's program
ÿÿ1ÿ 11 21 31 41 51 61 71 81
ÿÿ2ÿ 12 22 32 42 52 62 72 82
ÿÿ3ÿ 13 23 33 43 53 63 73 83
ÿÿ4ÿ 14 24 34 44 54 64 74 84
ÿÿ5ÿ 15 25 35 45 55 65 75 85
ÿÿ6ÿ 16 26 36 46 56 66 76 86
ÿÿ7ÿ 17 27 37 47 57 67 77 87
ÿÿ8ÿ 18 28 38 48 58 68 78 88
ÿÿ9ÿ 19 29 39 49 59 69 79 89
ÿÿ10 20 30 40 50 60 70 80 90
That's a 10x9 matrix.
But the request is for a 10x10 matrix with a cut-off of 90.
What's the difference between that, and a specifying only the cut-off of
90, where the numbers need to be within a square matrix for the smallest square that can display 90 numbers? That would be 10x10 too.
The difference not only appears to be very subtle, but I don't
understand why it is important.
If I disable that restriction for my version that only does cut-offs
within a square matrix, and show "-" where there is no output, then this output for N=4-7:
ÿinput = 4
ÿ1 3
ÿ2 4
ÿinput = 5
ÿnot possible to output 1-5 where rows=columns
ÿinput = 6
ÿnot possible to output 1-6 where rows=columns
ÿinput = 7
ÿ1 4 7
ÿ2 5
ÿ3 6
becomes instead:
ÿinput = 4
ÿ1 3
ÿ2 4
ÿinput = 5
ÿ1 4 -
ÿ2 5 -
ÿ3 - -
ÿinput = 6
ÿ1 4 -
ÿ2 5 -
ÿ3 6 -
ÿinput = 7
ÿ1 4 7
ÿ2 5 -
ÿ3 6 -
What exactly is the problem?
That "input = 6" version (minus the hypens)
is also what I get with Lew's program with inputs of "3 3 6". I asked
for 3 columns, and got only two.
ÿÿ 89ÿÿÿ not possibleÿÿÿ 9.43
ÿÿ 90ÿÿÿ not possibleÿÿÿ 9.49
ÿÿ 91ÿÿÿ possibleÿÿÿÿÿÿÿ 9.54
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
I've looked, but can't see a pattern!
On 07.03.26 04:14, DFS wrote:
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
I don't see what the sqrt value would demonstrate here.
On 07/03/2026 13:33, Bart wrote:
ÿÿ 89ÿÿÿ not possibleÿÿÿ 9.43
ÿÿ 90ÿÿÿ not possibleÿÿÿ 9.49
ÿÿ 91ÿÿÿ possibleÿÿÿÿÿÿÿ 9.54
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
I've looked, but can't see a pattern!
All I can see is that it's possible for x.00 and >= x.50, and not
possible for < x.50
I don't know why.ÿ I could (easily) be completely wrong :)
On 07/03/2026 13:33, Bart wrote:?????? # run LP's program
On 07/03/2026 03:14, DFS wrote:
On 3/6/2026 4:53 PM, Bart wrote:
On 06/03/2026 17:11, DFS wrote:
On 3/6/2026 11:02 AM, Bart wrote:
I assume it works according to the spec, where I admit I don't
fully understand the conditions. So input of '10 10 90' is fine
(prints 1-90 within 10x10 matrix) omits final column), but
input of '90' fails, even though it's the same square matrix.
The condition is "Can a square matrix contain only 1-N?"
Only a non-square matrix of 10x9 or 9x10 can contain 1-90.
Only a square matrix of 10x10 can contain 1-91.
I still don't get it. Doesn't an input of '10 10 90' specify a
square matrix? But it still prints the numbers 1-90:
??c:\cx>t 10 10 90???????????????
??1? 11 21 31 41 51 61 71 81
??2? 12 22 32 42 52 62 72 82
??3? 13 23 33 43 53 63 73 83
??4? 14 24 34 44 54 64 74 84
??5? 15 25 35 45 55 65 75 85
??6? 16 26 36 46 56 66 76 86
??7? 17 27 37 47 57 67 77 87
??8? 18 28 38 48 58 68 78 88
??9? 19 29 39 49 59 69 79 89
??10 20 30 40 50 60 70 80 90
That's a 10x9 matrix.
But the request is for a 10x10 matrix with a cut-off of 90.
What's the difference between that, and a specifying only the
cut-off of 90, where the numbers need to be within a square matrix
for the smallest square that can display 90 numbers? That would be
10x10 too.
The difference not only appears to be very subtle, but I don't
understand why it is important.
If I disable that restriction for my version that only does
cut-offs within a square matrix, and show "-" where there is no
output, then this output for N=4-7:
?input = 4
?1 3
?2 4
?input = 5
?not possible to output 1-5 where rows=columns
?input = 6
?not possible to output 1-6 where rows=columns
?input = 7
?1 4 7
?2 5
?3 6
becomes instead:
?input = 4
?1 3
?2 4
?input = 5
?1 4 -
?2 5 -
?3 - -
?input = 6
?1 4 -
?2 5 -
?3 6 -
?input = 7
?1 4 7
?2 5 -
?3 6 -
What exactly is the problem? That "input = 6" version (minus the
hypens) is also what I get with Lew's program with inputs of "3 3
6". I asked for 3 columns, and got only two.
?? 89??? not possible??? 9.43
?? 90??? not possible??? 9.49
?? 91??? possible??????? 9.54
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
I've looked, but can't see a pattern!
All I can see is that it's possible for x.00 and >= x.50, and not
possible for < x.50
I don't know why. I could (easily) be completely wrong :)
On 3/7/2026 1:33 AM, Janis Papanagnou wrote:
On 07.03.26 04:14, DFS wrote:
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
I don't see what the sqrt value would demonstrate here.
Look at the remainders of the square roots.
On Thu, 05 Mar 2026 20:31:39 -0800, Tim Rentsch wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
OK, it's not pretty, but here it is
No worries - being pretty is not on the list of requested properties. :)
Congratulations on being the first to post an answer.
Two problems related to how setjmp()/longjmp() are used:
1. Any local variable changed between a setjmp() and the longjmp()
that goes back to it must be declared 'volatile' to avoid problems
with indeterminate values. (Minor.)
2. A pattern like 'x = setjmp( jbuf );' is not one of the officially
approved forms in the C standard for setjmp(). More specifically,
any such usage has undefined behavior. (More serious.)
If you look in the C standard for setjmp(), there is a subsection
titled 'Environmental limits' that explains which forms are approved
for use. Personally I think it's regrettable that 'x = setjmp( jbuf );'
is not one of them, but I feel obliged to observe that limitation and
follow what the standard prescribes for using setjmp().
yah.
As you can tell, I haven't used setjmp()/longjmp() much, and am
unfamiliar with the caveats surrounding them.
I'll look at revising my code, in the light of your comments, and
repost with a more "legal" version.
On 07.03.26 16:24, DFS wrote:
On 3/7/2026 1:33 AM, Janis Papanagnou wrote:
On 07.03.26 04:14, DFS wrote:
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
I don't see what the sqrt value would demonstrate here.
Look at the remainders of the square roots.
I did of course. (Why would I have otherwise asked.)
I don't see what the sqrt value would demonstrate here.
Mind to explain what you meant?
Janis
On Fri, 06 Mar 2026 13:51:58 +0000, Lew Pitcher wrote:
I'll look at revising my code, in the light of your comments, and
repost with a more "legal" version.
And, here it is
[...]
[...] I look forward to seeing /your/ code :-)
On 05.03.26 22:12, Lew Pitcher wrote:
On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:[...]
But, I now need to find a replacement for sqrt() that doesn't take
a lot of space. Back to first principles for me, then.
The roguelike game Nethack that historically deliberately didn't
use any floating point had this code (most is just comments):
/* integer square root function without using floating point */
int
isqrt(val)
int val;
{
int rt = 0;
int odd = 1;
/*
* This could be replaced by a faster algorithm, but has not
been because:
* + the simple algorithm is easy to read;
* + this algorithm does not require 64-bit support;
* + in current usage, the values passed to isqrt() are not
really that
* large, so the performance difference is negligible;
* + isqrt() is used in only few places, which are not
bottle-necks. */
while (val >= odd) {
val = val - odd;
odd = odd + 2;
rt = rt + 1;
}
return rt;
}
Janis
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
On Fri, 06 Mar 2026 13:51:58 +0000, Lew Pitcher wrote:[...]
I'll look at revising my code, in the light of your comments, and
repost with a more "legal" version.
And, here it is
[...]
First of two responses
1. I think your error checking is more thorough than what I did.
I do check that inputs are well formed but it's possible that
out of range values will give inappropriate results.
2. I don't have any error return. I do diagnose various conditions
(and in particular the no-square-possible cutoff values) but don't
bother with status. It would be easy to add but I didn't do it. :)
3. How setjmp() is used is still out of bounds. The rule for setjmp()
in a switch() is the setjmp() must be the entire expression that is
switched on. Effectively longjmp() can pass only constant values,
because there is no way to do anything with the value except see if
it is true or false (in an if()) or match it against 'case' labels.
My code in the next followup.
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:[snip]
[...] I look forward to seeing /your/ code :-)
Here we go...
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
[...] I look forward to seeing /your/ code :-)
Here we go...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
typedef size_t Z;
typedef _Bool B;
static Z k, h, w, c;
static int d;
static jmp_buf jb;
#define GO(x) longjmp( jb, x )
#define NUMBERISH(p) ((p) && *(p) && (p)[ strspn((p),"0123456789") ] == 0)
enum {
START, // the initial state; must be zero
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( setjmp( jb ) ){
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) );
}
}
}
A nit you may have forgotten: you earlier said main() was not allowed:
On Fri, 6 Mar 2026 00:18:43 +0100
Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
On 05.03.26 22:12, Lew Pitcher wrote:
On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:[...]
But, I now need to find a replacement for sqrt() that doesn't take
a lot of space. Back to first principles for me, then.
The roguelike game Nethack that historically deliberately didn't
use any floating point had this code (most is just comments):
/* integer square root function without using floating point */
int
isqrt(val)
int val;
{
int rt = 0;
int odd = 1;
/*
* This could be replaced by a faster algorithm, but has not
been because:
* + the simple algorithm is easy to read;
* + this algorithm does not require 64-bit support;
* + in current usage, the values passed to isqrt() are not
really that
* large, so the performance difference is negligible;
* + isqrt() is used in only few places, which are not
bottle-necks. */
while (val >= odd) {
val = val - odd;
odd = odd + 2;
rt = rt + 1;
}
return rt;
}
Janis
That code is O(sqrt(val)). Good enough in this particular case, because
main print loop is much slower than that at O(val), but I find it non-satisfactory.
Here is O(log(N)) variant that is even simpler than code above.
unsigned usqrt(unsigned x)
{
if (x < 2)
return x;
unsigned y = x/2, r;
while ((r = x / y) < y)
y = (r + y) / 2;
return y;
}
And here is variation that is a little less simple, but not complicated
and faster than one before, because it does fewer divisions.
The number of divisions that can't be implemented as shift is at most ceil(sqrt(ceil(log2(ceil(sqrt(val)))
unsigned usqrt(unsigned x)
{
if (x < 2)
return x;
unsigned y = 8, xx = x;
while (xx > 63) {
xx /= 64;
y *= 8;
}
unsigned r;
while ((r = x / y) < y)
y = (r + y) / 2;
return y;
}
And here is less simple but still obvious implementation that does no divisions at all. No multiplications as well.
unsigned usqrt(unsigned x)
{
if (x < 2)
return x;
unsigned xx = x;
int e = 0;
while (xx > 63) {
xx /= 64;
e += 3;
}
while (xx > 3) {
xx /= 4;
e += 1;
}
unsigned y = 1u << e;
x -= y << e;
for (e = e - 1; e >= 0; --e) {
unsigned d = y*2 + (1u << e);
if (d <= (x >> e)) {
x -= d << e;
y += 1u << e;
}
}
return y;
}
On 3/7/2026 3:02 PM, Tim Rentsch wrote:
[...]
What do you think would be the reaction in a corporate programming dept
to this unique kind of code?
On 3/7/2026 1:16 PM, Janis Papanagnou wrote:
On 07.03.26 16:24, DFS wrote:
On 3/7/2026 1:33 AM, Janis Papanagnou wrote:
On 07.03.26 04:14, DFS wrote:
Look at the square roots, and you'll see a pattern that determines
whether the square matrix is possible or not.
I don't see what the sqrt value would demonstrate here.
Look at the remainders of the square roots.
I did of course. (Why would I have otherwise asked.)
I don't see what the sqrt value would demonstrate here.
Mind to explain what you meant?
The values of the remainders correspond 1:1 with the possibility of a
square matrix.
remainder between 0.01 and 0.50: square matrix not possible [...]
typedef size_t Z;[...]
typedef _Bool B;
I'm a bit astonished by the last variants, though, with its constants
(63 and 64); this is something that looks like a variant specifically tailored to some system architecture. But okay, I see that you might
want to "cluster" the arithmetics.
On 3/7/2026 3:02 PM, Tim Rentsch wrote:
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
[...] I look forward to seeing /your/ code :-)
Here we go...
OMG!ÿ Congrats on an innovative piece of C code.ÿ Never seen anything
like it.
I don't understand everything yet, but nested ternaries aside, it's
pretty easy to follow too.
A nit you may have forgotten: you earlier said main() was not allowed:
"not mentioning main() was an oversight on my part.
(Still not okay to call it.)"
I saw David Brown offered about 5 ways to bypass main().
On 07.03.26 22:58, DFS wrote:
On 3/7/2026 3:02 PM, Tim Rentsch wrote:
[...]
What do you think would be the reaction in a corporate programming
dept to this unique kind of code?
From my experiences in a couple such departments of professional
software development...
The "uniqueness" would not be a problem. It would have failed to
many requirements that maintainable code was expected to have.
I can explain the (positive) excitement only by some nerdy stance
in this specific CLC domain.
On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
On 07.03.26 22:58, DFS wrote:
On 3/7/2026 3:02 PM, Tim Rentsch wrote:
[...]
What do you think would be the reaction in a corporate programming
dept to this unique kind of code?
From my experiences in a couple such departments of professional
software development...
The "uniqueness" would not be a problem. It would have failed to
many requirements that maintainable code was expected to have.
I figured as much.
Nested ternaries like this:
ÿ c = square ? a1ÿ :ÿ !hwc ? h*wÿ :ÿ a3 > h*w ? h*wÿ :ÿ a3;
are harder to decipher at first glance than 3 or 4 levels of indented if-then-elses.
I can explain the (positive) excitement only by some nerdy stance
in this specific CLC domain.
Give the man his due.ÿ It's extremely unique and excitement-worthy.
What's also very nice is there are no long lines that wrap.
Sure it's a bearded-lady novelty, but I think he knocked it out of the
park.
Sure it's a bearded-lady novelty, but I think he knocked it out of the park.
On Sun, 8 Mar 2026 00:26:15 +0100
Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
I'm a bit astonished by the last variants, though, with its constants
(63 and 64); this is something that looks like a variant specifically
tailored to some system architecture. But okay, I see that you might
want to "cluster" the arithmetics.
Quite opposite to what you say
- in the spirit of comp.lang.c this
part of code uses most generic of relatively fast methods of
calculation of non-precise value of floor(log2(x)/2) when expected
result is in range [0:15].
The expected range is [0:15] because 32 bits is the most popular size
of 'unsigned' type.
Using bigger threshold number (4**4-1==255) will on average increase
a # of more expensive iterations in the next loop.
Using smaller number (15 or 3) will increase # of iteration in this
loop.
If it was tailored I'd avoid this loop completely and instead will use language extension, like __bultin_clz() on gcc and compatible or _BitScanReverse() on MSVC and compatible
C23 has standard way to express it - stdc_leading_zeros(). But C23 is
not yet accepted as de-facto C Standard of comp.lang.c and rightfully
so.
In the languages I create,
Funny though how TR castigated me for not offering a C solution,
but his solution is one I would not class as C code,
My script code is however trivially convertible to C
(which I later posted)
On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
On 07.03.26 22:58, DFS wrote:
On 3/7/2026 3:02 PM, Tim Rentsch wrote:[...]
[...]
What do you think would be the reaction in a corporate programming
dept to this unique kind of code?
The "uniqueness" would not be a problem. It would have failed to
many requirements that maintainable code was expected to have.
I figured as much.
Nested ternaries like this:
ÿ c = square ? a1ÿ :ÿ !hwc ? h*wÿ :ÿ a3 > h*w ? h*wÿ :ÿ a3;
are harder to decipher at first glance than 3 or 4 levels of indented if-then-elses.
But all the decision-making in one short line is a thing of beauty.
I can explain the (positive) excitement only by some nerdy stance
in this specific CLC domain.
Give the man his due.ÿ It's extremely unique and excitement-worthy.
What's also very nice is there are no long lines that wrap.
Sure it's a bearded-lady novelty, but I think he knocked it out of the
park.
On 08/03/2026 14:42, DFS wrote:
Nested ternaries like this:
ÿÿ c = square ? a1ÿ :ÿ !hwc ? h*wÿ :ÿ a3 > h*w ? h*wÿ :ÿ a3;
are harder to decipher at first glance than 3 or 4 levels of indented
if-then-elses.
TR doesn't like parentheses around ?: terms; everyone is expected to
know their precedence.
[...]
On 3/8/2026 11:18 AM, Bart wrote:
In the languages I create,
plural?
It's very impressive that you developed your own working language.ÿ Is
the BartScript interpreter written in C?ÿ Can you post it?
The reference Python implementation is written in C. https://github.com/python/cpython
Funny though how TR castigated me for not offering a C solution,
but his solution is one I would not class as C code,
It is.ÿ It compiled with gcc, and uses C library functions.
Funny though how TR castigated me for not offering a C solution, but[...]
his solution is one I would not class as C code, as it only uses a
subset of the language and in a weird manner (a bit like some of my
generated C which is not meant to be human-readable).
Nested ternaries like this:
c = square ? a1 : !hwc ? h*w : a3 > h*w ? h*w : a3;
are harder to decipher at first glance than 3 or 4 levels of indented if-then-elses.
But all the decision-making in one short line is a thing of beauty.
On 08/03/2026 14:42, DFS wrote:
On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
On 07.03.26 22:58, DFS wrote:
On 3/7/2026 3:02 PM, Tim Rentsch wrote:
[...]
What do you think would be the reaction in a corporate programming
dept to this unique kind of code?
From my experiences in a couple such departments of professional
software development...
The "uniqueness" would not be a problem. It would have failed to
many requirements that maintainable code was expected to have.
I figured as much.
Nested ternaries like this:
ÿ c = square ? a1ÿ :ÿ !hwc ? h*wÿ :ÿ a3 > h*w ? h*wÿ :ÿ a3;
are harder to decipher at first glance than 3 or 4 levels of indented
if-then-elses.
TR doesn't like parentheses around ?: terms; everyone is expected to
know their precedence.
Bart <bc@freeuk.com> writes:
On 08/03/2026 14:42, DFS wrote:
On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
On 07.03.26 22:58, DFS wrote:
On 3/7/2026 3:02 PM, Tim Rentsch wrote:
[...]
What do you think would be the reaction in a corporate programming
dept to this unique kind of code?
From my experiences in a couple such departments of professional
software development...
The "uniqueness" would not be a problem. It would have failed to
many requirements that maintainable code was expected to have.
I figured as much.
Nested ternaries like this:
ÿ c = square ? a1ÿ :ÿ !hwc ? h*wÿ :ÿ a3 > h*w ? h*wÿ :ÿ a3;
are harder to decipher at first glance than 3 or 4 levels of indented
if-then-elses.
TR doesn't like parentheses around ?: terms; everyone is expected to
know their precedence.
Most coding standards, IIRC, specify that explicit groupings
should be used, so any future code reader would know what
the programmer intended.
Google AI agrees:
Safety and Intent: Parentheses explicitly define the intended order of operations,
ensuring the code behaves as expected regardless of the specific
language's precedence rules.
Readability and Maintenance: Code is written for humans to read. Extra parenthess
make complex expressions easier to understand, reducing the "cognitive load" needed
to calculate the precedence mentally.
Preventing Errors: Using parentheses prevents bugs when expressions are modified
later by other developers who may not be fully aware of the default order of operations.
Compiler/Standard Limitations: Some, albeit rare, languages or strict
standards (like MISRA C:2023 or the Pony language) require explicit
parentheses to eliminate ambiguity entirely.
Bart <bc@freeuk.com> writes:
[...]
Funny though how TR castigated me for not offering a C solution, but[...]
his solution is one I would not class as C code, as it only uses a
subset of the language and in a weird manner (a bit like some of my
generated C which is not meant to be human-readable).
Nonsense. Of course Tim's code was C code. It compiles without
error with a conforming C compiler, and does not depend on any
extensions. Practically all C programs only use a subset of the
language.
Classifying C code that you don't like as "not C" is absurd.
Your code, on the other hand, was not written in C at all.
On 3/8/2026 2:42 PM, Scott Lurndal wrote:
Bart <bc@freeuk.com> writes:
On 08/03/2026 14:42, DFS wrote:
On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
On 07.03.26 22:58, DFS wrote:
On 3/7/2026 3:02 PM, Tim Rentsch wrote:
[...]
What do you think would be the reaction in a corporate programming >>>>>> dept to this unique kind of code?
ÿFrom my experiences in a couple such departments of professional
software development...
The "uniqueness" would not be a problem. It would have failed to
many requirements that maintainable code was expected to have.
I figured as much.
Nested ternaries like this:
ÿ ÿ c = square ? a1ÿ :ÿ !hwc ? h*wÿ :ÿ a3 > h*w ? h*wÿ :ÿ a3;
are harder to decipher at first glance than 3 or 4 levels of indented
if-then-elses.
TR doesn't like parentheses around ?: terms; everyone is expected to
know their precedence.
Most coding standards, IIRC, specify that explicit groupings
should be used, so any future code reader would know what
the programmer intended.
Google AI agrees:
ÿÿÿ Safety and Intent: Parentheses explicitly define the intended
order of operations,
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ensuring the code behaves as expected
regardless of the specific
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ language's precedence rules.
ÿÿÿ Readability and Maintenance: Code is written for humans to read.
Extra parenthess
ÿÿÿÿÿ make complex expressions easier to understand, reducing the
"cognitive load" needed
ÿÿÿÿÿ to calculate the precedence mentally.
ÿÿÿ Preventing Errors: Using parentheses prevents bugs when
expressions are modified
ÿÿÿÿÿ later by other developers who may not be fully aware of the
default order of operations.
ÿÿÿ Compiler/Standard Limitations: Some, albeit rare, languages or strict
ÿÿÿÿÿ standards (like MISRA C:2023 or the Pony language) require explicit
ÿÿÿÿÿ parentheses to eliminate ambiguity entirely.
(x * y) + z
Well, its, ivho its "better" to have the parenthesis in there...
Where you put the requirements in a coding standard can depend on many factors.ÿ Are you aiming for code that is easily understood even by relatively new C programmers, or do you expect only experts to be
dealing with the code? [...]
| Sysop: | Tetrazocine |
|---|---|
| Location: | Melbourne, VIC, Australia |
| Users: | 15 |
| Nodes: | 8 (0 / 8) |
| Uptime: | 84:46:24 |
| Calls: | 208 |
| Files: | 21,502 |
| Messages: | 81,377 |