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