• Sort of trivial code challenge - may be interesting to you anyway

    From DFS@3:633/10 to All on Thu Feb 19 16:55:25 2026
    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

    Kind of goes without saying the solution should handle any row x column
    input:

    input rows columns

    input 1 1
    1

    input 1 4
    1 2 3 4

    input 5 2
    1 6
    2 7
    3 8
    4 9
    5 10

    input 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 trivial to
    less trivial!

    --------------------------------------------------------------------
    1) must be able to cut the output off at any arbitrary value
    lower than rows x columns --------------------------------------------------------------------
    input = 5 5 (no cutoff)
    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 = 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 = 5 5 6
    1 6
    2
    3
    4
    5

    input = 5 5 3
    1
    2
    3

    input = 1 10 (no cutoff)
    1 2 3 4 5 6 7 8 9 10

    input = 1 10 3 (cutoff at 3)
    1 2 3



    --------------------------------------------------------------------
    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 = N

    input = 1 (1 row and 1 column includes 1)
    1

    input = 2
    not possible to output 1-2 where rows=columns

    input = 3 (2 rows and 2 columns includes 3)
    1 3
    2

    input = 4 (2 rows and 2 columns includes 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 (3 rows and 3 columns includes 7)
    1 4 7
    2 5
    3 6

    input = 8
    1 4 7
    2 5 8
    3 6

    input = 9
    1 4 7
    2 5 8
    3 6 9

    input = 10 11 or 12
    not possible to output 1-10/11/12 where rows=columns

    input = 13
    1 5 9 13
    2 6 10
    3 7 11
    4 8 12

    input = 14
    1 5 9 13
    2 6 10 14
    3 7 11
    4 8 12

    input = 15
    1 5 9 13
    2 6 10 14
    3 7 11 15
    4 8 12

    input = 16
    1 5 9 13
    2 6 10 14
    3 7 11 15
    4 8 12 16

    input = 17 18 19 or 20
    not possible to output 1-17/18/19/20 where rows=columns

    input = 21
    1 6 11 16 21
    2 7 12 17
    3 8 13 18
    4 9 14 19
    5 10 15 20

    input = 22
    1 6 11 16 21
    2 7 12 17 22
    3 8 13 18
    4 9 14 19
    5 10 15 20

    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.

    No code spying until you post yours!

    Enjoy!























































    --------------------------------------------------------------------------
    C listing --------------------------------------------------------------------------
    // this public domain program outputs numbers by column then row
    // usage examples
    // $prog rows columns (print a sequential nbr matrix of size rows x columns)
    // $prog rows columns stop (output discontinued past stop)
    // $prog N (try to find rows=columns that will include only 1-N in output

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    //print a separator line
    void printline(int linewidth, char *linechar) {
    for(int i = 0; i < linewidth; i++) {
    printf(linechar);
    }
    printf("\n");
    }

    //print column count headers
    void printcolheader(int cols, int charwidth) {
    printline(cols * charwidth,"-");
    for (int p = 1; p <= cols; p++) {
    printf("%*d",charwidth,p);
    }
    printf("\n");
    printline(cols * charwidth,"-");
    }

    //twist: try to find rows=columns that will include the input number
    void calc_rows_columns(int *rows, int *cols, int nbr) {
    int m = 10000;

    for (int i = 1; i < m; i++) {
    if (i*i == nbr) {
    *rows = i;
    *cols = i;
    return;
    }
    }

    for (int i = 2; i < m; i++) {
    if ((i*(i-1) < nbr) && ((i*i) >= nbr)) {
    *rows = i;
    *cols = i;
    return;
    }
    }

    printf("%s%d%s\n","Not possible to output 1-", nbr ," where rows = columns");
    exit(0);
    }


    //core routine to write row x column data to screen
    void output(int rows, int cols, int max)
    {

    //calc horizontal spacing of columns based on largest number (minimum 3)
    char strmax[10];
    sprintf(strmax, "%d", max);
    int colwidth = 1 + strlen(strmax);
    if (colwidth == 2) {colwidth = 3;}

    //print column header lines
    //TODO: maybe print no header columns beyond the column containing the max value
    printcolheader(cols, colwidth);

    //nbr matrix
    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;
    if (nbr <= max) {
    printf("%*d",colwidth,nbr);
    }
    }
    printf("\n");
    }
    else
    {
    break;
    }
    }

    //repeat the headers for readability
    if (rows >= 40 && max >= 40) {printcolheader(cols, colwidth);}

    }

    int main(int argc, char *argv[]) {

    //validation
    if (argc < 2 || argc > 4) {
    printf("Use one of these input formats:\n");
    printf(" $prog rows columns\n");
    printf(" $prog rows columns max (program will halt output past max)\n");
    printf(" $prog N (program will try to determine a square matrix to
    incl N)\n");
    return 0;
    }

    //vars
    int rows, cols, max;

    //only 1 argument = try to calc the rows = columns values
    // that will include the input number
    if (argc == 2) {
    max = atoi(argv[1]);
    calc_rows_columns(&rows, &cols, max);
    }

    if (argc == 3) {
    rows = atoi(argv[1]);
    cols = atoi(argv[2]);
    max = rows * cols;
    }


    if (argc == 4) {
    rows = atoi(argv[1]);
    cols = atoi(argv[2]);
    max = atoi(argv[3]);
    }

    //write data to screen
    output(rows, cols, max);

    return 0;
    } --------------------------------------------------------------------------

    --- PyGate Linux v1.5.11
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From jayjwa@3:633/10 to All on Wed Feb 25 15:56:05 2026
    DFS <nospam@dfs.com> writes:

    Kind of goes without saying the solution should handle any row x
    column input:
    input 1 1
    $ cc /version
    Compaq C V6.4-005 on OpenVMS VAX V7.3
    $ cc rowcol.c
    $ link rowcol
    $ mcr []rowcol 1 1
    1

    input 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
    $ 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 trivial
    to less trivial!
    Sure, sure... if you're a professional C programmer with a BS and 5+
    years experience. This was a bit above where I am but once I started it
    I had to finish it so here I am. Of course, the second case is the nasty
    one and only last night did I find the way forward: I had put the
    columns accumulator in the wrong place.

    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

    $ mcr []rowcol 5 5 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)
    1 2 3 4 5 6 7 8 9 10
    $ mcr []rowcol 1 10
    1 2 3 4 5 6 7 8 9 10

    input = 1 10 3 (cutoff at 3)
    1 2 3
    $ mcr []rowcol 1 10 3
    1 2 3

    --------------------------------------------------------------------
    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
    @compile rowcol.c
    KCC: ROWCOL
    <PROGRAMMING>ROWCOL.PRE.1
    <PROGRAMMING>ROWCOL.FAI.1
    FAIL: ROWCOL
    @load rowcol
    LINK: Loading
    @save rowcol
    ROWCOL.EXE.2 Saved

    @rowcol 1
    1

    input = 2
    not possible to output 1-2 where rows=columns
    @rowcol 2
    Not possible to output 1-2 where rows=columns.

    input = 4 (2 rows and 2 columns includes 4)
    1 3
    2 4
    @rowcol 4
    1 3
    2 4

    input = 5
    not possible to output 1-5 where rows=columns
    @rowcol 5
    Not possible to output 1-5 where rows=columns.

    input = 6
    not possible to output 1-6 where rows=columns
    $ cc /define=DEBUG=1 rowcol.c
    $ link rowcol
    $ mcr []rowcol 6
    validInput(): Looking at input value 6
    1
    Checking next grid...

    1 3
    2 4
    Checking next grid...

    1 4
    2 5
    3 6
    Not possible to output 1-6 where rows=columns.

    input = 9
    1 4 7
    2 5 8
    3 6 9
    @rowcol 9
    1 4 7
    2 5 8
    3 6 9

    input = 10 11 or 12
    not possible to output 1-10/11/12 where rows=columns
    @rowcol 11
    Not possible to output 1-11 where rows=columns.


    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
    @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 kind
    of brute-forced it with 2 loops. As you can see, N = prime isn't
    enough to know if it can be done.
    I 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
    don't want to mess with it.

    @rowcol
    Please enter 1, 2, or 3 integers (in range 1-30) on the command line.
    Ex: ROWCOL 5 5 23
    @rowcol 4 5 6 7
    Please enter 1, 2, or 3 integers (in range 1-30) on the command line.
    Ex: ROWCOL 5 5 23
    @rowcol 5 5 0
    5, 5, and/or 0 are invalid input. All must be in range 1-30.
    @rowcol 5 31 4
    5, 31, and/or 4 are invalid input. All must be in range 1-30.

    My code is below.
    I have not looked until I posted this. Obviously very different. I have
    not used LLM/AI but I had to check my notes for the va_args stuff since
    I almost never use it. Runs on/with GCC, Clang, KCC/TOPS-20 and Compaq C
    (where I actually wrote it). Define DEBUG if you want to see what it's
    doing.


    /* rowcols.c
    * The user enters 1-3 integers on the command line and the program
    * attempts to print a grid pattern based on the numbers given. If
    * a STOP NUMBER is given, cut the grid on that number. If one number
    * is given, try to make a grid confined by ROWS = COLS, where grid is
    * 1 - targetNum, such that this grid prints until targetNum number else
    * print "not possible".
    *
    * Input is as:
    * $rowcols ROWS COLUMNS (STOP NUMBER, if used).
    */
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdarg.h>
    #include <iso646.h>
    #include <stdbool.h> /* Written for Compaq C v6.4, adjust for C23 std */

    #define AC_NORMAL "\x1b[m" /* ASCII color normal */
    #define AC_RED "\x1b[31m" /* ASCII color red */
    #define UPPERBOUNDS 30 /* Largest grid params we deal with, lest wonky output */

    bool validInput( int num, ... ); /* Check any/all args against UPPERBOUNDS */


    int main( int argc, char *argv[] ) {
    int columns, rows; /* Track columns, rows to build grid */
    int reqCols, reqRows; /* The number of cols/rows the user requests */
    int targetNum; /* Stop num or grid target num (mode dependant) */
    bool found; /* Flag if number found in grid */
    int foundRows, foundCols; /* Track where targetNum found */
    int cntRows, cntCols; /* Count rows/cols used to find num */

    /* Determine course of action based on number of command line
    * arguments (argc - 1: don't include program name in arg count).
    * zero = give usage message
    * one = make a grid 1 to targetNum where row = col or
    * inform user if not possible
    * two = make a grid, row by column as input on the cmd line
    * three = as above, but stop at number given as 3rd parameter
    * four or more = same as zero, usage message
    */
    switch ( argc ) {
    case 2:
    /* Handle case of one integer given on command line. Check for
    * valid input else the tables will not display correctly.
    */
    targetNum = atoi( argv[1] );
    if ( not validInput( 1, targetNum ) ) {
    printf( "%d is invalid input. Please enter 1 - %d\n", targetNum, UPPERBOUNDS );
    return EXIT_FAILURE;
    }

    /* Track if we found targetNum yet */
    found = false;

    /* Set reqRows = reqCols = 1 and keep stepping up until we hit
    * targetNum. Tally cols and rows seen via accumulators. Check if
    * equal on arriving at the target number. If yes, print
    * table, else print "not possible". We only search until UPPERBOUNDS.
    */
    for ( reqRows = 1, reqCols = 1; reqRows <= UPPERBOUNDS; reqRows++, reqCols++ ) {
    cntRows = 0;
    cntCols = 0;
    rows = 1;
    do {
    columns = 0;
    do {
    /* Is this higher than the stop number? Blur
    * it out if so. We can't cut out entirely
    * because we need to print the rest of the
    * lower numbers.
    */
    if ( ( columns * reqRows + rows ) > targetNum ) {
    /* Keep compiler happy when not using debugging output */
    ;
    #ifdef DEBUG
    printf( " " );
    #endif /* DEBUG */
    } else {
    /* Increase column count of used columns */
    if ( rows == 1 ) cntCols++; #ifdef DEBUG
    printf( "%2d ", columns * reqRows + rows);
    #endif /* DEBUG */
    /* If we spot the number, note it and where we found it
    * but only on the first time.
    */
    if ( ( (columns * reqRows + rows) == targetNum ) && !found ) {
    found = true;
    foundRows = rows;
    foundCols = columns + 1;
    }
    }
    } while ( columns++ < reqCols - 1 );
    #ifdef DEBUG
    printf("\n");
    #endif /* DEBUG */
    cntRows++;
    } while ( rows++ < reqRows );
    if ( found ) break;
    #ifdef DEBUG
    printf( "Checking next grid...\n\n" );
    #endif /* DEBUG */
    }
    if ( (found) and (cntRows == cntCols) ) {
    #ifdef DEBUG
    printf( "targetNum %d found at row %d column %d.\n", targetNum, foundRows, foundCols );
    printf( "Used %d rows, %d columns. Outputting grid.\n\n", cntRows, cntCols );
    #endif /* DEBUG */

    /* Output the grid we know is correct. targetNum already set */
    reqRows = cntRows;
    reqCols = cntCols;
    rows = 1;
    do {
    columns = 0;
    do {
    /* Is this higher than the stop number? Blur
    * it out if so. We can't cut out entirely
    * because we need to print the rest of the
    * lower numbers.
    */
    if ( ( columns * reqRows + rows ) > targetNum )
    printf( " " );
    else
    printf( "%2d ", columns * reqRows + rows);
    } while ( columns++ < reqCols - 1 );
    printf("\n");
    } while ( rows++ < reqRows );
    } else {
    /* If we are here, the special case did not trip, and it's not possible to print grid. */
    printf( "%sNot possible to output 1-%d where rows=columns.%s\n",
    AC_RED, targetNum, AC_NORMAL );
    }
    break;

    case 3:
    /* Handle case of 2 integers given - print full grid */
    reqRows = atoi( argv[1] );
    reqCols = atoi( argv[2] );

    /* First check user's input */
    if ( not validInput( 2, reqRows, reqCols ) ) {
    printf( "%d and/or %d is invalid input. Both must be in range 1-%d.\n",
    reqRows, reqCols, UPPERBOUNDS );
    return EXIT_FAILURE;
    }

    rows = 1;
    do {
    columns = 0;
    do {
    printf( "%2d ", columns * reqRows + rows);
    } while ( columns++ < reqCols - 1 );
    printf( "\n" );
    } while ( rows++ < reqRows );
    break;

    case 4:
    /* Handle 3 ints given - stop number case */
    reqRows = atoi( argv[1] );
    reqCols = atoi( argv[2] );
    targetNum = atoi( argv[3] );

    /* Check user input */
    if ( not validInput( 3, reqRows, reqCols, targetNum ) ) {
    printf( "%d, %d, and/or %d are invalid input. All must be in range 1-%d.\n",
    reqRows, reqCols, targetNum, UPPERBOUNDS );
    return EXIT_FAILURE;
    }

    rows = 1;
    do {
    columns = 0;
    do {
    /* Is this higher than the stop number? Blur
    * it out if so. We can't cut out entirely
    * because we need to print the rest of the
    * lower numbers.
    */
    if ( ( columns * reqRows + rows ) > targetNum )
    printf( " " );
    else
    printf( "%2d ", columns * reqRows + rows);
    } while ( columns++ < reqCols - 1 );
    printf("\n");
    } while ( rows++ < reqRows );
    break;

    default:
    /* Give usage if anything else then bail */
    printf( "Please enter 1, 2, or 3 integers (in range 1-%d) on the command line.\n",
    UPPERBOUNDS );
    printf( " Ex: %s 5 5 23\n", argv[0] );
    return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
    }

    /* Assume valid, but switch to false at invalid input. Every one
    * of these should be 1..UPPERBOUNDS, inclusive.
    */
    bool validInput( int num, ... ) {
    va_list arguments;
    int i;
    bool valid;
    int chkValue;

    va_start( arguments, num );
    valid = true;
    for ( i = 1; i <= num; i++ ) {
    /* We need multiple checks on this value, but calling va_arg
    * will jump to the next value (I think). Store it first and
    * check that.
    */
    chkValue = va_arg( arguments, int );
    #ifdef DEBUG
    printf( "validInput(): Looking at input value %d\n", chkValue );
    #endif /* DEBUG */
    if ( (chkValue < 1) or (chkValue > UPPERBOUNDS) ) valid = false;
    }
    va_end( arguments );
    return valid;
    }

    /* EOF */


    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

    --
    PGP Key ID: 781C A3E2 C6ED 70A6 B356 7AF5 B510 542E D460 5CAE
    "The Internet should always be the Wild West!"

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Thu Feb 26 10:05:24 2026
    On 2/25/2026 3:56 PM, jayjwa wrote:
    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 trivial
    to less trivial!
    Sure, sure... if you're a professional C programmer with a BS and 5+
    years experience.


    I'm an rank amateur C coder, with about a year of dedicated experience,
    and no formal education in programming.

    I write more Python than anything (then duplicate the .py programs in C
    for exercise).

    What started this little program was I output a list of 200+ school
    names by row then column, and didn't like the way it looked.

    So I decided to try the column-then-row approach with numbers. Now that
    I have it working I put the school names in alpha-order (in an array)
    and index into it using the algorithm in this code.

    Before and after: https://imgur.com/a/MSSeRxN



    This was a bit above where I am but once I started it
    I had to finish it so here I am.

    "I had to finish" ha! I'm with you there.



    * 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.
    I 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
    don't want to mess with it.


    Give it a week and come back to it and you'll see all kinds of things
    you could change/improve. Couple things I would suggest:


    1) figure out where to put a break so your program doesn't print blank
    lines if stop < rows (such as 8 8 3)


    2) remove the 30 limit on the stop

    $ ./rcj 10 11 108 says:
    10, 11, and/or 108 are invalid input. All must be in range 1-30.

    When it should print:
    1 11 21 31 41 51 61 71 81 91 101
    2 12 22 32 42 52 62 72 82 92 102
    3 13 23 33 43 53 63 73 83 93 103
    4 14 24 34 44 54 64 74 84 94 104
    5 15 25 35 45 55 65 75 85 95 105
    6 16 26 36 46 56 66 76 86 96 106
    7 17 27 37 47 57 67 77 87 97 107
    8 18 28 38 48 58 68 78 88 98 108
    9 19 29 39 49 59 69 79 89 99
    10 20 30 40 50 60 70 80 90 100




    On my script I took out all the comments and blank lines and print
    header rows and combined the two for..loops, and it's 57 LOC.
    3 includes, 3 functions =================================================================================
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    void calc_rows_columns(int *rows, int *cols, int nbr) {
    for (int i = 1; i < 1000; i++) {
    if ((i*i == nbr) || (i*(i+1) < nbr && ((i+1)*(i+1) >= nbr))) {
    *rows = i+1;
    *cols = i+1;
    return;
    }
    }
    printf("%s%d%s\n","Not possible to output 1-", nbr ," where rows = columns");
    exit(0);
    }
    void output(int rows, int cols, int max)
    {
    char strmax[10];
    sprintf(strmax, "%d", max);
    int colwidth = 1 + strlen(strmax);
    if (colwidth == 2) {colwidth = 3;}
    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;
    if (nbr <= max) {
    printf("%*d",colwidth,nbr);
    }
    }
    printf("\n");
    }
    else
    {
    break;
    }
    }
    }
    int main(int argc, char *argv[]) {
    int rows, cols, max;
    if (argc == 2) {
    max = atoi(argv[1]);
    calc_rows_columns(&rows, &cols, max);
    }
    if (argc == 3) {
    rows = atoi(argv[1]);
    cols = atoi(argv[2]);
    max = rows * cols;
    }
    if (argc == 4) {
    rows = atoi(argv[1]);
    cols = atoi(argv[2]);
    max = atoi(argv[3]);
    }
    output(rows, cols, max);
    return 0;
    } =================================================================================


    <snip jayjwa code>



    Glad to be done with this!

    Congrats! Good job on seeing it all the way thru.

    It was tougher than it looked initially, huh?

    FYI: your code compiled cleanly 1st time on gcc

    You did a lot of input/validity checking I didn't do. And I like the
    red 'error' messages.

    I notice you stopped at 30x30, I guess because of your monitor?

    I have a wide-screen monitor, and can see 48 x 56:
    https://imgur.com/a/PIZKGHH.




    @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


    Your name is close to my home state of Jawja.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Feb 26 17:06:53 2026
    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:

    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' --------------------------------------------------------------------
    [snip]

    * 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.


    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Feb 26 17:27:37 2026
    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:

    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'
    --------------------------------------------------------------------
    [snip]

    * 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 started on Thu 26 Feb 2026 12:24:39 PM EST
    12:24:39 $ ./rowcol 1 1

    1


    12:24:43 $ ./rowcol 2 3

    1 3 5

    2 4 6


    12:24:51 $ ./rowcol 4 5 17

    1 5 9 13 17

    2 6 10 14

    3 7 11 15

    4 8 12 16


    12:25:02 $ ./rowcol 17

    Cut off value 17 not possible where rows=cols

    Usage: ./rowcol #_rows #_cols [ cut-off ]

    or ./rowcol cut-off


    12:25:11 $ ./rowcol 19

    Cut off value 19 not possible where rows=cols

    Usage: ./rowcol #_rows #_cols [ cut-off ]

    or ./rowcol cut-off


    12:25:18 $ ./rowcol 21

    1 6 11 16 21

    2 7 12 17

    3 8 13 18

    4 9 14 19

    5 10 15 20


    12:25:21 $
    12:25:21 $ exit

    exit


    Script done on Thu 26 Feb 2026 12:25:33 PM EST


    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From jayjwa@3:633/10 to All on Thu Feb 26 13:20:07 2026
    DFS <nospam@dfs.com> writes:

    I write more Python than anything (then duplicate the .py programs in
    C for exercise).
    Python'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
    for now.

    FYI: your code compiled cleanly 1st time on gcc
    After I tested it on Linux, I see it did. Before, when I was building
    another project (not mine), it errored out once the new GCC landed and
    had to be fixed. Checking now, stdbool.h is there but accounts for the
    new standard.

    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
    at 24x80 and doesn't resize if you log from something bigger. Actually,
    it looks like 21x21 is the largest table it will print without the text wrapping around and making a mess. You can change the #define at top to something larger and it should work, assuming large enough screen to
    output on.

    Your name is close to my home state of Jawja.
    It was my login name in computer class in highschool. It just stuck over
    the years for lack of anything better.

    --
    PGP Key ID: 781C A3E2 C6ED 70A6 B356 7AF5 B510 542E D460 5CAE
    "The Internet should always be the Wild West!"

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From jayjwa@3:633/10 to All on Thu Feb 26 13:33:40 2026
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

    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'm not seeing it. You can cleanly take the square root of 1, 4, and 9
    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
    @

    --
    PGP Key ID: 781C A3E2 C6ED 70A6 B356 7AF5 B510 542E D460 5CAE
    "The Internet should always be the Wild West!"

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Feb 26 18:49:41 2026
    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, 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'm not seeing it. You can cleanly take the square root of 1, 4, and 9
    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 */
    }

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Feb 26 18:55:50 2026
    On Thu, 26 Feb 2026 18:49:41 +0000, Lew Pitcher wrote:

    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, 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'm not seeing it. You can cleanly take the square root of 1, 4, and 9
    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;
    }
    13:54:21 $ ./cutoff
    Cut off = 1, Rows = 1, Cols = 1
    Cut off value 2 not possible where rows=cols
    Cut off = 3, Rows = 2, Cols = 2
    Cut off = 4, Rows = 2, Cols = 2
    Cut off value 5 not possible where rows=cols
    Cut off value 6 not possible where rows=cols
    Cut off = 7, Rows = 3, Cols = 3
    Cut off = 8, Rows = 3, Cols = 3
    Cut off = 9, Rows = 3, Cols = 3
    Cut off value 10 not possible where rows=cols
    Cut off value 11 not possible where rows=cols
    Cut off value 12 not possible where rows=cols
    Cut off = 13, Rows = 4, Cols = 4
    Cut off = 14, Rows = 4, Cols = 4
    Cut off = 15, Rows = 4, Cols = 4
    Cut off = 16, Rows = 4, Cols = 4
    Cut off value 17 not possible where rows=cols
    Cut off value 18 not possible where rows=cols
    Cut off value 19 not possible where rows=cols
    Cut off value 20 not possible where rows=cols
    Cut off = 21, Rows = 5, Cols = 5
    Cut off = 22, Rows = 5, Cols = 5
    Cut off = 23, Rows = 5, Cols = 5
    Cut off = 24, Rows = 5, Cols = 5
    Cut off = 25, Rows = 5, Cols = 5
    Cut off value 26 not possible where rows=cols
    Cut off value 27 not possible where rows=cols
    Cut off value 28 not possible where rows=cols
    Cut off value 29 not possible where rows=cols
    Cut off value 30 not possible where rows=cols
    Cut off = 31, Rows = 6, Cols = 6
    13:54:25 $

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Feb 26 19:17:41 2026
    On Thu, 26 Feb 2026 18:55:50 +0000, Lew Pitcher wrote:

    On Thu, 26 Feb 2026 18:49:41 +0000, Lew Pitcher wrote:

    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, 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'm not seeing it. You can cleanly take the square root of 1, 4, and 9
    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;
    }
    [snip]

    Even simpler, I can remove a redundant test and get

    #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) )
    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;
    }
    with the same results.


    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Thu Feb 26 14:31:52 2026
    On 2/26/2026 12:27 PM, Lew Pitcher wrote:
    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:

    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'
    --------------------------------------------------------------------
    [snip]

    * 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.

    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.

    But it didn't.



    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.

    Yes. I loop thru this many times:

    if ((i*i == nbr) || (i*(i+1) < nbr && ((i+1)*(i+1) >= nbr)))

    If no hit I consider it not possible.



    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.


    Let us know when you figure it out. I'm curious.




    Script done on Thu 26 Feb 2026 12:25:33 PM EST


    code?


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Feb 26 19:34:29 2026
    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:

    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'
    --------------------------------------------------------------------
    [snip]

    * 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("");
    }
    }



    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Feb 26 20:01:19 2026
    On Thu, 26 Feb 2026 19:34:29 +0000, Lew Pitcher wrote:

    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:

    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'
    --------------------------------------------------------------------
    [snip]

    * 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));

    For any cut-off, the biggest allowable square has rows and columns
    equal to the square root of the cut-off, rounded up to the nearest integer. But, not all cut-offs are allowed in a square that size.

    Looking at a few squares and cut-offs, we see
    Size Min Cutoff Max Cutoff
    1x1 1 1
    2x2 3 4
    3x3 7 9
    4x4 13 16
    5x5 21 25

    We can see a relationship here:
    Where row == col == ceiling(square_root(cut-off))
    - the maximum cut-off for any square is row x col
    - the minimum cut-off for any square is (row x col) - (row - 1)
    or (row x col) - row + 1
    Now, as we derive row and col from the square root of cut-off,
    we know that cut-off will never be greater than row x col.

    And, that just leaves us with the minimum to check.


    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("");
    }
    }




    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Fri Feb 27 00:12:43 2026
    On 19/02/2026 21:55, DFS wrote:
    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.

    These don't appear in your examples, only in your C solution.

    I did my version before I looked at your C code, as you said we weren't allowed to look!

    I used my scripting language to come up with the solution below for when
    there is a single N input, as that looked more challenging.

    It took 20 minutes to get output corresponding more or less to your
    examples. (While columns are lined up, they don't exactly match in white
    space esp. at the start of each line; see example after the code.)

    Once the algorithm is done, rewriting to any other language, including
    C, would be trivial.


    --------------------------------------
    func getrows(n)=
    m:=s:=1
    while s<n do ++m; s:=sqr(m) end
    m
    end

    proc solve(n)=
    rows:=cols:=getrows(n)
    size:=rows*cols

    println "input =", n

    if size-n >= rows then
    fprintln "not possible to output 1-# where rows=columns", n
    println
    return
    end

    fmt:=tostr(tostr(n).len+1)

    for r in 1..rows do
    i:=r
    for c in 1..cols when i<=n do
    print i:fmt # fmt = eg. "3" when N is 10..99
    i+:=rows
    end
    println
    end
    println
    end

    for n in 1..27 do
    solve(n)
    end


    ----------------
    Outputs for N = 25 and 26:

    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






    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Mon Mar 2 00:44:57 2026
    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).

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Mon Mar 2 11:07:20 2026
    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.






    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Mon Mar 2 06:35:32 2026
    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 I found it more interesting to write that
    version than one where for() or while() were used. I think
    that would make a nice second-level challenge.

    For a third challenge, write a version that doesn't use for(),
    while(), do/while(), goto, and also does not have recursive
    function calls.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Mon Mar 2 17:50:47 2026
    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!


    and also does not have recursive
    function calls.

    Is that a hint that the loop-less version you had in mind used recursion instead?

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Mon Mar 2 17:40:07 2026
    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.

    Code bounces back and forth between number generator and number
    validator functions.

    Plus I figured out a one-line formula for the 'extra credit'!



    compile with -lm for the math lib:

    $ gcc codefile.c -o programname -lm


    ==========================================================================================
    #include <stdio.h>
    #include <math.h>

    int r, c, num;
    int rows, cols, max;

    void generate();
    void validate();

    void generate() {
    if (r <= rows && c < cols) {
    num = r + (c * rows);
    if (num <= max) {
    printf("%3d ",num);
    }
    c++;
    validate();
    }
    }


    void validate() {
    if (num < (rows * cols) && c < cols) {
    generate();
    }
    else
    {
    printf("\n");
    c = 0;
    r++;
    if (num < (rows * cols) && c < cols) {
    generate();
    }
    }
    }

    void extracredit() {
    double i,f;
    for (int n = 1; n <= 30; n++) {
    printf("input = %2d %s\n",n,((modf(sqrt(n), &i) > 0.01 && modf(sqrt(n), &i) < 0.50) ) ? "not possible" : "possible");
    }
    }


    int main(void) {
    printf("\nCol x Row matrices produced without for.. while... do... or recursion\n");
    printf("------------------------------------------------------------------------\n");

    //matrix examples
    r = 1; c = 0; num = 0;
    printf(" 5 x 5 stop 21\n");
    printf("-------------------\n");
    rows = 5; cols = 5; max = 21;
    generate();
    printf("\n\n");

    r = 1; c = 0; num = 0;
    rows = 5; cols = 20; max = rows * cols;
    printf(" 5 x 20 no stop\n");
    printf("-------------------\n");
    generate();
    printf("\n\n");

    r = 1; c = 0; num = 0;
    rows = 10; cols = 2; max = 19;
    printf(" 10 x 2 stop 19\n");
    printf("-------------------\n");
    generate();
    printf("\n\n");


    //one-line formula
    printf("'Extra Credit': results of one-line formula to determine\n if a
    square matrix is possible for the input\n");
    printf("--------------------------------------------------------\n");
    extracredit();
    return 0;
    }

    ==========================================================================================





    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Mon Mar 2 21:09:21 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Mon Mar 2 21:15:19 2026
    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 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!

    I see no reason to answer your questions since you seem to have
    no interest in writing C code.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Tue Mar 3 08:23:32 2026
    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.

    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.


    "third challenge, write a version that doesn't use for(),
    while(), do/while(), goto, and also does not have recursive
    function calls."


    Recursion means the function calls itself. Thus, my code technically
    met all the requirements of your third challenge.

    But I get you.



    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Tue Mar 3 06:20:33 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Tue Mar 3 16:39:12 2026
    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;
    }

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Tue Mar 3 15:40:40 2026
    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');
    }


    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Tue Mar 3 12:00:26 2026
    On 3/3/2026 10:39 AM, Bonita Montero wrote:

    I think it's better to do that in C++ and not in C:


    Disregarding your 0-base, a few fails:

    ./rc-montero 5 10
    0, 10, 20, 30, 40, 50
    1, 11, 21, 31, 41,
    2, 12, 22, 32, 42,
    3, 13, 23, 33, 43,
    4, 14, 24, 34, 44,

    should print
    1 6 11 16 21 26 31 36 41 46
    2 7 12 17 22 27 32 37 42 47
    3 8 13 18 23 28 33 38 43 48
    4 9 14 19 24 29 34 39 44 49
    5 10 15 20 25 30 35 40 45 50


    ./rc-montero 5 100 10
    0,
    1,
    2,
    3,
    4,

    should print:
    1 6
    2 7
    3 8
    4 9
    5 10


    ./rc-montero 1 100 3
    0,

    should print
    1 2 3


    ./rc-montero 100 100 1
    0,
    1

    (followed by 98 blank lines)




    Note: none of that would've happened if you wrote it in C, like all the
    best people do.


    Also, why didn't you attempt the 2nd requirement?




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


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Mar 3 17:29:56 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Tue Mar 3 19:20:20 2026
    Am 03.03.2026 um 18:29 schrieb Scott Lurndal:
    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.

    That's a matter of opinion. For me C is an awful language.
    You need mutiple times the code like in C++.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Tue Mar 3 20:48:06 2026
    On 03/03/2026 05:15, Tim Rentsch wrote:
    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 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!

    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.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Tue Mar 3 22:47:44 2026
    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".


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Tue Mar 3 23:56:36 2026
    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?


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Tue Mar 3 15:51:08 2026
    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.)

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Tue Mar 3 16:23:54 2026
    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.)

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Tue Mar 3 16:26:27 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Wed Mar 4 05:27:27 2026
    Am 04.03.2026 um 01:26 schrieb Tim Rentsch:
    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.

    Comparisons in both directions fit in either group.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Mar 4 08:48:57 2026
    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:
    [...]

    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").


    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.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Wed Mar 4 01:07:18 2026
    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:
    [...]

    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").

    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.)

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Wed Mar 4 11:45:41 2026
    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Wed Mar 4 12:09:22 2026
    On Wed, 04 Mar 2026 01:07:18 -0800
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    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:
    [...]

    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").

    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.

    Actually, I would not mind demonstration of how it can be done in C++
    if it presents a novel way of implementing control flow that is not
    available in C. Some jucy trick with lambdas or co-routines. May be,
    even with templates, but I don't believe that templates could be of
    help.
    Thinking few seconds about it, even in "old" C++ there is one control
    flow tool that is up to the task. I didn't figure it out immediatly
    beacuse I happen to hate this construct.

    Of course, Bonita's attempt was nothing of that sort. It was yet
    another boring demonstration of inferiority of C++ iostream formatted
    output.
    Other than that it was written in C subset of C++.

    (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.)




    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Wed Mar 4 11:44:21 2026
    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Mar 4 12:58:48 2026
    On 04/03/2026 10:07, Keith Thompson wrote:
    David Brown <david.brown@hesbynett.no> writes:

    <snip>


    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.)


    I have no problem with the thread here in comp.lang.c, and no problem
    with people being interested in the challenge.

    But I don't think it is reasonable to call it "writing C code". I would
    not like to draw a line and declare that omitting this or that
    particular feature means the code no longer resembles code written in
    normal C. However, remove enough features and it becomes clear - once
    people are using "longjmp" instead of basic C control flow statements,
    it's not C any more even if a C compiler can handle it.

    I do agree that posting code in other languages is normally off-topic
    for the group - though sometimes it makes sense for comparison to C.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Wed Mar 4 13:20:35 2026
    On 03/03/2026 21:47, Janis Papanagnou wrote:
    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.[****]

    The other, possibly 'easier' language doesn't have to use a clever
    approach. In fact, too clever and it becomes harder to write, understand
    or port.

    The softer language in this case didn't need these distractions needed by C:

    * #include lines
    * Variable declarations /and/ types
    * Semicolons
    * Long-winded for-loop headers
    * Various extra parentheses around conditions and so on
    * Even needing to create a 'main' routine
    * And, being run from source, no compile/link step for each
    edit-run cycle

    These would all impact productivity and be a distraction.

    Once the program /is/ working, then the above is less of an imposition,
    since you only need to worry about all that once.

    [****] But for *that* your language would not qualify because,
    as you said, it can be "trivially converted to C".

    Let's say 'mechanically'. There's one detail with the dynamic width of
    each column which I'm not sure about, but I will start now:

    Ok, 8-9 minutes later, I got the C version shown below. I'm a poor
    typist and all that extra punctiation is troublesome. The width thing
    was easier than I expected.


    -------------------------------------

    #include <stdio.h>
    #include <string.h>

    int getrows(int n) {
    int m=1, s=1;
    while (s<n) {++m; s=m*m;}
    return m;
    }

    void solve(int n) {
    int rows, cols, size, i, width;
    char str[16];
    rows=cols=getrows(n);

    size=rows*cols;
    printf("input = %d\n", n);

    if ((size-n)>=rows) {
    printf("not possible to output 1-%d where rows=columns\n", n);
    return;
    }

    width=sprintf(str,"%d", n);

    for (int r=1; r<=rows; ++r) {
    i=r;
    for (int c=1; c<=cols; ++c) {
    printf(" %*d", width, i);
    i+=rows;
    }
    puts("");
    }
    puts("");
    }

    int main() {
    for (int n=1; n<=27; ++n)
    solve(n);
    }








    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Wed Mar 4 08:29:29 2026
    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().

    Why? Just for s's and giggles?



    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.

    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 KNEW I'd learn something new on clc.



    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?





    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Wed Mar 4 08:30:35 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Wed Mar 4 14:36:28 2026
    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.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Wed Mar 4 07:01:56 2026
    Michael S <already5chosen@yahoo.com> writes:

    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.

    It's a challenge to make it less tedious. Personally I found
    that interesting. If other folks have a different reaction
    that's okay with me. If you try it though you might find it more
    interesting than you expect; there are some skills to learn,
    similarly in a way to when doing functional programming for the
    first time. Or like assembly language programming - I wouldn't
    do assembly programming now, but I'm glad I went through the
    process of learning and doing assembly programming all those
    years ago.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Wed Mar 4 10:02:02 2026
    On 3/4/2026 9:36 AM, Bart wrote:
    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.


    OK, sorry. But that wasn't the last post in the thread before you
    submitted yours. That was 3 posts prior.

    I did write this 'challenge' in python first, so I could print various
    lists in alphabetical order by column then row.

    To my eye, printing sequential numbers or names by column-row looks
    better than by row-column.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Mar 4 16:02:56 2026
    On 2026-03-04 14:29, DFS wrote:

    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.

    Yes, it depends on how we learned programming and what we're used. "C" programmers naturally use loops and variables. Bauer/W”ssner[1981], for example, wrote a monography _without using loops and variables_ in the
    first 320 pages; they derived their existence coming from a functional
    approach with recursive functions.

    Janis


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Wed Mar 4 15:31:44 2026
    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 ;-)

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Wed Mar 4 08:09:43 2026
    DFS <nospam@dfs.com> writes:

    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.

    Just a note that a function can be tail recursive without being
    directly recursive. A tail call is one where the result of the call
    is the return value of the calling function, regardless of whether
    the call is recursive, including being indirectly 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.

    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().

    To me that would make the problem outside the realm of C programs,
    and so subject to a technical out-of-bounds in this newsgroup. I
    know other people have different stances on this question, I am
    simply explaining my own view so you know where I'm coming from.

    [...]

    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.

    Like what you say, for() and while() feel more natural because
    you're more used to them. That will change as you use a functional
    and/or recursive style more. My own experience with functional
    programming and writing functions resursively is that at first they
    seemed somewhat contrived but as I gained experience they felt more
    natural, and later in many cases a functional/recursive writing
    seemed easier and more direct. So I urge you to continue pushing
    forward on this path.

    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.

    Hmmm. Well I give you points for originality. ;)

    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?

    My hint is there are some powerful functions in the C standard
    library that make this feasible.

    If that hint isn't enough, someone else asked a question in this
    thread (and I responded) that should point you in the right
    direction.

    If both of those hints aren't enough, ask again and I'll try to get
    you closer to the goal.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Wed Mar 4 19:27:11 2026
    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?


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Wed Mar 4 09:38:16 2026
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

    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.

    Yeah, me too. Incidentally, I used a different way to determine
    the field width to use, something like this:

    int field_width = snprintf( 0, 0, "%u", cutoff );

    The minor differences in spacing come from me not remembering
    which version I posted. Mea culpa.

    The change in spacing didn't bother me, I mentioned it only
    out of a penchant for accuracy in my writing.

    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 ;-)

    That isn't hard once you see the basic technique, but it has its
    own set of challenges that I think make it interesting. I'm
    looking forward to seeing your solution. My first version is
    kind of ugly, probably I will rewrite it before posting.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Wed Mar 4 11:19:35 2026
    Michael S <already5chosen@yahoo.com> writes:
    [...]
    Actually, I would not mind demonstration of how it can be done in C++
    [...]

    Of course I have no problem with that. If you want comp.lang.c++, you
    know where to find it.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Wed Mar 4 11:25:05 2026
    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.

    For freestanding implementations, the name and type of the entry
    point are implementation-defined, and portability goes out the
    window.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Opus@3:633/10 to All on Wed Mar 4 22:42:44 2026
    On 19/02/2026 22:55, DFS wrote:
    Challenge is to output sequential numbers by column then row:

    1ÿÿ 6ÿ 11ÿ 16ÿ 21
    2ÿÿ 7ÿ 12ÿ 17ÿ 22
    3ÿÿ 8ÿ 13ÿ 18ÿ 23
    4ÿÿ 9ÿ 14ÿ 19ÿ 24
    5ÿ 10ÿ 15ÿ 20ÿ 25
    (...)

    A challenge, or homework.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Wed Mar 4 17:44:12 2026
    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 )
    | ^
    rc-montero2.cpp:13:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:13:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:13:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:15:1: error: extended character ÿ is not valid in an identifier
    15 | ÿÿÿÿoptional<size_t>
    | ^
    rc-montero2.cpp:15:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:15:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:15:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:18:1: error: extended character ÿ is not valid in an identifier
    18 | ÿÿÿÿif( !rows || !cols )
    | ^
    rc-montero2.cpp:18:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:18:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:18:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:20:1: error: extended character ÿ is not valid in an identifier
    20 | ÿÿÿÿsize_t clip = *rows * *cols - 1;
    | ^
    rc-montero2.cpp:20:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:20:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:20:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:21:1: error: extended character ÿ is not valid in an identifier
    21 | ÿÿÿÿif( argc >= 4 )
    | ^
    rc-montero2.cpp:21:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:21:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:21:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:26:1: error: extended character ÿ is not valid in an identifier
    26 | ÿÿÿÿunsigned width = [&]
    | ^
    rc-montero2.cpp:26:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:26:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:26:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:32:1: error: extended character ÿ is not valid in an identifier
    32 | ÿÿÿÿif( clip < rows )
    | ^
    rc-montero2.cpp:32:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:32:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:32:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:34:1: error: extended character ÿ is not valid in an identifier
    34 | ÿÿÿÿfor( size_t row = 0; row < rows; ++row )
    | ^
    rc-montero2.cpp:34:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:34:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:34:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:35:1: error: extended character ÿ is not valid in an identifier
    35 | ÿÿÿÿ{
    | ^
    rc-montero2.cpp:35:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:35:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:35:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:46:1: error: extended character ÿ is not valid in an identifier
    46 | ÿÿÿÿ}
    | ^
    rc-montero2.cpp:46:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:46:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:46:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:51:1: error: extended character ÿ is not valid in an identifier
    51 | ÿÿÿÿistringstream iss( str );
    | ^
    rc-montero2.cpp:51:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:51:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:51:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:52:1: error: extended character ÿ is not valid in an identifier
    52 | ÿÿÿÿsize_t ret;
    | ^
    rc-montero2.cpp:52:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:52:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:52:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:53:1: error: extended character ÿ is not valid in an identifier
    53 | ÿÿÿÿiss >> ret;
    | ^
    rc-montero2.cpp:53:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:53:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:53:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:54:1: error: extended character ÿ is not valid in an identifier
    54 | ÿÿÿÿif( !iss || !iss.eof() )
    | ^
    rc-montero2.cpp:54:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:54:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:54:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:56:1: error: extended character ÿ is not valid in an identifier
    56 | ÿÿÿÿreturn ret;
    | ^
    rc-montero2.cpp:56:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:56:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp:56:1: error: extended character ÿ is not valid in an identifier
    rc-montero2.cpp: In function ?int main(int, char**)?:
    rc-montero2.cpp:13:1: error: ?ÿÿÿÿif? was not declared in this scope
    13 | ÿÿÿÿif( argc < 3 )
    | ^~~~~~
    rc-montero2.cpp:15:1: error: ?ÿÿÿÿoptional? was not declared in this scope
    15 | ÿÿÿÿoptional<size_t>
    | ^~~~~~~~~~~~
    rc-montero2.cpp:15:20: error: expected primary-expression before ?>? token
    15 | ÿÿÿÿoptional<size_t>
    | ^
    rc-montero2.cpp:16:9: error: ?rows? was not declared in this scope
    16 | rows = parse( argv[1] ),
    | ^~~~
    rc-montero2.cpp:17:9: error: ?cols? was not declared in this scope
    17 | cols = parse( argv[2] );
    | ^~~~
    rc-montero2.cpp:20:1: error: ?ÿÿÿÿsize_t? was not declared in this scope
    20 | ÿÿÿÿsize_t clip = *rows * *cols - 1;
    | ^~~~~~~~~~
    rc-montero2.cpp:22:56: error: ?pClip? was not declared in this scope
    22 | if( optional<size_t> pClip = parse( argv[3] ); pClip )
    | ^~~~~ rc-montero2.cpp:24:9: error: ?else? without a previous ?if?
    24 | else
    | ^~~~
    rc-montero2.cpp:26:1: error: ?ÿÿÿÿunsigned? was not declared in this scope
    26 | ÿÿÿÿunsigned width = [&]
    | ^~~~~~~~~~~~
    rc-montero2.cpp:31:11: error: expected primary-expression before ?)? token
    31 | }();
    | ^
    rc-montero2.cpp:32:9: error: ?clip? was not declared in this scope
    32 | ÿÿÿÿif( clip < rows )
    | ^~~~
    rc-montero2.cpp:34:17: error: expected primary-expression before ?row?
    34 | ÿÿÿÿfor( size_t row = 0; row < rows; ++row )
    | ^~~
    rc-montero2.cpp:34:26: error: ?row? was not declared in this scope
    34 | ÿÿÿÿfor( size_t row = 0; row < rows; ++row )
    | ^~~
    rc-montero2.cpp: In function ?std::optional<long unsigned int>
    parse(const char*)?:
    rc-montero2.cpp:51:1: error: ?ÿÿÿÿistringstream? was not declared in
    this scope
    51 | ÿÿÿÿistringstream iss( str );
    | ^~~~~~~~~~~~~~~~~
    rc-montero2.cpp:52:1: error: ?ÿÿÿÿsize_t? was not declared in this scope
    52 | ÿÿÿÿsize_t ret;
    | ^~~~~~~~~~
    rc-montero2.cpp:53:1: error: ?ÿÿÿÿiss? was not declared in this scope
    53 | ÿÿÿÿiss >> ret;
    | ^~~~~~~
    rc-montero2.cpp:53:12: error: ?ret? was not declared in this scope
    53 | ÿÿÿÿiss >> ret;
    | ^~~
    rc-montero2.cpp:54:10: error: ?iss? was not declared in this scope
    54 | ÿÿÿÿif( !iss || !iss.eof() )
    | ^~~
    rc-montero2.cpp:54:1: error: ?ÿÿÿÿif? was not declared in this scope
    54 | ÿÿÿÿif( !iss || !iss.eof() )
    | ^~~~~~
    rc-montero2.cpp:56:1: error: ?ÿÿÿÿreturn? was not declared in this scope
    56 | ÿÿÿÿreturn ret;
    | ^~~~~~~~~~
    rc-montero2.cpp:57:1: warning: no return statement in function returning non-void [-Wreturn-type]
    57 | }
    | ^



    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.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Wed Mar 4 15:13:52 2026
    DFS <nospam@dfs.com> writes:
    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 )
    | ^
    [277 lines deleted]

    Apparently the code you compiled contained NO-BREAK-SPACE (U+00a0)
    characters, and your compiler didn't tolerate them. They have
    have been in the original source (and compiled with a compiler that
    accepts them), or they may have been introduced in the process of
    posting the code to Usenet. (I frankly don't care which.)

    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.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Wed Mar 4 23:37:04 2026
    DFS <nospam@dfs.com> writes:
    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 )


    Probably junk inserted by your browser or due to
    the use of an odd charset or character encoding to create the post.

    Replace those characters with whitespace characters to get past that
    error.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Wed Mar 4 21:07:13 2026
    On 3/4/2026 6:13 PM, Keith Thompson wrote:
    DFS <nospam@dfs.com> writes:
    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 )
    | ^
    [277 lines deleted]

    Apparently the code you compiled contained NO-BREAK-SPACE (U+00a0) characters, and your compiler didn't tolerate them.

    You're right - I forgot I had to fix Montero's code the first time.
    Notepad++ shows them as NBSP characters.


    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.

    If I make Montero cry am I forgiven?



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Thu Mar 5 07:32:33 2026
    It was thunderbird which made a NBSP-row out of my tabs.
    Here my final code, somewhat more simplified.

    #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> pClip = parse( argv[3] ); pClip && *pClip )
    clip = (*pClip <= clip ? *pClip : clip) + 1;
    else
    return EXIT_FAILURE;
    size_t nMtx = *rows * *cols;
    clip = clip <= nMtx ? clip : nMtx;
    unsigned width = [&]
    {
    ostringstream oss;
    oss << clip - 1;
    return (unsigned)oss.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;
    }

    I especially like the sub-statement:

    " "sv.substr( head, !head )

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Thu Mar 5 08:23:26 2026
    Am 05.03.2026 um 07:32 schrieb Bonita Montero:
    It was thunderbird which made a NBSP-row out of my tabs.

    ÿÿÿ unsigned width = [&]
    ÿÿÿÿÿÿÿ {
    ÿÿÿÿÿÿÿÿÿÿÿ ostringstream oss;
    ÿÿÿÿÿÿÿÿÿÿÿ oss << clip - 1;
    ÿÿÿÿÿÿÿÿÿÿÿ return (unsigned)oss.str().length();
    ÿÿÿÿÿÿÿ }();

    Even simpler:
    unsigned width = (unsigned)(ostringstream() << clip - 1).str().length();
    C++ really rocks !

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Thu Mar 5 02:24:25 2026
    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;
    }
    ----------------------------------------------------------


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Thu Mar 5 08:46:37 2026
    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;
    }



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Thu Mar 5 09:52:08 2026
    Now it's even shorter - and still *with* error handling:

    #include <iostream>
    #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] ),
    clip;
    if( !rows || !*rows || !cols || !*cols )
    return EXIT_FAILURE;
    clip.emplace( *rows * *cols );
    if( argc >= 4 && (!(clip = parse( argv[3] )) || !*clip) )
    return EXIT_FAILURE;
    *clip = min( *clip, *rows * *cols );
    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 < *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;
    }

    If you're familiar with C++ this code is more readable.
    And the C++ streams are type safe, C streams not.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Thu Mar 5 10:49:39 2026
    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.


    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Thu Mar 5 11:03:12 2026
    Am 05.03.2026 um 10:49 schrieb tTh:

    And *still* in the wrong group.
    I'm impressed about how far your reading goes.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Thu Mar 5 05:06:24 2026
    On 3/5/2026 2:46 AM, Bonita Montero wrote:
    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

    Definitely not. But if you indented correctly it would be easier to read.
    Win for C either way.

    and *with* error handling while parsing the
    parameters. You don't have that.

    Yes I do. Lines 4-7. And it actually works better than yours.

    Wrong # of inputs and your program just quits.
    Wrong # of inputs and my program shows you what to do.
    Win for DFS ------------------------------------------------------------------------ Invalid inputs (such as ./rc a b c) and both our programs just quit.
    Tie
    ------------------------------------------------------------------------
    You pull in 6 headers, vs my 2.
    Win for C ------------------------------------------------------------------------
    You use 10 variables: rows, cols, clip, psClip, nMtx, width, row, head,
    value, ret
    I use 8 variables: rows, cols, max, cw, colwidth, r, nbr, i
    Win for DFS ------------------------------------------------------------------------ Changing the start value of your code from 0 to 1 results in 1 fewer
    rows than input.
    Changing the start value of my code from 1 to 0 results in 1 extra row
    than input.
    Tie
    ------------------------------------------------------------------------
    I didn't time them, but both programs feel about the same speed, with
    and without printf() and cout.
    Tie
    ------------------------------------------------------------------------
    Both our programs apparently correctly print very large matrices. I
    tried 10000 x 10000 and they both ran all the way thru. But because I
    set a char to 6 (not considering massive matrices), my program generated
    a buffer overflow and a "stack smashing detected" error at the very end
    for values >= 1,000,000.

    Yours never did.
    unsigned width = (unsigned)(ostringstream() << clip - 1).str().length();
    saved your ass.

    Changed the size of my char variable 'cw' from 6 to 12 and no more messages. Win for Montero and C++ ------------------------------------------------------------------------
    Your line count is 42
    My line count is 29 (31% shorter).
    Win for C ------------------------------------------------------------------------
    Your compiled code is 32,304 bytes.
    My compiled code is 16,176 bytes.
    Win for C ------------------------------------------------------------------------
    The output of g++ -S rc-montero.cpp is 2092 lines
    The output of gcc -S rc-dfs.c is 152 lines
    Win for C ------------------------------------------------------------------------

    11 comparisons

    C/DFS vs C++/Montero win-loss-tie: 7-1-3

    Overall it's a total beatdown!

    You may need to rethink your commitment to C++, and apologize for your aggressive trolling of comp.lang.c.






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




    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Thu Mar 5 11:13:41 2026
    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Thu Mar 5 14:49:13 2026
    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


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Kenny McCormack@3:633/10 to All on Thu Mar 5 15:22:52 2026
    In article <10objjj$hie$1@news.gegeweb.eu>, tTh <tth@none.invalid> wrote:
    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.

    Bonita obviously don't care. That ship has long since sailed.
    No point in continuing to harp on it.

    BTW, it seems to me that Bonita takes the view that C is merely a concept,
    and that C++ is the current implementation of that concept.

    I've taken this sort of view myself, in other forums, in other contexts.
    It can be a useful mental framework.

    --
    BigBusiness types (aka, Republicans/Conservatives/Independents/Liberatarians/whatevers)
    don't hate big government. They *love* big government as a means for them to get
    rich, sucking off the public teat. What they don't like is *democracy* - you know,
    like people actually having the right to vote and stuff like that.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Thu Mar 5 19:27:52 2026
    On 05.03.26 15:49, Scott Lurndal wrote:
    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

    Just two remarks. These two function variants are called just once,
    so there's hardly any performance issue in this case. And note that
    the original program uses no reals/floats at all; usually I try to
    stay within a minimum required feature set, here concerning the used
    types, the float functions and %f formatter, that I'd avoid. (YMMV.
    No biggie anyway.)

    With *printf's definition I actually like the sprintf variant; to me
    it appears to be clearer. For the float-expression I'd certainly add
    a comment.

    BTW, since you're using shell code to demonstrate your idea; with
    the shell I'm typically using a "string / no math variant" of DFS'
    code to determine the length

    max=$(( 8*8 ))
    colwidth=${#max}

    (where there's of course no printf or math functions necessary in
    shell). (Upthread folks were talking about readability.)

    Janis


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Thu Mar 5 13:46:39 2026
    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Thu Mar 5 19:46:58 2026
    Am 05.03.2026 um 15:49 schrieb Scott Lurndal:
    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


    Don't do that with 64 bit integrals and a FPU which has 53 bits mantissa.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Thu Mar 5 13:49:24 2026
    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
    s='news server'
    g='comp.lang.c'
    n=t.NNTP(s,119,'usr','pw')
    r,a,b,e,gn=n.group(g)
    def printStat(st,hd,rg):
    r,d=n.xhdr(st,'%s-%s'%rg)
    p=[]
    for i in range(len(d)):
    v=d[i][1]
    if st=='Subject': v=v[4:] if v[:3]=='Re:' else v
    p.append(v)
    x=[(i,p.count(i)) for i in set(p)]
    x.sort(key=lambda s:(-s[1],s[0].lower()))
    print('Posts %s %s'%(len(set(p)),hd))
    for v in x: print(' %s %s'%(v[1],v[0]))
    print()
    print("Last " + y.argv[1] + " Posts")
    m=(int(e)-int(y.argv[1])+1,int(e))
    printStat("From","Posters",m)
    printStat("Subject","Subjects",m)
    n.quit()
    -------------------------------------------------------


    $ python program.py N


    (ignore the nntp deprecation warning - someone at Python thinks Usenet
    is dead. Long live Usenet.)


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Thu Mar 5 21:02:12 2026
    On Thu, 5 Mar 2026 13:49:24 -0500
    DFS <nospam@dfs.com> wrote:

    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?


    As far as I know, it isn't.
    My comment was related to column-major order that Fortran uses for multidimensional arrays.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Mar 5 19:09:37 2026
    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.

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Thu Mar 5 14:11:40 2026
    On 3/5/2026 5:13 AM, Bonita Montero wrote:
    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.

    Both are fugly, but C++ much moreso.


    It's the typical C code which is prone to buffer-over-
    flows (sprintf)

    s/typical/untested


    and there's no checking of the validity of the command-
    line-parameters.

    ? You can validate command line arguments all day and night with C.


    But usually C++ is about five times less code

    You're getting desperate.



    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/




    That's the most popular reason C++ is mostly much less code, but there a few further.

    Accept your beatdown. Learn some humility.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Thu Mar 5 20:50:22 2026
    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 ?

    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Thu Mar 5 22:34:26 2026
    On Thu, 5 Mar 2026 20:50:22 +0100
    tTh <tth@none.invalid> wrote:

    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 ?


    I don't understand why this formula is good even for smaller numbers.
    For example, ceil(log10(10*10)) returns 2. Desired answer is 3.

    But at least for small numbers the formula gives a wrong answer only
    when x*y is an exact power of 10. For big numbers it can miscalculate in
    other cases as well. E.g. (20877*478996024333).

    Of course, considering the entire problem, really big row*col is a bad
    idea for more prosaic reason than inaccuracy of double precisions
    calculations. The reason is that neither you nor your computer will live
    long enough to see/print the whole output.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Thu Mar 5 21:34:37 2026
    On 05/03/2026 19:46, DFS wrote:
    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)"


    There are more imaginative ways to get a program without a "main"
    function (all of which are non-portable). You can use a gcc "alias"
    attribute to make "main" an alias for your "real_main" function. You
    could make your "main" a data object, containing the opcodes for "jmp real_main". You could use a gcc "constructor" alias to have "real_main"
    run before main(), and have "main" simply be a symbol in the linker or C
    file. You could replace the C startup code that runs before main, and
    have it call "real_main" instead. There may be other ways - that's just
    off the top of my head.


    Rentsch's motivation seems to be doing something way outside the box.

    All will be revealed when he releases his double-secret code.


    /If/ he reveals it. And /if/ he reveals it this year, rather than
    months after everyone has forgotten the thread.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Thu Mar 5 20:39:19 2026
    On 05/03/2026 18:49, DFS wrote:
    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

    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'.)



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Mar 5 21:12:23 2026
    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.

    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.




    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Thu Mar 5 13:49:49 2026
    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.

    #include <stdio.h>
    #include <math.h>

    int
    main(){
    printf( " cutoff snprintf ceil(log)\n" );
    printf( " ------ -------- -----------\n" );
    for( signed cutoff = 0; cutoff < 12; cutoff++ ){
    int a = snprintf( 0, 0, "%d", cutoff );
    int b = ceil(log10(cutoff));
    printf( " %6d %8d %11d\n", cutoff, a, b );
    }
    }

    gives

    cutoff snprintf ceil(log)
    ------ -------- -----------
    0 1 -2147483648
    1 1 0
    2 1 1
    3 1 1
    4 1 1
    5 1 1
    6 1 1
    7 1 1
    8 1 1
    9 1 1
    10 2 1
    11 2 2

    Also the snprintf() way doesn't need -lm. :)

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Thu Mar 5 13:54:21 2026
    Michael S <already5chosen@yahoo.com> writes:

    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?

    I did program in Fortran in my youth (and not just my youth), but
    I prefer the "down the rows first" ordering independent of Fortran,
    because I find it easier to look for things. Like 'ls' output.

    Choice of C-style or Fortran-style multidimensional arrays is
    another kettle of fish entirely.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Thu Mar 5 14:04:42 2026
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

    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 :-)

    Yes I do enjoy looking at alternative approaches. Guilty as
    charged. :)

    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.

    Yeah, argument processing is a bitch, especially if you want to
    guard against malformed invocations. It's vaguely satisfying to
    find an approach that doesn't suck.

    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.

    I've just gone through my first (and probably last) rewrite, and
    the result is a lot cleaner. I won't say more just now, and let
    you continue on your current path.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Thu Mar 5 14:12:19 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Thu Mar 5 22:24:53 2026
    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

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Mar 6 01:00:16 2026
    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.

    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




    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Thu Mar 5 15:05:09 2026
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

    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

    The simple counter method is what I first coded. Then I did a
    binary search. The binary search is kind of clunky in a
    "no for() or while()" environment, so I figured out a way
    to use Newton-Raphson iteration. A little bit tricky to get
    right, but after wrestling with it I managed to get a fairly
    nice formulation.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Thu Mar 5 15:08:17 2026
    Michael S <already5chosen@yahoo.com> writes:

    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.

    Definitely not. Use of switch() is allowed (and 'case' also).

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Fri Mar 6 00:18:43 2026
    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


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Fri Mar 6 00:12:13 2026
    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>

    /*
    ** define RIGHT_ALIGN to right-align all numeric results
    ** otherwise, numeric results will align to the left
    */
    #ifdef RIGHT_ALIGN
    #define FORMAT "%*u"
    #else
    #define FORMAT "%-*u"
    #endif

    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 */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[3],&eptr,10);
    valid = ((*eptr == 0) && (result <= UINT_MAX));
    cut_off = valid ? result : 0;
    switch (!valid || (cut_off == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for cut-off (\"%s\")\n",argv[3]);
    args_ok = 0;
    }
    }

    case 3: /* rowcol #rows #cols */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[1],&eptr,10);
    valid = ((eptr != argv[1]) && (*eptr == 0) && (result <= UINT_MAX));
    n_rows = valid ? result : 0;
    switch (!valid || (n_rows == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for # rows (\"%s\")\n",argv[1]);
    args_ok = 0;
    }

    result = strtoul(argv[2],&eptr,10);
    valid = ((eptr != argv[2]) && (*eptr == 0) && (result <= UINT_MAX));
    n_cols = valid ? result : 0;
    switch (!valid || (n_cols == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for # columns (\"%s\")\n",argv[2]);
    args_ok = 0;
    }
    }

    switch (cut_off)
    {
    case 0:
    cut_off = n_rows * n_cols;
    break;

    default:
    args_ok = (cut_off > n_rows * n_cols) ? fprintf(stderr,"cut off value %u not found in table\n",cut_off), 0 : args_ok;
    break;
    }

    break;

    case 2: /* rowcol cutoff */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[1],&eptr,10);
    valid = ((eptr != argv[1]) && (*eptr == 0) && (result <= UINT_MAX));
    cut_off = valid ? result : 0;

    switch (!valid || (cut_off == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for cut-off (\"%s\")\n",argv[1]);
    args_ok = 0;

    case 0:
    {
    int valu;
    jmp_buf CompRoot;

    valu = setjmp(CompRoot);
    switch (valu >= cut_off)
    {
    case 0:
    ++n_rows;
    longjmp(CompRoot,(n_rows * n_rows));
    break;
    }
    n_cols = n_rows;
    }

    switch ( (cut_off < (n_rows * (n_cols-1)) + 1) )
    {
    case 1:
    fprintf(stderr,"Cut off value %u not possible where rows=cols\n",cut_off);
    args_ok = 0;
    }
    break;
    }
    }
    break;

    default:
    args_ok = 0; /* default error msg is usage message */
    break;
    }

    switch (args_ok)
    {
    case 1:
    {
    jmp_buf ByRow, ByCol;
    unsigned int row, col, valu;
    int want_eol;

    cut_off = (cut_off == 0) ? n_rows * n_cols : cut_off ;
    row = setjmp(ByRow);
    want_eol = 0;
    col = setjmp(ByCol);
    valu = 1 + row + (col * n_rows);
    want_eol = (valu <= cut_off) ? printf(FORMAT,1 + snprintf(NULL,0,"%u",cut_off),valu), 1 :want_eol;
    (col + 1 < n_cols) ? longjmp(ByCol,col+1), 1 : 0 ;
    (want_eol) ? putchar('\n') : 0 ;
    (row + 1 < n_rows) ? longjmp(ByRow,row+1), 1 : 0 ;

    status = EXIT_SUCCESS;
    }
    break;

    default:
    fprintf(stderr,"Usage:\t%s #_rows #_cols [ cut-off ]\nor\t%s cut-off\n",argv[0],argv[0]);
    }

    exit(status);
    }




    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Fri Mar 6 00:14:13 2026
    On Fri, 06 Mar 2026 00:12:13 +0000, Lew Pitcher wrote:

    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>

    Oops... This doesn't use anything from math.h
    I forgot to remove it once I got rid of the floatingpoint math functions

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Thu Mar 5 19:24:37 2026
    On 3/5/2026 3:39 PM, Bart wrote:
    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'?


    TONS more.

    You would go down a level and use Python socket and ssl library code
    (which nntplib wraps).

    The most handy thing nntplib does for you is return the results of NNTP
    calls in python list or dictionary objects.

    send the request:
    response, data = newsserver.xhdr("From","322356-322365")

    valid response comes back from the server:
    221 Header or metadata information for From follows (from overview)

    data is:
    [('322356', 'Lew Pitcher <lew.pitcher@digitalfreehold.ca>'),
    ('322357', 'Tim Rentsch <tr.17687@z991.linuxsc.com>'),
    ('322358', 'Tim Rentsch <tr.17687@z991.linuxsc.com>'),
    ('322359', 'Tim Rentsch <tr.17687@z991.linuxsc.com>'),
    ('322360', 'Tim Rentsch <tr.17687@z991.linuxsc.com>'),
    ('322361', 'Lew Pitcher <lew.pitcher@digitalfreehold.ca>'),
    ('322362', 'Michael S <already5chosen@yahoo.com>'),
    ('322363', 'Tim Rentsch <tr.17687@z991.linuxsc.com>'),
    ('322364', 'Tim Rentsch <tr.17687@z991.linuxsc.com>'),
    ('322365', 'Janis Papanagnou <janis_papanagnou@hotmail.com>')]


    If you're interested in python nntplib code, I wrote a lot of it I'll be
    glad to share.



    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'.)


    pip install standard-nntplib should set you straight.


    They deprecated nntplib a while ago, but docs as of Python 3.12: https://docs.python.org/3.12/library/nntplib.html


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Fri Mar 6 02:17:48 2026
    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Fri Mar 6 03:35:15 2026
    Am 05.03.2026 um 20:11 schrieb DFS:

    It's the typical C code which is prone to buffer-over-
    flows (sprintf)

    s/typical/untested

    Then write assembly and say that's all a matter of testing.

    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/

    Five seconds in C++:

    unordered_map<Key, Value> um;
    um.emplace( k, v );



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Thu Mar 5 20:06:22 2026
    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...

    By the way, I see no reason to disallow a cutoff value of 0.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Thu Mar 5 20:31:39 2026
    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().

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Fri Mar 6 07:48:05 2026
    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Mar 6 11:49:41 2026
    On Fri, 6 Mar 2026 07:48:05 +0100
    Bonita Montero <Bonita.Montero@gmail.com> wrote:

    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Fri Mar 6 13:41:22 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Mar 6 15:33:24 2026
    On Fri, 6 Mar 2026 13:41:22 +0100
    Bonita Montero <Bonita.Montero@gmail.com> wrote:

    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Fri Mar 6 14:42:29 2026
    Am 06.03.2026 um 14:33 schrieb Michael S:

    There's more than one way to skin a cat.
    Ogh, sorry. I mean, more than one to post a picture of kitten.

    If efficiency doesn't count (log10 is about 20 cycles on my PC)
    chose the precise solution, even more if anyone understands that.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Fri Mar 6 13:51:58 2026
    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 :-)

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Fri Mar 6 14:58:24 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Mar 6 17:13:42 2026
    On Fri, 06 Mar 2026 14:58:24 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    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.

    The challenge is to print numbers starting from 1.
    Look at the 1st post.
    That is, if your newsreader allows it. If it is not then just believe
    me.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Fri Mar 6 10:34:55 2026
    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.

    I see Lew Pitcher submitted his - mind-blowing stuff. I compiled and
    tested, and it seemed to work fine.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Fri Mar 6 10:36:19 2026
    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:

    with 1-column inputs like 10 1 3 or 100 1 25, your program prints (row
    - cutoff) blank lines after the cutoff.

    prompt$./rc-lew 10 1 3
    1
    2
    3







    prompt$



    Adding
    if (valu > cut_off) {exit(0);}
    right after
    puts("");
    fixes it.


    Thanks


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Fri Mar 6 16:02:14 2026
    On 06/03/2026 00:12, Lew Pitcher wrote:
    OK, it's not pretty, but here it is

    I tried it really just to see if my C compiler would manage it, which it
    did. So nothing too scary in it.

    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.

    One thing I've noticed is that numbers are shown left-justified when
    narrower than the maximum, so '9 ' rather than ' 9'. For tabular data in they're normally right-justified.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Fri Mar 6 08:37:35 2026
    scott@slp53.sl.home (Scott Lurndal) writes:

    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.

    You changed the subject. We were talking about how to
    calculate an appropriate field width given a maximum value.
    The problem under discussion produces values from 1 to
    maximum value, inclusive. The expression ceil(log10( max ) )
    gives wrong answers when max is a power of 10. I haven't
    looked at Bonita Montero's code but based on the snippet
    above it seems clear he is responding to the original problem
    statement, even if he may have misunderstood what that was
    asking for.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Fri Mar 6 08:46:20 2026
    DFS <nospam@dfs.com> writes:

    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 wasn't being sarcastic; I do give you points for originality. I
    leave it to you to decide how much value to ascribe to that.

    To be frank I didn't quite understand what you were suggesting. I
    was waiting for you to post some code so I could see what you meant.

    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.

    Exploring a new method, even if unsuccessful, still has value.

    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.

    I'm still hoping you will post an attempt first, especially now that
    you have seen Lew Pitcher's response. If you tell me where you are
    stuck I can try to give a suitable hint to get you over the hump.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Fri Mar 6 08:53:25 2026
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

    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 became aware of the restrictions some time ago, after seeing
    discussion in comp.lang.c. After that I looked carefully at the
    C standard to learn the official rules.

    I'll look at revising my code, in the light of your comments, and
    repost with a more "legal" version.

    Great, I'm cheering you on. :)

    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Fri Mar 6 12:11:32 2026
    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Fri Mar 6 17:38:04 2026
    On Fri, 06 Mar 2026 10:36:19 -0500, DFS wrote:

    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:

    with 1-column inputs like 10 1 3 or 100 1 25, your program prints (row
    - cutoff) blank lines after the cutoff.
    [snip]

    Yes, I'm aware :-)

    I fixed it in a later version, which I have not posted yet.
    The restricted-C version I posted in response to Tim Rentsch's counter-counter challenge behaves properly (albeit, with the UB that he identified).


    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Fri Mar 6 17:48:51 2026
    On Fri, 06 Mar 2026 17:38:04 +0000, Lew Pitcher wrote:

    On Fri, 06 Mar 2026 10:36:19 -0500, DFS wrote:

    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:

    with 1-column inputs like 10 1 3 or 100 1 25, your program prints (row
    - cutoff) blank lines after the cutoff.
    [snip]

    Yes, I'm aware :-)

    I fixed it in a later version, which I have not posted yet.

    And, 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 00:44:57 -0800
    ** Message-ID: <86v7feei2e.fsf@linuxsc.com>
    **
    ** Here is a counter challenge to make things more interesting: as above,
    ** but don't use nested loops (or goto's, etc).
    **
    ** -----------------------------------------------------------------------
    **
    ** From: Michael S <already5chosen@yahoo.com>
    ** Newsgroups: comp.lang.c
    ** Subject: Re: Sort of trivial code challenge - may be interesting to you anyway
    ** Date: Mon, 2 Mar 2026 11:07:20 +0200
    ** Message-ID: <20260302110720.00007698@yahoo.com>
    **
    ** Another counter challenge could have been to commpletely avoid loops/goto. **
    ** ========================================================================== **
    ** DFS challenge; solution by Lew Pitcher 2026-02-26
    ** cc -o rowcol_CLC -mtune=native -Wall -std=c99 -pedantic -lm rowcol_CLC.c
    **
    ** Tim Rentsch counter-challenge; solution by Lew Pitcher 2026-03-03
    ** cc -o rowcol_CLC -mtune=native -Wall -std=c99 -pedantic -lm -DNO_NESTED_LOOPS rowcol_CLC.c
    **
    ** Michael S counter-challenge; solution by Lew Pitcher 2026-03-03
    ** cc -o rowcol_CLC -mtune=native -Wall -std=c99 -pedantic -lm -DNO_LOOPS rowcol_CLC.c
    **
    ** NB: solutions use ceil(), sqrt(), and log10() calls from math lib
    **
    ** This code released into the public domain. Lew Pitcher, 2026-03-04
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <limits.h>


    /*
    ** define RIGHT_ALIGN to right-align all numeric results
    ** otherwise, numeric results will align to the left
    */
    #ifdef RIGHT_ALIGN
    #define FORMAT "%*u"
    #else
    #define FORMAT "%-*u"
    #endif

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

    /* cut-off value must occur within table bounds */
    if (cut_off)
    {
    if (cut_off > n_rows * n_cols)
    {
    fprintf(stderr,"cut off value %u not found in table\n",cut_off);
    args_ok = 0;
    }
    }
    else cut_off = n_rows * n_cols;

    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
    {
    /*
    ** Compute n_rows and n_cols, and validate that cut_off
    ** value occurs as last entry in final column
    **
    ** ----- Narrative -----
    ** As problem definition states that, for this configuration,
    ** n_rows must equal n_cols, and that n_rows * n_cols must
    ** include the cut_off value, we first approximate the value
    ** of n_rows and n_cols by taking the square root of cut_off
    ** and rounding that value up to the nearest integer. This
    ** guarantees that n_rows * n_cols is the smallest square
    ** that will contain the cut_off value.
    **
    ** But, this rounded value might be too big to place cut_off
    ** in the last column. So, we compute the first entry in
    ** the last column, and make sure that cut_off is not less
    ** than that value (if it is, then cut_off occurs in a column
    ** prior to the last column, and violates the constraints
    ** of this configuration).
    **
    ** FWIW, because of the way we compute n_rows and n_cols,
    ** we know that cut_off will never /exceed/ n_rows * n_cols.
    */
    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) /* then our inputs are valid and within our constraints */
    {
    if (cut_off == 0) cut_off = n_rows * n_cols;
    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);
    /*
    ** NB: will honour the "-" negative flag, resulting in an extremely
    ** large unsigned value. We will consider this an error, detected
    ** by a result greater than UINT_MAX.
    */

    if ((eptr !=string) && (*eptr == 0) && (result <= UINT_MAX))
    {
    *valu = result;
    status = 1;
    }
    return status;
    }

    #ifdef NO_LOOPS
    /*
    ** =================== NO LOOPS at all, so we go recursive =================== */
    static int oneCol(unsigned int col, unsigned int row, unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
    {
    unsigned int field_width = ceil(log10(cut_off)) + 1;
    unsigned int valu = 1 + row + (col * n_rows);
    int want_eol = 0;

    if (col > 0) want_eol = oneCol(col-1,row,n_rows,n_cols,cut_off);
    if (valu <= cut_off)
    {
    printf(FORMAT,field_width,valu);
    want_eol = 1;
    }
    return want_eol;
    }

    static void oneRow(unsigned int row, unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
    {
    if (row > 0) oneRow(row-1,n_rows,n_cols,cut_off);
    if (oneCol(n_cols,row,n_rows,n_cols,cut_off)) putchar('\n');
    }

    static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
    {
    oneRow(n_rows-1,n_rows,n_cols,cut_off);
    }
    #else
    #ifdef NO_NESTED_LOOPS
    /*
    ** =================== NO NESTED LOOPS at all, so we go linear ===================
    */
    static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
    {
    unsigned int field_width = ceil(log10(cut_off)) + 1;
    int max = n_rows * n_cols,
    want_eol = 0;

    for (unsigned int count = 0; count < max; ++count)
    {
    unsigned int row, col, valu;

    row = count / n_cols;
    col = count % n_cols;
    if (col == 0) want_eol = 0;

    valu = 1 + row + (col * n_rows);

    if (valu <= cut_off)
    {
    printf(FORMAT,field_width,valu);
    want_eol = 1;
    }

    if ((col == n_cols - 1) && (want_eol)) putchar('\n');
    }
    }
    #else
    /*
    ** =================== NO RESTRICTIONS, so we use nested loops ===================
    */
    static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
    {
    unsigned int field_width = ceil(log10(cut_off)) + 1;

    for (unsigned int row = 0; row < n_rows; ++row)
    {
    int want_eol = 0;

    for (unsigned int col = 0; col < n_cols; ++col)
    {
    unsigned int valu = 1 + row + (col * n_rows);
    if (valu <= cut_off)
    {
    printf(FORMAT,field_width,valu);
    want_eol = 1;
    }
    }
    if (want_eol) putchar('\n');
    }
    }
    #endif
    #endif

    [snip]


    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Fri Mar 6 13:01:31 2026
    On 3/6/2026 12:11 PM, 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.


    Let me be a little more clear. I stated the condition correctly, but
    the examples didn't adhere to it.

    The question is "Can a square matrix contain only 1-N?"

    Examples:

    1) only a non-square matrix of 10x9 or 9x10 can contain only 1-90.

    10x9
    ---------------------------
    1 2 3 4 5 6 7 8 9
    ---------------------------
    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

    9x10
    ------------------------------
    1 2 3 4 5 6 7 8 9 10
    ------------------------------
    1 10 19 28 37 46 55 64 73 82
    2 11 20 29 38 47 56 65 74 83
    3 12 21 30 39 48 57 66 75 84
    4 13 22 31 40 49 58 67 76 85
    5 14 23 32 41 50 59 68 77 86
    6 15 24 33 42 51 60 69 78 87
    7 16 25 34 43 52 61 70 79 88
    8 17 26 35 44 53 62 71 80 89
    9 18 27 36 45 54 63 72 81 90



    2) only a square matrix of 10x10 can contain only 1-91 (92 93 ... 100)

    ------------------------------
    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



    This is kind-of a constraint maximization exercise. The answer provides
    the fewest rows and columns necessary to consume the data points.

    One use of this calculation might be to determine - in order to maximize available horizontal screen space - how many columns you can use to
    print sorted data to screen, given screen width, # of data points,
    spacing and length of data. If you know you have 91-100 data points
    (numbers or text) you need one more column than if you have 81-90 data
    points.

    Or you can just print the sorted data in 1 column and suffer
    professional embarrassment...


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Fri Mar 6 13:28:59 2026
    On 3/6/2026 1:01 PM, DFS wrote:
    On 3/6/2026 12:11 PM, DFS wrote:

    1) only a non-square matrix of 10x9 or 9x10 can contain only 1-90.

    Dum dum! Obviously any row x column combination that equals 90 is
    sufficient.


    2) only a square matrix of 10x10 can contain only 1-91

    I do believe this is a true statement.


    ------------------------------
    ÿ 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




    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Fri Mar 6 21:53:35 2026
    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?

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Fri Mar 6 19:36:30 2026
    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.

    I just want to print to screen some sorted text data by column then row.
    I should have a new post about it tomorrow.


    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.

    Remember what Tom Petty said: "The waiting is the hardest part"


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Fri Mar 6 18:14:04 2026
    DFS <nospam@dfs.com> writes:

    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.

    Have you looked up setjmp()/longjmp() yet in the C standard (or
    maybe do an online search)? That could help jog your thinking,
    and once you get the main idea things might fall into place
    fairly quickly.

    I say again that ?: is an important part of the battle here.

    Feeling merciful, I am giving one more big hint. The outline of
    my program looks like this

    ...
    ... a few #include's, macros, typedef's, variable declarations
    ...

    static jmp_buf jb;

    int
    main( int argc, char *argv[] ){
    switch( setjmp( jb ) ){
    ...
    ... (inside the switch there are several 'case' arms)
    ... (however there are no 'break' statements used)
    ...
    }
    }

    Obviously some longjmp()'s are needed in the body of the switch() to
    make this all work. Good luck!

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Fri Mar 6 22:14:15 2026
    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 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?


    Every number N can be contained *somewhere within* a square matrix.

    But the question is: is there a 'row equals columns' matrix that can
    contain *only* 1 thru N.

    For 90 that answer is no. Only matrices where row != column stop at 90.

    r c
    1 90
    2 45
    3 30
    4
    5 18
    6 15
    7
    8
    9 10
    10 9


    For 91 the answer is Yes: it is possible to construct a rows=columns
    matrix containing 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


    I think your initial BartScript code got it exactly right, using a
    simple formula.


    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sat Mar 7 07:33:01 2026
    On 07.03.26 04:14, DFS wrote:
    [...]

    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.

    I don't see what the sqrt value would demonstrate here. But the
    pattern can be seen directly and derived from the second column;
    it's a sequence of
    1 possible, 1 not possible,
    2 possible, 2 not possible,
    3 possible, 3 not possible,
    ...
    9 possible, 9 not possible,
    ...


    Janis


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Sat Mar 7 13:33:59 2026
    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!


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Richard Harnden@3:633/10 to All on Sat Mar 7 14:53:56 2026
    On 07/03/2026 13:33, Bart wrote:
    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!


    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 :)




    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Sat Mar 7 10:22:04 2026
    On 3/7/2026 8:33 AM, Bart wrote:
    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.

    And that's what you got. But 90 stopped it from creating a 10x10
    matrix. There is no size matrix where rows = columns that consumes only
    1-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 is you asked for a 10x10 matrix with a cutoff of 90.

    When you put in just a single value, you're not asking for a square
    matrix - you're asking if a square matrix can be created that consumes 1
    to the single value. Half the time it can, and half the time it can't.

    When I was writing the initial code, I noticed it happening but didn't
    spend much time looking for why - I only saw that being prime wasn't the explanation.


    The difference not only appears to be very subtle, but I don't
    understand why it is important.

    Not important, it was just to kick the challenge up a notch. Otherwise
    it was too easy.


    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?


    They're entirely consistent.

    Outputting dashes, you can see how 1-5 and 1-6 can't form a square
    matrix, but 1-4 and 1-7 can.

    1-4: only a 2x2 matrix can use 1 to 4, and only 1 to 4
    1-5: no square matrix can use 1 to 5, and only 1 to 5
    1-6: no square matrix can use 1 to 6, and only 1 to 6
    1-7: only a 3x3 matrix can use 1 to 7, and only 1 to 7


    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.

    You got as many columns as were needed to consume 1 to 6, given the
    inputs 3 3 6.

    10 1 6 will give you a different number of columns, as will 1 10 6
    and 2 8 6.



    ÿÿ 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!

    Look at the remainders of the square roots.

    That will provide a hint to the mathematical explanation for why a
    square matrix is or isn't possible for a given number (not that I can formalize that mathematical explanation, but there is one).






    new code that might help your understanding.
    compile with =lm to use math.h ================================================================================
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>


    //print a separator line
    void printline(int linewidth, char *linechar) {
    printf(" ");
    for(int i = 0; i < linewidth; i++) {
    printf("%s",linechar);
    }
    printf("\n");
    }

    //print column headers
    void printcolheader(int cols, int charwidth) {
    printline(cols * charwidth,"-");
    for (int p = 1; p <= cols; p++) {
    printf("%*d",charwidth,p);
    }
    printf("\n");
    printline(cols * charwidth,"-");
    }


    //with math.h: test if the fraction remainder of the square root of the
    input is between .01 and .5
    //if so, you can't output a square matrix that includes the input
    void calc_rows_columns(int *rows, int *cols, int max) {
    double i,f;
    printf(" square matrix for 1-%d %s\n", max, ((modf(sqrt(max), &i) > 0.01 && modf(sqrt(max), &i) < 0.50) ) ? "not possible" : "");
    *rows = *cols = ceil(sqrt(max));
    }


    //core routine to write row x column data to screen
    void output(int rows, int cols, int max) {

    //width of columns
    char cw[10];
    int colwidth = sprintf(cw,"%d",max) + 2;

    //print column headers for visual aid
    printcolheader(cols, colwidth);

    //print nbr matrix
    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;
    if (nbr <= max) {
    printf("%*d",colwidth,nbr);
    }
    }
    printf("\n");
    }
    else
    {
    break;
    }
    }


    }

    int main(int argc, char *argv[]) {

    int rows, cols, max;
    if (argc > 2) {
    rows = atoi(argv[1]);
    cols = atoi(argv[2]);
    max = (argc == 4) ? atoi(argv[3]) : rows * cols ;
    }
    if (argc == 2) {
    max = atoi(argv[1]);
    calc_rows_columns(&rows, &cols, max);
    }

    //write data to screen
    output(rows, cols, max);

    printf("\n");
    return 0;
    } ================================================================================

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Sat Mar 7 10:24:28 2026
    On 3/7/2026 1:33 AM, Janis Papanagnou wrote:
    On 07.03.26 04:14, DFS wrote:

    <snip>


    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Sat Mar 7 15:44:33 2026
    On 07/03/2026 14:53, Richard Harnden wrote:
    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 :)

    Yes, you're right. Given N to be 1-100, then a value of fmod(sqrt(N),
    1.0) which is either 0.0, or 0.5 to 1.0, means it is possible. (Whatever significance 'possible' has!)

    At least a table generated by such a loop has the same
    possible/not-possible sequences that JP noticed.

    But then, I still can't see the point of using square roots and floating point. I use a solution involving integer arithmetic only. For each N I
    need to calculate the Rows of the smallest Rows*Rows containing square
    matrix, which I do with a loop.

    Then the formula is simple:

    if (Rows*Rows - N < Rows) // possible

    That loop would be inefficient for large N, but traversing all values
    from 1 to N and converting each as a decimal would take longer.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sat Mar 7 19:53:50 2026
    On Sat, 7 Mar 2026 14:53:56 +0000
    Richard Harnden <richard.nospam@gmail.invalid> wrote:

    On 07/03/2026 13:33, Bart wrote:
    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!


    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 :)





    It is not coincedence.
    For table of size n x n, the smallest possible max_val is n*(n-1)+1 =
    n*n - n + 1 = (n - 0.5)**2 + 0.75.
    Obbviosly, sqrt((n - 0.5)**2 + 0.75) > n-0.5
    OTOH, max_val-1 = (n - 0.5)**2 - 0.25, so sqrt(max_val-1) < n-0.5.












    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sat Mar 7 19:16:08 2026
    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


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Sat Mar 7 18:21:53 2026
    On Fri, 06 Mar 2026 13:51:58 +0000, Lew Pitcher wrote:

    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.

    And, 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_TR2a -mtune=native -Wall -std=c99 -pedantic -w rowcol_TR2a.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-07
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <setjmp.h>

    /*
    ** define RIGHT_ALIGN to right-align all numeric results
    ** otherwise, numeric results will align to the left
    */
    #ifdef RIGHT_ALIGN
    #define FORMAT "%*u"
    #else
    #define FORMAT "%-*u"
    #endif

    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 */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[3],&eptr,10);
    valid = ((*eptr == 0) && (result <= UINT_MAX));
    cut_off = valid ? result : 0;
    switch (!valid || (cut_off == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for cut-off (\"%s\")\n",argv[3]);
    args_ok = 0;
    }
    }

    case 3: /* rowcol #rows #cols */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[1],&eptr,10);
    valid = ((eptr != argv[1]) && (*eptr == 0) && (result <= UINT_MAX));
    n_rows = valid ? result : 0;
    switch (!valid || (n_rows == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for # rows (\"%s\")\n",argv[1]);
    args_ok = 0;
    }

    result = strtoul(argv[2],&eptr,10);
    valid = ((eptr != argv[2]) && (*eptr == 0) && (result <= UINT_MAX));
    n_cols = valid ? result : 0;
    switch (!valid || (n_cols == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for # columns (\"%s\")\n",argv[2]);
    args_ok = 0;
    }
    }

    switch (cut_off)
    {
    case 0:
    cut_off = n_rows * n_cols;
    break;

    default:
    args_ok = (cut_off > n_rows * n_cols) ? fprintf(stderr,"cut off value %u not found in table\n",cut_off), 0 : args_ok;
    break;
    }

    break;

    case 2: /* rowcol cutoff */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[1],&eptr,10);
    valid = ((eptr != argv[1]) && (*eptr == 0) && (result <= UINT_MAX));
    cut_off = valid ? result : 0;

    switch (!valid || (cut_off == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for cut-off (\"%s\")\n",argv[1]);
    args_ok = 0;

    case 0:
    {
    static jmp_buf LocalState; /* work variable; static storage with block scope */
    static unsigned int num_rows = 0; /* work variable; static storage with block scope */

    switch (setjmp(LocalState) >= cut_off)
    {
    case 0:
    ++num_rows;
    longjmp(LocalState,(num_rows * num_rows));
    }
    n_cols = n_rows = num_rows;
    }

    switch ( (cut_off < (n_rows * (n_cols-1)) + 1) )
    {
    case 1:
    fprintf(stderr,"Cut off value %u not possible where rows=cols\n",cut_off);
    args_ok = 0;
    }
    break;
    }
    }
    break;

    default:
    args_ok = 0; /* default error msg is usage message */
    break;
    }

    switch (args_ok)
    {
    case 1:
    {
    static jmp_buf LocalState; /* work variable; static storage with block scope */
    static unsigned int count = 0, /* work variable; static storage with block scope */
    want_eol = 0; /* work variable; static storage with block scope */

    switch (setjmp(LocalState) < (n_rows * n_cols))
    {
    case 1:
    {
    static unsigned int row, col, valu; /* work variables; static storage with block scope */

    row = count / n_cols;
    col = count % n_cols;
    want_eol = (col == 0) ? 0 : want_eol;
    valu = 1 + row + (col * n_rows);
    want_eol = (valu <= cut_off) ? printf(FORMAT,1 + snprintf(NULL,0,"%u",cut_off),valu), 1: want_eol;
    ((col == n_cols - 1) && (want_eol)) ? putchar('\n') : 0;
    ++count; longjmp(LocalState,count);
    }
    }

    status = EXIT_SUCCESS;
    }
    break;

    default:
    fprintf(stderr,"Usage:\t%s #_rows #_cols [ cut-off ]\nor\t%s cut-off\n",argv[0],argv[0]);
    }

    exit(status);
    }

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Sat Mar 7 14:18:08 2026
    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?

    Janis


    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


    #include <math.h>
    double r = modf(sqrt(N), &i);
    printf("square matrix for 1-%d %s\n", N, (r > 0.01 && r < 0.50) ? "not possible" : "possible");


    From what I can tell, 1/2 of all numbers can be captured in a square
    matrix, and 1/2 cannot.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Sat Mar 7 11:55:13 2026
    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.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Sat Mar 7 12:02:11 2026
    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) );
    }
    }
    }

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sat Mar 7 22:04:46 2026
    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;
    }











    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Sat Mar 7 20:10:09 2026
    On Sat, 07 Mar 2026 11:55:13 -0800, Tim Rentsch wrote:

    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.

    You (and the standards) are a hard task-master :-)

    Corrected version follows

    /*
    ** 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_TR2a -mtune=native -Wall -std=c99 -pedantic -w rowcol_TR2a.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-07
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <setjmp.h>

    /*
    ** define RIGHT_ALIGN to right-align all numeric results
    ** otherwise, numeric results will align to the left
    */
    #ifdef RIGHT_ALIGN
    #define FORMAT "%*u"
    #else
    #define FORMAT "%-*u"
    #endif

    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 */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[3],&eptr,10);
    valid = ((*eptr == 0) && (result <= UINT_MAX));
    cut_off = valid ? result : 0;
    switch (!valid || (cut_off == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for cut-off (\"%s\")\n",argv[3]);
    args_ok = 0;
    }
    }

    case 3: /* rowcol #rows #cols */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[1],&eptr,10);
    valid = ((eptr != argv[1]) && (*eptr == 0) && (result <= UINT_MAX));
    n_rows = valid ? result : 0;
    switch (!valid || (n_rows == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for # rows (\"%s\")\n",argv[1]);
    args_ok = 0;
    }

    result = strtoul(argv[2],&eptr,10);
    valid = ((eptr != argv[2]) && (*eptr == 0) && (result <= UINT_MAX));
    n_cols = valid ? result : 0;
    switch (!valid || (n_cols == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for # columns (\"%s\")\n",argv[2]);
    args_ok = 0;
    }
    }

    switch (cut_off)
    {
    case 0:
    cut_off = n_rows * n_cols;
    break;

    default:
    args_ok = (cut_off > n_rows * n_cols) ? fprintf(stderr,"cut off value %u not found in table\n",cut_off), 0 : args_ok;
    break;
    }

    break;

    case 2: /* rowcol cutoff */
    {
    char *eptr;
    unsigned long int result;
    int valid;

    result = strtoul(argv[1],&eptr,10);
    valid = ((eptr != argv[1]) && (*eptr == 0) && (result <= UINT_MAX));
    cut_off = valid ? result : 0;

    switch (!valid || (cut_off == 0))
    {
    case 1:
    fprintf(stderr,"Invalid value for cut-off (\"%s\")\n",argv[1]);
    args_ok = 0;

    case 0:
    {
    static jmp_buf LocalState; /* work variable; static storage with block scope */
    static unsigned int num_rows = 0; /* work variable; static storage with block scope */

    switch (setjmp(LocalState))
    {
    case 0: /* initial setjmp(), will always be false */
    case 1: /* false value from longjmp() */
    ++num_rows;
    longjmp(LocalState,1 + ((num_rows * num_rows) >= cut_off)); /* false == 1, true == 2 */
    }
    n_cols = n_rows = num_rows;
    }

    switch ( (cut_off < (n_rows * (n_cols-1)) + 1) )
    {
    case 1:
    fprintf(stderr,"Cut off value %u not possible where rows=cols\n",cut_off);
    args_ok = 0;
    }
    break;
    }
    }
    break;

    default:
    args_ok = 0; /* default error msg is usage message */
    break;
    }

    switch (args_ok)
    {
    case 1:
    {
    static jmp_buf LocalState; /* work variable; static storage with block scope */
    static unsigned int count = 0, /* work variable; static storage with block scope */
    want_eol = 0; /* work variable; static storage with block scope */

    switch (setjmp(LocalState))
    {
    case 0: /* initial value from setjmp() */
    case 2: /* true value from longjmp() */
    {
    static unsigned int row, col, valu; /* work variables; static storage with block scope */

    row = count / n_cols;
    col = count % n_cols;
    want_eol = (col == 0) ? 0 : want_eol;
    valu = 1 + row + (col * n_rows);
    want_eol = (valu <= cut_off) ? printf(FORMAT,1 + snprintf(NULL,0,"%u",cut_off),valu), 1: want_eol;
    ((col == n_cols - 1) && (want_eol)) ? putchar('\n') : 0;
    ++count; longjmp(LocalState,1 + (count < (n_rows * n_cols))); /* false == 1, true == 2 */
    }
    }

    status = EXIT_SUCCESS;
    }
    break;

    default:
    fprintf(stderr,"Usage:\t%s #_rows #_cols [ cut-off ]\nor\t%s cut-off\n",argv[0],argv[0]);
    }

    exit(status);
    }




    My code in the next followup.




    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Sat Mar 7 20:14:15 2026
    On Sat, 07 Mar 2026 12:02:11 -0800, Tim Rentsch wrote:

    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

    [...] I look forward to seeing /your/ code :-)

    Here we go...
    [snip]

    Brilliant!
    I bow to the master. I obviously have a lot to learn

    Thank you, I've learned something new today.
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Sat Mar 7 16:58:48 2026
    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().


    Also I have a 'challenge' to add to your program - that I already added
    to mine - to make it even more compelling:

    * when looking for a square matrix, instead of printing 'no joy' print
    out a matrix that will visually demonstrate why the number doesn't fit
    in a square matrix.

    For instance:

    ./rc-dfs 17
    square matrix for 1-17 not possible
    --------------------
    1 2 3 4 5
    --------------------
    1 6 11 16
    2 7 12 17
    3 8 13
    4 9 14
    5 10 15

    If you get stuck, I'll give you a hint :)




    #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) );
    }
    }
    }


    I'm gonna try and borrow some techniques from this banger, if I think
    they're appropriate.

    What do you think would be the reaction in a corporate programming dept
    to this unique kind of code?


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sun Mar 8 00:35:57 2026
    On Sat, 7 Mar 2026 16:58:48 -0500
    DFS <nospam@dfs.com> wrote:


    A nit you may have forgotten: you earlier said main() was not allowed:


    You misunderstood.
    Having main() is allowed and necessary. Calling main() in your code is forbidden.
    If calling main() recursively was allowed then possible solution could
    be just uglier than previos counter-challenge, but would not require
    any different ideas.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sun Mar 8 00:26:15 2026
    On 07.03.26 21:04, Michael S wrote:
    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.

    I have no stakes here. If it were my code I'd have at least simplified
    it with the trivial 2-address replacements { val-=odd; odd+=2; rt++; }
    that I consider clearer ("simpler") without muddying the simplicity of
    the underlying expressions.


    Here is O(log(N)) variant that is even simpler than code above.

    Not sure what you mean by "simpler". Personally I perceive below code
    less "simple" with the less trivial expressions and stuffing of the
    assignment into the while-loop condition. It's a nice case of applied
    code tweaking anyway.

    And in other application cases certainly worth any performance gains.
    (I haven't yet closely inspected the code but I probably will do.)

    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.

    I like especially the attempts to reduce arithmetic divisions (given
    that the original Nethack code didn't have these in the first place).

    Janis


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












    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sun Mar 8 00:40:14 2026
    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.

    Janis


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sun Mar 8 00:47:55 2026
    On 07.03.26 20:18, DFS wrote:
    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 [...]

    Okay, thanks for explaining. - I saw later that someone amended some mathematical derivation in the sqrt() context.

    My critical stance here remains that the visible pattern I mentioned
    is IMO much easier seen compared to a (sort of) ad hoc math function
    with truncated values presented.

    A mathematical derivation (as we've seen) would of course be necessary
    in both cases-

    Janis


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Sat Mar 7 16:43:31 2026
    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    [...]
    typedef size_t Z;
    typedef _Bool B;
    [...]

    Why do you do this? I find that it makes the code more difficult to
    read.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sun Mar 8 02:45:33 2026
    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.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Sun Mar 8 12:22:18 2026
    On 07/03/2026 22:58, DFS wrote:
    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().


    Note that none of the methods I suggested are portable - and I believe
    the challenge required portable C. The challenge did allow you to have
    a main() function (indeed, I think it is implicitly required) - it just disallowed /calling/ main() from your code.

    If you can think of a portable way to have a C program linked and
    running code without a main(), I would be curious to hear it.

    (I did once have a real program for a real product, where the code was
    written in C but did not have a "main". This was a /very/ small microcontroller, and the compiler automatically added extra code at the
    start of "main" that I wanted to avoid. So I had my own C runtime
    startup code from device reset, jumping to my C "real_main()" function
    without ever having a "main()" function.)


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Sun Mar 8 10:42:34 2026
    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.

    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Sun Mar 8 15:18:30 2026
    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.

    (BTW I would class ?: as 'if'. In the languages I create, the 'if'
    statement the the ternary operator, which I write as (||), are interchangeable.)


    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.


    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).

    My script code is however trivially convertible to C (which I later
    posted) or to any other language. While his C solution is much harder to
    port as it is; it would need rewriting, once you can figure out how it
    works.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lew Pitcher@3:633/10 to All on Sun Mar 8 16:00:34 2026
    On Sun, 08 Mar 2026 10:42:34 -0400, DFS wrote:
    [snip]

    Sure it's a bearded-lady novelty, but I think he knocked it out of the park.

    I think of it as an educational opportunity. Look at how succinctly Tim's code satisfied not only your requirements, but the outrageously restrictive constraints his counter-challenge posed.

    With his solution, he implemented an 84 line finite state machine that matched your 131 line example. I, for one, will spend a fair bit of time studying
    /how/ his code works, and gleaning some techniques to improve /my/ coding.


    Just my $0.02 worth.

    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sun Mar 8 17:05:03 2026
    On 08.03.26 01:45, Michael S wrote:
    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

    Oh, rally? - What you write below ("most popular size") sounds not
    like a focus on the algorithm but on concrete (typical) systems.

    Don't get me wrong; I think it's fine to do that for concrete
    implementations.

    What you suggested looks like a sort of "clustering", as I said.
    I did that myself in the past for an arbitrary precision modulus
    operator; I could have worked on universal octet sizes but chose
    to assume at least 32 byte arithmetic available to speed up the
    process. Given contemporary architectures I could increase that
    further, I could tailor it to 64 bit entities for another speed
    factor of 2 (in cases where we'd need every nanosecond). Nowadays
    I'd probably inquire the available "register sizes" per program
    logic (or at compile time) and use optimally tailored sizes where
    it matters. Personally I prefer avoiding such hard-coded constants.

    - 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

    (If you had read "tailored" as a vendor specific tailoring using
    proprietary features you misunderstood what I said. - Nevermind.)

    Janis


    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.




    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From DFS@3:633/10 to All on Sun Mar 8 12:21:55 2026
    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.



    My script code is however trivially convertible to C
    (which I later posted)

    I just tested it. It prints past the cutoffs, but does make the correct decision about the square matrix.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sun Mar 8 17:36:32 2026
    On 08.03.26 15: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?
    [...]
    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.

    I assumed so but wanted to be on the safe side.


    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.

    Personally I've no reservations concerning the ternary conditional.
    I think it depends on the actual code complexity and code context
    what to be best used.

    And using the conditional ternary is also not the primary problem
    with that code. (The unreadability here stems from a couple other
    factors, the ternary at best supports these factors.)


    But all the decision-making in one short line is a thing of beauty.

    Well, personally I like, for example, the Obfuscated "C" Contest.
    And generally, in other contexts, also clever one-liner solutions.
    (The code here reminds me of some of my BASIC code that I wrote in
    the 1970's, though.)

    Whether it's sensible to apply this in an algorithmic challenge is
    obviously a matter of taste (as it seems).


    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.

    On a CLC nerd level, yes. (My own excitement went in the other
    direction, though; hoping that this code will not become a paragon
    for software developers.)


    What's also very nice is there are no long lines that wrap.

    That's not a quality measure if it's gained by unreadable content.

    Janis


    Sure it's a bearded-lady novelty, but I think he knocked it out of the
    park.



    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sun Mar 8 17:57:47 2026
    On 08.03.26 16:18, Bart wrote:
    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.

    Is the (unfamiliar) precedence here really the problem? - I may be
    already too long used to the "C" operators so that didn't appear as
    a problem to me. Given that this is basically just a simple if-elif
    sequence (as opposed to branching cascades) it appears also not
    per se as a problem (i.e. not from the perspective of the syntax
    structure). I'm sure that if the conditions were just wrapped to an
    own line you wouldn't have any problems to follow the control flow
    even without parenthesis. (And the free space then gained on these
    lines could be used to use more appropriate identifier names and a
    comment or two where sensible.)

    Janis

    [...]


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Sun Mar 8 19:29:52 2026
    On 08/03/2026 16:21, DFS wrote:
    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?

    I normally run my own systems programming language. I've been doing that
    for well over 40 years (but the language has evolved a little!).

    It is written in itself ('self-hosted'). It was used to implement that scripting language. And it was used to implement a C compiler of sorts
    which I used to test some of the code posted here including Tim's version.


    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.

    Using C functions means nothing. I can use C functions too (note that setjmp/longjmp are not functions); so can many languages.

    But C is very frequently used to emulate all sorts of different
    paradigms, and/or syntaxes. People have written programs entirely using
    using C's preprocessor macros.

    I can turn code written in my systems language into an intermediate,
    linear language, and can then turn that into attrocious C source code.

    IOCCC entries offer more examples.

    It will all compile with gcc, but again I would hesitate to call it
    'writing in C'; more like 'abusing C'!

    My own manually written C code is very conservative in style.

    (I did start translating TR's C code into my language, just to see of it
    could also express such a program.

    I got as far as implementing versions of setjmp/longjmp, which my
    language lacks. But there I stopped: I found it too annoying to just
    slavishly follow the same coding style, and I would probably have
    rewritten half of it.)


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Sun Mar 8 13:19:21 2026
    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.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Sun Mar 8 13:27:23 2026
    DFS <nospam@dfs.com> writes:
    [...]
    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.

    A nested ternary can be readable if you format it carefully,
    particularly if implements something similar to a linear if/else chain.
    I might write the above at:

    c = square ? a1 :
    !hwc ? h*w :
    a3 > h*w ? h*w :
    a3;

    or even:

    c = square ? a1 :
    !hwc ? h*w :
    a3 > h*w ? h*w :
    a3;

    (The second and third conditions could be combined with "||".)

    It could be rewritten as an if/else chain like this:

    if (square) c = a1;
    else if (!hwc) c = h*w;
    else if (a3 > h*w) c = h*w;
    else c = a3;

    But all the decision-making in one short line is a thing of beauty.

    For certain values of "beauty".

    [...]

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Sun Mar 8 21:42:36 2026
    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.


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Mar 8 15:58:56 2026
    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...

    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bart@3:633/10 to All on Mon Mar 9 01:12:02 2026
    On 08/03/2026 20:19, Keith Thompson wrote:
    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.

    See my followup to DFS's reply to my post.

    Classifying C code that you don't like as "not C" is absurd.

    That it compiles is a low bar. You should see some of the 'flat' C code
    I generate from a linear IL, where there is no code structure, and no
    proper data structures (everything is a struct containing only a
    byte-array.)

    It is only technically C, yet it also 'compiles'.

    Normally that kind of program is machine-generated, but some like to
    write it manually (IOCCC for example).

    Your code, on the other hand, was not written in C at all.

    If plotted on a chart which quantifies easy of understanding, that it
    will be next to the C version that I also posted, which TR's version
    will be quite a way off.

    Of course, mine doesn't have the same restrictions, and a slightly
    different spec. If I had some time (and could figure out how it worked),
    I could duplicate the approach in another language, with the same
    limitations, and it would probably be much clearer, because that's what
    I do.

    (For that matter, even the C as posted could be improved.)


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Mon Mar 9 08:09:41 2026
    On 08/03/2026 23:58, Chris M. Thomasson wrote:
    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...

    You need to find the right balance when deciding when parentheses are appropriate. The precedence of multiply and addition is well
    established from arithmetic in early school days, so "x * y + z" is
    clear. The tertiary operator is only known from C and a few other
    programming languages, thus its precedence is not clear until the
    programmer is familiar with it. And since it is not nearly as widely
    used as multiplication and addition, especially in complex expressions,
    even many experienced C programmers can sometimes get it wrong.

    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? Are you writing code that can be used with a
    wide variety of compilers (some of which may be buggy, or generate poor quality code, especially in complex situations) ? What are the
    consequences of misunderstandings of the code? (You have different
    rules for aircraft engine control systems and a computer game.)

    All sorts of things affect readability, and operator precedence and parentheses is only one of them.

    (Of course the code in this thread is not written for readability.)


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Mon Mar 9 08:53:17 2026
    On 09.03.26 08:09, David Brown wrote:

    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? [...]

    Just a comment on this point. - In commercial companies the code is the
    (sort of) invariant, the people (the programmers) change. So generally
    you can't make such assumptions about the staff. You want provisions
    for the code quality by rules to obtain sufficient maintainability. Or
    else you need a sophisticated risk management. (Or replace programmers
    by AI in the first place. - *shudder* - I am joking, others might not.)

    Even when having employed only "experts" - in whatever way you would
    qualify that - (and their availability also somehow guaranteed), the
    code should be easily readable, not cryptic or convoluted. IME even the "experts" amongst the programmers are grateful for maintainable code,
    and the management as well, saving time, money, and keeping reputation
    high by preventing or reducing issues from bad code quality effects.

    Janis


    --- PyGate Linux v1.5.12
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)