From c7fc0959b361dc6831b930daf3d0c20483e126e3 Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Sun, 22 Oct 2023 08:29:19 -0700 Subject: [PATCH 1/6] Updates to 2018/ferguson Format changes in the README.md. Update the test.sh and test-strings.txt files: modify the goodbye message in the script (for fun) and add some fun strings for it to search out. --- 2018/ferguson/README.md | 236 ++++++++++++++++----------------- 2018/ferguson/test-strings.txt | 8 ++ 2018/ferguson/test.sh | 2 +- 3 files changed, 127 insertions(+), 119 deletions(-) diff --git a/2018/ferguson/README.md b/2018/ferguson/README.md index 90ef15269..179dbe648 100644 --- a/2018/ferguson/README.md +++ b/2018/ferguson/README.md @@ -103,7 +103,7 @@ more thorough than this. program; if you're familiar with genetic algorithms there won't be any problem following this section but it might be of some value to read anyway. There is a randomised mode that doesn't use a genetic algorithm; it can be triggered a -number of ways but the **`-m`** option enables it specially (I discuss this +number of ways but the `-m` option enables it specially (I discuss this thoroughly in **[Hints](#hints)**). **[Hints](#hints):** Perhaps the longest part of this document because in it I @@ -116,16 +116,16 @@ don't need this unless there is something specific you're after. **[Obfuscation](#obfuscation):** Some of the techniques that might not be used. **[How to build](#build):** Here I describe briefly -[the constants that can be redefined](#constants) **`S`** and **`N`**: the -maximum size of the chromosome (target string; the maximum length is **`S - 1`** +[the constants that can be redefined](#constants) `S` and `N`: the +maximum size of the chromosome (target string; the maximum length is `S - 1` but it must be >= the default 38) and the number of offspring, respectively. I also give [example compiler invocations](#compiling), [portability notes](#portability), an [more portability notes](#bugs) and a [note on rpm.md](#rpm). -On the subject of **`S`** and **`N`**: As the judges' suggested runs imply you -can change the target string at runtime; **`make test`** runs a script -*`test.sh`* which reads from the file *`test-strings.txt`*, running the program +On the subject of `S` and `N`: As the judges' suggested runs imply you +can change the target string at runtime; `make test` runs a script +`test.sh` which reads from the file `test-strings.txt`, running the program for each string in the file, waiting approximately two seconds before continuing. I explain how to pass options to the script in part of **[Hints](#test)**. @@ -162,8 +162,8 @@ He refers to the [Infinite Monkey Theorem][] (Wikipedia). As he points out the operative phrase is *given enough time*; but even if it's extremely unlikely *technically the probability is greater than 0*. He simplified it for the monkey; I thought the monkey had it too easy: unlike his limited keyboard I have -(besides space) every character in the ASCII range **`0<=126`** that -**`isprint()`** returns non-zero except that only capital letters are included; +(besides space) every character in the ASCII range `0<=126` that +`isprint()` returns non-zero except that only capital letters are included; the file [prog.alt.c](prog.alt.c) has a slightly smaller keyboard. There are some additional features I have added (including two Easter eggs); amongst others: ability to change the target string and maximum length. See\ @@ -171,8 +171,8 @@ ability to change the target string and maximum length. See\ more details. In its simplest invocation this program will work its way (using a genetic -algorithm) towards the solution of the string **`METHINKS IT IS LIKE A WEASEL`** -(note that I use **`toupper()`** so it doesn't matter what case the input is the +algorithm) towards the solution of the string `METHINKS IT IS LIKE A WEASEL` +(note that I use `toupper()` so it doesn't matter what case the input is the comparison and output will always be capitalised). [Infinite Monkey Theorem]: https://en.wikipedia.org/wiki/Infinite_monkey_theorem @@ -201,7 +201,7 @@ try and show the way they work) for those interested I will cite the summary: **SPOILER WARNING: Some of the below might help you follow the code more easily.** -For each *generation* there is a total of **`N`** *offspring*; generation 0 is +For each *generation* there is a total of `N` *offspring*; generation 0 is the pseudo-randomly initialised array *without parents.* Each offspring has its own *chromosome* to be compared to the *target string* and a *fitness score*; the higher the fitness score the more likely it will be a *parent of the next @@ -220,11 +220,11 @@ every character will be assigned a value*). Before mutation the offspring chromosome will be printed; after mutation it will show what it was mutated to (on the same output line). After the new generation has been sequenced the loop goes back to the top and it starts all over until the maximum number of -generations **`SIZE_MAX - 1`** is reached or the target chromosome has been +generations `SIZE_MAX - 1` is reached or the target chromosome has been found. Note that the generation is checked *before the scoring takes place* by a prefix -increment equality check; when the generation is **`SIZE_MAX - 1`** the fitness +increment equality check; when the generation is `SIZE_MAX - 1` the fitness test loop will not be entered; instead the outer loop will end after printing: > Too many attempts, blaming the monkey Eric even if he isn't typing or doesn't exist. Bye. @@ -236,7 +236,7 @@ exist. The second to last example limitation example note (it's improved in the final but this is relevant) they give is: > The judges might not have a pet fish named Eric, so might want to state: ->\ +> > This entry factors integers between 1 and 2305567963945518424753102147331756070. > Attempting to factor anything else will cause the program to insult your > pet fish Eric, or in the case that you lack such a pet, will insult the @@ -248,7 +248,7 @@ After the final message they ask: The answer is this: **it is the primorial prime of 97:** the product of all prime numbers less than or equal to N; **and the primorial prime of `N == 97` is -`2305567963945518424753102147331756070`**. There is no reference to this number +`2305567963945518424753102147331756070`. There is no reference to this number in my entry but it's nonetheless possible to **change the default target to it without modifying the source code**; there are two hints in this very paragraph; the first sentence in fact: the answer to the judges' question and @@ -261,12 +261,12 @@ second time for the same entry. ### On user monkey errors -If the generation reaches **`SIZE_MAX - 1`** I consider it a monkey (or if you +If the generation reaches `SIZE_MAX - 1` I consider it a monkey (or if you insist: user) error; if the user insists on being so petulant enough as to try such a ridiculous set of parameters in an attempt to make it be no more successful than a monkey typing *then it shouldn't be any more successful than a monkey; if it by chance reaches the target it's because a monkey could too!* -Either way unless the number reaches **`SIZE_MAX - 1`** the monkey Eric won't be +Either way unless the number reaches `SIZE_MAX - 1` the monkey Eric won't be blamed. It should be noted that depending on the parameters (size of chromosome, number of offspring, the string itself) the program could take quite a lot of system resources; and whether the OS kills it, Eric the monkey falls asleep or @@ -296,8 +296,8 @@ Skip to [Options](#options). The keyboard, as noted, has more than just the alphabet and space. To be precise the following characters are acceptable; it equates to this in C (note -it includes a literal space **`' '`** but it doesn't include other -**`isspace()`** characters) and this is why some of the characters are escaped: +it includes a literal space `' '` but it doesn't include other +`isspace()` characters) and this is why some of the characters are escaped: const char keyboard[]=" !\"#$<%:>&'()*+,-./0123456789;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~"; @@ -316,7 +316,7 @@ Skip to [Spoilers](#spoiler). There are a number of options you can pass to the program besides the target string; some I will document here (the summary being in the man page). You can -join options but there is a caveat with spaces and **`-r`** option as well as +join options but there is a caveat with spaces and `-r` option as well as the target string (see below). **Enable quiet output:** @@ -332,7 +332,7 @@ output) and the final answer. -r -Please note that there cannot be a space between the **`-r`** and the number. +Please note that there cannot be a space between the `-r` and the number. This is to simplify the parsing of options. As for combining options you can do any of the following (amongst others): @@ -342,9 +342,9 @@ any of the following (amongst others): -q -r5 The third invocation will set quiet output and have no valid value to parse for -the mutation rate and **`strtol()`** in this case returns 0. **`strtol()`** can +the mutation rate and `strtol()` in this case returns 0. `strtol()` can legitimately return 0 but in no instance is it valid input in this program: the -valid mutation rate is **`>= 1 && <= 100`**. +valid mutation rate is `>= 1 && <= 100`. When the mutation rate is out of range it does something interesting: take a look at the output and compare it to the output when the range is valid. Can you @@ -371,12 +371,12 @@ decent parameters - come to an answer here but if necessary kill the program. offspring output. If you still don't see what it is and want to know see **[Spoilers](#spoiler)** below. -Finally any argument that doesn't start with a **`-`** passed into the program -will become the target string. The same rule applies to the number for **`-r`**: +Finally any argument that doesn't start with a `-` passed into the program +will become the target string. The same rule applies to the number for `-r`: it must be a single parameter which means you'll need to quote the string if it has more than one word (that is it contains spaces) or anything else interpreted specially by your shell e.g. parentheses. For instance if you just want to find -**`METHINKS`** you could do one of: +`METHINKS` you could do one of: ```sh ./weasel METHINKS @@ -384,7 +384,7 @@ specially by your shell e.g. parentheses. For instance if you just want to find ./weasel 'METHINKS' ``` -If you wanted **`YOU ARE A MONKEY`**: +If you wanted `YOU ARE A MONKEY`: ```sh ./weasel "YOU ARE A MONKEY" @@ -398,12 +398,12 @@ If you do one of: ./weasel METHINKS IT IS A MONKEY ``` \ -It will search for **`MONKEY`** in both cases; in other words it's the last one. -If the string is too long given the value of **`S`** (see\ +It will search for `MONKEY` in both cases; in other words it's the last one. +If the string is too long given the value of `S` (see\ **[How to build](#build)**) it will be truncated. -If you actually do want to search for a string starting with a **`-`** you must -disable further parsing of options by using the **`-`** option itself; for +If you actually do want to search for a string starting with a `-` you must +disable further parsing of options by using the `-` option itself; for example if you were to do any of: ```sh @@ -412,14 +412,14 @@ example if you were to do any of: ./weasel -q -- -test ``` -The target string will be: **`-TEST`**. This means though that here: +The target string will be: `-TEST`. This means though that here: ```sh ./weasel -q -- -test -r5 ``` -The string to be searched would actually be **`-r5`** and the mutation rate -will remain the default because after the **`-`** option is seen it will no +The string to be searched would actually be `-r5` and the mutation rate +will remain the default because after the `-` option is seen it will no longer parse additional options: only target strings if anything left on the command line. Because of the joining of arguments this means that the first two examples of the last set of three above are equivalent i.e. the following two @@ -437,8 +437,8 @@ As for the caveat I referenced what does the following do? In fact it will set quiet output and set the target string to be '5'. So the mutation rate will be out of range, thus enabling that Easter egg, but it will likely come to an answer fairly quickly because it's just a single character. A -note on the parsing of the **`-`** option; if the program is currently parsing -**`argv[N]`**, for example, and it encounters a **`--`** then depending on where +note on the parsing of the `-` option; if the program is currently parsing +`argv[N]`, for example, and it encounters a `--` then depending on where the other options are in the command line it might still parse the options. Thus you have: @@ -466,11 +466,11 @@ If you were instead to do one of (for example): ./weasel -q -q- -r ``` -Then it *would* set quiet output then see the **`--`** (the **`-`** option -itself) and then the target string would *literally* be set to **`-r`** because -it no longer cares about the **`-`** for option parsing. In other words options -are only parsed if the first character is **`-`** and if the parser hasn't seen -the **`-`** - *in an earlier element of `argv`. This is not a bug!* +Then it *would* set quiet output then see the `--` (the `-` option +itself) and then the target string would *literally* be set to `-r` because +it no longer cares about the `-` for option parsing. In other words options +are only parsed if the first character is `-` and if the parser hasn't seen +the `-` - *in an earlier element of `argv`. This is not a bug!* ### Spoilers @@ -485,20 +485,20 @@ select characters for every character in the target string; that is to say if the string is of length 28 (the default) then all 28 characters in each offspring of each generation will be assigned a pseudo-randomly positioned character in the keyboard. If you want to enable this specially you can use the -**`-m`** option (*-m for monkey*). +`-m` option (*-m for monkey*). ### Example Invocations Skip to [Input Error Example](#error). The following examples are used to demonstrate better the command line parsing. -In order to do that though I had to first document the **`-m`** option because +In order to do that though I had to first document the `-m` option because if the mutation rate is out of range monkey mode is activated (that's the first Easter egg). But what happens if you later set a valid mutation rate? Should monkey mode be disabled? If yes how do we know if monkey mode was specially requested? There are at least two ways to go about it: I took the monkey safe ('fool safe') method; *if you explicitly request monkey mode you cannot disable -it in the same invocation of `weasel`*! +it in the same invocation of `weasel`! ```sh $ ./weasel -qr101r5r101r1r test @@ -514,51 +514,51 @@ Generation 16844 Offspring 22: TEST So in this case I joined the options in the following order: -1. **`-q`** +1. `-q` Quiet output. -2. **`-r101`** +2. `-r101` Mutation rate 101 (out of range). -3. **`-r5`** +3. `-r5` Mutation rate of 5 but note that during parsing I only print invalid mutation rate (only after parsing do I print the final mutation rate whatever it ends up being); so while it appears there is a bug, showing mutation rate out of range -three times, this is expected (given the next one, **`-r101`**). This means here +three times, this is expected (given the next one, `-r101`). This means here the typewriter was taken from Eric the monkey. -4. **`-r101`** +4. `-r101` Mutation rate to 101: this too is out of range (this is the second mutation rate out of range message). The typewriter returns to Eric. -5. **`-r1`** +5. `-r1` Set mutation rate to 1. Take that typewriter away! -6. **`-r`** +6. `-r` Set mutation rate to 0; when there are no valid characters passed to -**`strtol()`** it should return 0: this is the third message about being out of -range. Note here that **`rand()`** returns an **`int`** and **`strtol()`** -returns a **`long`** but I compare the return value of **`rand()`** to the +`strtol()` it should return 0: this is the third message about being out of +range. Note here that `rand()` returns an `int` and `strtol()` +returns a `long` but I compare the return value of `rand()` to the mutation rate; if there are any systems where the widths differ this *shouldn't -matter* because of truncation but I do in any case specifically check for **`R < -0 || R > 100`**. Either way the invalid range returns the typewriter to Eric. +matter* because of truncation but I do in any case specifically check for `R < +0 || R > 100`. Either way the invalid range returns the typewriter to Eric. -7. **`test`** +7. `test` - Finally I requested it find the string **`test`** (will search for **`TEST`**). + Finally I requested it find the string `test` (will search for `TEST`). Given that it was a short string it did find the answer relatively quickly, even in monkey mode. @@ -575,7 +575,7 @@ Generation 109 Offspring 13: TEST ``` In this case I also enabled quiet mode but I didn't join the options; the -**`-r101`** reports that it's out of range and sets monkey mode. I then specify +`-r101` reports that it's out of range and sets monkey mode. I then specify the target string and then set a valid mutation rate. This disabled monkey mode which means that it'll use the genetic algorithm. @@ -595,7 +595,7 @@ Here I also requested quiet output and then *explicitly requested that Eric the monkey types.* After this I set the mutation rate to be 101 which would have set monkey mode (*in this case only temporarily as I later set it to a valid number*) but since I have also requested monkey mode that won't matter. Then I -set the string to **`test`** and then set a valid mutation rate of 5. Now note +set the string to `test` and then set a valid mutation rate of 5. Now note that it is actually set to 5 but also note that monkey mode remains active: it also took a lot longer to come to a conclusion for even four characters. This example does demonstrate one other thing in a subtle way though. @@ -616,10 +616,10 @@ Whereas with quiet output: Of course it isn't only down to the printing but the point is it slows it down significantly. Adding an option to print every X lines would go over the limit -(**`iocccsize -i`** reports 2052!). +(`iocccsize -i` reports 2052!). Finally I'll show a default example in normal output (I omit many lines showing -instead **[...]**). Note that the real/user/sys times are from the **`time`** +instead **[...]**). Note that the real/user/sys times are from the `time` bash shell built-in utility: that isn't output from my entry. @@ -650,9 +650,9 @@ Keep in mind the way I display the generations and the fact that generation 0 has no parents; it is generation 1 that starts working towards the goal. You'll see also **(mutation)** at the end of the line at this point (if you enable monkey mode you'll find that it shows something else). The lines that only have -`**` are separators: you won't see this between generation 0 and 1 but you will +`` are separators: you won't see this between generation 0 and 1 but you will between future generations - as well as the final answer (if the answer is in -generation 0 you won't see the `**`). +generation 0 you won't see the ``). One final thing to consider is that **the program doesn't directly read from a @@ -666,17 +666,17 @@ people. Take the following invocations: (5) $ < test-strings.txt ./weasel (6) $ cat | ./weasel -Only the first invocation of **`./weasel`** will search for **`TEST`** because -the string **`test`** was explicitly passed to the program (If the file *`test`* -wasn't found by that path it would still have searched for **`TEST`**). +Only the first invocation of `./weasel` will search for `TEST` because +the string `test` was explicitly passed to the program (If the file `test` +wasn't found by that path it would still have searched for `TEST`). The second invocation will search for the default string if there is a file or -directory called *`test`*; else you will get an error about no such file or +directory called `test`; else you will get an error about no such file or directory (unless your shell for some reason doesn't consider it an error; bash most certainly does consider it an error and halts). -The third invocation would if there exists a file *`test`* cat that file and -pipe the output to **`./weasel`**; *however it will search for the default +The third invocation would if there exists a file `test` cat that file and +pipe the output to `./weasel`; *however it will search for the default string.* If there is no such file to cat then an error will be reported but without quiet mode you'd probably not even see the error. @@ -684,15 +684,15 @@ The fourth invocation will also search for the default string unless the file doesn't exist in which case you'd get an error like in the second invocation. The fifth invocation will actually search for the default string even with the -file *`test-strings.txt`* existing. As far as I am aware it's equivalent to the +file `test-strings.txt` existing. As far as I am aware it's equivalent to the third invocation except that the file exists in this case. -The final invocation will search for the default and then read from *`stdin`*; +The final invocation will search for the default and then read from `stdin`; it won't do anything with it however. What this amounts to is *if you want input from a file you have to read from the file and pass each string to the program itself*. I've included a script -*`test.sh`* and a file of sample input *`test-strings.txt`* that you can play +`test.sh` and a file of sample input `test-strings.txt` that you can play with. @@ -711,7 +711,7 @@ chmod +x test.sh The script will first try compiling the program (if necessary) and if it fails for any reason it will exit; else it will read each line in the file -*`test-strings.txt`* (if the file doesn't exist or can't be read the script will +`test-strings.txt` (if the file doesn't exist or can't be read the script will exit with return status of 1) and pass it to the program. After finding the string it'll sleep approximately 2 seconds and then read the next string (passing it to the program, continuing until all the strings have been read and @@ -724,21 +724,21 @@ stops when there are no more strings in the file - so if you try: ./test.sh -q test ``` -The final string **`test`** won't be searched for; it will however run the program +The final string `test` won't be searched for; it will however run the program in all invocations with quiet output enabled. The following are some notes about how the shell and the program interact with each other: Because the script quotes the strings that it reads from the file if you were to -put in the file: **`-q STRING`** quiet mode would be enabled; however the +put in the file: `-q STRING` quiet mode would be enabled; however the default string would be searched for. If the quotes were removed from the script it would print the final word specified. To be specific with the quotes: if in -the file you had the line **`-q STRING -m TEST`** it would enable quiet output +the file you had the line `-q STRING -m TEST` it would enable quiet output and monkey typewriter mode; but it would search for the default string. Without the quotes on the other hand it would enable quiet output, monkey typewriter and -search for **`TEST`**. In other words **if you want to pass options to the +search for `TEST`. In other words **if you want to pass options to the script you will have to directly pass the options to the script** like the above example shows (but the strings will still only be read from the -*`test-strings.txt`* file). +`test-strings.txt` file). ### Input Error Example @@ -747,10 +747,10 @@ Skip to [Obfuscation](#obfuscation). There is a type of input error, as I said, that might appear to be a bug. What actually is going on though is due to a technicality on how spaces are printed and the fact the program does not accept spaces other than a literal space\ -**` `**; when a character in the string to be found isn't in the keyboard the +` `; when a character in the string to be found isn't in the keyboard the program prints an error message and then exits (returning 1). But since the -keyboard doesn't have **`'\n'`** if you were to type a **`'`** and send a -**`'\n'`** before the closing **`'`** you might see something like: +keyboard doesn't have `'\n'` if you were to type a `'` and send a +`'\n'` before the closing `'` you might see something like: ```sh $ ./weasel '!! @@ -760,16 +760,16 @@ $ ./weasel '!! ' not in keyboard " !"#$<%:>&'()*+,-./0123456789;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`{|}~" ``` -I showed that **`'`** is in the keyboard already; however the user sent a -**`\n`** (hence the secondary prompt **`>`** on line two) before literally typing the -closing **`'`** (also line two). But in order to make it clear what character is invalid I -surround the character with **`'`**s so what you actually see after typing the -closing **`'`** and hitting Enter (or however you send the **`'\n'`**) there is -the third blank line; *but then the program prints* **`'`** followed by the -invalid character (**`'\n'`** itself which means another line break) and then -finally the closing **`'`**. Specifically **`isspace()` characters aren't +I showed that `'` is in the keyboard already; however the user sent a +`\n` (hence the secondary prompt `>` on line two) before literally typing the +closing `'` (also line two). But in order to make it clear what character is invalid I +surround the character with `'`s so what you actually see after typing the +closing `'` and hitting Enter (or however you send the `'\n'`) there is +the third blank line; *but then the program prints* `'` followed by the +invalid character (`'\n'` itself which means another line break) and then +finally the closing `'`. Specifically `isspace()` characters aren't distinctly seen like a letter, digit or symbol is: `isprint('\n') == 0 && -isspace('\n') == 1`**. You can add these characters but the output will be +isspace('\n') == 1`. You can add these characters but the output will be rather confusing and hard to read. ## **4. Obfuscation** @@ -780,10 +780,10 @@ Skip to [Beauty](#beauty). The following might be some of the techniques used in this entry: -1. Helpful and descriptive names for all variables and constants (like **`S`**) +1. Helpful and descriptive names for all variables and constants (like `S`) as well as some C keywords. -2. The way **`main()`** is declared is: +2. The way `main()` is declared is: ```c /* Special C main() handler (encapsulation): */ @@ -798,13 +798,13 @@ encapsulation and executing code is it actually nothing? And if it's nothing why is it there? If it is something what is it doing? Could it be both? Or maybe it really isn't nothing or nothing? :) -3. A special C parser called **`H()`**. It might help to observe that there +3. A special C parser called `H()`. It might help to observe that there might be recursive calls and much of the program might use it. Or so it seems. Then again it might not help to not notice it. 4. Digraphs. In their simplest form it's probably not a big deal but consider: some source code formatters don't like them at all (neither, incidentally, does -**`splint`**, which completely baulks). There also is a trick; if you try +`splint`, which completely baulks). There also is a trick; if you try translating them then depending upon how you do it there can be functional changes in the program! @@ -854,31 +854,31 @@ be made clear in the comments! :)* Skip to [Compilation](#compiling). -These two **`#define`**d constants can be redefined at compilation to modify the +These two `#define`d constants can be redefined at compilation to modify the behaviour of the program in a number of ways (see the **[Compilation](#compiling)** subsection for example invocations). Both are -capped to be no greater than **`SIZE_MAX - 1`**. This is handled by the C +capped to be no greater than `SIZE_MAX - 1`. This is handled by the C preprocessor. -**`S`** +`S` This determines the maximum size of the target string but it **must be at least -38**; this is because **`38 >= 29`** and because **`strlen("METHINKS IT IS LIKE -A WEASEL") == 28`** (which is the default target string - it would hardly be an +38**; this is because `38 >= 29` and because `strlen("METHINKS IT IS LIKE +A WEASEL") == 28` (which is the default target string - it would hardly be an implementation of the Weasel program otherwise). -There is obviously a reason **`38`** is the chosen size but the only hints I +There is obviously a reason `38` is the chosen size but the only hints I provide are those in **[How it works](#how)** and specifically an Easter egg I referenced there (it's *not the only Easter egg* but it's the only Easter egg I won't spoil; yes this ironically and amusingly means I've left a rotten egg somewhere!). -**`N`** +`N` This is the number of offspring per generation. Anything less than 4 will be set to 3 (that's not a typo!) and this is part of an Easter egg. -Be aware that depending on the size of **`S`** and **`N`** (individually and +Be aware that depending on the size of `S` and `N` (individually and together) the program will use varying amounts of memory and the larger the values the more memory it'll require. @@ -892,23 +892,23 @@ The following options **must always be passed to the compiler:** -DQ='typedef' -D'g(o)'='goto o;' -D'w(x)'="x:" -D'H(main)'='r(main)' ``` -If you want to increase the number of offspring to **`50`** and the size of the -chromosome to **`75`** you would pass to the compiler: +If you want to increase the number of offspring to `50` and the size of the +chromosome to `75` you would pass to the compiler: ```sh -DQ='typedef' -D'g(o)'='goto o;' -D'w(x)'="x:" -D'H(main)'='r(main)' -DN=50 -DS=75 ``` -If you wanted to change **`N`** to **`3`**: +If you wanted to change `N` to `3`: ```sh -DQ='typedef' -D'g(o)'='goto o;' -D'w(x)'="x:" -D'H(main)'='r(main)' -DN=3 ``` -Remember that it cannot be less than **`3`**; *more correctly if it's less than -4 it's redefined to 3* so you could have passed in **`-DN=2`** and have the same -result. Remember too that **`S`** cannot be less than **`38`**. Both **`S`** and -**`N`** are capped at **`SIZE_MAX - 1`**. +Remember that it cannot be less than `3`; *more correctly if it's less than +4 it's redefined to 3* so you could have passed in `-DN=2` and have the same +result. Remember too that `S` cannot be less than `38`. Both `S` and +`N` are capped at `SIZE_MAX - 1`. ### Portability @@ -917,7 +917,7 @@ Skip to [An aside on bugs](#bugs). This entry requires at least C99 even if you translate digraphs. The program doesn't require third-party libraries and should work on any Unix based system. It works on both 64-bit and 32-bit (but inevitably some data type sizes will be -smaller and this I believe includes **`SIZE_MAX`**). I don't think Windows gcc +smaller and this I believe includes `SIZE_MAX`). I don't think Windows gcc ports would have many issues (if any) either but I have no way to test this. Originally I tested it on the below systems. @@ -982,12 +982,12 @@ Skip to [Installing](#rpm). Any undocumented bugs are the result of insolent monkeys tampering with any number of things. That includes but is not limited to running the program on a -non-ASCII system; non little-endian; meddling with **`S`** or **`N`** too much, -changing the references to **`SIZE_MAX`** to be larger than **`SIZE_MAX`** or a -signed value (**`size_t`** is unsigned) or too small of a value; changing data +non-ASCII system; non little-endian; meddling with `S` or `N` too much, +changing the references to `SIZE_MAX` to be larger than `SIZE_MAX` or a +signed value (`size_t` is unsigned) or too small of a value; changing data types or variables; expecting really long strings - including but not limited to -the complete works of Shakespeare (hint: **`isprint('\n') == 0`** so it won't -ever find any string with **`'\n'`**) - to be found by the program in a quick +the complete works of Shakespeare (hint: `isprint('\n') == 0` so it won't +ever find any string with `'\n'`) - to be found by the program in a quick and easy fashion if ever; or any other meddling including being petulant and/or unreasonable monkeys. I will say though that there is at least one place I see after having won that could be slightly more efficient (can you find it?); I am @@ -1142,7 +1142,7 @@ for(;P("\n"),R=;P("|"))for(e=C;e=P("_"+(*u++/ 8)%2))P("|"+(*u/4)%2); ``` \ -How is **`R=;`** valid? Since I don't have the context maybe there is something +How is `R=;` valid? Since I don't have the context maybe there is something I'm missing but either way it's a funny piece. It could also be for irony itself (actually I had previously thought of somehow implementing something like that for the contest but decided for the message by itself in the end). I would @@ -1174,7 +1174,7 @@ so happy to have had you in my life. But I want to also dedicate it to (and thank) my dear friend [Martijn Schoemaker](https://www.ficture.nl) whom provided me with the spark a very long time ago (and whom has stood by me and helped me in more ways than he can know - -**`#including C`**); if it wasn't for you Martijn I wouldn't have been able to +`#including C`); if it wasn't for you Martijn I wouldn't have been able to win so consider this a recursive thank you thank you! :) I would also like to give thanks and much love to my dear friend Vicky Wilmore diff --git a/2018/ferguson/test-strings.txt b/2018/ferguson/test-strings.txt index 2839f0559..6a1c48a5f 100644 --- a/2018/ferguson/test-strings.txt +++ b/2018/ferguson/test-strings.txt @@ -1,9 +1,17 @@ YOU ARE LIKE A WEASEL YOU SMELL LIKE A WEASEL +I SMELL LIKE A WEASEL YOU ARE A WEASEL I AM THE WEASEL I AM THE WALRUS YOU ARE THE WALRUS YOU ARE THE WEASEL PAULINE HANSEN ACTS LIKE A WEASEL +METHINKS IT IS LIKE A WEASEL +MONKEY SEE, MONKEY DO! +STOP MONKEYING ABOUT! +WHAT DO YOU MEAN I'M A MONKEY?! +PROBLEM BETWEEN KEYBOARD AND CHAIR +MY PRECIOUS. YES, MY PRECIOUS. +MY PRECIOUS! O MY PRECIOUS! IOCCC BEST USE OF WEASEL WORDS diff --git a/2018/ferguson/test.sh b/2018/ferguson/test.sh index ce92de269..c7823ea7e 100755 --- a/2018/ferguson/test.sh +++ b/2018/ferguson/test.sh @@ -8,4 +8,4 @@ while read -r f; do # NOTE: ./weasel $* $f would just be the final word sleep 2 done < test-strings.txt || exit 1 -echo "All done. Goodbye." +echo "All done. Goodbye, you old monkeying weasel!" From ccfafbb2a2ff4ec674404781cf0a3c5f2951cacc Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Sun, 22 Oct 2023 08:34:32 -0700 Subject: [PATCH 2/6] Updates to 1984/decot wrt alt/orig code Update formatting of the alt code (heading levels) and added subsections for how to build and run (rather than having it all together). Updated the historical remarks as well. It's important in this case to refer to decot.orig.c and not decot.alt.c because the orig code is the one that was submitted whereas the alt code is the modification the judges made. --- 1984/decot/README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/1984/decot/README.md b/1984/decot/README.md index e5d5514d6..f97928731 100644 --- a/1984/decot/README.md +++ b/1984/decot/README.md @@ -16,10 +16,19 @@ make all ### Alternate code: -To try the original code that requires `-traditional-cpp`: +This alternate code, the original, requires a compiler that supports +`-traditional-cpp` or an old enough compiler. If you have such a compiler you +can use this entry. + +#### To build: ```sh make alt +``` + +#### To run: + +```sh ./decot.alt ``` @@ -45,7 +54,8 @@ to: for(signal=0;*k *x * __FILE__ *i;) do { ``` -To see what we mean look at the [original source file](decot.orig.c). +To see what we mean look at the [original source file](decot.orig.c). The +[alternate code](decot.alt.c) is the version that we modified. ## Author's remarks: From 02e6e9e37f260e01c1a223bb31e1bada12426b61 Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Sun, 22 Oct 2023 08:50:59 -0700 Subject: [PATCH 3/6] Minor fix in 1984/laman The judges noted that some new compilers dislike ... but that was a very long time ago now so I added in parentheses 'in 1984' to be explicit about it. --- 1984/laman/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1984/laman/README.md b/1984/laman/README.md index ec9d8f9af..9d7f0acf4 100644 --- a/1984/laman/README.md +++ b/1984/laman/README.md @@ -36,7 +36,7 @@ This code should run you in circles. ## Judges' remarks: -Some new compilers dislike lines 6 and 10 of the source, so we changed +Some new compilers (in 1984) dislike lines 6 and 10 of the source, so we changed them from: ```c From 35570d4e90328c1857f58376d373238e9d630600 Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Sun, 22 Oct 2023 08:53:23 -0700 Subject: [PATCH 4/6] Minor format fixes in 1984/mullender --- 1984/mullender/README.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/1984/mullender/README.md b/1984/mullender/README.md index 663ca90ad..83989c595 100644 --- a/1984/mullender/README.md +++ b/1984/mullender/README.md @@ -19,7 +19,7 @@ make all ./mullender ``` -NOTE: If your machine is not a [VAX-11](https://en.wikipedia.org/wiki/VAX-11) +NOTE: if your machine is not a [VAX-11](https://en.wikipedia.org/wiki/VAX-11) or [PDP-11](https://en.wikipedia.org/wiki/PDP-11), this program will not execute correctly. In later years, machine dependent code was discouraged. An alternate version that will work with other systems is provided as alternate code below. @@ -83,10 +83,11 @@ the rules were changed, requesting non-machine specific code. This program was selected for the 1987 t-shirt collection. -The C startup routine (via [crt0.o](https://en.wikipedia.org/wiki/Crt0)) transfers control to a location named `main`. -In this case, `main` just happens to be in the data area. The array of `short`s, -which has been further obfuscated by use of different data types, just happens -to form a meaningful set of [PDP-11](https://en.wikipedia.org/wiki/PDP-11) and +The C startup routine (via [crt0.o](https://en.wikipedia.org/wiki/Crt0)) +transfers control to a location named `main`. In this case, `main` just happens +to be in the data area. The array of `short`s, which has been further +obfuscated by use of different data types, just happens to form a meaningful set +of [PDP-11](https://en.wikipedia.org/wiki/PDP-11) and [VAX](https://en.wikipedia.org/wiki/VAX) instructions. The first word is a [PDP-11](https://en.wikipedia.org/wiki/PDP-11) branch @@ -121,12 +122,26 @@ close to as the original as possible we used a copy of in the *fabulous* [Unix History Repo](https://github.com/dspinellis/unix-history-repo/tree/Research-Release). -This tool can be built by running: +#### To build: + +`gentab.c` can be built like: + ```sh make gentab ``` +#### To use: + +```sh +./gentab file +``` + +#### Try: + +```sh +./gentab gentab +``` ## Author's remarks: From a7e2f8001b0d94ec7fc28667355ad562d20dfd1c Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Sun, 22 Oct 2023 08:55:16 -0700 Subject: [PATCH 5/6] Format fix in 1985/lycklama wrt original code --- 1985/lycklama/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/1985/lycklama/README.md b/1985/lycklama/README.md index 93c81c9b4..46132ad0d 100644 --- a/1985/lycklama/README.md +++ b/1985/lycklama/README.md @@ -61,7 +61,9 @@ which would set it at 700. Then, whether you use the default value or not, try: As explained above, because modern systems run this entry way too fast to fully appreciate what it does, we encourage you to first try the alternate version. After this, however, you might wish to try the original version, fixed for -modern systems. To do this: +modern systems. + +#### To build: ```sh make all From 4ffebe9a1db5bd4989f4dccfe14d6a6c96842299 Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Sun, 22 Oct 2023 08:58:57 -0700 Subject: [PATCH 6/6] Format fixes in 1985/sicherman/README.md --- 1985/sicherman/README.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/1985/sicherman/README.md b/1985/sicherman/README.md index 099594189..3ea910406 100644 --- a/1985/sicherman/README.md +++ b/1985/sicherman/README.md @@ -8,6 +8,13 @@ Col. G. L. Sicherman make all ``` +## To use: + +```sh +./sicherman < file + +echo foo | ./sicherman +``` ## Try: @@ -15,18 +22,35 @@ make all ./sicherman < sicherman.c echo IOCCC | ./sicherman + +./sicherman < sicherman.c | ./sicherman ``` ### Alternate code: -If you do have a compiler that supports `-traditional-cpp` you may compile the -original like: +This alternate version, which is the original entry, requires either an old +enough compiler or a compiler that supports `-traditional-cpp`. If you have such +a compiler you can try this version. + +#### To build: + ```sh make alt ``` -Use `sicherman.alt` as you would `sicherman`. +#### To run: + +```sh +./sicherman.alt < file +``` + +#### Try: + + +```sh +./sicherman.alt < README.md | ./sicherman.alt +``` ## Judges' remarks: