diff --git a/1993/plummer/README.md b/1993/plummer/README.md index 288782bb8..af92be4bb 100644 --- a/1993/plummer/README.md +++ b/1993/plummer/README.md @@ -13,69 +13,73 @@ ./plummer number arg - where: +where: - number a number (try 21701) - arg any argument + number is a number (try 21701) + arg is any argument -## Judges' comments +[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) added a check in the +code so that it will not segfault if not enough args are specified. Thank you +Cody! + +## Judges' comments: - For extra credit: What happens when 'number' contains non-numeric - characters, and why? +For extra credit: What happens when 'number' contains non-numeric +characters, and why? ## Author's comments - This program prints out all numbers up to a given number of digits - on a single line. When the largest number is reached, the program - starts again with 0. It takes two arguments: the first argument - specifies the number to start counting from and uses leading 0's to - indicate the number of digits, the second argument can be anything - but must be present. +This program prints out all numbers up to a given number of digits +on a single line. When the largest number is reached, the program +starts again with 0. It takes two arguments: the first argument +specifies the number to start counting from and uses leading 0's to +indicate the number of digits, the second argument can be anything +but must be present. - Variable names are single characters chosen for their similarity to - other characters (O for 0, l for 1, S for 5 (in some fonts), and _ - for ... well nothing really, but it is easy to miss). To prevent - the need for strlen(), the fact that argv is laid out sequentially - is exploited (ie. argv[i + 1] == argv[i] + strlen(argv[i]) + 1). - This is not portable (by the books), but it seems to work - everywhere I try (actually, for vms, that only holds for i > 1). - Also, I depend on the fact that a carriage return causes the line - just written to be overwritten. lint (and most compilers) complain - that there is no control path leading to a return from main(). At - 125 characters, it still fits on a single line (for those of us who - don't mind ruining our eyes with 132 column screens). +Variable names are single characters chosen for their similarity to +other characters (O for 0, l for 1, S for 5 (in some fonts), and _ +for ... well nothing really, but it is easy to miss). To prevent +the need for `strlen()`, the fact that argv is laid out sequentially +is exploited (ie. `argv[i + 1] == argv[i] + strlen(argv[i]) + 1`). +This is not portable (by the books), but it seems to work +everywhere I try (actually, for vms, that only holds for `i > 1`). +Also, I depend on the fact that a carriage return causes the line +just written to be overwritten. lint (and most compilers) complain +that there is no control path leading to a return from main(). At +125 characters, it still fits on a single line (for those of us who +don't mind ruining our eyes with 132 column screens). - The first statement points the base of l (the argument vector) to - be the first argument by incrementing it. It then assigns O to - point to the character before the first character of the second - argument which also happens to be the null termination of the first - argument. *O gets a \r assigned to it. Finally 0 is assigned to - the first character of the second argument which has the effect of - null terminating the first argument after the carriage return had - removed its null termination. I really tried to make the last part - of that statement part of the original expression, but the best I - could do was attach it with a comma (against the advice of K&R). - The for loop runs the next for loop continuously (actually until - the machine crashes or the user gets tired of seeing the - counting). The next for loop is the meat of the program. In the - initialization statement, the string pointed to by l (the first - argument containing the digits used for counting followed by a \r) - is printed, and _ is started at the least significant digit in the - string. In the test portion, _ is insured not to be past the - beginning of the string (the most significant digit), and the digit - pointed to by _ is incremented and checked to be sure that it _is_ - greater than '9' (written here as (S+*O+S)*S). If the test fails, - either the string has been incremented or each digit in the string - has been reset to '0'. If the test succeeded, the iteration - statement assigns '0' (written here as (S+*O)*S (which has the - added bonus of having the code be a cry for help)) to *_ and - decrements _ to point to the next more significant digit to be - incremented; it is done only when a carry situation results (*_ has - been incremented past '9'). +The first statement points the base of `l` (the argument vector) to +be the first argument by incrementing it. It then assigns `O` to +point to the character before the first character of the second +argument which also happens to be the null termination of the first +argument. `*O` gets a `\r` assigned to it. Finally `0` is assigned to +the first character of the second argument which has the effect of +null terminating the first argument after the carriage return had +removed its null termination. I really tried to make the last part +of that statement part of the original expression, but the best I +could do was attach it with a comma (against the advice of K&R). +The for loop runs the next for loop continuously (actually until +the machine crashes or the user gets tired of seeing the +counting). The next for loop is the meat of the program. In the +initialization statement, the string pointed to by `l` (the first +argument containing the digits used for counting followed by a `\r`) +is printed, and `_` is started at the least significant digit in the +string. In the test portion, `_` is insured not to be past the +beginning of the string (the most significant digit), and the digit +pointed to by `_` is incremented and checked to be sure that it _is_ +greater than `9` (written here as `(S+*O+S)*S`). If the test fails, +either the string has been incremented or each digit in the string +has been reset to `0`. If the test succeeded, the iteration +statement assigns `0` (written here as `(S+*O)*S` (which has the +added bonus of having the code be a cry for help)) to `*_` and +decrements `_` to point to the next more significant digit to be +incremented; it is done only when a carry situation results (`*_` has +been incremented past `9`). - The inspiration for this program came from actual code which dealt - with scanning for a unique temporary filename by appending a - successively larger number to the end of a string. +The inspiration for this program came from actual code which dealt +with scanning for a unique temporary filename by appending a +successively larger number to the end of a string. ## Copyright and CC BY-SA 4.0 License: diff --git a/1993/plummer/plummer.c b/1993/plummer/plummer.c index d0c61daa2..af348c6f8 100644 --- a/1993/plummer/plummer.c +++ b/1993/plummer/plummer.c @@ -1 +1 @@ -char*_,*O;main(S,l)char**l;{*(O=*(l+++S-1)-1)=13,*l[1]=0;for(;;)for(printf(*l),_=O-1;_>=*l&&++*_>(S+*O+S)*S;*_--=(S+*O)*S);} +char*_,*O;main(S,l)char**l;{if(S>2){*(O=*(l+++S-1)-1)=13,*l[1]=0;for(;;)for(printf(*l),_=O-1;_>=*l&&++*_>(S+*O+S)*S;*_--=(S+*O)*S);}}