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

    From DFS@[email protected] to comp.lang.c on Thu Feb 19 16:55:25 2026
    From Newsgroup: comp.lang.c

    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;
    } --------------------------------------------------------------------------
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From jayjwa@[email protected] to comp.lang.c on Wed Feb 25 15:56:05 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> 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!"
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Thu Feb 26 10:05:24 2026
    From Newsgroup: comp.lang.c

    On 2/25/2026 3:56 PM, jayjwa wrote:
    DFS <[email protected]> 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.


    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Feb 26 17:06:53 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Feb 26 17:27:37 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From jayjwa@[email protected] to comp.lang.c on Thu Feb 26 13:20:07 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> 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!"
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From jayjwa@[email protected] to comp.lang.c on Thu Feb 26 13:33:40 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> 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!"
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Feb 26 18:49:41 2026
    From Newsgroup: comp.lang.c

    On Thu, 26 Feb 2026 13:33:40 -0500, jayjwa wrote:

    Lew Pitcher <[email protected]> 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.
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Feb 26 18:55:50 2026
    From Newsgroup: comp.lang.c

    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 <[email protected]> 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.
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Feb 26 19:17:41 2026
    From Newsgroup: comp.lang.c

    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 <[email protected]> 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.
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Thu Feb 26 14:31:52 2026
    From Newsgroup: comp.lang.c

    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?

    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Feb 26 19:34:29 2026
    From Newsgroup: comp.lang.c

    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 <[email protected]>
    ** 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$[email protected]>
    **
    ** 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.
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Feb 26 20:01:19 2026
    From Newsgroup: comp.lang.c

    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 <[email protected]>
    ** 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$[email protected]>
    **
    ** 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.
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Fri Feb 27 00:12:43 2026
    From Newsgroup: comp.lang.c

    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





    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Mon Mar 2 00:44:57 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> 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).
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Mon Mar 2 11:07:20 2026
    From Newsgroup: comp.lang.c

    On Mon, 02 Mar 2026 00:44:57 -0800
    Tim Rentsch <[email protected]> wrote:

    DFS <[email protected]> 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.





    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Mon Mar 2 06:35:32 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> writes:

    On Mon, 02 Mar 2026 00:44:57 -0800
    Tim Rentsch <[email protected]> wrote:

    DFS <[email protected]> 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.
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Mon Mar 2 17:50:47 2026
    From Newsgroup: comp.lang.c

    On 02/03/2026 14:35, Tim Rentsch wrote:
    Michael S <[email protected]> writes:

    On Mon, 02 Mar 2026 00:44:57 -0800
    Tim Rentsch <[email protected]> wrote:

    DFS <[email protected]> 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?
    --- Synchronet 3.21c-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Mon Mar 2 17:40:07 2026
    From Newsgroup: comp.lang.c

    On 3/2/2026 3:44 AM, Tim Rentsch wrote:
    DFS <[email protected]> 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;
    }

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




    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Mon Mar 2 21:09:21 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:

    On 3/2/2026 3:44 AM, Tim Rentsch wrote:

    DFS <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Mon Mar 2 21:15:19 2026
    From Newsgroup: comp.lang.c

    Bart <[email protected]> writes:

    On 02/03/2026 14:35, Tim Rentsch wrote:

    Michael S <[email protected]> writes:

    On Mon, 02 Mar 2026 00:44:57 -0800
    Tim Rentsch <[email protected]> wrote:

    DFS <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Tue Mar 3 08:23:32 2026
    From Newsgroup: comp.lang.c

    On 3/3/2026 12:09 AM, Tim Rentsch wrote:
    DFS <[email protected]> writes:

    On 3/2/2026 3:44 AM, Tim Rentsch wrote:

    DFS <[email protected]> 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.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Tue Mar 3 06:20:33 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:

    On 3/3/2026 12:09 AM, Tim Rentsch wrote:

    DFS <[email protected]> writes:

    On 3/2/2026 3:44 AM, Tim Rentsch wrote:

    DFS <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Tue Mar 3 16:39:12 2026
    From Newsgroup: comp.lang.c

    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;
    }
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Tue Mar 3 15:40:40 2026
    From Newsgroup: comp.lang.c

    On Mon, 02 Mar 2026 00:44:57 -0800, Tim Rentsch wrote:

    DFS <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Tue Mar 3 12:00:26 2026
    From Newsgroup: comp.lang.c

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Tue Mar 3 17:29:56 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Tue Mar 3 19:20:20 2026
    From Newsgroup: comp.lang.c

    Am 03.03.2026 um 18:29 schrieb Scott Lurndal:
    Bonita Montero <[email protected]> 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++.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Tue Mar 3 20:48:06 2026
    From Newsgroup: comp.lang.c

    On 03/03/2026 05:15, Tim Rentsch wrote:
    Bart <[email protected]> writes:

    On 02/03/2026 14:35, Tim Rentsch wrote:

    Michael S <[email protected]> writes:

    On Mon, 02 Mar 2026 00:44:57 -0800
    Tim Rentsch <[email protected]> wrote:

    DFS <[email protected]> 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.


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Tue Mar 3 22:47:44 2026
    From Newsgroup: comp.lang.c

    On 2026-03-03 21:48, Bart wrote:
    On 03/03/2026 05:15, Tim Rentsch wrote:
    [...]

    This kind of challenge can be done in any language. My algorithm
    can be trivially converted to C if needed; it is clear enough.

    Sure. But let's have a closer look...

    It's debatable whether the algorithm is the challenge or whether
    writing actual "C" code is the challenge, say, because "C" may
    be so convoluted or just inappropriate for such tasks that it's
    difficult to solve such challenges with the "C" language. - But
    obviously this challenge is not challenging the "C" language in
    any way; it's an ordinary ("C", or other) programming task.[*]
    So I basically agree with you.[**]

    Though, with the subsequent refinements, to abstain from certain
    types of language constructs, i.e. programming with one arm tied
    behind your back, the question is not as clearly to answer; it's
    just easier to compare the various variants and code evolutions
    if you have a common language base (and here in CLC that's "C").

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Tue Mar 3 23:56:36 2026
    From Newsgroup: comp.lang.c

    On Tue, 03 Mar 2026 06:20:33 -0800
    Tim Rentsch <[email protected]> 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?

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Tue Mar 3 15:51:08 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> writes:

    On Tue, 03 Mar 2026 06:20:33 -0800
    Tim Rentsch <[email protected]> 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.)
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Tue Mar 3 16:23:54 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    On Mon, 02 Mar 2026 00:44:57 -0800, Tim Rentsch wrote:

    DFS <[email protected]> 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.)
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Tue Mar 3 16:26:27 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Wed Mar 4 05:27:27 2026
    From Newsgroup: comp.lang.c

    Am 04.03.2026 um 01:26 schrieb Tim Rentsch:
    Bonita Montero <[email protected]> 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.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From David Brown@[email protected] to comp.lang.c on Wed Mar 4 08:48:57 2026
    From Newsgroup: comp.lang.c

    On 03/03/2026 22:47, Janis Papanagnou wrote:
    On 2026-03-03 21:48, Bart wrote:
    On 03/03/2026 05:15, Tim Rentsch wrote:
    [...]

    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.


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Wed Mar 4 01:07:18 2026
    From Newsgroup: comp.lang.c

    David Brown <[email protected]> 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) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Wed Mar 4 11:45:41 2026
    From Newsgroup: comp.lang.c

    On Tue, 03 Mar 2026 15:51:08 -0800
    Tim Rentsch <[email protected]> wrote:

    Michael S <[email protected]> writes:

    On Tue, 03 Mar 2026 06:20:33 -0800
    Tim Rentsch <[email protected]> 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.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Wed Mar 4 12:09:22 2026
    From Newsgroup: comp.lang.c

    On Wed, 04 Mar 2026 01:07:18 -0800
    Keith Thompson <[email protected]> wrote:

    David Brown <[email protected]> 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.)



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Wed Mar 4 11:44:21 2026
    From Newsgroup: comp.lang.c

    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.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From David Brown@[email protected] to comp.lang.c on Wed Mar 4 12:58:48 2026
    From Newsgroup: comp.lang.c

    On 04/03/2026 10:07, Keith Thompson wrote:
    David Brown <[email protected]> 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.


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Wed Mar 4 13:20:35 2026
    From Newsgroup: comp.lang.c

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







    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Wed Mar 4 08:29:29 2026
    From Newsgroup: comp.lang.c

    On 3/3/2026 9:20 AM, Tim Rentsch wrote:
    DFS <[email protected]> writes:

    On 3/3/2026 12:09 AM, Tim Rentsch wrote:

    DFS <[email protected]> writes:

    On 3/2/2026 3:44 AM, Tim Rentsch wrote:

    DFS <[email protected]> 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?




    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Wed Mar 4 08:30:35 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Wed Mar 4 14:36:28 2026
    From Newsgroup: comp.lang.c

    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.


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 4 07:01:56 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> writes:

    On Tue, 03 Mar 2026 15:51:08 -0800
    Tim Rentsch <[email protected]> wrote:

    Michael S <[email protected]> writes:

    On Tue, 03 Mar 2026 06:20:33 -0800
    Tim Rentsch <[email protected]> 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.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Wed Mar 4 10:02:02 2026
    From Newsgroup: comp.lang.c

    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.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Wed Mar 4 16:02:56 2026
    From Newsgroup: comp.lang.c

    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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Wed Mar 4 15:31:44 2026
    From Newsgroup: comp.lang.c

    On Tue, 03 Mar 2026 16:23:54 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    On Mon, 02 Mar 2026 00:44:57 -0800, Tim Rentsch wrote:

    DFS <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 4 08:09:43 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:

    On 3/3/2026 9:20 AM, Tim Rentsch wrote:

    DFS <[email protected]> writes:

    On 3/3/2026 12:09 AM, Tim Rentsch wrote:

    DFS <[email protected]> writes:

    On 3/2/2026 3:44 AM, Tim Rentsch wrote:

    DFS <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Wed Mar 4 19:27:11 2026
    From Newsgroup: comp.lang.c

    On Wed, 4 Mar 2026 10:02:02 -0500
    DFS <[email protected]> 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?

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 4 09:38:16 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    On Tue, 03 Mar 2026 16:23:54 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    On Mon, 02 Mar 2026 00:44:57 -0800, Tim Rentsch wrote:

    DFS <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Wed Mar 4 11:19:35 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> 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) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Wed Mar 4 11:25:05 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:
    On 3/3/2026 9:20 AM, Tim Rentsch wrote:
    DFS <[email protected]> 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) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Opus@[email protected] to comp.lang.c on Wed Mar 4 22:42:44 2026
    From Newsgroup: comp.lang.c

    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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Wed Mar 4 17:44:12 2026
    From Newsgroup: comp.lang.c

    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.


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Wed Mar 4 15:13:52 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> 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) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Wed Mar 4 23:37:04 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> 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.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Wed Mar 4 21:07:13 2026
    From Newsgroup: comp.lang.c

    On 3/4/2026 6:13 PM, Keith Thompson wrote:
    DFS <[email protected]> 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?


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Thu Mar 5 07:32:33 2026
    From Newsgroup: comp.lang.c

    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 )
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Thu Mar 5 08:23:26 2026
    From Newsgroup: comp.lang.c

    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 !
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Thu Mar 5 02:24:25 2026
    From Newsgroup: comp.lang.c

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Thu Mar 5 08:46:37 2026
    From Newsgroup: comp.lang.c

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


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Thu Mar 5 09:52:08 2026
    From Newsgroup: comp.lang.c

    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.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From tTh@[email protected] to comp.lang.c on Thu Mar 5 10:49:39 2026
    From Newsgroup: comp.lang.c

    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/ *
    ** **
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Thu Mar 5 11:03:12 2026
    From Newsgroup: comp.lang.c

    Am 05.03.2026 um 10:49 schrieb tTh:

    And *still* in the wrong group.
    I'm impressed about how far your reading goes.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Thu Mar 5 05:06:24 2026
    From Newsgroup: comp.lang.c

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



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Thu Mar 5 11:13:41 2026
    From Newsgroup: comp.lang.c

    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.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Thu Mar 5 14:49:13 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:
    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.


    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From gazelle@[email protected] (Kenny McCormack) to comp.lang.c on Thu Mar 5 15:22:52 2026
    From Newsgroup: comp.lang.c

    In article <10objjj$hie$[email protected]>, tTh <[email protected]d> wrote:
    On 3/5/26 09:52, Bonita Montero wrote:
    Now it's even shorter - and still *with* error handling:

    #include <iostream>

    And *still* in the wrong group.

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

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

    I've taken this sort of view myself, in other forums, in other contexts.
    It can be a useful mental framework.
    --
    BigBusiness types (aka, Republicans/Conservatives/Independents/Liberatarians/whatevers)
    don't hate big government. They *love* big government as a means for them to get
    rich, sucking off the public teat. What they don't like is *democracy* - you know,
    like people actually having the right to vote and stuff like that.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Thu Mar 5 19:27:52 2026
    From Newsgroup: comp.lang.c

    On 05.03.26 15:49, Scott Lurndal wrote:
    DFS <[email protected]> writes:
    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.

    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000

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

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

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

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

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

    Janis

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Thu Mar 5 13:46:39 2026
    From Newsgroup: comp.lang.c

    On 3/4/2026 2:25 PM, Keith Thompson wrote:
    DFS <[email protected]> writes:
    On 3/3/2026 9:20 AM, Tim Rentsch wrote:
    DFS <[email protected]> writes:
    Is main() OK?
    Yes, sorry, not mentioning main() was an oversight on my part.
    (Still not okay to call it.)

    I was actually kidding, but I see online you can do some trickery to
    make a standalone C program work without main().

    Why? Just for s's and giggles?
    [...]

    I'm curious what you're referring to. It's not possible to have a
    working *portable* C program (for a hosted implementation) without
    a main function. There might be some compiler-specific tricks for
    using or specifying an entry point with a different name.


    Correct, per Google AI Overview (for "c program without main function")

    "While the C standard requires a main() function for programs running in
    a standard "hosted" environment, it is technically possible to create an executable program without explicitly defining main() using
    non-standard, implementation-specific methods.

    These methods often fall into two main categories:
    1. Using Preprocessor Directives (Macros)
    2. Modifying the Entry Point (Linker Options)"


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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Thu Mar 5 19:46:58 2026
    From Newsgroup: comp.lang.c

    Am 05.03.2026 um 15:49 schrieb Scott Lurndal:
    DFS <[email protected]> writes:
    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.


    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000


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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Thu Mar 5 13:49:24 2026
    From Newsgroup: comp.lang.c

    On 3/4/2026 12:27 PM, Michael S wrote:
    On Wed, 4 Mar 2026 10:02:02 -0500
    DFS <[email protected]> wrote:


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


    Were you programming in Fortran in your youth?

    Nah. Never looked at it.

    Is column-row output an option in Fortran?


    I programmed internal business software my entire IT career.

    Lotus-1-2-3 macros
    dBase, clipper and Paradox (DOS)
    ObjectPAL (an offshoot of Delphi used in Borland Paradox for Windows
    desktop database)
    small amts of Rexx and perl and Java
    T-SQL and Oracle PL/SQL
    tons of VB and VBA

    hobby coding
    PowerBuilder
    first C program May 2014
    first Python early 2016



    I like C for raw performance and strictness of code.

    I like python for ease of use and productivity.

    Where else but Python can you get meaningful Usenet stats in 22 lines?

    -------------------------------------------------------
    import sys as y,nntplib as t
    s='news server'
    g='comp.lang.c'
    n=t.NNTP(s,119,'usr','pw')
    r,a,b,e,gn=n.group(g)
    def printStat(st,hd,rg):
    r,d=n.xhdr(st,'%s-%s'%rg)
    p=[]
    for i in range(len(d)):
    v=d[i][1]
    if st=='Subject': v=v[4:] if v[:3]=='Re:' else v
    p.append(v)
    x=[(i,p.count(i)) for i in set(p)]
    x.sort(key=lambda s:(-s[1],s[0].lower()))
    print('Posts %s %s'%(len(set(p)),hd))
    for v in x: print(' %s %s'%(v[1],v[0]))
    print()
    print("Last " + y.argv[1] + " Posts")
    m=(int(e)-int(y.argv[1])+1,int(e))
    printStat("From","Posters",m)
    printStat("Subject","Subjects",m)
    n.quit()
    -------------------------------------------------------


    $ python program.py N


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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Thu Mar 5 21:02:12 2026
    From Newsgroup: comp.lang.c

    On Thu, 5 Mar 2026 13:49:24 -0500
    DFS <[email protected]> wrote:

    On 3/4/2026 12:27 PM, Michael S wrote:
    On Wed, 4 Mar 2026 10:02:02 -0500
    DFS <[email protected]> wrote:


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


    Were you programming in Fortran in your youth?

    Nah. Never looked at it.

    Is column-row output an option in Fortran?


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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Mar 5 19:09:37 2026
    From Newsgroup: comp.lang.c

    On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
    [snip]
    The latest challenge, which I just got through doing, is to
    disallow if, for, while, goto, return, and to forbid functions
    and function calls except for calls to C standard library
    functions. Also no math library. :)

    Inventive, aren't you :-)

    I've got a working matrix print that (I think) satisfies your
    requirements, but have not started on the argument processing
    logic yet. I may, yet again, revise my approach, as the solution
    I'm using is quite tedious to code.

    The program is a bit on the long side because of argument
    processing but the matrix print code is less than 20 lines,
    including 5 blank lines.

    20 lines, including 4 blank lines, but I can reduce it a bit.
    I should be able to match (or at least approximate) your line
    count.
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Thu Mar 5 14:11:40 2026
    From Newsgroup: comp.lang.c

    On 3/5/2026 5:13 AM, Bonita Montero wrote:
    Am 05.03.2026 um 11:06 schrieb DFS:

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

    Absolutely not.

    Both are fugly, but C++ much moreso.


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

    s/typical/untested


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

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


    But usually C++ is about five times less code

    You're getting desperate.



    since there are no built
    -in complex containers like a map<> or an unordered_map in C. If you
    want to to that in C you have to stick with external libraries which
    do the polymorphic behaviour with callbacks (slower).

    External library not necessary. It's a little bit of code, such as:

    https://www.geeksforgeeks.org/dsa/implementation-on-map-or-dictionary-data-structure-in-c/




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

    Accept your beatdown. Learn some humility.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From tTh@[email protected] to comp.lang.c on Thu Mar 5 20:50:22 2026
    From Newsgroup: comp.lang.c

    On 3/5/26 19:46, Bonita Montero wrote:

    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000


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

    Why ?
    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Thu Mar 5 22:34:26 2026
    From Newsgroup: comp.lang.c

    On Thu, 5 Mar 2026 20:50:22 +0100
    tTh <[email protected]d> wrote:

    On 3/5/26 19:46, Bonita Montero wrote:

    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000


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

    Why ?


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

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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From David Brown@[email protected] to comp.lang.c on Thu Mar 5 21:34:37 2026
    From Newsgroup: comp.lang.c

    On 05/03/2026 19:46, DFS wrote:
    On 3/4/2026 2:25 PM, Keith Thompson wrote:
    DFS <[email protected]> writes:
    On 3/3/2026 9:20 AM, Tim Rentsch wrote:
    DFS <[email protected]> writes:
    Is main() OK?
    Yes, sorry, not mentioning main() was an oversight on my part.
    (Still not okay to call it.)

    I was actually kidding, but I see online you can do some trickery to
    make a standalone C program work without main().

    Why?  Just for s's and giggles?
    [...]

    I'm curious what you're referring to.  It's not possible to have a
    working *portable* C program (for a hosted implementation) without
    a main function.  There might be some compiler-specific tricks for
    using or specifying an entry point with a different name.


    Correct, per Google AI Overview (for "c program without main function")

    "While the C standard requires a main() function for programs running in
    a standard "hosted" environment, it is technically possible to create an executable program without explicitly defining main() using non-
    standard, implementation-specific methods.

    These methods often fall into two main categories:
    1. Using Preprocessor Directives (Macros)
    2. Modifying the Entry Point (Linker Options)"


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


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

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


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


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Thu Mar 5 20:39:19 2026
    From Newsgroup: comp.lang.c

    On 05/03/2026 18:49, DFS wrote:
    On 3/4/2026 12:27 PM, Michael S wrote:
    On Wed, 4 Mar 2026 10:02:02 -0500
    DFS <[email protected]> wrote:


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


    Were you programming in Fortran in your youth?

    Nah.  Never looked at it.

    Is column-row output an option in Fortran?


    I programmed internal business software my entire IT career.

    Lotus-1-2-3 macros
    dBase, clipper and Paradox (DOS)
    ObjectPAL (an offshoot of Delphi used in Borland Paradox for Windows
    desktop database)
    small amts of Rexx and perl and Java
    T-SQL and Oracle PL/SQL
    tons of VB and VBA

    hobby coding
    PowerBuilder
    first C program May 2014
    first Python early 2016



    I like C for raw performance and strictness of code.

    I like python for ease of use and productivity.

    Where else but Python can you get meaningful Usenet stats in 22 lines?

    -------------------------------------------------------
    import sys as y,nntplib as t

    How many lines would it be without using 'nntplib'?

    Most of Python's usefulness is due to the availability of lots of
    different libraries. It is an actual scripting language.

    (However when I ran your script, it was missing 'nntplib'.)


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Mar 5 21:12:23 2026
    From Newsgroup: comp.lang.c

    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:

    On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
    [snip]
    The latest challenge, which I just got through doing, is to
    disallow if, for, while, goto, return, and to forbid functions
    and function calls except for calls to C standard library
    functions. Also no math library. :)

    Inventive, aren't you :-)

    I've got a working matrix print that (I think) satisfies your
    requirements, but have not started on the argument processing
    logic yet. I may, yet again, revise my approach, as the solution
    I'm using is quite tedious to code.

    OK, so the "no if statements" is a bit of a bother, but not
    insurmountable. It's just a case of switching things around.
    And, perhaps there's a third option as well.

    As I said, the alternatives are just tedious to code.

    But, I now need to find a replacement for sqrt() that doesn't take
    a lot of space. Back to first principles for me, then.

    The program is a bit on the long side because of argument
    processing but the matrix print code is less than 20 lines,
    including 5 blank lines.

    20 lines, including 4 blank lines, but I can reduce it a bit.
    I should be able to match (or at least approximate) your line
    count.
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Thu Mar 5 13:49:49 2026
    From Newsgroup: comp.lang.c

    [email protected] (Scott Lurndal) writes:

    DFS <[email protected]> writes:

    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.


    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000

    Using snprintf() is more correct and also more obviously correct.

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

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

    gives

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

    Also the snprintf() way doesn't need -lm. :)
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Thu Mar 5 13:54:21 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> writes:

    On Wed, 4 Mar 2026 10:02:02 -0500
    DFS <[email protected]> wrote:

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

    Were you programming in Fortran in your youth?

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

    Choice of C-style or Fortran-style multidimensional arrays is
    another kettle of fish entirely.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Thu Mar 5 14:04:42 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
    [snip]

    The latest challenge, which I just got through doing, is to
    disallow if, for, while, goto, return, and to forbid functions
    and function calls except for calls to C standard library
    functions. Also no math library. :)

    Inventive, aren't you :-)

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

    I've got a working matrix print that (I think) satisfies your
    requirements, but have not started on the argument processing
    logic yet. I may, yet again, revise my approach, as the solution
    I'm using is quite tedious to code.

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

    The program is a bit on the long side because of argument
    processing but the matrix print code is less than 20 lines,
    including 5 blank lines.

    20 lines, including 4 blank lines, but I can reduce it a bit.
    I should be able to match (or at least approximate) your line
    count.

    I've just gone through my first (and probably last) rewrite, and
    the result is a lot cleaner. I won't say more just now, and let
    you continue on your current path.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Thu Mar 5 14:12:19 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:

    On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
    [snip]

    The latest challenge, which I just got through doing, is to
    disallow if, for, while, goto, return, and to forbid functions
    and function calls except for calls to C standard library
    functions. Also no math library. :)

    Inventive, aren't you :-)

    I've got a working matrix print that (I think) satisfies your
    requirements, but have not started on the argument processing
    logic yet. I may, yet again, revise my approach, as the solution
    I'm using is quite tedious to code.

    OK, so the "no if statements" is a bit of a bother, but not
    insurmountable. It's just a case of switching things around.
    And, perhaps there's a third option as well.

    As I said, the alternatives are just tedious to code.

    I did manage to find some tricks to make things simpler, but
    probably the most important is ?: is your friend.

    But, I now need to find a replacement for sqrt() that doesn't take
    a lot of space. Back to first principles for me, then.

    There is an easy way to do this, if not especially elegant: start a
    counter at 0 and count it up until counter*counter >= cutoff. Then
    there is a straightword arithmetic test to see if counter is good or
    bad.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Thu Mar 5 22:24:53 2026
    From Newsgroup: comp.lang.c

    On Thu, 05 Mar 2026 14:12:19 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:

    On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
    [snip]

    The latest challenge, which I just got through doing, is to
    disallow if, for, while, goto, return, and to forbid functions
    and function calls except for calls to C standard library
    functions. Also no math library. :)

    Inventive, aren't you :-)

    I've got a working matrix print that (I think) satisfies your
    requirements, but have not started on the argument processing
    logic yet. I may, yet again, revise my approach, as the solution
    I'm using is quite tedious to code.

    OK, so the "no if statements" is a bit of a bother, but not
    insurmountable. It's just a case of switching things around.
    And, perhaps there's a third option as well.

    As I said, the alternatives are just tedious to code.

    I did manage to find some tricks to make things simpler, but
    probably the most important is ?: is your friend.

    that, and switch()/case, which is a nice substitute for if () statements
    with complex bodies, or if () / else statements.

    But, I now need to find a replacement for sqrt() that doesn't take
    a lot of space. Back to first principles for me, then.

    There is an easy way to do this, if not especially elegant: start a
    counter at 0 and count it up until counter*counter >= cutoff. Then
    there is a straightword arithmetic test to see if counter is good or
    bad.

    I was playing with the Heron's method of approximation, but was
    getting anomalous numbers when coded to the restrictions of the
    challenge.

    I don't mind burning cycles, and might go for the straightforward
    way, but I'm still thinking on it
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Fri Mar 6 01:00:16 2026
    From Newsgroup: comp.lang.c

    On Thu, 5 Mar 2026 22:24:53 -0000 (UTC)
    Lew Pitcher <[email protected]> wrote:

    On Thu, 05 Mar 2026 14:12:19 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:

    On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
    [snip]

    The latest challenge, which I just got through doing, is to
    disallow if, for, while, goto, return, and to forbid functions
    and function calls except for calls to C standard library
    functions. Also no math library. :)

    Inventive, aren't you :-)

    I've got a working matrix print that (I think) satisfies your
    requirements, but have not started on the argument processing
    logic yet. I may, yet again, revise my approach, as the solution
    I'm using is quite tedious to code.

    OK, so the "no if statements" is a bit of a bother, but not
    insurmountable. It's just a case of switching things around.
    And, perhaps there's a third option as well.

    As I said, the alternatives are just tedious to code.

    I did manage to find some tricks to make things simpler, but
    probably the most important is ?: is your friend.

    that, and switch()/case, which is a nice substitute for if ()
    statements with complex bodies, or if () / else statements.


    My impression was that switch is omitted from the list of disallowed
    constructs by mistake.

    But, I now need to find a replacement for sqrt() that doesn't take
    a lot of space. Back to first principles for me, then.

    There is an easy way to do this, if not especially elegant: start a counter at 0 and count it up until counter*counter >= cutoff. Then
    there is a straightword arithmetic test to see if counter is good or
    bad.

    I was playing with the Heron's method of approximation, but was
    getting anomalous numbers when coded to the restrictions of the
    challenge.

    I don't mind burning cycles, and might go for the straightforward
    way, but I'm still thinking on it



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Thu Mar 5 15:05:09 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    On Thu, 05 Mar 2026 14:12:19 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:

    On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
    [snip]

    The latest challenge, which I just got through doing, is to
    disallow if, for, while, goto, return, and to forbid functions
    and function calls except for calls to C standard library
    functions. Also no math library. :)

    Inventive, aren't you :-)

    I've got a working matrix print that (I think) satisfies your
    requirements, but have not started on the argument processing
    logic yet. I may, yet again, revise my approach, as the solution
    I'm using is quite tedious to code.

    OK, so the "no if statements" is a bit of a bother, but not
    insurmountable. It's just a case of switching things around.
    And, perhaps there's a third option as well.

    As I said, the alternatives are just tedious to code.

    I did manage to find some tricks to make things simpler, but
    probably the most important is ?: is your friend.

    that, and switch()/case, which is a nice substitute for if () statements
    with complex bodies, or if () / else statements.

    But, I now need to find a replacement for sqrt() that doesn't take
    a lot of space. Back to first principles for me, then.

    There is an easy way to do this, if not especially elegant: start a
    counter at 0 and count it up until counter*counter >= cutoff. Then
    there is a straightword arithmetic test to see if counter is good or
    bad.

    I was playing with the Heron's method of approximation, but was
    getting anomalous numbers when coded to the restrictions of the
    challenge.

    I don't mind burning cycles, and might go for the straightforward
    way, but I'm still thinking on it

    The simple counter method is what I first coded. Then I did a
    binary search. The binary search is kind of clunky in a
    "no for() or while()" environment, so I figured out a way
    to use Newton-Raphson iteration. A little bit tricky to get
    right, but after wrestling with it I managed to get a fairly
    nice formulation.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Thu Mar 5 15:08:17 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> writes:

    On Thu, 5 Mar 2026 22:24:53 -0000 (UTC)
    Lew Pitcher <[email protected]> wrote:

    On Thu, 05 Mar 2026 14:12:19 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:

    On Mon, 02 Mar 2026 21:09:21 -0800, Tim Rentsch wrote:
    [snip]

    The latest challenge, which I just got through doing, is to
    disallow if, for, while, goto, return, and to forbid functions
    and function calls except for calls to C standard library
    functions. Also no math library. :)

    Inventive, aren't you :-)

    I've got a working matrix print that (I think) satisfies your
    requirements, but have not started on the argument processing
    logic yet. I may, yet again, revise my approach, as the solution
    I'm using is quite tedious to code.

    OK, so the "no if statements" is a bit of a bother, but not
    insurmountable. It's just a case of switching things around.
    And, perhaps there's a third option as well.

    As I said, the alternatives are just tedious to code.

    I did manage to find some tricks to make things simpler, but
    probably the most important is ?: is your friend.

    that, and switch()/case, which is a nice substitute for if ()
    statements with complex bodies, or if () / else statements.

    My impression was that switch is omitted from the list of disallowed constructs by mistake.

    Definitely not. Use of switch() is allowed (and 'case' also).
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Fri Mar 6 00:18:43 2026
    From Newsgroup: comp.lang.c

    On 05.03.26 22:12, Lew Pitcher wrote:
    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:
    [...]

    But, I now need to find a replacement for sqrt() that doesn't take
    a lot of space. Back to first principles for me, then.

    The roguelike game Nethack that historically deliberately didn't
    use any floating point had this code (most is just comments):

    /* integer square root function without using floating point */
    int
    isqrt(val)
    int val;
    {
    int rt = 0;
    int odd = 1;
    /*
    * This could be replaced by a faster algorithm, but has not been because:
    * + the simple algorithm is easy to read;
    * + this algorithm does not require 64-bit support;
    * + in current usage, the values passed to isqrt() are not really that
    * large, so the performance difference is negligible;
    * + isqrt() is used in only few places, which are not bottle-necks.
    */
    while (val >= odd) {
    val = val - odd;
    odd = odd + 2;
    rt = rt + 1;
    }
    return rt;
    }


    Janis

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Fri Mar 6 00:12:13 2026
    From Newsgroup: comp.lang.c

    OK, it's not pretty, but here it is

    /*
    ** From: DFS <[email protected]>
    ** 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$[email protected]>
    **
    ** Challenge is to output sequential numbers by column then row:
    ** Kind of goes without saying the solution should handle any row x column
    ** input:
    **
    ** input rows columns
    ** --------------------------------------------------------------------
    ** 1) must be able to cut the output off at any arbitrary value
    ** lower than rows x columns
    ** --------------------------------------------------------------------
    ** 2) if you don't specify rows and columns, your solution must try
    ** to calculate them to form a square (same # of rows and columns)
    ** that includes only 1 to N.
    **
    ** If rows=columns can't be calculated, return message 'not possible'
    ** --------------------------------------------------------------------
    **
    ** * Extra Credit if you determine a formula for this requirement. I kind
    ** of brute-forced it with 2 loops. As you can see, N = prime isn't
    ** enough to know if it can be done.
    ** -----------------------------------------------------------------------
    **
    ** From: Tim Rentsch <[email protected]>
    ** Newsgroups: comp.lang.c
    ** Subject: Re: Sort of trivial code challenge - may be interesting to you anyway
    ** Date: Mon, 02 Mar 2026 21:09:21 -0800
    ** Message-ID: <[email protected]>
    **
    ** The latest challenge, which I just got through doing, is to
    ** disallow if, for, while, goto, return, and to forbid functions
    ** and function calls except for calls to C standard library
    ** functions. Also no math library. :)
    **
    ** ========================================================================== **
    ** Tim Rentsch counter-counter-challenge; solution by Lew Pitcher 2026-03-05
    ** cc -o rowcol_TR2 -mtune=native -Wall -std=c99 -pedantic -w rowcol_TR2.c
    **
    ** Note: -w to suppress warnings relating to using switch() to evaluate
    ** a boolean value
    **
    ** This code released into the public domain. Lew Pitcher, 2026-03-04
    */

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

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

    int main(int argc, char *argv[])
    {
    int status = EXIT_FAILURE,
    args_ok = 1;
    unsigned int n_rows = 0,
    n_cols = 0,
    cut_off = 0;

    switch (argc)
    {
    case 4: /* rowcol #rows #cols cutoff */
    {
    char *eptr;
    unsigned long int result;
    int valid;

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

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

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

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

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

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

    break;

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

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

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

    case 0:
    {
    int valu;
    jmp_buf CompRoot;

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

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

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

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

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

    status = EXIT_SUCCESS;
    }
    break;

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

    exit(status);
    }
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Fri Mar 6 00:14:13 2026
    From Newsgroup: comp.lang.c

    On Fri, 06 Mar 2026 00:12:13 +0000, Lew Pitcher wrote:

    OK, it's not pretty, but here it is

    /*
    ** From: DFS <[email protected]>
    ** 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$[email protected]>
    **
    ** Challenge is to output sequential numbers by column then row:
    ** Kind of goes without saying the solution should handle any row x column ** input:
    **
    ** input rows columns
    ** --------------------------------------------------------------------
    ** 1) must be able to cut the output off at any arbitrary value
    ** lower than rows x columns
    ** --------------------------------------------------------------------
    ** 2) if you don't specify rows and columns, your solution must try
    ** to calculate them to form a square (same # of rows and columns)
    ** that includes only 1 to N.
    **
    ** If rows=columns can't be calculated, return message 'not possible'
    ** --------------------------------------------------------------------
    **
    ** * Extra Credit if you determine a formula for this requirement. I kind
    ** of brute-forced it with 2 loops. As you can see, N = prime isn't
    ** enough to know if it can be done.
    ** -----------------------------------------------------------------------
    **
    ** From: Tim Rentsch <[email protected]>
    ** Newsgroups: comp.lang.c
    ** Subject: Re: Sort of trivial code challenge - may be interesting to you anyway
    ** Date: Mon, 02 Mar 2026 21:09:21 -0800
    ** Message-ID: <[email protected]>
    **
    ** The latest challenge, which I just got through doing, is to
    ** disallow if, for, while, goto, return, and to forbid functions
    ** and function calls except for calls to C standard library
    ** functions. Also no math library. :)
    **
    ** ========================================================================== **
    ** Tim Rentsch counter-counter-challenge; solution by Lew Pitcher 2026-03-05 ** cc -o rowcol_TR2 -mtune=native -Wall -std=c99 -pedantic -w rowcol_TR2.c
    **
    ** Note: -w to suppress warnings relating to using switch() to evaluate
    ** a boolean value
    **
    ** This code released into the public domain. Lew Pitcher, 2026-03-04
    */

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

    Oops... This doesn't use anything from math.h
    I forgot to remove it once I got rid of the floatingpoint math functions
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Thu Mar 5 19:24:37 2026
    From Newsgroup: comp.lang.c

    On 3/5/2026 3:39 PM, Bart wrote:
    On 05/03/2026 18:49, DFS wrote:
    On 3/4/2026 12:27 PM, Michael S wrote:


    Where else but Python can you get meaningful Usenet stats in 22 lines?

    -------------------------------------------------------
    import sys as y,nntplib as t

    How many lines would it be without using 'nntplib'?


    TONS more.

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

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

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

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

    data is:
    [('322356', 'Lew Pitcher <[email protected]>'),
    ('322357', 'Tim Rentsch <[email protected]>'),
    ('322358', 'Tim Rentsch <[email protected]>'),
    ('322359', 'Tim Rentsch <[email protected]>'),
    ('322360', 'Tim Rentsch <[email protected]>'),
    ('322361', 'Lew Pitcher <[email protected]>'),
    ('322362', 'Michael S <[email protected]>'),
    ('322363', 'Tim Rentsch <[email protected]>'),
    ('322364', 'Tim Rentsch <[email protected]>'),
    ('322365', 'Janis Papanagnou <[email protected]>')]


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



    Most of Python's usefulness is due to the availability of lots of
    different libraries. It is an actual scripting language.

    (However when I ran your script, it was missing 'nntplib'.)


    pip install standard-nntplib should set you straight.


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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Fri Mar 6 02:17:48 2026
    From Newsgroup: comp.lang.c

    Tim Rentsch <[email protected]> writes:
    [email protected] (Scott Lurndal) writes:

    DFS <[email protected]> writes:

    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.


    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000

    Using snprintf() is more correct and also more obviously correct.


    Yes, I had assumed the first row, first column would be zero, not one.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Fri Mar 6 03:35:15 2026
    From Newsgroup: comp.lang.c

    Am 05.03.2026 um 20:11 schrieb DFS:

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

    s/typical/untested

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

    But usually C++ is about five times less code


    since there are no built
    -in complex containers like a map<> or an unordered_map in C. If you
    want to to that in C you have to stick with external libraries which
    do the polymorphic behaviour with callbacks (slower).

    External library not necessary.  It's a little bit of code, such as: https://www.geeksforgeeks.org/dsa/implementation-on-map-or-dictionary- data-structure-in-c/

    Five seconds in C++:

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


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Thu Mar 5 20:06:22 2026
    From Newsgroup: comp.lang.c

    [email protected] (Scott Lurndal) writes:

    Tim Rentsch <[email protected]> writes:

    [email protected] (Scott Lurndal) writes:

    DFS <[email protected]> writes:

    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.


    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000

    Using snprintf() is more correct and also more obviously correct.

    Yes, I had assumed the first row, first column would be zero, not one.

    The value for 10 is also wrong. And 100. And 1000. etc...

    By the way, I see no reason to disallow a cutoff value of 0.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Thu Mar 5 20:31:39 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    OK, it's not pretty, but here it is

    No worries - being pretty is not on the list of requested properties. :)

    Congratulations on being the first to post an answer.

    Two problems related to how setjmp()/longjmp() are used:

    1. Any local variable changed between a setjmp() and the longjmp()
    that goes back to it must be declared 'volatile' to avoid problems
    with indeterminate values. (Minor.)

    2. A pattern like 'x = setjmp( jbuf );' is not one of the officially
    approved forms in the C standard for setjmp(). More specifically,
    any such usage has undefined behavior. (More serious.)

    If you look in the C standard for setjmp(), there is a subsection
    titled 'Environmental limits' that explains which forms are approved
    for use. Personally I think it's regrettable that 'x = setjmp( jbuf );'
    is not one of them, but I feel obliged to observe that limitation and
    follow what the standard prescribes for using setjmp().
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Fri Mar 6 06:37:19 2026
    From Newsgroup: comp.lang.c

    On 27.02.26 01:12, Bart wrote:
    [...]
    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.

    Just one question about your algorithm; why this line...?

    for c in 1..cols when i<=n do

    Assuming that 'when' works like 'while', it seems to me that

    while i<=n do

    should suffice. - No?

    Janis


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

    [...]


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Fri Mar 6 07:48:05 2026
    From Newsgroup: comp.lang.c

    Am 05.03.2026 um 20:50 schrieb tTh:
    On 3/5/26 19:46, Bonita Montero wrote:

    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000


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

       Why ?

    Because the 53 bits may mistakenly represent a power of ten because
    the lower bits were dropped.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Fri Mar 6 11:49:41 2026
    From Newsgroup: comp.lang.c

    On Fri, 6 Mar 2026 07:48:05 +0100
    Bonita Montero <[email protected]> wrote:
    Am 05.03.2026 um 20:50 schrieb tTh:
    On 3/5/26 19:46, Bonita Montero wrote:

    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000


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

    �� Why ?

    Because the 53 bits may mistakenly represent a power of ten because
    the lower bits were dropped.

    The formula is incorrect, regardless.
    With correct formula, i.e. floor(..)+1, imprecision become harmless.
    For numbers like 9999999999999979 you get one unnecessary space.
    Not a big deal.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Fri Mar 6 13:41:22 2026
    From Newsgroup: comp.lang.c

    Am 06.03.2026 um 10:49 schrieb Michael S:

    The formula is incorrect, regardless.
    With correct formula, i.e. floor(..)+1, imprecision become harmless.
    For numbers like 9999999999999979 you get one unnecessary space.
    Not a big deal.

    Then better count characters.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Fri Mar 6 15:33:24 2026
    From Newsgroup: comp.lang.c

    On Fri, 6 Mar 2026 13:41:22 +0100
    Bonita Montero <[email protected]> wrote:

    Am 06.03.2026 um 10:49 schrieb Michael S:

    The formula is incorrect, regardless.
    With correct formula, i.e. floor(..)+1, imprecision become harmless.
    For numbers like 9999999999999979 you get one unnecessary space.
    Not a big deal.

    Then better count characters.

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Fri Mar 6 14:42:29 2026
    From Newsgroup: comp.lang.c

    Am 06.03.2026 um 14:33 schrieb Michael S:

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

    If efficiency doesn't count (log10 is about 20 cycles on my PC)
    chose the precise solution, even more if anyone understands that.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Fri Mar 6 13:51:58 2026
    From Newsgroup: comp.lang.c

    On Thu, 05 Mar 2026 20:31:39 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    OK, it's not pretty, but here it is

    No worries - being pretty is not on the list of requested properties. :)

    Congratulations on being the first to post an answer.

    Two problems related to how setjmp()/longjmp() are used:

    1. Any local variable changed between a setjmp() and the longjmp()
    that goes back to it must be declared 'volatile' to avoid problems
    with indeterminate values. (Minor.)

    2. A pattern like 'x = setjmp( jbuf );' is not one of the officially
    approved forms in the C standard for setjmp(). More specifically,
    any such usage has undefined behavior. (More serious.)

    If you look in the C standard for setjmp(), there is a subsection
    titled 'Environmental limits' that explains which forms are approved
    for use. Personally I think it's regrettable that 'x = setjmp( jbuf );'
    is not one of them, but I feel obliged to observe that limitation and
    follow what the standard prescribes for using setjmp().

    yah.

    As you can tell, I haven't used setjmp()/longjmp() much, and am
    unfamiliar with the caveats surrounding them.

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

    Thanks for the observations. I look forward to seeing /your/ code :-)
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Fri Mar 6 14:58:24 2026
    From Newsgroup: comp.lang.c

    Tim Rentsch <[email protected]> writes:
    [email protected] (Scott Lurndal) writes:

    Tim Rentsch <[email protected]> writes:

    [email protected] (Scott Lurndal) writes:

    DFS <[email protected]> writes:

    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.


    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000

    Using snprintf() is more correct and also more obviously correct.

    Yes, I had assumed the first row, first column would be zero, not one.

    The value for 10 is also wrong. And 100. And 1000. etc...

    No, 10*10 yields 100 values from 0 to 99.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Fri Mar 6 17:13:42 2026
    From Newsgroup: comp.lang.c

    On Fri, 06 Mar 2026 14:58:24 GMT
    [email protected] (Scott Lurndal) wrote:

    Tim Rentsch <[email protected]> writes:
    [email protected] (Scott Lurndal) writes:

    Tim Rentsch <[email protected]> writes:

    [email protected] (Scott Lurndal) writes:

    DFS <[email protected]> writes:

    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.


    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000

    Using snprintf() is more correct and also more obviously correct.


    Yes, I had assumed the first row, first column would be zero, not
    one.

    The value for 10 is also wrong. And 100. And 1000. etc...

    No, 10*10 yields 100 values from 0 to 99.

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Fri Mar 6 10:34:55 2026
    From Newsgroup: comp.lang.c

    On 3/4/2026 11:09 AM, Tim Rentsch wrote:
    DFS <[email protected]> writes:


    I recently thought of a new approach: fill an array with 1 to the
    cutoff (min(cutoff, rows*cols) anyway), and just print the whole array
    col by row. Then there's never a need to check each value as you're
    printing it.

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


    I'm sensing sarcasm.

    I pursued the array approach (a little differently than I described
    above), but in the end it was useless and a waste of time.

    example: 4x4 array looked like this:

    position: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
    initial : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    filled : 1 5 9 13 0 2 6 10 14 0 3 7 11 15 0 4 8 12 16
    printed :
    1 5 9 13
    2 6 10 14
    3 7 11 15
    4 8 12 16

    When you come to a 0 you do newline.

    Worked great with no cutoffs, but couldn't quite get the printing right
    when there were cutoff values. And it ended up being about 50% MORE
    code than my original algorithm. And it used an unnecessary array object.

    Altogether a fail.


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

    I'll wait until you post your majestic code.

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Fri Mar 6 10:36:19 2026
    From Newsgroup: comp.lang.c

    On 2/26/2026 2:34 PM, Lew Pitcher wrote:


    static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
    {
    unsigned int field_width; /* for equal spacing of output data */

    if (cut_off == 0) cut_off = n_rows * n_cols;
    field_width = ceil(log10(cut_off)) + 1;

    for (unsigned int row = 0; row < n_rows; ++row)
    {
    for (unsigned int col = 0; col < n_cols; ++col)
    {
    unsigned int valu = 1 + row + (col * n_rows);
    if (valu <= cut_off)
    printf("%-*u",field_width,valu);
    }
    puts("");
    }
    }


    I found a nit:

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

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







    prompt$



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


    Thanks

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Fri Mar 6 15:48:30 2026
    From Newsgroup: comp.lang.c

    On 06/03/2026 05:37, Janis Papanagnou wrote:
    On 27.02.26 01:12, Bart wrote:
    [...]
    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.

    Just one question about your algorithm; why this line...?

             for c in 1..cols when i<=n do

    Assuming that 'when' works like 'while', it seems to me that

             while i<=n do

    should suffice. - No?

    'when' is a per-iteration guard. It skips only that iteration when
    false, unlike 'for-while' in Algol68 which terminates the loop.

    In C terms it's more like for()if(){}.

    ('if' is not used as 'if' can be an expression-starter and there are
    some grammatical issues.)


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Fri Mar 6 16:02:14 2026
    From Newsgroup: comp.lang.c

    On 06/03/2026 00:12, Lew Pitcher wrote:
    OK, it's not pretty, but here it is

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

    I assume it works according to the spec, where I admit I don't fully understand the conditions. So input of '10 10 90' is fine (prints 1-90
    within 10x10 matrix) omits final column), but input of '90' fails, even
    though it's the same square matrix.

    One thing I've noticed is that numbers are shown left-justified when
    narrower than the maximum, so '9 ' rather than ' 9'. For tabular data in they're normally right-justified.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Fri Mar 6 08:37:35 2026
    From Newsgroup: comp.lang.c

    [email protected] (Scott Lurndal) writes:

    Tim Rentsch <[email protected]> writes:

    [email protected] (Scott Lurndal) writes:

    Tim Rentsch <[email protected]> writes:

    [email protected] (Scott Lurndal) writes:

    DFS <[email protected]> writes:

    On 3/4/2026 5:44 AM, Bonita Montero wrote:

    int colwidth = sprintf(cw,"%d",max) + 1;

    using ciel(log10(rows*columns)) performs better than snprintf
    in this application.


    $ printf '%f\n' $(( ceil(log10( 8*8)) ))
    2.000000

    Using snprintf() is more correct and also more obviously correct.

    Yes, I had assumed the first row, first column would be zero, not one.

    The value for 10 is also wrong. And 100. And 1000. etc...

    No, 10*10 yields 100 values from 0 to 99.

    You changed the subject. We were talking about how to
    calculate an appropriate field width given a maximum value.
    The problem under discussion produces values from 1 to
    maximum value, inclusive. The expression ceil(log10( max ) )
    gives wrong answers when max is a power of 10. I haven't
    looked at Bonita Montero's code but based on the snippet
    above it seems clear he is responding to the original problem
    statement, even if he may have misunderstood what that was
    asking for.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Fri Mar 6 08:46:20 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:

    On 3/4/2026 11:09 AM, Tim Rentsch wrote:

    DFS <[email protected]> writes:

    I recently thought of a new approach: fill an array with 1 to the
    cutoff (min(cutoff, rows*cols) anyway), and just print the whole array
    col by row. Then there's never a need to check each value as you're
    printing it.

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

    I'm sensing sarcasm.

    I wasn't being sarcastic; I do give you points for originality. I
    leave it to you to decide how much value to ascribe to that.

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

    I pursued the array approach (a little differently than I described
    above), but in the end it was useless and a waste of time.

    example: 4x4 array looked like this:

    position: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
    initial : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    filled : 1 5 9 13 0 2 6 10 14 0 3 7 11 15 0 4 8 12 16
    printed :
    1 5 9 13
    2 6 10 14
    3 7 11 15
    4 8 12 16

    When you come to a 0 you do newline.

    Worked great with no cutoffs, but couldn't quite get the printing
    right when there were cutoff values. And it ended up being about 50%
    MORE code than my original algorithm. And it used an unnecessary
    array object.

    Altogether a fail.

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

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

    I'll wait until you post your majestic code.

    I'm still hoping you will post an attempt first, especially now that
    you have seen Lew Pitcher's response. If you tell me where you are
    stuck I can try to give a suitable hint to get you over the hump.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Fri Mar 6 08:53:25 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    On Thu, 05 Mar 2026 20:31:39 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    OK, it's not pretty, but here it is

    No worries - being pretty is not on the list of requested properties. :)

    Congratulations on being the first to post an answer.

    Two problems related to how setjmp()/longjmp() are used:

    1. Any local variable changed between a setjmp() and the longjmp()
    that goes back to it must be declared 'volatile' to avoid problems
    with indeterminate values. (Minor.)

    2. A pattern like 'x = setjmp( jbuf );' is not one of the officially
    approved forms in the C standard for setjmp(). More specifically,
    any such usage has undefined behavior. (More serious.)

    If you look in the C standard for setjmp(), there is a subsection
    titled 'Environmental limits' that explains which forms are approved
    for use. Personally I think it's regrettable that 'x = setjmp( jbuf );'
    is not one of them, but I feel obliged to observe that limitation and
    follow what the standard prescribes for using setjmp().

    yah.

    As you can tell, I haven't used setjmp()/longjmp() much, and am
    unfamiliar with the caveats surrounding them.

    I became aware of the restrictions some time ago, after seeing
    discussion in comp.lang.c. After that I looked carefully at the
    C standard to learn the official rules.

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

    Great, I'm cheering you on. :)

    Thanks for the observations. I look forward to seeing /your/ code :-)

    I'm eager to post it. I'm still hoping DFS will at least post an
    attempt. I'm happy to give a hint if someone asks. Let's say I
    will wait another day or so and can post after that whether or
    not DFS has come forward.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Fri Mar 6 12:11:32 2026
    From Newsgroup: comp.lang.c

    On 3/6/2026 11:02 AM, Bart wrote:

    I assume it works according to the spec, where I admit I don't fully understand the conditions. So input of '10 10 90' is fine (prints 1-90 within 10x10 matrix) omits final column), but input of '90' fails, even though it's the same square matrix.


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

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

    Only a square matrix of 10x10 can contain 1-91.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Fri Mar 6 18:17:44 2026
    From Newsgroup: comp.lang.c

    On 06.03.26 16:48, Bart wrote:
    On 06/03/2026 05:37, Janis Papanagnou wrote:
    On 27.02.26 01:12, Bart wrote:
    [...]
    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.

    Just one question about your algorithm; why this line...?

              for c in 1..cols when i<=n do

    Assuming that 'when' works like 'while', it seems to me that

              while i<=n do

    should suffice. - No?

    'when' is a per-iteration guard. It skips only that iteration when
    false, unlike 'for-while' in Algol68 which terminates the loop.

    Ah, okay, I see. A condition for exceptional cases during the loop.

    My question on the algorithm still remains; can't that for/when loop
    be replaced by the simpler while condition? - It appears to me that
    the simpler 'while' condition is sufficient here to express what's algorithmically needed.

    Janis


    In C terms it's more like for()if(){}.

    ('if' is not used as 'if' can be an expression-starter and there are
    some grammatical issues.)



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Fri Mar 6 17:38:04 2026
    From Newsgroup: comp.lang.c

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

    On 2/26/2026 2:34 PM, Lew Pitcher wrote:


    static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
    {
    unsigned int field_width; /* for equal spacing of output data */

    if (cut_off == 0) cut_off = n_rows * n_cols;
    field_width = ceil(log10(cut_off)) + 1;

    for (unsigned int row = 0; row < n_rows; ++row)
    {
    for (unsigned int col = 0; col < n_cols; ++col)
    {
    unsigned int valu = 1 + row + (col * n_rows);
    if (valu <= cut_off)
    printf("%-*u",field_width,valu);
    }
    puts("");
    }
    }


    I found a nit:

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

    Yes, I'm aware :-)

    I fixed it in a later version, which I have not posted yet.
    The restricted-C version I posted in response to Tim Rentsch's counter-counter challenge behaves properly (albeit, with the UB that he identified).
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Fri Mar 6 17:48:51 2026
    From Newsgroup: comp.lang.c

    On Fri, 06 Mar 2026 17:38:04 +0000, Lew Pitcher wrote:

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

    On 2/26/2026 2:34 PM, Lew Pitcher wrote:


    static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off)
    {
    unsigned int field_width; /* for equal spacing of output data */

    if (cut_off == 0) cut_off = n_rows * n_cols;
    field_width = ceil(log10(cut_off)) + 1;

    for (unsigned int row = 0; row < n_rows; ++row)
    {
    for (unsigned int col = 0; col < n_cols; ++col)
    {
    unsigned int valu = 1 + row + (col * n_rows);
    if (valu <= cut_off)
    printf("%-*u",field_width,valu);
    }
    puts("");
    }
    }


    I found a nit:

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

    Yes, I'm aware :-)

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

    And, here it is...

    /*
    ** From: DFS <[email protected]>
    ** 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$[email protected]>
    **
    ** Challenge is to output sequential numbers by column then row:
    ** Kind of goes without saying the solution should handle any row x column
    ** input:
    **
    ** input rows columns
    ** --------------------------------------------------------------------
    ** 1) must be able to cut the output off at any arbitrary value
    ** lower than rows x columns
    ** --------------------------------------------------------------------
    ** 2) if you don't specify rows and columns, your solution must try
    ** to calculate them to form a square (same # of rows and columns)
    ** that includes only 1 to N.
    **
    ** If rows=columns can't be calculated, return message 'not possible'
    ** --------------------------------------------------------------------
    **
    ** * Extra Credit if you determine a formula for this requirement. I kind
    ** of brute-forced it with 2 loops. As you can see, N = prime isn't
    ** enough to know if it can be done.
    ** -----------------------------------------------------------------------
    **
    ** From: Tim Rentsch <[email protected]>
    ** Newsgroups: comp.lang.c
    ** Subject: Re: Sort of trivial code challenge - may be interesting to you anyway
    ** Date: Mon, 02 Mar 2026 00:44:57 -0800
    ** Message-ID: <[email protected]>
    **
    ** Here is a counter challenge to make things more interesting: as above,
    ** but don't use nested loops (or goto's, etc).
    **
    ** -----------------------------------------------------------------------
    **
    ** From: Michael S <[email protected]>
    ** Newsgroups: comp.lang.c
    ** Subject: Re: Sort of trivial code challenge - may be interesting to you anyway
    ** Date: Mon, 2 Mar 2026 11:07:20 +0200
    ** Message-ID: <[email protected]>
    **
    ** Another counter challenge could have been to commpletely avoid loops/goto. **
    ** ========================================================================== **
    ** DFS challenge; solution by Lew Pitcher 2026-02-26
    ** cc -o rowcol_CLC -mtune=native -Wall -std=c99 -pedantic -lm rowcol_CLC.c
    **
    ** Tim Rentsch counter-challenge; solution by Lew Pitcher 2026-03-03
    ** cc -o rowcol_CLC -mtune=native -Wall -std=c99 -pedantic -lm -DNO_NESTED_LOOPS rowcol_CLC.c
    **
    ** Michael S counter-challenge; solution by Lew Pitcher 2026-03-03
    ** cc -o rowcol_CLC -mtune=native -Wall -std=c99 -pedantic -lm -DNO_LOOPS rowcol_CLC.c
    **
    ** NB: solutions use ceil(), sqrt(), and log10() calls from math lib
    **
    ** This code released into the public domain. Lew Pitcher, 2026-03-04
    */

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


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

    static int StrUint(const char *string, unsigned int *valu);
    static void dosquare(unsigned int n_rows, unsigned int n_cols, unsigned int cut_off);

    int main(int argc, char *argv[])
    {
    int status = EXIT_FAILURE,
    args_ok = 1;
    unsigned int n_rows = 0,
    n_cols = 0,
    cut_off = 0;

    switch (argc)
    {
    case 4: /* rowcol #rows #cols cutoff */
    if ((StrUint(argv[3],&cut_off) == 0) || (cut_off == 0))
    {
    fprintf(stderr,"Invalid value for cut-off (\"%s\")\n",argv[3]);
    args_ok = 0;
    }
    case 3: /* rowcol #rows #cols */
    if ((StrUint(argv[1],&n_rows) == 0) || (n_rows == 0))
    {
    fprintf(stderr,"Invalid value for # rows (\"%s\")\n",argv[1]);
    args_ok = 0;
    }
    if ((StrUint(argv[2],&n_cols) == 0) || (n_cols == 0))
    {
    fprintf(stderr,"Invalid value for # columns (\"%s\")\n",argv[2]);
    args_ok = 0;
    }

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

    break;

    case 2: /* rowcol cutoff */
    if ((StrUint(argv[1],&cut_off) == 0) || (cut_off == 0))
    {
    fprintf(stderr,"Invalid value for cut off (\"%s\")\n",argv[1]);
    args_ok = 0;
    }
    else
    {
    /*
    ** Compute n_rows and n_cols, and validate that cut_off
    ** value occurs as last entry in final column
    **
    ** ----- Narrative -----
    ** As problem definition states that, for this configuration,
    ** n_rows must equal n_cols, and that n_rows * n_cols must
    ** include the cut_off value, we first approximate the value
    ** of n_rows and n_cols by taking the square root of cut_off
    ** and rounding that value up to the nearest integer. This
    ** guarantees that n_rows * n_cols is the smallest square
    ** that will contain the cut_off value.
    **
    ** But, this rounded value might be too big to place cut_off
    ** in the last column. So, we compute the first entry in
    ** the last column, and make sure that cut_off is not less
    ** than that value (if it is, then cut_off occurs in a column
    ** prior to the last column, and violates the constraints
    ** of this configuration).
    **
    ** FWIW, because of the way we compute n_rows and n_cols,
    ** we know that cut_off will never /exceed/ n_rows * n_cols.
    */
    n_rows = n_cols = ceil(sqrt(cut_off));
    if ( (cut_off < (n_rows * (n_cols-1)) + 1) )
    {
    fprintf(stderr,"Cut off value %u not possible where rows=cols\n",cut_off);
    args_ok = 0;
    }
    }
    break;

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

    if (args_ok) /* then our inputs are valid and within our constraints */
    {
    if (cut_off == 0) cut_off = n_rows * n_cols;
    dosquare(n_rows,n_cols,cut_off);
    status = EXIT_SUCCESS;
    }
    else fprintf(stderr,"Usage:\t%s #_rows #_cols [ cut-off ]\nor\t%s cut-off\n",argv[0],argv[0]);

    return status;
    }

    /*
    ** StrUint() parse string for numeric decimal integer value
    ** returns 0 on failure,
    ** 1, valu updated on success
    */
    static int StrUint(const char *string, unsigned int *valu)
    {
    int status = 0;
    char *eptr;
    unsigned long int result;

    result = strtoul(string,&eptr,10);
    /*
    ** NB: will honour the "-" negative flag, resulting in an extremely
    ** large unsigned value. We will consider this an error, detected
    ** by a result greater than UINT_MAX.
    */

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

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

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

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

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

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

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

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

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

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

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

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

    [snip]
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Fri Mar 6 13:01:31 2026
    From Newsgroup: comp.lang.c

    On 3/6/2026 12:11 PM, DFS wrote:
    On 3/6/2026 11:02 AM, Bart wrote:

    I assume it works according to the spec, where I admit I don't fully
    understand the conditions. So input of '10 10 90' is fine (prints 1-90
    within 10x10 matrix) omits final column), but input of '90' fails,
    even though it's the same square matrix.


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

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

    Only a square matrix of 10x10 can contain 1-91.


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

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

    Examples:

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

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

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



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

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



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

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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Fri Mar 6 13:28:59 2026
    From Newsgroup: comp.lang.c

    On 3/6/2026 1:01 PM, DFS wrote:
    On 3/6/2026 12:11 PM, DFS wrote:

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

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


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

    I do believe this is a true statement.


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



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Fri Mar 6 21:46:59 2026
    From Newsgroup: comp.lang.c

    On 06/03/2026 17:17, Janis Papanagnou wrote:
    On 06.03.26 16:48, Bart wrote:
    On 06/03/2026 05:37, Janis Papanagnou wrote:
    On 27.02.26 01:12, Bart wrote:
    [...]
    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.

    Just one question about your algorithm; why this line...?

              for c in 1..cols when i<=n do

    Assuming that 'when' works like 'while', it seems to me that

              while i<=n do

    should suffice. - No?

    'when' is a per-iteration guard. It skips only that iteration when
    false, unlike 'for-while' in Algol68 which terminates the loop.

    Ah, okay, I see. A condition for exceptional cases during the loop.

    My question on the algorithm still remains; can't that for/when loop
    be replaced by the simpler while condition? - It appears to me that
    the simpler 'while' condition is sufficient here to express what's algorithmically needed.

    Well, I tried it and it still works, so you're right.

    But it's not intuitive to me: we're iterating over a square matrix, so a nested loop over rows and cols is the obvious way to do it (I was also
    doing it under a time constraint).

    The 'when' condition is to suppress output for the last column here,
    where N is 23, and the matrix is 5 x 5 elements:

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


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Fri Mar 6 21:53:35 2026
    From Newsgroup: comp.lang.c

    On 06/03/2026 17:11, DFS wrote:
    On 3/6/2026 11:02 AM, Bart wrote:

    I assume it works according to the spec, where I admit I don't fully
    understand the conditions. So input of '10 10 90' is fine (prints 1-90
    within 10x10 matrix) omits final column), but input of '90' fails,
    even though it's the same square matrix.


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

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

    Only a square matrix of 10x10 can contain 1-91.


    I still don't get it. Doesn't an input of '10 10 90' specify a square
    matrix? But it still prints the numbers 1-90:

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


    But this fails:

    c:\cx>t 90
    Cut off value 90 not possible where rows=cols
    Usage: t #_rows #_cols [ cut-off ]
    or t cut-off

    This second invocation couldn't print 1-90 within a 10x10 matrix, but
    the first one could. Or is that first one not considered square; it's a rectangle where height and width happen to be the same?
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Fri Mar 6 19:36:30 2026
    From Newsgroup: comp.lang.c

    On 3/6/2026 11:53 AM, Tim Rentsch wrote:
    Lew Pitcher <[email protected]> writes:

    Thanks for the observations. I look forward to seeing /your/ code :-)

    I'm eager to post it.

    It's time!


    I'm still hoping DFS will at least post an attempt.

    You're an optimist. You'd make a good lion tamer.

    "disallow if, for, while, goto, return, and to forbid functions and
    function calls except for calls to C standard library functions. Also
    no math library."

    would probably take me 3 days solid to research and write

    I did deliver a "no fors, whiles, gotos, or returns" version.

    Then I bowed out.

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


    I'm happy to give a hint if someone asks. Let's say I
    will wait another day or so and can post after that whether or
    not DFS has come forward.

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Fri Mar 6 18:14:04 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:

    On 3/6/2026 11:53 AM, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    Thanks for the observations. I look forward to seeing /your/ code :-)

    I'm eager to post it.

    It's time!


    I'm still hoping DFS will at least post an attempt.

    You're an optimist. You'd make a good lion tamer.

    "disallow if, for, while, goto, return, and to forbid functions and
    function calls except for calls to C standard library functions. Also
    no math library."

    would probably take me 3 days solid to research and write

    I did deliver a "no fors, whiles, gotos, or returns" version.

    Then I bowed out.

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

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

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

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

    static jmp_buf jb;

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

    Obviously some longjmp()'s are needed in the body of the switch() to
    make this all work. Good luck!
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Fri Mar 6 22:14:15 2026
    From Newsgroup: comp.lang.c

    On 3/6/2026 4:53 PM, Bart wrote:
    On 06/03/2026 17:11, DFS wrote:
    On 3/6/2026 11:02 AM, Bart wrote:

    I assume it works according to the spec, where I admit I don't fully
    understand the conditions. So input of '10 10 90' is fine (prints
    1-90 within 10x10 matrix) omits final column), but input of '90'
    fails, even though it's the same square matrix.


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

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

    Only a square matrix of 10x10 can contain 1-91.


    I still don't get it. Doesn't an input of '10 10 90' specify a square matrix? But it still prints the numbers 1-90:

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


    That's a 10x9 matrix.



    But this fails:

     c:\cx>t 90
     Cut off value 90 not possible where rows=cols
     Usage:  t #_rows #_cols [ cut-off ]
     or      t cut-off

    This second invocation couldn't print 1-90 within a 10x10 matrix, but
    the first one could. Or is that first one not considered square; it's a rectangle where height and width happen to be the same?


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

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

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

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


    For 91 the answer is Yes: it is possible to construct a rows=columns
    matrix containing only 1-91.

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


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


    For another view:

    Input Sqr Matrix? sqrt(Input)
    ----------------------------------
    1 possible 1.00
    2 not possible 1.41
    3 possible 1.73
    4 possible 2.00
    5 not possible 2.24
    6 not possible 2.45
    7 possible 2.65
    8 possible 2.83
    9 possible 3.00
    10 not possible 3.16
    11 not possible 3.32
    12 not possible 3.46
    13 possible 3.61
    14 possible 3.74
    15 possible 3.87
    16 possible 4.00
    17 not possible 4.12
    18 not possible 4.24
    19 not possible 4.36
    20 not possible 4.47
    21 possible 4.58
    22 possible 4.69
    23 possible 4.80
    24 possible 4.90
    25 possible 5.00
    26 not possible 5.10
    27 not possible 5.20
    28 not possible 5.29
    29 not possible 5.39
    30 not possible 5.48
    31 possible 5.57
    32 possible 5.66
    33 possible 5.74
    34 possible 5.83
    35 possible 5.92
    36 possible 6.00
    37 not possible 6.08
    38 not possible 6.16
    39 not possible 6.24
    40 not possible 6.32
    41 not possible 6.40
    42 not possible 6.48
    43 possible 6.56
    44 possible 6.63
    45 possible 6.71
    46 possible 6.78
    47 possible 6.86
    48 possible 6.93
    49 possible 7.00
    50 not possible 7.07
    51 not possible 7.14
    52 not possible 7.21
    53 not possible 7.28
    54 not possible 7.35
    55 not possible 7.42
    56 not possible 7.48
    57 possible 7.55
    58 possible 7.62
    59 possible 7.68
    60 possible 7.75
    61 possible 7.81
    62 possible 7.87
    63 possible 7.94
    64 possible 8.00
    65 not possible 8.06
    66 not possible 8.12
    67 not possible 8.19
    68 not possible 8.25
    69 not possible 8.31
    70 not possible 8.37
    71 not possible 8.43
    72 not possible 8.49
    73 possible 8.54
    74 possible 8.60
    75 possible 8.66
    76 possible 8.72
    77 possible 8.77
    78 possible 8.83
    79 possible 8.89
    80 possible 8.94
    81 possible 9.00
    82 not possible 9.06
    83 not possible 9.11
    84 not possible 9.17
    85 not possible 9.22
    86 not possible 9.27
    87 not possible 9.33
    88 not possible 9.38
    89 not possible 9.43
    90 not possible 9.49
    91 possible 9.54
    92 possible 9.59
    93 possible 9.64
    94 possible 9.70
    95 possible 9.75
    96 possible 9.80
    97 possible 9.85
    98 possible 9.90
    99 possible 9.95
    100 possible 10.00

    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Sat Mar 7 07:33:01 2026
    From Newsgroup: comp.lang.c

    On 07.03.26 04:14, DFS wrote:
    [...]

    For another view:

    Input   Sqr Matrix?    sqrt(Input)
    ----------------------------------
       1    possible        1.00
       2    not possible    1.41
       3    possible        1.73
       4    possible        2.00
       5    not possible    2.24
       6    not possible    2.45
       7    possible        2.65
       8    possible        2.83
       9    possible        3.00
      10    not possible    3.16
      11    not possible    3.32
      12    not possible    3.46
      13    possible        3.61
      14    possible        3.74
      15    possible        3.87
      16    possible        4.00
      17    not possible    4.12
      18    not possible    4.24
      19    not possible    4.36
      20    not possible    4.47
      21    possible        4.58
      22    possible        4.69
      23    possible        4.80
      24    possible        4.90
      25    possible        5.00
      26    not possible    5.10
      27    not possible    5.20
      28    not possible    5.29
      29    not possible    5.39
      30    not possible    5.48
      31    possible        5.57
      32    possible        5.66
      33    possible        5.74
      34    possible        5.83
      35    possible        5.92
      36    possible        6.00
      37    not possible    6.08
      38    not possible    6.16
      39    not possible    6.24
      40    not possible    6.32
      41    not possible    6.40
      42    not possible    6.48
      43    possible        6.56
      44    possible        6.63
      45    possible        6.71
      46    possible        6.78
      47    possible        6.86
      48    possible        6.93
      49    possible        7.00
      50    not possible    7.07
      51    not possible    7.14
      52    not possible    7.21
      53    not possible    7.28
      54    not possible    7.35
      55    not possible    7.42
      56    not possible    7.48
      57    possible        7.55
      58    possible        7.62
      59    possible        7.68
      60    possible        7.75
      61    possible        7.81
      62    possible        7.87
      63    possible        7.94
      64    possible        8.00
      65    not possible    8.06
      66    not possible    8.12
      67    not possible    8.19
      68    not possible    8.25
      69    not possible    8.31
      70    not possible    8.37
      71    not possible    8.43
      72    not possible    8.49
      73    possible        8.54
      74    possible        8.60
      75    possible        8.66
      76    possible        8.72
      77    possible        8.77
      78    possible        8.83
      79    possible        8.89
      80    possible        8.94
      81    possible        9.00
      82    not possible    9.06
      83    not possible    9.11
      84    not possible    9.17
      85    not possible    9.22
      86    not possible    9.27
      87    not possible    9.33
      88    not possible    9.38
      89    not possible    9.43
      90    not possible    9.49
      91    possible        9.54
      92    possible        9.59
      93    possible        9.64
      94    possible        9.70
      95    possible        9.75
      96    possible        9.80
      97    possible        9.85
      98    possible        9.90
      99    possible        9.95
     100    possible        10.00

    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.

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


    Janis

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Sat Mar 7 13:33:59 2026
    From Newsgroup: comp.lang.c

    On 07/03/2026 03:14, DFS wrote:
    On 3/6/2026 4:53 PM, Bart wrote:
    On 06/03/2026 17:11, DFS wrote:
    On 3/6/2026 11:02 AM, Bart wrote:

    I assume it works according to the spec, where I admit I don't fully
    understand the conditions. So input of '10 10 90' is fine (prints
    1-90 within 10x10 matrix) omits final column), but input of '90'
    fails, even though it's the same square matrix.


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

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

    Only a square matrix of 10x10 can contain 1-91.


    I still don't get it. Doesn't an input of '10 10 90' specify a square
    matrix? But it still prints the numbers 1-90:

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


    That's a 10x9 matrix.

    But the request is for a 10x10 matrix with a cut-off of 90.

    What's the difference between that, and a specifying only the cut-off of
    90, where the numbers need to be within a square matrix for the
    smallest square that can display 90 numbers? That would be 10x10 too.

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

    If I disable that restriction for my version that only does cut-offs
    within a square matrix, and show "-" where there is no output, then this output for N=4-7:

    input = 4
    1 3
    2 4

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

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

    input = 7
    1 4 7
    2 5
    3 6

    becomes instead:

    input = 4
    1 3
    2 4

    input = 5
    1 4 -
    2 5 -
    3 - -

    input = 6
    1 4 -
    2 5 -
    3 6 -

    input = 7
    1 4 7
    2 5 -
    3 6 -

    What exactly is the problem? That "input = 6" version (minus the hypens)
    is also what I get with Lew's program with inputs of "3 3 6". I asked
    for 3 columns, and got only two.


      89    not possible    9.43
      90    not possible    9.49
      91    possible        9.54


    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.


    I've looked, but can't see a pattern!

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Richard Harnden@[email protected] to comp.lang.c on Sat Mar 7 14:53:56 2026
    From Newsgroup: comp.lang.c

    On 07/03/2026 13:33, Bart wrote:
    On 07/03/2026 03:14, DFS wrote:
    On 3/6/2026 4:53 PM, Bart wrote:
    On 06/03/2026 17:11, DFS wrote:
    On 3/6/2026 11:02 AM, Bart wrote:

    I assume it works according to the spec, where I admit I don't
    fully understand the conditions. So input of '10 10 90' is fine
    (prints 1-90 within 10x10 matrix) omits final column), but input of >>>>> '90' fails, even though it's the same square matrix.


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

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

    Only a square matrix of 10x10 can contain 1-91.


    I still don't get it. Doesn't an input of '10 10 90' specify a square
    matrix? But it still prints the numbers 1-90:

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


    That's a 10x9 matrix.

    But the request is for a 10x10 matrix with a cut-off of 90.

    What's the difference between that, and a specifying only the cut-off of
    90, where the numbers need to be within a square matrix for the smallest square that can display 90 numbers? That would be 10x10 too.

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

    If I disable that restriction for my version that only does cut-offs
    within a square matrix, and show "-" where there is no output, then this output for N=4-7:

     input = 4
     1 3
     2 4

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

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

     input = 7
     1 4 7
     2 5
     3 6

    becomes instead:

     input = 4
     1 3
     2 4

     input = 5
     1 4 -
     2 5 -
     3 - -

     input = 6
     1 4 -
     2 5 -
     3 6 -

     input = 7
     1 4 7
     2 5 -
     3 6 -

    What exactly is the problem? That "input = 6" version (minus the hypens)
    is also what I get with Lew's program with inputs of "3 3 6". I asked
    for 3 columns, and got only two.


       89    not possible    9.43
       90    not possible    9.49
       91    possible        9.54


    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.


    I've looked, but can't see a pattern!


    All I can see is that it's possible for x.00 and >= x.50, and not
    possible for < x.50

    I don't know why. I could (easily) be completely wrong :)



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Sat Mar 7 10:22:04 2026
    From Newsgroup: comp.lang.c

    On 3/7/2026 8:33 AM, Bart wrote:
    On 07/03/2026 03:14, DFS wrote:
    On 3/6/2026 4:53 PM, Bart wrote:
    On 06/03/2026 17:11, DFS wrote:
    On 3/6/2026 11:02 AM, Bart wrote:

    I assume it works according to the spec, where I admit I don't
    fully understand the conditions. So input of '10 10 90' is fine
    (prints 1-90 within 10x10 matrix) omits final column), but input of >>>>> '90' fails, even though it's the same square matrix.


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

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

    Only a square matrix of 10x10 can contain 1-91.


    I still don't get it. Doesn't an input of '10 10 90' specify a square
    matrix? But it still prints the numbers 1-90:

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


    That's a 10x9 matrix.

    But the request is for a 10x10 matrix with a cut-off of 90.

    And that's what you got. But 90 stopped it from creating a 10x10
    matrix. There is no size matrix where rows = columns that consumes only
    1-90.


    What's the difference between that, and a specifying only the cut-off of
    90, where the numbers need to be within a square matrix for the smallest square that can display 90 numbers? That would be 10x10 too.

    The difference is you asked for a 10x10 matrix with a cutoff of 90.

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

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


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

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


    If I disable that restriction for my version that only does cut-offs
    within a square matrix, and show "-" where there is no output, then this output for N=4-7:

     input = 4
     1 3
     2 4

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

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

     input = 7
     1 4 7
     2 5
     3 6

    becomes instead:

     input = 4
     1 3
     2 4

     input = 5
     1 4 -
     2 5 -
     3 - -

     input = 6
     1 4 -
     2 5 -
     3 6 -

     input = 7
     1 4 7
     2 5 -
     3 6 -

    What exactly is the problem?


    They're entirely consistent.

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

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


    That "input = 6" version (minus the hypens)
    is also what I get with Lew's program with inputs of "3 3 6". I asked
    for 3 columns, and got only two.

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

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



       89    not possible    9.43
       90    not possible    9.49
       91    possible        9.54


    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.


    I've looked, but can't see a pattern!

    Look at the remainders of the square roots.

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






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


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

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


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


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

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

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

    //print nbr matrix
    for (int r = 1; r <= rows; r++) {
    if (r <= max) {
    int nbr = r;
    printf("%*d",colwidth,nbr);
    for (int i = 0; i < cols-1; i++) {
    nbr += rows;
    if (nbr <= max) {
    printf("%*d",colwidth,nbr);
    }
    }
    printf("\n");
    }
    else
    {
    break;
    }
    }


    }

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

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

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

    printf("\n");
    return 0;
    } ================================================================================
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Sat Mar 7 10:24:28 2026
    From Newsgroup: comp.lang.c

    On 3/7/2026 1:33 AM, Janis Papanagnou wrote:
    On 07.03.26 04:14, DFS wrote:

    <snip>


    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.

    I don't see what the sqrt value would demonstrate here.


    Look at the remainders of the square roots.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Sat Mar 7 15:44:33 2026
    From Newsgroup: comp.lang.c

    On 07/03/2026 14:53, Richard Harnden wrote:
    On 07/03/2026 13:33, Bart wrote:

       89    not possible    9.43
       90    not possible    9.49
       91    possible        9.54


    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.


    I've looked, but can't see a pattern!


    All I can see is that it's possible for x.00 and >= x.50, and not
    possible for < x.50

    I don't know why.  I could (easily) be completely wrong :)

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

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

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

    Then the formula is simple:

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

    That loop would be inefficient for large N, but traversing all values
    from 1 to N and converting each as a decimal would take longer.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Sat Mar 7 19:53:50 2026
    From Newsgroup: comp.lang.c

    On Sat, 7 Mar 2026 14:53:56 +0000
    Richard Harnden <[email protected]d> wrote:
    On 07/03/2026 13:33, Bart wrote:
    On 07/03/2026 03:14, DFS wrote:
    On 3/6/2026 4:53 PM, Bart wrote:
    On 06/03/2026 17:11, DFS wrote:
    On 3/6/2026 11:02 AM, Bart wrote:

    I assume it works according to the spec, where I admit I don't
    fully understand the conditions. So input of '10 10 90' is fine
    (prints 1-90 within 10x10 matrix) omits final column), but
    input of '90' fails, even though it's the same square matrix.


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

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

    Only a square matrix of 10x10 can contain 1-91.


    I still don't get it. Doesn't an input of '10 10 90' specify a
    square matrix? But it still prints the numbers 1-90:

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


    That's a 10x9 matrix.

    But the request is for a 10x10 matrix with a cut-off of 90.

    What's the difference between that, and a specifying only the
    cut-off of 90, where the numbers need to be within a square matrix
    for the smallest square that can display 90 numbers? That would be
    10x10 too.

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

    If I disable that restriction for my version that only does
    cut-offs within a square matrix, and show "-" where there is no
    output, then this output for N=4-7:

    �input = 4
    �1 3
    �2 4

    �input = 5
    �not possible to output 1-5 where rows=columns

    �input = 6
    �not possible to output 1-6 where rows=columns

    �input = 7
    �1 4 7
    �2 5
    �3 6

    becomes instead:

    �input = 4
    �1 3
    �2 4

    �input = 5
    �1 4 -
    �2 5 -
    �3 - -

    �input = 6
    �1 4 -
    �2 5 -
    �3 6 -

    �input = 7
    �1 4 7
    �2 5 -
    �3 6 -

    What exactly is the problem? That "input = 6" version (minus the
    hypens) is also what I get with Lew's program with inputs of "3 3
    6". I asked for 3 columns, and got only two.


    �� 89��� not possible��� 9.43
    �� 90��� not possible��� 9.49
    �� 91��� possible������� 9.54


    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.


    I've looked, but can't see a pattern!


    All I can see is that it's possible for x.00 and >= x.50, and not
    possible for < x.50

    I don't know why. I could (easily) be completely wrong :)



    It is not coincedence.
    For table of size n x n, the smallest possible max_val is n*(n-1)+1 =
    n*n - n + 1 = (n - 0.5)**2 + 0.75.
    Obbviosly, sqrt((n - 0.5)**2 + 0.75) > n-0.5
    OTOH, max_val-1 = (n - 0.5)**2 - 0.25, so sqrt(max_val-1) < n-0.5.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Sat Mar 7 19:16:08 2026
    From Newsgroup: comp.lang.c

    On 07.03.26 16:24, DFS wrote:
    On 3/7/2026 1:33 AM, Janis Papanagnou wrote:
    On 07.03.26 04:14, DFS wrote:

    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.

    I don't see what the sqrt value would demonstrate here.

    Look at the remainders of the square roots.

    I did of course. (Why would I have otherwise asked.)

    I don't see what the sqrt value would demonstrate here.

    Mind to explain what you meant?

    Janis

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Sat Mar 7 18:21:53 2026
    From Newsgroup: comp.lang.c

    On Fri, 06 Mar 2026 13:51:58 +0000, Lew Pitcher wrote:

    On Thu, 05 Mar 2026 20:31:39 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    OK, it's not pretty, but here it is

    No worries - being pretty is not on the list of requested properties. :)

    Congratulations on being the first to post an answer.

    Two problems related to how setjmp()/longjmp() are used:

    1. Any local variable changed between a setjmp() and the longjmp()
    that goes back to it must be declared 'volatile' to avoid problems
    with indeterminate values. (Minor.)

    2. A pattern like 'x = setjmp( jbuf );' is not one of the officially
    approved forms in the C standard for setjmp(). More specifically,
    any such usage has undefined behavior. (More serious.)

    If you look in the C standard for setjmp(), there is a subsection
    titled 'Environmental limits' that explains which forms are approved
    for use. Personally I think it's regrettable that 'x = setjmp( jbuf );'
    is not one of them, but I feel obliged to observe that limitation and
    follow what the standard prescribes for using setjmp().

    yah.

    As you can tell, I haven't used setjmp()/longjmp() much, and am
    unfamiliar with the caveats surrounding them.

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

    And, here it is

    /*
    ** From: DFS <[email protected]>
    ** 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$[email protected]>
    **
    ** Challenge is to output sequential numbers by column then row:
    ** Kind of goes without saying the solution should handle any row x column
    ** input:
    **
    ** input rows columns
    ** --------------------------------------------------------------------
    ** 1) must be able to cut the output off at any arbitrary value
    ** lower than rows x columns
    ** --------------------------------------------------------------------
    ** 2) if you don't specify rows and columns, your solution must try
    ** to calculate them to form a square (same # of rows and columns)
    ** that includes only 1 to N.
    **
    ** If rows=columns can't be calculated, return message 'not possible'
    ** --------------------------------------------------------------------
    **
    ** * Extra Credit if you determine a formula for this requirement. I kind
    ** of brute-forced it with 2 loops. As you can see, N = prime isn't
    ** enough to know if it can be done.
    ** -----------------------------------------------------------------------
    **
    ** From: Tim Rentsch <[email protected]>
    ** Newsgroups: comp.lang.c
    ** Subject: Re: Sort of trivial code challenge - may be interesting to you anyway
    ** Date: Mon, 02 Mar 2026 21:09:21 -0800
    ** Message-ID: <[email protected]>
    **
    ** The latest challenge, which I just got through doing, is to
    ** disallow if, for, while, goto, return, and to forbid functions
    ** and function calls except for calls to C standard library
    ** functions. Also no math library. :)
    **
    ** ========================================================================== **
    ** Tim Rentsch counter-counter-challenge; solution by Lew Pitcher 2026-03-05
    ** cc -o rowcol_TR2a -mtune=native -Wall -std=c99 -pedantic -w rowcol_TR2a.c
    **
    ** Note: -w to suppress warnings relating to using switch() to evaluate
    ** a boolean value
    **
    ** This code released into the public domain. Lew Pitcher, 2026-03-07
    */

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

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

    int main(int argc, char *argv[])
    {
    int status = EXIT_FAILURE,
    args_ok = 1;
    unsigned int n_rows = 0,
    n_cols = 0,
    cut_off = 0;

    switch (argc)
    {
    case 4: /* rowcol #rows #cols cutoff */
    {
    char *eptr;
    unsigned long int result;
    int valid;

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

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

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

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

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

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

    break;

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

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

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

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

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

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

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

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

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

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

    status = EXIT_SUCCESS;
    }
    break;

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

    exit(status);
    }
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Sat Mar 7 14:18:08 2026
    From Newsgroup: comp.lang.c

    On 3/7/2026 1:16 PM, Janis Papanagnou wrote:
    On 07.03.26 16:24, DFS wrote:
    On 3/7/2026 1:33 AM, Janis Papanagnou wrote:
    On 07.03.26 04:14, DFS wrote:

    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.

    I don't see what the sqrt value would demonstrate here.

    Look at the remainders of the square roots.

    I did of course. (Why would I have otherwise asked.)

    I don't see what the sqrt value would demonstrate here.

    Mind to explain what you meant?

    Janis


    The values of the remainders correspond 1:1 with the possibility of a
    square matrix.

    remainder between 0.01 and 0.50: square matrix not possible


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


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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Sat Mar 7 11:55:13 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    On Fri, 06 Mar 2026 13:51:58 +0000, Lew Pitcher wrote:

    [...]

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

    And, here it is
    [...]

    First of two responses

    1. I think your error checking is more thorough than what I did.
    I do check that inputs are well formed but it's possible that
    out of range values will give inappropriate results.

    2. I don't have any error return. I do diagnose various conditions
    (and in particular the no-square-possible cutoff values) but don't
    bother with status. It would be easy to add but I didn't do it. :)

    3. How setjmp() is used is still out of bounds. The rule for setjmp()
    in a switch() is the setjmp() must be the entire expression that is
    switched on. Effectively longjmp() can pass only constant values,
    because there is no way to do anything with the value except see if
    it is true or false (in an if()) or match it against 'case' labels.

    My code in the next followup.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Sat Mar 7 12:02:11 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

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

    Here we go...

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

    typedef size_t Z;
    typedef _Bool B;

    static Z k, h, w, c;
    static int d;
    static jmp_buf jb;

    #define GO(x) longjmp( jb, x )
    #define NUMBERISH(p) ((p) && *(p) && (p)[ strspn((p),"0123456789") ] == 0)

    enum {
    START, // the initial state; must be zero
    AFU, USAGE, // give suitable message and exit
    ROOT, DRAT, // find ceiling( sqrt( cutoff ) ); possible no joy exit
    HWC, // display H*W values with cutoff C
    FIN, // exit program
    };

    int
    main( int argc, char *argv[] ){
    switch( setjmp( jb ) ){
    case START: {
    B usage = argc < 2 || argc > 4;

    B g1 = argc > 1 && NUMBERISH( argv[1] );
    B g2 = argc > 2 && NUMBERISH( argv[2] );
    B g3 = argc > 3 && NUMBERISH( argv[3] );

    Z a1 = g1 ? strtoul( argv[1], 0, 10 ) : 0;
    Z a2 = g2 ? strtoul( argv[2], 0, 10 ) : 0;
    Z a3 = g3 ? strtoul( argv[3], 0, 10 ) : 0;

    B square = argc == 2 && g1;
    B hw = argc == 3 && g1&&g2 && a1&&a2;
    B hwc = argc == 4 && g1&&g2 && a1&&a2 && g3;

    k = 0;
    h = hw || hwc ? a1 : a1/4 + !a1; // note: initial value(h) > 0
    w = hw || hwc ? a2 : h;
    c = square ? a1 : !hwc ? h*w : a3 > h*w ? h*w : a3;
    d = snprintf( 0, 0, "%zu", c );

    GO( usage ?USAGE : square ?ROOT : (hw||hwc) && a1&&a2 ?HWC : AFU );
    }

    case AFU:
    printf( " urk... bad arguments\n" );
    GO( USAGE );

    case USAGE:
    printf( " usage:\n" );
    printf( " %s cutoff {{for square}}\n", argv[0] );
    printf( " %s rows columns [cutoff]\n", argv[0] );
    GO( FIN );

    case ROOT: {
    h = c < 2 ? 1 : c < 5 ? 2 : (h + c/h) / 2;
    h += h*h < c;
    w = h;
    B done = c < 2 || h*h < c+2*h && c <= h*h;
    B good = c < 2 || h*h < c+h && c <= h*h;
    GO( !done ?ROOT : good ?HWC : DRAT );
    }

    case DRAT:
    printf( " square with cutoff %zu - no joy\n", c );
    GO( FIN );

    case HWC: {
    B eol = k/h + 1 == w;
    B end = k+1 + (h>c ? h-c : 0) >= h*w;
    Z nextk = eol ? k - (w-1)*h + 1 : k+h;

    printf( k < c ? " %*zu" : "", d, k+1 );
    printf( c > 0 && eol ? "\n" : "" );

    GO( end ?(printf( "------\n" ), FIN) : (k = nextk, HWC) );
    }
    }
    }
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Sat Mar 7 22:04:46 2026
    From Newsgroup: comp.lang.c

    On Fri, 6 Mar 2026 00:18:43 +0100
    Janis Papanagnou <[email protected]> wrote:

    On 05.03.26 22:12, Lew Pitcher wrote:
    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:
    [...]

    But, I now need to find a replacement for sqrt() that doesn't take
    a lot of space. Back to first principles for me, then.

    The roguelike game Nethack that historically deliberately didn't
    use any floating point had this code (most is just comments):

    /* integer square root function without using floating point */
    int
    isqrt(val)
    int val;
    {
    int rt = 0;
    int odd = 1;
    /*
    * This could be replaced by a faster algorithm, but has not
    been because:
    * + the simple algorithm is easy to read;
    * + this algorithm does not require 64-bit support;
    * + in current usage, the values passed to isqrt() are not
    really that
    * large, so the performance difference is negligible;
    * + isqrt() is used in only few places, which are not
    bottle-necks. */
    while (val >= odd) {
    val = val - odd;
    odd = odd + 2;
    rt = rt + 1;
    }
    return rt;
    }


    Janis


    That code is O(sqrt(val)). Good enough in this particular case, because
    main print loop is much slower than that at O(val), but I find it non-satisfactory.

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

    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned y = x/2, r;
    while ((r = x / y) < y)
    y = (r + y) / 2;
    return y;
    }

    And here is variation that is a little less simple, but not complicated
    and faster than one before, because it does fewer divisions.
    The number of divisions that can't be implemented as shift is at most ceil(sqrt(ceil(log2(ceil(sqrt(val)))

    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned y = 8, xx = x;
    while (xx > 63) {
    xx /= 64;
    y *= 8;
    }
    unsigned r;
    while ((r = x / y) < y)
    y = (r + y) / 2;
    return y;
    }

    And here is less simple but still obvious implementation that does no
    divisions at all. No multiplications as well.

    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned xx = x;
    int e = 0;
    while (xx > 63) {
    xx /= 64;
    e += 3;
    }
    while (xx > 3) {
    xx /= 4;
    e += 1;
    }
    unsigned y = 1u << e;
    x -= y << e;
    for (e = e - 1; e >= 0; --e) {
    unsigned d = y*2 + (1u << e);
    if (d <= (x >> e)) {
    x -= d << e;
    y += 1u << e;
    }
    }
    return y;
    }










    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Sat Mar 7 20:10:09 2026
    From Newsgroup: comp.lang.c

    On Sat, 07 Mar 2026 11:55:13 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    On Fri, 06 Mar 2026 13:51:58 +0000, Lew Pitcher wrote:

    [...]

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

    And, here it is
    [...]

    First of two responses

    1. I think your error checking is more thorough than what I did.
    I do check that inputs are well formed but it's possible that
    out of range values will give inappropriate results.

    2. I don't have any error return. I do diagnose various conditions
    (and in particular the no-square-possible cutoff values) but don't
    bother with status. It would be easy to add but I didn't do it. :)

    3. How setjmp() is used is still out of bounds. The rule for setjmp()
    in a switch() is the setjmp() must be the entire expression that is
    switched on. Effectively longjmp() can pass only constant values,
    because there is no way to do anything with the value except see if
    it is true or false (in an if()) or match it against 'case' labels.

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

    Corrected version follows

    /*
    ** From: DFS <[email protected]>
    ** 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$[email protected]>
    **
    ** Challenge is to output sequential numbers by column then row:
    ** Kind of goes without saying the solution should handle any row x column
    ** input:
    **
    ** input rows columns
    ** --------------------------------------------------------------------
    ** 1) must be able to cut the output off at any arbitrary value
    ** lower than rows x columns
    ** --------------------------------------------------------------------
    ** 2) if you don't specify rows and columns, your solution must try
    ** to calculate them to form a square (same # of rows and columns)
    ** that includes only 1 to N.
    **
    ** If rows=columns can't be calculated, return message 'not possible'
    ** --------------------------------------------------------------------
    **
    ** * Extra Credit if you determine a formula for this requirement. I kind
    ** of brute-forced it with 2 loops. As you can see, N = prime isn't
    ** enough to know if it can be done.
    ** -----------------------------------------------------------------------
    **
    ** From: Tim Rentsch <[email protected]>
    ** Newsgroups: comp.lang.c
    ** Subject: Re: Sort of trivial code challenge - may be interesting to you anyway
    ** Date: Mon, 02 Mar 2026 21:09:21 -0800
    ** Message-ID: <[email protected]>
    **
    ** The latest challenge, which I just got through doing, is to
    ** disallow if, for, while, goto, return, and to forbid functions
    ** and function calls except for calls to C standard library
    ** functions. Also no math library. :)
    **
    ** ========================================================================== **
    ** Tim Rentsch counter-counter-challenge; solution by Lew Pitcher 2026-03-05
    ** cc -o rowcol_TR2a -mtune=native -Wall -std=c99 -pedantic -w rowcol_TR2a.c
    **
    ** Note: -w to suppress warnings relating to using switch() to evaluate
    ** a boolean value
    **
    ** This code released into the public domain. Lew Pitcher, 2026-03-07
    */

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

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

    int main(int argc, char *argv[])
    {
    int status = EXIT_FAILURE,
    args_ok = 1;
    unsigned int n_rows = 0,
    n_cols = 0,
    cut_off = 0;

    switch (argc)
    {
    case 4: /* rowcol #rows #cols cutoff */
    {
    char *eptr;
    unsigned long int result;
    int valid;

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

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

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

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

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

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

    break;

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

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

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

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

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

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

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

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

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

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

    status = EXIT_SUCCESS;
    }
    break;

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

    exit(status);
    }




    My code in the next followup.
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Sat Mar 7 20:14:15 2026
    From Newsgroup: comp.lang.c

    On Sat, 07 Mar 2026 12:02:11 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

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

    Here we go...
    [snip]

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

    Thank you, I've learned something new today.
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Sat Mar 7 16:58:48 2026
    From Newsgroup: comp.lang.c

    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    Lew Pitcher <[email protected]> writes:

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

    Here we go...


    OMG! Congrats on an innovative piece of C code. Never seen anything
    like it.

    I don't understand everything yet, but nested ternaries aside, it's
    pretty easy to follow too.

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

    "not mentioning main() was an oversight on my part.
    (Still not okay to call it.)"

    I saw David Brown offered about 5 ways to bypass main().


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

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

    For instance:

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

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




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

    typedef size_t Z;
    typedef _Bool B;

    static Z k, h, w, c;
    static int d;
    static jmp_buf jb;

    #define GO(x) longjmp( jb, x )
    #define NUMBERISH(p) ((p) && *(p) && (p)[ strspn((p),"0123456789") ] == 0)

    enum {
    START, // the initial state; must be zero
    AFU, USAGE, // give suitable message and exit
    ROOT, DRAT, // find ceiling( sqrt( cutoff ) ); possible no joy exit
    HWC, // display H*W values with cutoff C
    FIN, // exit program
    };

    int
    main( int argc, char *argv[] ){
    switch( setjmp( jb ) ){
    case START: {
    B usage = argc < 2 || argc > 4;

    B g1 = argc > 1 && NUMBERISH( argv[1] );
    B g2 = argc > 2 && NUMBERISH( argv[2] );
    B g3 = argc > 3 && NUMBERISH( argv[3] );

    Z a1 = g1 ? strtoul( argv[1], 0, 10 ) : 0;
    Z a2 = g2 ? strtoul( argv[2], 0, 10 ) : 0;
    Z a3 = g3 ? strtoul( argv[3], 0, 10 ) : 0;

    B square = argc == 2 && g1;
    B hw = argc == 3 && g1&&g2 && a1&&a2;
    B hwc = argc == 4 && g1&&g2 && a1&&a2 && g3;

    k = 0;
    h = hw || hwc ? a1 : a1/4 + !a1; // note: initial value(h) > 0
    w = hw || hwc ? a2 : h;
    c = square ? a1 : !hwc ? h*w : a3 > h*w ? h*w : a3;
    d = snprintf( 0, 0, "%zu", c );

    GO( usage ?USAGE : square ?ROOT : (hw||hwc) && a1&&a2 ?HWC : AFU );
    }

    case AFU:
    printf( " urk... bad arguments\n" );
    GO( USAGE );

    case USAGE:
    printf( " usage:\n" );
    printf( " %s cutoff {{for square}}\n", argv[0] );
    printf( " %s rows columns [cutoff]\n", argv[0] );
    GO( FIN );

    case ROOT: {
    h = c < 2 ? 1 : c < 5 ? 2 : (h + c/h) / 2;
    h += h*h < c;
    w = h;
    B done = c < 2 || h*h < c+2*h && c <= h*h;
    B good = c < 2 || h*h < c+h && c <= h*h;
    GO( !done ?ROOT : good ?HWC : DRAT );
    }

    case DRAT:
    printf( " square with cutoff %zu - no joy\n", c );
    GO( FIN );

    case HWC: {
    B eol = k/h + 1 == w;
    B end = k+1 + (h>c ? h-c : 0) >= h*w;
    Z nextk = eol ? k - (w-1)*h + 1 : k+h;

    printf( k < c ? " %*zu" : "", d, k+1 );
    printf( c > 0 && eol ? "\n" : "" );

    GO( end ?(printf( "------\n" ), FIN) : (k = nextk, HWC) );
    }
    }
    }


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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Sun Mar 8 00:35:57 2026
    From Newsgroup: comp.lang.c

    On Sat, 7 Mar 2026 16:58:48 -0500
    DFS <[email protected]> wrote:


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


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


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Sun Mar 8 00:26:15 2026
    From Newsgroup: comp.lang.c

    On 07.03.26 21:04, Michael S wrote:
    On Fri, 6 Mar 2026 00:18:43 +0100
    Janis Papanagnou <[email protected]> wrote:

    On 05.03.26 22:12, Lew Pitcher wrote:
    On Thu, 05 Mar 2026 19:09:37 +0000, Lew Pitcher wrote:
    [...]

    But, I now need to find a replacement for sqrt() that doesn't take
    a lot of space. Back to first principles for me, then.

    The roguelike game Nethack that historically deliberately didn't
    use any floating point had this code (most is just comments):

    /* integer square root function without using floating point */
    int
    isqrt(val)
    int val;
    {
    int rt = 0;
    int odd = 1;
    /*
    * This could be replaced by a faster algorithm, but has not
    been because:
    * + the simple algorithm is easy to read;
    * + this algorithm does not require 64-bit support;
    * + in current usage, the values passed to isqrt() are not
    really that
    * large, so the performance difference is negligible;
    * + isqrt() is used in only few places, which are not
    bottle-necks. */
    while (val >= odd) {
    val = val - odd;
    odd = odd + 2;
    rt = rt + 1;
    }
    return rt;
    }


    Janis


    That code is O(sqrt(val)). Good enough in this particular case, because
    main print loop is much slower than that at O(val), but I find it non-satisfactory.

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


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

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

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

    I'm a bit astonished by the last variants, though, with its constants
    (63 and 64); this is something that looks like a variant specifically
    tailored to some system architecture. But okay, I see that you might
    want to "cluster" the arithmetics.

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

    Janis


    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned y = x/2, r;
    while ((r = x / y) < y)
    y = (r + y) / 2;
    return y;
    }

    And here is variation that is a little less simple, but not complicated
    and faster than one before, because it does fewer divisions.
    The number of divisions that can't be implemented as shift is at most ceil(sqrt(ceil(log2(ceil(sqrt(val)))

    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned y = 8, xx = x;
    while (xx > 63) {
    xx /= 64;
    y *= 8;
    }
    unsigned r;
    while ((r = x / y) < y)
    y = (r + y) / 2;
    return y;
    }

    And here is less simple but still obvious implementation that does no divisions at all. No multiplications as well.

    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned xx = x;
    int e = 0;
    while (xx > 63) {
    xx /= 64;
    e += 3;
    }
    while (xx > 3) {
    xx /= 4;
    e += 1;
    }
    unsigned y = 1u << e;
    x -= y << e;
    for (e = e - 1; e >= 0; --e) {
    unsigned d = y*2 + (1u << e);
    if (d <= (x >> e)) {
    x -= d << e;
    y += 1u << e;
    }
    }
    return y;
    }











    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Sun Mar 8 00:40:14 2026
    From Newsgroup: comp.lang.c

    On 07.03.26 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    [...]

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

    From my experiences in a couple such departments of professional
    software development...

    The "uniqueness" would not be a problem. It would have failed to
    many requirements that maintainable code was expected to have.

    I can explain the (positive) excitement only by some nerdy stance
    in this specific CLC domain.

    Janis

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Sun Mar 8 00:47:55 2026
    From Newsgroup: comp.lang.c

    On 07.03.26 20:18, DFS wrote:
    On 3/7/2026 1:16 PM, Janis Papanagnou wrote:
    On 07.03.26 16:24, DFS wrote:
    On 3/7/2026 1:33 AM, Janis Papanagnou wrote:
    On 07.03.26 04:14, DFS wrote:

    Look at the square roots, and you'll see a pattern that determines
    whether the square matrix is possible or not.

    I don't see what the sqrt value would demonstrate here.

    Look at the remainders of the square roots.

    I did of course. (Why would I have otherwise asked.)

    I don't see what the sqrt value would demonstrate here.

    Mind to explain what you meant?

    The values of the remainders correspond 1:1 with the possibility of a
    square matrix.

    remainder between 0.01 and 0.50: square matrix not possible [...]

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

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

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

    Janis

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Sat Mar 7 16:43:31 2026
    From Newsgroup: comp.lang.c

    Tim Rentsch <[email protected]> writes:
    [...]
    typedef size_t Z;
    typedef _Bool B;
    [...]

    Why do you do this? I find that it makes the code more difficult to
    read.
    --
    Keith Thompson (The_Other_Keith) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Sun Mar 8 03:45:33 2026
    From Newsgroup: comp.lang.c

    On Sun, 8 Mar 2026 00:26:15 +0100
    Janis Papanagnou <[email protected]> wrote:


    I'm a bit astonished by the last variants, though, with its constants
    (63 and 64); this is something that looks like a variant specifically tailored to some system architecture. But okay, I see that you might
    want to "cluster" the arithmetics.


    Quite opposite to what you say - in the spirit of comp.lang.c this
    part of code uses most generic of relatively fast methods of
    calculation of non-precise value of floor(log2(x)/2) when expected
    result is in range [0:15].
    The expected range is [0:15] because 32 bits is the most popular size
    of 'unsigned' type.
    Using bigger threshold number (4**4-1==255) will on average increase
    a # of more expensive iterations in the next loop.
    Using smaller number (15 or 3) will increase # of iteration in this
    loop.

    If it was tailored I'd avoid this loop completely and instead will use
    language extension, like __bultin_clz() on gcc and compatible or _BitScanReverse() on MSVC and compatible

    C23 has standard way to express it - stdc_leading_zeros(). But C23 is
    not yet accepted as de-facto C Standard of comp.lang.c and rightfully
    so.


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From David Brown@[email protected] to comp.lang.c on Sun Mar 8 12:22:18 2026
    From Newsgroup: comp.lang.c

    On 07/03/2026 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    Lew Pitcher <[email protected]> writes:

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

    Here we go...


    OMG!  Congrats on an innovative piece of C code.  Never seen anything
    like it.

    I don't understand everything yet, but nested ternaries aside, it's
    pretty easy to follow too.

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

    "not mentioning main() was an oversight on my part.
    (Still not okay to call it.)"

    I saw David Brown offered about 5 ways to bypass main().


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

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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Sun Mar 8 10:42:34 2026
    From Newsgroup: comp.lang.c

    On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
    On 07.03.26 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    [...]

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

    From my experiences in a couple such departments of professional
    software development...

    The "uniqueness" would not be a problem. It would have failed to
    many requirements that maintainable code was expected to have.

    I figured as much.


    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of indented if-then-elses.

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





    I can explain the (positive) excitement only by some nerdy stance
    in this specific CLC domain.


    Give the man his due. It's extremely unique and excitement-worthy.

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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Sun Mar 8 15:18:30 2026
    From Newsgroup: comp.lang.c

    On 08/03/2026 14:42, DFS wrote:
    On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
    On 07.03.26 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    [...]

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

    From my experiences in a couple such departments of professional
    software development...

    The "uniqueness" would not be a problem. It would have failed to
    many requirements that maintainable code was expected to have.

    I figured as much.


    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of indented if-then-elses.

    TR doesn't like parentheses around ?: terms; everyone is expected to
    know their precedence.

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


    I can explain the (positive) excitement only by some nerdy stance
    in this specific CLC domain.


    Give the man his due.  It's extremely unique and excitement-worthy.

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

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


    Funny though how TR castigated me for not offering a C solution, but his solution is one I would not class as C code, as it only uses a subset of
    the language and in a weird manner (a bit like some of my generated C
    which is not meant to be human-readable).

    My script code is however trivially convertible to C (which I later
    posted) or to any other language. While his C solution is much harder to
    port as it is; it would need rewriting, once you can figure out how it
    works.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Lew Pitcher@[email protected] to comp.lang.c on Sun Mar 8 16:00:34 2026
    From Newsgroup: comp.lang.c

    On Sun, 08 Mar 2026 10:42:34 -0400, DFS wrote:
    [snip]

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

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

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


    Just my $0.02 worth.
    --
    Lew Pitcher
    "In Skills We Trust"
    Not LLM output - I'm just like this.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Sun Mar 8 17:05:03 2026
    From Newsgroup: comp.lang.c

    On 08.03.26 01:45, Michael S wrote:
    On Sun, 8 Mar 2026 00:26:15 +0100
    Janis Papanagnou <[email protected]> wrote:


    I'm a bit astonished by the last variants, though, with its constants
    (63 and 64); this is something that looks like a variant specifically
    tailored to some system architecture. But okay, I see that you might
    want to "cluster" the arithmetics.


    Quite opposite to what you say

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

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

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

    - in the spirit of comp.lang.c this
    part of code uses most generic of relatively fast methods of
    calculation of non-precise value of floor(log2(x)/2) when expected
    result is in range [0:15].
    The expected range is [0:15] because 32 bits is the most popular size
    of 'unsigned' type.
    Using bigger threshold number (4**4-1==255) will on average increase
    a # of more expensive iterations in the next loop.
    Using smaller number (15 or 3) will increase # of iteration in this
    loop.

    If it was tailored I'd avoid this loop completely and instead will use language extension, like __bultin_clz() on gcc and compatible or _BitScanReverse() on MSVC and compatible

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

    Janis


    C23 has standard way to express it - stdc_leading_zeros(). But C23 is
    not yet accepted as de-facto C Standard of comp.lang.c and rightfully
    so.



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Sun Mar 8 12:21:55 2026
    From Newsgroup: comp.lang.c

    On 3/8/2026 11:18 AM, Bart wrote:


    In the languages I create,

    plural?

    It's very impressive that you developed your own working language. Is
    the BartScript interpreter written in C? Can you post it?


    The reference Python implementation is written in C. https://github.com/python/cpython



    Funny though how TR castigated me for not offering a C solution,
    but his solution is one I would not class as C code,

    It is. It compiled with gcc, and uses C library functions.



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

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


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Sun Mar 8 17:36:32 2026
    From Newsgroup: comp.lang.c

    On 08.03.26 15:42, DFS wrote:
    On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
    On 07.03.26 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    [...]

    What do you think would be the reaction in a corporate programming
    dept to this unique kind of code?
    [...]
    The "uniqueness" would not be a problem. It would have failed to
    many requirements that maintainable code was expected to have.

    I figured as much.

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


    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of indented if-then-elses.

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

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


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

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

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


    I can explain the (positive) excitement only by some nerdy stance
    in this specific CLC domain.

    Give the man his due.  It's extremely unique and excitement-worthy.

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


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

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

    Janis


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


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Sun Mar 8 17:57:47 2026
    From Newsgroup: comp.lang.c

    On 08.03.26 16:18, Bart wrote:
    On 08/03/2026 14:42, DFS wrote:

    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of indented
    if-then-elses.

    TR doesn't like parentheses around ?: terms; everyone is expected to
    know their precedence.

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

    Janis

    [...]

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Sun Mar 8 19:29:52 2026
    From Newsgroup: comp.lang.c

    On 08/03/2026 16:21, DFS wrote:
    On 3/8/2026 11:18 AM, Bart wrote:


    In the languages I create,

    plural?

    It's very impressive that you developed your own working language.  Is
    the BartScript interpreter written in C?  Can you post it?

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

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


    The reference Python implementation is written in C. https://github.com/python/cpython



    Funny though how TR castigated me for not offering a C solution,
    but his solution is one I would not class as C code,

    It is.  It compiled with gcc, and uses C library functions.

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

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

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

    IOCCC entries offer more examples.

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

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

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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Sun Mar 8 13:19:21 2026
    From Newsgroup: comp.lang.c

    Bart <[email protected]> writes:
    [...]
    Funny though how TR castigated me for not offering a C solution, but
    his solution is one I would not class as C code, as it only uses a
    subset of the language and in a weird manner (a bit like some of my
    generated C which is not meant to be human-readable).
    [...]

    Nonsense. Of course Tim's code was C code. It compiles without
    error with a conforming C compiler, and does not depend on any
    extensions. Practically all C programs only use a subset of the
    language.

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

    Your code, on the other hand, was not written in C at all.
    --
    Keith Thompson (The_Other_Keith) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Sun Mar 8 13:27:23 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:
    [...]
    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of indented if-then-elses.

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

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

    or even:

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

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

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

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

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

    For certain values of "beauty".

    [...]
    --
    Keith Thompson (The_Other_Keith) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Sun Mar 8 21:42:36 2026
    From Newsgroup: comp.lang.c

    Bart <[email protected]> writes:
    On 08/03/2026 14:42, DFS wrote:
    On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
    On 07.03.26 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    [...]

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

    From my experiences in a couple such departments of professional
    software development...

    The "uniqueness" would not be a problem. It would have failed to
    many requirements that maintainable code was expected to have.

    I figured as much.


    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of indented
    if-then-elses.

    TR doesn't like parentheses around ?: terms; everyone is expected to
    know their precedence.

    Most coding standards, IIRC, specify that explicit groupings
    should be used, so any future code reader would know what
    the programmer intended.

    Google AI agrees:

    Safety and Intent: Parentheses explicitly define the intended order of operations,
    ensuring the code behaves as expected regardless of the specific
    language's precedence rules.

    Readability and Maintenance: Code is written for humans to read. Extra parenthess
    make complex expressions easier to understand, reducing the "cognitive load" needed
    to calculate the precedence mentally.

    Preventing Errors: Using parentheses prevents bugs when expressions are modified
    later by other developers who may not be fully aware of the default order of operations.

    Compiler/Standard Limitations: Some, albeit rare, languages or strict
    standards (like MISRA C:2023 or the Pony language) require explicit
    parentheses to eliminate ambiguity entirely.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.lang.c on Sun Mar 8 15:58:56 2026
    From Newsgroup: comp.lang.c

    On 3/8/2026 2:42 PM, Scott Lurndal wrote:
    Bart <[email protected]> writes:
    On 08/03/2026 14:42, DFS wrote:
    On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
    On 07.03.26 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    [...]

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

    From my experiences in a couple such departments of professional
    software development...

    The "uniqueness" would not be a problem. It would have failed to
    many requirements that maintainable code was expected to have.

    I figured as much.


    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of indented
    if-then-elses.

    TR doesn't like parentheses around ?: terms; everyone is expected to
    know their precedence.

    Most coding standards, IIRC, specify that explicit groupings
    should be used, so any future code reader would know what
    the programmer intended.

    Google AI agrees:

    Safety and Intent: Parentheses explicitly define the intended order of operations,
    ensuring the code behaves as expected regardless of the specific
    language's precedence rules.

    Readability and Maintenance: Code is written for humans to read. Extra parenthess
    make complex expressions easier to understand, reducing the "cognitive load" needed
    to calculate the precedence mentally.

    Preventing Errors: Using parentheses prevents bugs when expressions are modified
    later by other developers who may not be fully aware of the default order of operations.

    Compiler/Standard Limitations: Some, albeit rare, languages or strict
    standards (like MISRA C:2023 or the Pony language) require explicit
    parentheses to eliminate ambiguity entirely.


    (x * y) + z

    Well, its, ivho its "better" to have the parenthesis in there...
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Mon Mar 9 01:12:02 2026
    From Newsgroup: comp.lang.c

    On 08/03/2026 20:19, Keith Thompson wrote:
    Bart <[email protected]> writes:
    [...]
    Funny though how TR castigated me for not offering a C solution, but
    his solution is one I would not class as C code, as it only uses a
    subset of the language and in a weird manner (a bit like some of my
    generated C which is not meant to be human-readable).
    [...]

    Nonsense. Of course Tim's code was C code. It compiles without
    error with a conforming C compiler, and does not depend on any
    extensions. Practically all C programs only use a subset of the
    language.

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

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

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

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

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

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

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

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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From David Brown@[email protected] to comp.lang.c on Mon Mar 9 08:09:41 2026
    From Newsgroup: comp.lang.c

    On 08/03/2026 23:58, Chris M. Thomasson wrote:
    On 3/8/2026 2:42 PM, Scott Lurndal wrote:
    Bart <[email protected]> writes:
    On 08/03/2026 14:42, DFS wrote:
    On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
    On 07.03.26 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    [...]

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

     From my experiences in a couple such departments of professional
    software development...

    The "uniqueness" would not be a problem. It would have failed to
    many requirements that maintainable code was expected to have.

    I figured as much.


    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of indented
    if-then-elses.

    TR doesn't like parentheses around ?: terms; everyone is expected to
    know their precedence.

    Most coding standards, IIRC, specify that explicit groupings
    should be used, so any future code reader would know what
    the programmer intended.

    Google AI agrees:

        Safety and Intent: Parentheses explicitly define the intended
    order of operations,
                           ensuring the code behaves as expected
    regardless of the specific
                           language's precedence rules.

        Readability and Maintenance: Code is written for humans to read.
    Extra parenthess
          make complex expressions easier to understand, reducing the
    "cognitive load" needed
          to calculate the precedence mentally.

        Preventing Errors: Using parentheses prevents bugs when
    expressions are modified
          later by other developers who may not be fully aware of the
    default order of operations.

        Compiler/Standard Limitations: Some, albeit rare, languages or strict >>       standards (like MISRA C:2023 or the Pony language) require explicit
          parentheses to eliminate ambiguity entirely.


    (x * y) + z

    Well, its, ivho its "better" to have the parenthesis in there...

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

    Where you put the requirements in a coding standard can depend on many factors. Are you aiming for code that is easily understood even by
    relatively new C programmers, or do you expect only experts to be
    dealing with the code? Are you writing code that can be used with a
    wide variety of compilers (some of which may be buggy, or generate poor quality code, especially in complex situations) ? What are the
    consequences of misunderstandings of the code? (You have different
    rules for aircraft engine control systems and a computer game.)

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

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

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Janis Papanagnou@[email protected] to comp.lang.c on Mon Mar 9 08:53:17 2026
    From Newsgroup: comp.lang.c

    On 09.03.26 08:09, David Brown wrote:

    Where you put the requirements in a coding standard can depend on many factors.  Are you aiming for code that is easily understood even by relatively new C programmers, or do you expect only experts to be
    dealing with the code? [...]

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

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

    Janis

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.lang.c on Mon Mar 9 15:25:19 2026
    From Newsgroup: comp.lang.c

    On 3/9/2026 12:09 AM, David Brown wrote:
    On 08/03/2026 23:58, Chris M. Thomasson wrote:
    On 3/8/2026 2:42 PM, Scott Lurndal wrote:
    Bart <[email protected]> writes:
    On 08/03/2026 14:42, DFS wrote:
    On 3/7/2026 6:40 PM, Janis Papanagnou wrote:
    On 07.03.26 22:58, DFS wrote:
    On 3/7/2026 3:02 PM, Tim Rentsch wrote:
    [...]

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

     From my experiences in a couple such departments of professional >>>>>> software development...

    The "uniqueness" would not be a problem. It would have failed to
    many requirements that maintainable code was expected to have.

    I figured as much.


    Nested ternaries like this:

        c = square ? a1  :  !hwc ? h*w  :  a3 > h*w ? h*w  :  a3; >>>>>
    are harder to decipher at first glance than 3 or 4 levels of indented >>>>> if-then-elses.

    TR doesn't like parentheses around ?: terms; everyone is expected to
    know their precedence.

    Most coding standards, IIRC, specify that explicit groupings
    should be used, so any future code reader would know what
    the programmer intended.

    Google AI agrees:

        Safety and Intent: Parentheses explicitly define the intended
    order of operations,
                           ensuring the code behaves as expected
    regardless of the specific
                           language's precedence rules. >>>
        Readability and Maintenance: Code is written for humans to read. >>> Extra parenthess
          make complex expressions easier to understand, reducing the
    "cognitive load" needed
          to calculate the precedence mentally.

        Preventing Errors: Using parentheses prevents bugs when
    expressions are modified
          later by other developers who may not be fully aware of the
    default order of operations.

        Compiler/Standard Limitations: Some, albeit rare, languages or
    strict
          standards (like MISRA C:2023 or the Pony language) require
    explicit
          parentheses to eliminate ambiguity entirely.


    (x * y) + z

    Well, its, ivho its "better" to have the parenthesis in there...

    You need to find the right balance when deciding when parentheses are appropriate.

    Well, agreed for sure. x * y + z is, or should be easy to any
    "qualified" person to know about the precedence. But, I have seen some
    errors long time ago with somebody going:

    x * y + addend * z

    Well, they really wanted:

    (x * y + addend) * z

    ((x * y) + addend) * z

    ;^)

    So, it depends in a sense.


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

    I tend to shy away from the ? operator. If I do use it I make sure to
    add parentheses on all sides. ((condition) ? (true) : (false))


    Where you put the requirements in a coding standard can depend on many factors.  Are you aiming for code that is easily understood even by relatively new C programmers, or do you expect only experts to be
    dealing with the code?

    Say that expectation of "expert" can be "relative", what is an expert?
    Say expert in certain areas, not so much in others?



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

    Well, a little bug in a game can give it some spice, in a strange sense.
    A bug in an steering system, well it will make you taste kung pao
    scallops as you drive right off the road...



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

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



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Mon Mar 9 21:20:21 2026
    From Newsgroup: comp.lang.c

    On 3/8/2026 3:29 PM, Bart wrote:

    note that setjmp/longjmp are not functions


    huh?

    https://man7.org/linux/man-pages/man3/longjmp.3.html

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Mon Mar 9 22:18:41 2026
    From Newsgroup: comp.lang.c

    On 3/7/2026 6:47 PM, Janis Papanagnou wrote:
    On 07.03.26 20:18, DFS wrote:


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

    It's easier to see, but that glaring pattern, where groups of 'possible' alternate with growing same-size groups of 'not possible', is by itself
    nearly useless for determining if 1-N fits in a square matrix, whereas
    the remainders of the square root tell you immediately.

    remainder between 0.01 and 0.50 = square matrix not possible


    Input Sqr Matrix? sqrt(Input)
    ----------------------------------
    1 possible 1.00
    2 not possible 1.41
    3 possible 1.73
    4 possible 2.00
    5 not possible 2.24
    6 not possible 2.45
    7 possible 2.65
    8 possible 2.83
    9 possible 3.00
    10 not possible 3.16
    11 not possible 3.32
    12 not possible 3.46
    13 possible 3.61
    14 possible 3.74
    15 possible 3.87
    16 possible 4.00
    17 not possible 4.12
    18 not possible 4.24
    19 not possible 4.36
    20 not possible 4.47
    21 possible 4.58
    22 possible 4.69
    23 possible 4.80
    24 possible 4.90
    25 possible 5.00
    26 not possible 5.10
    27 not possible 5.20
    28 not possible 5.29
    29 not possible 5.39
    30 not possible 5.48


    In all the posting I didn't see whether anyone came up with a formula
    just using the Input nbr. I think maybe Lew Pitcher or Bart did.

    There's probably a simple formula in Rentsch's brainfsck-code, but it
    would take some work to decipher it.


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

    I may post a question to sci.math and see if anyone is interested.
    Don't know if this kind of thing fits into the topic of sequences?

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Richard Harnden@[email protected] to comp.lang.c on Tue Mar 10 10:14:21 2026
    From Newsgroup: comp.lang.c

    On 10/03/2026 02:18, DFS wrote:
    In all the posting I didn't see whether anyone came up with a formula
    just using the Input nbr.  I think maybe Lew Pitcher or Bart did.

    Avoids sqrt and fmod ...

    int is_possible(int n)
    {
    int side=1;
    int min, max;

    while (side < 100)
    {
    max = side * side;
    min = max - side + 1;

    if ( n >= min && n <= max )
    return 1;

    if ( max > n )
    break;

    side++;
    }

    return 0;
    }

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Tue Mar 10 14:43:28 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:
    On 3/8/2026 3:29 PM, Bart wrote:

    note that setjmp/longjmp are not functions


    huh?

    https://man7.org/linux/man-pages/man3/longjmp.3.html

    POSIX allows setjmp to be defined as a macro.

    https://pubs.opengroup.org/onlinepubs/9799919799/functions/setjmp.html

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.lang.c on Tue Mar 10 18:08:31 2026
    From Newsgroup: comp.lang.c

    On Tue, 10 Mar 2026 14:43:28 GMT
    [email protected] (Scott Lurndal) wrote:

    DFS <[email protected]> writes:
    On 3/8/2026 3:29 PM, Bart wrote:

    note that setjmp/longjmp are not functions


    huh?

    https://man7.org/linux/man-pages/man3/longjmp.3.html

    POSIX allows setjmp to be defined as a macro.

    https://pubs.opengroup.org/onlinepubs/9799919799/functions/setjmp.html


    Just allows?
    Are there real-world examples of implementing setjmp not as a macro?

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Giovanni@[email protected] to comp.lang.c on Tue Mar 10 17:18:04 2026
    From Newsgroup: comp.lang.c

    On 3/10/26 17:08, Michael S wrote:

    POSIX allows setjmp to be defined as a macro.

    https://pubs.opengroup.org/onlinepubs/9799919799/functions/setjmp.html

    Just allows?
    Are there real-world examples of implementing setjmp not as a macro?


    I had to implement it in a boot loader and did it in x86 assembler.

    Ciao
    Giovanni
    --
    A computer is like an air conditioner,
    it stops working when you open Windows.
    < https://giovanni.homelinux.net/ >
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Tue Mar 10 16:32:08 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> writes:
    On Tue, 10 Mar 2026 14:43:28 GMT
    [email protected] (Scott Lurndal) wrote:

    DFS <[email protected]> writes:
    On 3/8/2026 3:29 PM, Bart wrote:

    note that setjmp/longjmp are not functions


    huh?

    https://man7.org/linux/man-pages/man3/longjmp.3.html

    POSIX allows setjmp to be defined as a macro.

    https://pubs.opengroup.org/onlinepubs/9799919799/functions/setjmp.html


    Just allows?
    Are there real-world examples of implementing setjmp not as a macro?


    There may have been 33 years ago.

    From the P1003.4/D14.1 rationale (1993) Section B8.3.1 (Nonlocal jumps):

    "The C standard specifies various restrictions on the usage
    of the setjmp() macro in order to permit implementers to
    recognize the name in the compiler and not implement an
    actual function. These same restricts apply to the
    sigsetjmp macro."


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From antispam@[email protected] (Waldek Hebisch) to comp.lang.c on Tue Mar 10 20:18:36 2026
    From Newsgroup: comp.lang.c

    Bart <[email protected]> wrote:

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

    People here must be very bored. I have found this challenge rather uninteresting (bunch of arbitrary restrictions unlikely to happen in
    real use). And the "use longjmp" variant is especially silly and
    very specific to C: 'longjmp' is an indirect non-local goto so
    'no goto' condition normally would mean that 'longjmp' is forbiden too.
    And in most languages that can do nonlocal goto-s they are simply
    called 'goto'. So this variant makes no sense in such languages.

    BTW: I once implemented fibonacci function using explicit stack
    and indirect jumps in PL/I under OS/360. But that showed
    interesting feature: under OS/360 version using indirect jumps
    was faster than version using function calls. I do not think
    that version using 'longjmp' has any speed advantage on modern
    systems.
    --
    Waldek Hebisch
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Tue Mar 10 20:24:30 2026
    From Newsgroup: comp.lang.c

    On 10/03/2026 01:20, DFS wrote:
    On 3/8/2026 3:29 PM, Bart wrote:

    note that setjmp/longjmp are not functions


    huh?

    https://man7.org/linux/man-pages/man3/longjmp.3.html


    I was wrong, there in func some C libraries that use functions.

    Such as MSVCRT (but it didn't work when I tried it just now from another language).

    It might explain why 'setjump' works in such an unintuitive way: not
    only it is it used to set (implicitly) a recovery point, but that point
    must be this exact same function call.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Tue Mar 10 15:25:19 2026
    From Newsgroup: comp.lang.c

    [email protected] (Scott Lurndal) writes:
    DFS <[email protected]> writes:
    On 3/8/2026 3:29 PM, Bart wrote:
    note that setjmp/longjmp are not functions

    huh?

    https://man7.org/linux/man-pages/man3/longjmp.3.html

    POSIX allows setjmp to be defined as a macro.

    https://pubs.opengroup.org/onlinepubs/9799919799/functions/setjmp.html

    More to the point, ISO C (all editions from C90 to C23) specifies that
    setjmp is a macro, and longjmp is a function. (Like any library
    function, longjmp can *also* be implemented as a macro).

    As it happens, glibc's <setjmp.h> has:

    #define setjmp(env) _setjmp (env)

    where _setjmp is a function.

    POSIX says:

    It is unspecified whether setjmp() is a macro or a function. If
    a macro definition is suppressed in order to access an actual
    function, or a program defines an external identifier with the
    name setjmp, the behavior is undefined.

    which may be inconsistent with ISO C.
    --
    Keith Thompson (The_Other_Keith) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Keith Thompson@[email protected] to comp.lang.c on Tue Mar 10 15:29:12 2026
    From Newsgroup: comp.lang.c

    Bart <[email protected]> writes:
    On 10/03/2026 01:20, DFS wrote:
    On 3/8/2026 3:29 PM, Bart wrote:
    note that setjmp/longjmp are not functions
    huh?
    https://man7.org/linux/man-pages/man3/longjmp.3.html

    I was wrong, there in func some C libraries that use functions.

    You were right about setjmp, which is a macro. You were wrong about
    longjmp, which is a function (but like any library function it can
    additionally be implemented as a macro.)

    Such as MSVCRT (but it didn't work when I tried it just now from
    another language).

    It might explain why 'setjump' works in such an unintuitive way: not
    only it is it used to set (implicitly) a recovery point, but that
    point must be this exact same function call.

    I'm not sure how else it could work. I could imagine an alternative
    setjmp() that specifies a recovery point other than the call itself,
    but you'd need a way to specify that point. (A label wouldn't work,
    since setjmp and longjmp work across functions.)
    --
    Keith Thompson (The_Other_Keith) [email protected]
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Wed Mar 11 00:29:04 2026
    From Newsgroup: comp.lang.c

    On 10/03/2026 22:29, Keith Thompson wrote:
    Bart <[email protected]> writes:
    On 10/03/2026 01:20, DFS wrote:
    On 3/8/2026 3:29 PM, Bart wrote:
    note that setjmp/longjmp are not functions
    huh?
    https://man7.org/linux/man-pages/man3/longjmp.3.html

    I was wrong, there in func some C libraries that use functions.

    You were right about setjmp, which is a macro. You were wrong about
    longjmp, which is a function (but like any library function it can additionally be implemented as a macro.)

    Well, 'setjmp' is exported as a function from MSVCRT. (As I said,
    calling setjmp then longjmp crashed while calling the latter, but it
    could be for other reasons).

    Such as MSVCRT (but it didn't work when I tried it just now from
    another language).

    It might explain why 'setjump' works in such an unintuitive way: not
    only it is it used to set (implicitly) a recovery point, but that
    point must be this exact same function call.

    I'm not sure how else it could work. I could imagine an alternative
    setjmp() that specifies a recovery point other than the call itself,
    but you'd need a way to specify that point. (A label wouldn't work,
    since setjmp and longjmp work across functions.)


    Yes, the way I emulated setjmp (trying to port Tim's code), used a
    version where a label within this function (like a gnu C label pointer)
    was a second argument. Doing it otherwise would have needed inline
    assembly (and probably hidden behind setjmp as a macro!), which I no
    longer have.

    But I anyway prefer it like that. Then you don't need to use setjmp in
    this peculiar manner:

    if (setjmp(buff) == 0 ) // true after first set-up
    -- some code that ends up calling longjmp
    -- in some nested function
    else // here after that longjmp as it
    ... // magically restarts this 'if'


    (The way I do setjmp/longjmp in my C compiler is via dedicated IL instructions. The same IL is available to my other language, but it
    would need language + compiler changes to utilise them.)

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Wed Mar 11 00:33:27 2026
    From Newsgroup: comp.lang.c

    Keith Thompson <[email protected]> writes:
    Bart <[email protected]> writes:
    On 10/03/2026 01:20, DFS wrote:
    On 3/8/2026 3:29 PM, Bart wrote:
    note that setjmp/longjmp are not functions
    huh?
    https://man7.org/linux/man-pages/man3/longjmp.3.html

    I was wrong, there in func some C libraries that use functions.

    You were right about setjmp, which is a macro. You were wrong about
    longjmp, which is a function (but like any library function it can >additionally be implemented as a macro.)

    Such as MSVCRT (but it didn't work when I tried it just now from
    another language).

    It might explain why 'setjump' works in such an unintuitive way: not
    only it is it used to set (implicitly) a recovery point, but that
    point must be this exact same function call.

    I'm not sure how else it could work.

    When one realizes that setjmp simply saves the processor user
    state at the time of the call (all registers including
    the stack pointer and program counter along with the
    processor flags) and simply restores that state when longjmp is
    invoked, it seems rather intuitive.

    longjmp just needs to update the saved processor register that normally
    holds a function return value (e.g. %rax) before branching to the
    saved PC.

    Versions for AMD64:

    /**
    * Preserve the current register state. This function is only for the use
    * of c_rollback.
    *
    * On entry:
    * %rdi c_rollback::_rb_state *
    */
    ENTRY(_ZN10c_rollback7_setjmpEPNS_9_rb_stateE)
    pop %rsi # Get return address & adjust stack
    xorl %eax, %eax # Processor will zero-extend to 64 bits
    movq %rbx, (%rdi) # Save RBX register
    movq %rsp, 56(%rdi) # Save RSP after return
    push %rsi # Restore return address
    movq %rbp, 8(%rdi) # Save RBP
    movq %r12, 16(%rdi) # Save R12
    movq %r13, 24(%rdi) # Save R13
    movq %r14, 32(%rdi) # Save R14
    movq %r15, 40(%rdi) # Save R15
    movq %rsi, 48(%rdi) # Save Return Address
    ret

    /**
    * Restore current register state. This function is only for the use
    * of c_rollback.
    *
    * On entry:
    * %rdi c_rollback::_rb_state *
    * %rsi uint64
    */
    ENTRY(_ZN10c_rollback8_longjmpEPNS_9_rb_stateEm)
    movq %rsi, %rax # Return value
    movq (%rdi), %rbx # Restore RBX
    movq 8(%rdi), %rbp # Restore RBP
    movq 16(%rdi), %r12 # Restore R12
    movq 24(%rdi), %r13 # Restore R13
    movq 32(%rdi), %r14 # Restore R14
    movq 40(%rdi), %r15 # Restore R15
    movq 56(%rdi), %rsp # Restore RSP
    jmp *48(%rdi)

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Wed Mar 11 11:31:23 2026
    From Newsgroup: comp.lang.c

    Am 04.03.2026 um 12:58 schrieb David Brown:

    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.

    A comparison with a language derived from C is half on-topic.
    I think my style is pure beauty:

    #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>
    pRows = parse( argv[1] ),
    pCols = parse( argv[2] );
    if( !pRows || !pCols )
    return EXIT_FAILURE;
    size_t rows = *pRows, cols = *pCols;
    optional<size_t> pClip( rows * cols );
    if( argc >= 4 && !(pClip = parse( argv[3] )) )
    return EXIT_FAILURE;
    size_t clip = min( *pClip, rows * cols );
    streamsize width = (ostringstream() << clip).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 + 1;
    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 think C-code is somewhat longer with the same error handling features.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Wed Mar 11 11:35:09 2026
    From Newsgroup: comp.lang.c

    This C-code looks really "naked" and too long for me.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Wed Mar 11 11:36:34 2026
    From Newsgroup: comp.lang.c

    Am 03.03.2026 um 06:09 schrieb Tim Rentsch:

    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.

    Performance doesn't count if you print to the console, which is
    a kernel-flush.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Wed Mar 11 11:37:47 2026
    From Newsgroup: comp.lang.c

    Am 03.03.2026 um 22:56 schrieb Michael S:
    On Tue, 03 Mar 2026 06:20:33 -0800
    Tim Rentsch <[email protected]> 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?

    Raise a signal when you have a parameter-error and return to the calling function with a siglongjmp(); hrhr.

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Wed Mar 11 11:40:18 2026
    From Newsgroup: comp.lang.c

    This code *really* sucks because it is too complicated for what is
    requested.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bart@[email protected] to comp.lang.c on Wed Mar 11 11:04:03 2026
    From Newsgroup: comp.lang.c

    On 11/03/2026 00:33, Scott Lurndal wrote:
    Keith Thompson <[email protected]> writes:
    Bart <[email protected]> writes:
    On 10/03/2026 01:20, DFS wrote:
    On 3/8/2026 3:29 PM, Bart wrote:
    note that setjmp/longjmp are not functions
    huh?
    https://man7.org/linux/man-pages/man3/longjmp.3.html

    I was wrong, there in func some C libraries that use functions.

    You were right about setjmp, which is a macro. You were wrong about
    longjmp, which is a function (but like any library function it can
    additionally be implemented as a macro.)

    Such as MSVCRT (but it didn't work when I tried it just now from
    another language).

    It might explain why 'setjump' works in such an unintuitive way: not
    only it is it used to set (implicitly) a recovery point, but that
    point must be this exact same function call.

    I'm not sure how else it could work.

    When one realizes that setjmp simply saves the processor user
    state at the time of the call (all registers including
    the stack pointer and program counter along with the
    processor flags)


    The registers include PC, SP and FP. If 'setjmp' is written in a HLL,
    then these are by no means trivial to extract. It depends on the
    compiler's entry code for this function.

    That applies even if using inline assembly; you'd have to ask for a raw function where no entry code is generated.


    and simply restores that state when longjmp is
    invoked, it seems rather intuitive.


    Not so intuitive when it comes to registers. It can record the state of non-vol registers when setjmp is called, but those could change by code executed when setjmp returns the first time.

    It would depend on the code around the setjmp call:

    int a=1234; // resides in register
    ...
    while() {
    switch setjmp() {
    case 0: a=5678; ...
    case 1: ...
    }

    Here, how confident can the compiler be that at case 1+, 'a' will always
    have the value it had at the very first setjmp call? Maybe it can jump
    back to that first ... which is a bunch of conditional statements, which
    then calls code that eventually call longjmp.


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Richard Harnden@[email protected] to comp.lang.c on Wed Mar 11 11:40:01 2026
    From Newsgroup: comp.lang.c

    On 10/03/2026 02:18, DFS wrote:
    On 3/7/2026 6:47 PM, Janis Papanagnou wrote:
    On 07.03.26 20:18, DFS wrote:


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

    It's easier to see, but that glaring pattern, where groups of 'possible' alternate with growing same-size groups of 'not possible', is by itself nearly useless for determining if 1-N fits in a square matrix, whereas
    the remainders of the square root tell you immediately.

    remainder between 0.01 and 0.50 = square matrix not possible


    Input   Sqr Matrix?    sqrt(Input)
    ----------------------------------
       1    possible        1.00
       2    not possible    1.41
       3    possible        1.73
       4    possible        2.00
       5    not possible    2.24
       6    not possible    2.45
       7    possible        2.65
       8    possible        2.83
       9    possible        3.00
      10    not possible    3.16
      11    not possible    3.32
      12    not possible    3.46
      13    possible        3.61
      14    possible        3.74
      15    possible        3.87
      16    possible        4.00
      17    not possible    4.12
      18    not possible    4.24
      19    not possible    4.36
      20    not possible    4.47
      21    possible        4.58
      22    possible        4.69
      23    possible        4.80
      24    possible        4.90
      25    possible        5.00
      26    not possible    5.10
      27    not possible    5.20
      28    not possible    5.29
      29    not possible    5.39
      30    not possible    5.48


    In all the posting I didn't see whether anyone came up with a formula
    just using the Input nbr.  I think maybe Lew Pitcher or Bart did.

    There's probably a simple formula in Rentsch's brainfsck-code, but it
    would take some work to decipher it.


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

    I may post a question to sci.math and see if anyone is interested. Don't know if this kind of thing fits into the topic of sequences?


    The possible numbers are <https://oeis.org/A004201> "Accept one, reject
    one, accept two, reject two, ..."




    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 11 06:27:18 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:

    [some of posting being responded to has been taken out
    without further notice].

    On 3/7/2026 3:02 PM, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

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

    Here we go...

    OMG! Congrats on an innovative piece of C code. Never seen
    anything like it.

    Thank you, that's always nice to hear.

    I don't understand everything yet, but nested ternaries aside, it's
    pretty easy to follow too.

    Once you get used to them I think you'll find conditional
    expressions are easier to follow than if() chains.

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

    No, I didn't. You asked "Is main() OK?". I replied "Yes" followed
    by a short elaboration. Having main() be present is okay; calling
    it is not. The oversight was not mentioning that main is allowed.

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

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

    For instance:

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

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

    A straightforward exercise. A challenge for you is to start with my
    program and adapt it, writing in the same style, to add this
    functionality. Now that you have seen my example code I think you
    should be able to adapt it without too much difficulty.

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

    What characteristics or properties would you say are the salient
    ones for the question you're asking?
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 11 06:33:56 2026
    From Newsgroup: comp.lang.c

    DFS <[email protected]> writes:

    [...]

    Nested ternaries like this:

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

    are harder to decipher at first glance than 3 or 4 levels of
    indented if-then-elses.

    Again that is only because you aren't used to them. Note by the
    way that the conditional expression is not nested, any more than
    a chain of if-elseif-elseif-else is nested

    if(x){
    ...
    } else if(y){
    ...
    } else if(z){
    ...
    } else {
    ...
    }

    Of course syntactically this construct is nested, but normally
    how people think of it is not as being nested.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 11 07:07:09 2026
    From Newsgroup: comp.lang.c

    Keith Thompson <[email protected]> writes:

    [email protected] (Scott Lurndal) writes:

    DFS <[email protected]> writes:

    On 3/8/2026 3:29 PM, Bart wrote:

    note that setjmp/longjmp are not functions

    huh?

    https://man7.org/linux/man-pages/man3/longjmp.3.html

    POSIX allows setjmp to be defined as a macro.

    https://pubs.opengroup.org/onlinepubs/9799919799/functions/setjmp.html

    More to the point, ISO C (all editions from C90 to C23) specifies that
    setjmp is a macro, and longjmp is a function. (Like any library
    function, longjmp can *also* be implemented as a macro).

    As it happens, glibc's <setjmp.h> has:

    #define setjmp(env) _setjmp (env)

    where _setjmp is a function.

    POSIX says:

    It is unspecified whether setjmp() is a macro or a function. If
    a macro definition is suppressed in order to access an actual
    function, or a program defines an external identifier with the
    name setjmp, the behavior is undefined.

    which may be inconsistent with ISO C.

    The original ANSI C standard says this:

    It is unspecified whether setjmp is a macro or an identifier
    declared with external linkage. If a macro definition is
    suppressed in order to access an actual function, or a program
    defines an external identifier with the name setjmp, the
    behavior is undefined.

    I think every version of the ISO C standard says exactly the same
    thing. I did a quick check but didn't verify that the wording is
    exactly identical in every case.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 11 07:29:47 2026
    From Newsgroup: comp.lang.c

    Keith Thompson <[email protected]> writes:

    Tim Rentsch <[email protected]> writes:
    [...]

    typedef size_t Z;
    typedef _Bool B;

    [...]

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

    The reaction from Lew Pitcher was "Brilliant!". The reaction from
    DFS was "I think he knocked it out of the park." Because Lew and
    DFS (and to some extent Michael S) are the ones who had expressed
    an interest in my counter challenge, they were my target audience.
    So from my point of view there is no reason to be dissatisfied with
    what was posted.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 11 07:57:52 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> writes:

    [concerning implementing integer square root]

    Here is O(log(N)) variant [...]

    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned y = x/2, r;
    while ((r = x / y) < y)
    y = (r + y) / 2;
    return y;
    }

    Right, O(log(N)). The initial guess is kind of out in left field so
    it takes a while to get into a good zone of convergence.

    And here is variation that is a little less simple, but not
    complicated and faster than one before, because it does fewer
    divisions. The number of divisions that can't be implemented as
    shift is at most ceil(sqrt(ceil(log2(ceil(sqrt(val)))

    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned y = 8, xx = x;
    while (xx > 63) {
    xx /= 64;
    y *= 8;
    }
    unsigned r;
    while ((r = x / y) < y)
    y = (r + y) / 2;
    return y;
    }

    Here I think your analysis is a little off. Newton's Method has
    quadratic convergence, given an appropriate initial guess. That
    means the second while loop is O(log(# bits)), or O(log(log(N))).

    The initial loop, to find a good initial guess, can also be made to
    be O(log(log(N))); exercise for the reader.

    The foregoing assumes the usual C operators are O(1), which of
    course isn't right as the width of the type involved gets larger,
    but that assumption is typically made in this kind of analysis.

    (Note: since the width of unsigned int is fixed, technically the
    performance of these algorithms is all O(1). But usually that
    condition of constant width is ignored in this sort of discussion.)

    And here is less simple but still obvious implementation that does
    no divisions at all. No multiplications as well.

    unsigned usqrt(unsigned x)
    {
    if (x < 2)
    return x;
    unsigned xx = x;
    int e = 0;
    while (xx > 63) {
    xx /= 64;
    e += 3;
    }
    while (xx > 3) {
    xx /= 4;
    e += 1;
    }
    unsigned y = 1u << e;
    x -= y << e;
    for (e = e - 1; e >= 0; --e) {
    unsigned d = y*2 + (1u << e);
    if (d <= (x >> e)) {
    x -= d << e;
    y += 1u << e;
    }
    }
    return y;
    }

    Here the behavior is linear in the number of bits, or O(log(N)). At
    some point (but not for 32-bit integers) the division method wins
    out.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From DFS@[email protected] to comp.lang.c on Wed Mar 11 11:00:59 2026
    From Newsgroup: comp.lang.c

    On 3/11/2026 6:40 AM, Bonita Montero wrote:

    This C-code looks really "naked" and too long for me.

    and

    This code *really* sucks because it is too complicated for what is requested.



    Can't you quote who and what you're replying to?

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 11 08:23:12 2026
    From Newsgroup: comp.lang.c

    Michael S <[email protected]> writes:

    On Sat, 7 Mar 2026 16:58:48 -0500
    DFS <[email protected]> wrote:

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

    You misunderstood.
    Having main() is allowed and necessary. Calling main() in your code is forbidden.

    Right.

    If calling main() recursively was allowed then possible solution could
    be just uglier than previos counter-challenge, but would not require
    any different ideas.

    It may not require different ideas, but IMO it benefits from
    adopting an approach similar to the posted setjmp version. Here
    is a revision of the code I posted, changed so that it does not
    use setjmp()/longjmp() but instead calls main() recursively. I
    think using recursive calls to main to simulate having multiple
    functions would make the code more difficult to understand, not
    easier.

    Note by the way that all calls to main() below are tail calls,
    and are optimized away, so there is no stack depth penalty for
    this method, unlike using recursive calls to main to simulate
    having other functions available.


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

    typedef size_t Z;
    typedef _Bool B;

    static Z k, h, w, c;
    static int d;

    #define GO(x) return main( (x), argv )
    #define NUMBERISH(p) ((p) && *(p) && (p)[ strspn((p),"0123456789") ] == 0)

    enum {
    START, // the initial state; must be zero
    NADA = -99, // make the following values all be negative
    AFU, USAGE, // give suitable message and exit
    ROOT, DRAT, // find ceiling( sqrt( cutoff ) ); possible no joy exit
    HWC, // display H*W values with cutoff C
    FIN, // exit program
    };

    int
    main( int argc, char *argv[] ){
    switch( argc < 0 ? argc : 0 ){
    case START: {
    B usage = argc < 2 || argc > 4;

    B g1 = argc > 1 && NUMBERISH( argv[1] );
    B g2 = argc > 2 && NUMBERISH( argv[2] );
    B g3 = argc > 3 && NUMBERISH( argv[3] );

    Z a1 = g1 ? strtoul( argv[1], 0, 10 ) : 0;
    Z a2 = g2 ? strtoul( argv[2], 0, 10 ) : 0;
    Z a3 = g3 ? strtoul( argv[3], 0, 10 ) : 0;

    B square = argc == 2 && g1;
    B hw = argc == 3 && g1&&g2 && a1&&a2;
    B hwc = argc == 4 && g1&&g2 && a1&&a2 && g3;

    k = 0;
    h = hw || hwc ? a1 : a1/4 + !a1; // note: initial value(h) > 0
    w = hw || hwc ? a2 : h;
    c = square ? a1 : !hwc ? h*w : a3 > h*w ? h*w : a3;
    d = snprintf( 0, 0, "%zu", c );

    GO( usage ?USAGE : square ?ROOT : (hw||hwc) && a1&&a2 ?HWC : AFU );
    }

    case AFU:
    printf( " urk... bad arguments\n" );
    GO( USAGE );

    case USAGE:
    printf( " usage:\n" );
    printf( " %s cutoff {{for square}}\n", argv[0] );
    printf( " %s rows columns [cutoff]\n", argv[0] );
    GO( FIN );

    case ROOT: {
    h = c < 2 ? 1 : c < 5 ? 2 : (h + c/h) / 2;
    h += h*h < c;
    w = h;
    B done = c < 2 || h*h < c+2*h && c <= h*h;
    B good = c < 2 || h*h < c+h && c <= h*h;
    GO( !done ?ROOT : good ?HWC : DRAT );
    }

    case DRAT:
    printf( " square with cutoff %zu - no joy\n", c );
    GO( FIN );

    case HWC: {
    B eol = k/h + 1 == w;
    B end = k+1 + (h>c ? h-c : 0) >= h*w;
    Z nextk = eol ? k - (w-1)*h + 1 : k+h;

    printf( k < c ? " %*zu" : "", d, k+1 );
    printf( c > 0 && eol ? "\n" : "" );

    GO( end ?(printf( "------\n" ), FIN) : (k = nextk, HWC) );
    }
    }
    }
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From wij@[email protected] to comp.lang.c on Thu Mar 12 00:00:54 2026
    From Newsgroup: comp.lang.c

    On Wed, 2026-03-11 at 11:00 -0400, DFS wrote:
    On 3/11/2026 6:40 AM, wrote:

    This C-code looks really "naked" and too long for me.

    and

    This code *really* sucks because it is too complicated for what is requested.

    Most of the reason is that many people thought C is for their application
    but not, C is for building portable OS. Try using C++ (or other language) to write OS from bottom up to understand.
    Your C++ codes are hard to read because C++ is good at expressing idea, including good for making 'fantacy' codes looks professional (and others). Comparing to C, your codes are overly abstract and heavily depends on  libraries, Clib only contains those for building OS, nothing else.
    For example, Qt-library is in many ways better than c++stdlib for many applications (from my little experience of Qt3). Also, I think my own library is 'essentially' better than C++stdlib (limited).
    As I said, try write cp to know (I had heard, C++ cannot even implement cat)

    Can't you quote who and what you're replying to?
    I'm replying to Bonita Montero.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Bonita Montero@[email protected] to comp.lang.c on Wed Mar 11 18:03:48 2026
    From Newsgroup: comp.lang.c

    Am 11.03.2026 um 17:00 schrieb wij:

    Most of the reason is that many people thought C is for their application
    but not, C is for building portable OS. Try using C++ (or other language)
    to write OS from bottom up to understand.

    That's a very limited view. This would work even better in C++, but
    switching from the lowlevel to the medium level abstraction layers
    is too much for kernel hackers. Haiku f.e. is written completely
    in C++. OOP along with generic and functional saves a great amount
    of work.

    Your C++ codes are hard to read because C++ is good at expressing idea,

    My code is *much* easier to read if you know C++.

    Comparing to C, your codes are overly abstract and heavily depends
    on libraries, Clib only contains those for building OS, nothing else.

    The abstaction is rather simple and relying on the runtime isn't
    a problem since it saves a lot of work; not much with this example
    but usually C++ code is a fifth of the same functionality in C.

    For example, Qt-library is in many ways better than c++stdlib for many applications (from my little experience of Qt3).

    Absolutely not. F.e. consider the threading support, it's much more
    complicated to spawn a new thread in Qt. And Qt has no exceptions
    for historical reasons which makes much more work to handle errors.
    Qt is simply not modern C++.

    Also, I think my own library is 'essentially' better than C++stdlib (limited).

    It's more code and if you know C++ it's less readable. C really sucks.
    Image using sth. like a map<> or unordered_map<> in C. Even with a call-
    back'd library (like qsort()) that's a big amout of work. Or consider
    just having a vector of strings; a stringVec.emplace_back( "hello" )
    is hours of work if you implement the same size() / capacity() manage-
    ment. In C you've write much code and flip the bits yourself where in
    C++ you write only one line of code.
    It's all o.k. if your project is historically C or you don't have a
    C++ compiler for the target platform, otherwise you have multiple
    times the work as in C++.



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Tim Rentsch@[email protected] to comp.lang.c on Wed Mar 11 10:44:50 2026
    From Newsgroup: comp.lang.c

    Lew Pitcher <[email protected]> writes:

    On Sat, 07 Mar 2026 11:55:13 -0800, Tim Rentsch wrote:

    Lew Pitcher <[email protected]> writes:

    On Fri, 06 Mar 2026 13:51:58 +0000, Lew Pitcher wrote:

    [...]

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

    And, here it is
    [...]

    First of two responses

    1. I think your error checking is more thorough than what I did.
    I do check that inputs are well formed but it's possible that
    out of range values will give inappropriate results.

    2. I don't have any error return. I do diagnose various conditions
    (and in particular the no-square-possible cutoff values) but don't
    bother with status. It would be easy to add but I didn't do it. :)

    3. How setjmp() is used is still out of bounds. The rule for setjmp()
    in a switch() is the setjmp() must be the entire expression that is
    switched on. Effectively longjmp() can pass only constant values,
    because there is no way to do anything with the value except see if
    it is true or false (in an if()) or match it against 'case' labels.

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

    The C standard does need an attention to detail in many cases.
    Personally I think that is a plus as well as being a minus in
    some ways - being forced to pay attention to detail often helps
    clarify my thinking.

    Corrected version follows

    [...]

    I appreciate the effort. I was surprised by the use of
    setjmp() to simulate loops; probably I shouldn't have
    been but it hadn't occurred to me before now. Then again
    I have been used to functional programming techniques for
    more than 20 years now so loops feel less natural to me
    now than they used to.

    One point that confused me for a while was the lack of a
    'break' before the initial 'case 3:'. At first I thought
    it was just an oversight that it wasn't there. Of course
    it was deliberate, and I saw what you were doing. My code
    accepts and allows a cutoff of 0, which may have added to
    my confusion. Your code could do that by using a different
    value for the "no cutoff entered" condition.

    I may have other general comments later.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.lang.c on Wed Mar 11 17:52:57 2026
    From Newsgroup: comp.lang.c

    Bonita Montero <[email protected]> writes:
    Am 11.03.2026 um 17:00 schrieb wij:

    Most of the reason is that many people thought C is for their application
    but not, C is for building portable OS. Try using C++ (or other language)
    to write OS from bottom up to understand.

    That's a very limited view. This would work even better in C++, but
    switching from the lowlevel to the medium level abstraction layers
    is too much for kernel hackers. Haiku f.e. is written completely

    While it is de rigueur auf Deutsch to abbreviate zum beispiel as z.b.,
    in English one generally uses the latin abbreviation 'e.g.'
    --- Synchronet 3.21d-Linux NewsLink 1.2