diff --git a/2014/endoh1/.gitignore b/2014/endoh1/.gitignore index 2d72bda99..fe71f8ded 100644 --- a/2014/endoh1/.gitignore +++ b/2014/endoh1/.gitignore @@ -4,3 +4,11 @@ prog treacle treacle.c prog.orig +m.c +src/ +src.zip +seq.txt +alpha.txt +ast.txt +reg.txt +raw.txt diff --git a/2014/endoh1/Makefile b/2014/endoh1/Makefile index 27466657f..ef98edf25 100644 --- a/2014/endoh1/Makefile +++ b/2014/endoh1/Makefile @@ -139,6 +139,9 @@ main.c: prog ${RM} -f $@ ./${PROG} > $@ +rake: Rakefile rake.sh + @./rake.sh + # alternative executable # alt: data ${ALT_TARGET} diff --git a/2014/endoh1/README.md b/2014/endoh1/README.md index ce1ce6971..75fffef06 100644 --- a/2014/endoh1/README.md +++ b/2014/endoh1/README.md @@ -1,8 +1,9 @@ # Most square (YODA award) - Yusuke Endoh - - +Yusuke Endoh
+
+ +Mastodon: [@mame@ruby.social](https://ruby.social/@mame) ## To build: @@ -25,18 +26,43 @@ make main ./main Hello ``` +Also try: + +```sh +make rake +``` + +which will run the [rake.sh](rake.sh) script and then `prog` if all is built +okay. If `rake` is not installed then it will check that `gem` is installed. If +`gem` is not installed it will tell you where to get it and then tell you how to +install `rake`. Otherwise, if `rake` is installed it will try running `rake ` +and if that fails to run it will tell you to run a `gem` command as either root +or via sudo and then to try running `make rake` or `./rake.sh` again. If `rake` +succeeds it will run `./prog` which can be used to build `main.c`. + +What is the difference between running `./prog` and `main`? + + ## Judges' remarks: Big terminals with tiny fonts have their uses in certain cases. One of them is: +```sh +make treacl +./treacl +``` + +which is shorthand for: + ```sh ./prog < prog.c > treacle.c make treacle ./treacle ``` -When using a smart phone to read the output, you may need to + +When using a smartphone to read the output, you may need to step back to see the bigger picture because that picture is worth more than 1000 words. @@ -48,7 +74,7 @@ You may want to use a large display with a very small-font terminal. ### Spoiler -Decompress `src.zip` if you need explanation. +See [spoilers.md](spoilers.md). ## Copyright and CC BY-SA 4.0 License: diff --git a/2014/endoh1/rake.sh b/2014/endoh1/rake.sh new file mode 100755 index 000000000..0a599718d --- /dev/null +++ b/2014/endoh1/rake.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +if ! type -P rake >/dev/null 2>&1; then + echo "'rake' cannot be found." 1>&2 + echo "'rake' must be installed to run make rake or $0." 1>&2 + echo "" 1>&2 + if ! type -P gem >/dev/null 2>&1; then + echo "" 1>&2 + echo "'gem' cannot be found." 1>&2 + echo "To install 'rake' you will need the 'gem' tool." 1>&2 + echo "Please see the following GitHub repo for rubygems:" 1>&2 + echo "" 1>&2 + echo " https://github.com/rubygems/rubygems" 1>&2 + echo "" 1>&2 + echo "and then run:" 1>&2 + echo "" 1>&2 + echo " cd rubygems && exe/gem install rake" 1>&2 + echo "" 1>&2 + echo "and then try running make rake or running $0 again." 1>&2 + else + echo "Please run the following command as root or via sudo:" 1>&2 + echo "" + echo " gem install rake" 1>2 + echo "" 1>&2 + echo "and then try running make rake or running $0 again" 1>&2 + fi + exit 1 +elif ! rake 2>&1; then + echo "" 1>&2 + echo "It appears that using rake failed. Please try running the following" 1>&2 + echo "command as root or via sudo: " 1>&2 + echo "" 1>&2 + echo " gem install ruby-minisat" 1>&2; + echo "" 1>&2 + echo "and then try running make rake or $0 again" 1>&2 + exit 1 +elif [[ ! -x prog ]]; then + echo "" 1>&2 + echo "could not compile prog" 1>&2 + exit 1 +else + ./prog 1>&2 + exit "$?" +fi diff --git a/2014/endoh1/read_me.md b/2014/endoh1/read_me.md deleted file mode 100644 index 4a9858257..000000000 --- a/2014/endoh1/read_me.md +++ /dev/null @@ -1,149 +0,0 @@ -# Q(uine)R code generator - -## What is difficult? - -As you may know, QR code (specification: ISO/IEC 18004) is quite complex. -It requires a bit stream, Reed-Solomon codes, BCH codes, -data relocation, big (and irregular!) numerical tables, -human-oriented pattern arrangement (difficult to implement by a small program), -etc. - -On the other hand, a quine has a big restriction: -it needs to have two copies of the program! - -Do you think that it is possible to write QR code encoder in C within *1kB*? - - -## How did I achieve that? - -It is known that we can mitigate the quine restriction by `eval`. -For example, this is a quine written in Ruby: - - eval s="print 'eval s='; p s" - -Note that `print` appears just once in the program. - -To emulate this approach in C, I adopted the following structure. - - char s[]="
int main() { }"; - int main() { ; } - -* `` : An own VM implementation (written in C) that executes the main code -* `
` : An object code of quine and QR code encoder (written in the assembly language of the VM) - -`
` (about 1100 bytes) appears once -and `` (about 450 bytes) appears twice. -So the whole code is about 1100 + 450 * 2 = 2000 bytes. Hooray! - - -## What sort of VM is that? - -The VM is a kind of stack machine which makes the object code compact. -The instruction set is carefully selected -to minimize the sizes of both `
` and ``. - -* 21 integer registers access - * read, write, inc-and-read, dec-and-read -* Binary operations - * add, sub, mul, div, mod, xor, less than, equal, rshift -* Stack operation - * push (an immediate value) -* Heap access - * load, store -* If-Then-Else -* While-Loop -* Misc. - * putchar, exit - -The instructions have variable length, -but many of them are represented as one printable character. -(See `machine.rb` and `assemble.rb` in detail.) -The mapping between instructions and characters is also carefully designed -to minimize ``, -which makes the resulted program non-human-readable. - - -## How did I create the main code? - -It is too tedious to write the machine language directly. -So I wrote the source code in Ruby syntax and created a Ruby-to-VM compiler -that involves alpha renaming and automatic register allocation -only for this purpose. - -* `src.rb`: the source code of QR code encoder written in Ruby syntax. -* `vm.c`: the source code of the VM. - -The compiler tool chain is the following. - - src.rb interp.c - | | - | [parse.rb] | - V | - ast.txt | - | | - | [serialize.rb] | - V | - seq.txt | - | | - | [alpha.rb] | - V | - alpha.txt | - | | - | [register.rb] | - V | - reg.txt | - | | - | [assemble.rb] | - V | - raw.txt | - | | - +---------+---------+ - | - | [link.rb] - V - main.c - | - | [gen-prog.c] - V - prog.c - -* `parse.rb` converts Ruby to AST. -* `serialize.rb` converts AST to intermediate instruction sequence. -* `alpha.rb` applies "alpha-renaming" to the instruction sequence. -* `register.rb` applies "register allocation". -* `assemble.rb` converts the sequence to the final stack-machine instructions. -* `interp.c` is an implementation of the VM. -* `link.rb` generates `main.c` by linking the instructions and interpreter source. -* `gen-prog.c` generates `prog.c` based on `main.c` - -You can run the process by `rake` command. `ruby-minisat` gem is needed. - - $ gem install ruby-minisat - $ rake - -## Tools - -I checked that the following QR code readers can read the output of my program. - - * Linux: [ZBar bar code reader][1] - * Android: [Barcode Scanner][2] - -[1]: http://zbar.sourceforge.net/ -[2]: https://play.google.com/store/apps/details?id=com.google.zxing.client.android] - -You can use `tool.rb` to convert the output to a png file. - - $ ./main Hello | ruby tool.rb > hello.png - - $ zbarimg -q hello.png - QR-Code:Hello - - $ ruby tool.rb prog.c - $ ruby tool.rb prog.c | ruby tool.rb - -## Limitations - -* QR code error correction level is fixed to L (Low). -* It supports only byte mode (not numeric, alphanumeric, kanji mode...) -* The mask pattern is fixed to 4. -* The mask is not applied to the remained bits. diff --git a/2014/endoh1/spoilers.md b/2014/endoh1/spoilers.md new file mode 100644 index 000000000..87bab360f --- /dev/null +++ b/2014/endoh1/spoilers.md @@ -0,0 +1,155 @@ +# Q(uine)R code generator + +## What is difficult? + +As you may know, QR code (specification: ISO/IEC 18004) is quite complex. It +requires a bit stream, Reed-Solomon codes, BCH codes, data relocation, big (and +irregular!) numerical tables, human-oriented pattern arrangement (difficult to +implement by a small program), etc. + +On the other hand, a quine has a big restriction: +it needs to have two copies of the program! + +Do you think that it is possible to write QR code encoder in C within *1kB*? + + +## How did I achieve that? + +It is known that we can mitigate the quine restriction by `eval`. +For example, this is a quine written in Ruby: + + eval s="print 'eval s='; p s" + +Note that `print` appears just once in the program. + +To emulate this approach in C, I adopted the following structure. + +``` +char s[]="
int main() { }"; +int main() { ; } +``` + +* `` : An own VM implementation (written in C) that executes the main code +* `
` : An object code of quine and QR code encoder (written in the assembly language of the VM) + +`
` (about 1100 bytes) appears once and `` (about 450 bytes) +appears twice. So the whole code is about 1100 + 450 * 2 = 2000 bytes. Hooray! + + +## What sort of VM is that? + +The VM is a kind of stack machine which makes the object code compact. The +instruction set is carefully selected to minimize the sizes of both `
` and ``. + +* 21 integer registers access + * read, write, inc-and-read, dec-and-read +* Binary operations + * add, sub, mul, div, mod, xor, less than, equal, rshift +* Stack operation + * push (an immediate value) +* Heap access + * load, store +* If-Then-Else +* While-Loop +* Misc. + * putchar, exit + +The instructions have variable length, but many of them are represented as one +printable character. (See `machine.rb` and `assemble.rb` in detail.) The +mapping between instructions and characters is also carefully designed to +minimize ``, which makes the resulted program non-human-readable. + + +## How did I create the main code? + +It is too tedious to write the machine language directly. So I wrote the source +code in Ruby syntax and created a Ruby-to-VM compiler that involves alpha +renaming and automatic register allocation only for this purpose. + +* [src.rb](src.rb): the source code of QR code encoder written in Ruby syntax. +* [vm.c](vm.c): the source code of the VM. + +The compiler tool chain is the following. + +``` +src.rb interp.c + | | + | [parse.rb] | + V | +ast.txt | + | | + | [serialize.rb] | + V | +seq.txt | + | | + | [alpha.rb] | + V | +alpha.txt | + | | + | [register.rb] | + V | +reg.txt | + | | + | [assemble.rb] | + V | +raw.txt | + | | + +---------+---------+ + | + | [link.rb] + V + main.c + | + | [gen-prog.c] + V + prog.c +``` + +* [parse.rb](parse.rb) converts Ruby to AST. +* [serialize.rb](serialize.rb) converts AST to intermediate instruction sequence. +* [alpha.rb](alpha.rb) applies "alpha-renaming" to the instruction sequence. +* [register.rb](register.rb) applies "register allocation". +* [assemble.rb](assemble.rb) converts the sequence to the final stack-machine instructions. +* [interp.c](interp.c) is an implementation of the VM. +* [link.rb](link.rb) generates `main.c` by linking the instructions and interpreter source. +* [gen-prog.c](gen-prog.c) generates [prog.c](prog.c) based on `main.c`. + +You can run the process by `rake` command. `ruby-minisat` gem is needed. + +```sh +$ gem install ruby-minisat +$ rake +``` + +## Tools + +I checked that the following QR code readers can read the output of my program. + +* Linux: [ZBar bar code reader][1] + +### 2023 note from the judges: + +The author also tested an Android app called Barcode Scanner] which used to be +found at +`https://play.google.com/store/apps/details?id=com.google.zxing.client.android` +but it appears to no longer exist. + +[1]: http://zbar.sourceforge.net/ + +You can use `tool.rb` to convert the output to a png file. + + $ ./main Hello | ruby tool.rb > hello.png + + $ zbarimg -q hello.png + QR-Code:Hello + + $ ruby tool.rb prog.c + $ ruby tool.rb prog.c | ruby tool.rb + +## Limitations + +* QR code error correction level is fixed to L (Low). +* It supports only byte mode (not numeric, alphanumeric, kanji mode...) +* The mask pattern is fixed to 4. +* The mask is not applied to the remained bits. diff --git a/2014/endoh2/README.md b/2014/endoh2/README.md index 2981b1b28..a717641dd 100644 --- a/2014/endoh2/README.md +++ b/2014/endoh2/README.md @@ -1,8 +1,9 @@ # Best use of bioinformatics - Yusuke Endoh - - +Yusuke Endoh
+
+
+Mastodon: [@mame@ruby.social](https://ruby.social/@mame) ## To build: diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index 3fc2c2caf..bf46a67f7 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -1806,7 +1806,22 @@ It did not compile because a value was left off the `return` statement. Cody added this as alternate code just for fun and so one can more easily see the difference to really appreciate the obfuscation. -## [2014/maffiodo1](2014/maffiodo1/maffiodo1.c) ([README.md](2014/maffiodo1/README.md])) +## [2014/endoh1](2014/endoh1/prog.c) ([README.md](2014/endoh1/README.md])) + +Cody added the [rake.sh](2014/endoh1/rake.sh) script and `make rake` rule that +runs the script. This script will check that `rake` is installed and if it is +not it will report this and then check that `gem` is installed. It checks that +`gem` is installed in this case because `gem` is how you install `rake`. If +`gem` is not installed it tells you to get it along with how to install `gem`. +Then it tells you how to install `rake`. If `rake` fails to run then it tells +you to install a specific gem and then to try again. Finally if `rake` succeeds +it will verify that `prog` is executable and if it is it will run it. + +**_Barely_** worth noting but done nonetheless, Cody renamed the `read_me.md` +file to [spoilers.md](2014/endoh1/spoilers.md) to be clearer in its purpose as +it is a file with spoilers. + +## [2014/maffiodo1](2014/maffiodo1/prog.c) ([README.md](2014/maffiodo1/README.md])) Cody fixed the build for this entry: it does not require SDL2 but SDL1 so there were linking errors. diff --git a/todo.md b/todo.md index 8bb8089b7..277d54cf4 100644 --- a/todo.md +++ b/todo.md @@ -1,5 +1,5 @@ # A todo list of known things to check and/or do -*Last updated: Tue 10 Oct 2023 13:08:59 UTC* +*Last updated: Mon 16 Oct 11:22:52 UTC 2023* This document is primarily for [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) as he (that is I :-) ) wanted a way @@ -32,10 +32,16 @@ mind that abuses a bug in a now very old gcc version - this obviously cannot be fixed but I added an alt version that does what it used to do so it's fine) but many certainly can be - and actually most have been - fixed. -- Check for typos in README.md files. Although I did up through I believe 2011 I -have to do another pass through all except that as of 12 July 2023 I went -through 1984 and 1985. At the same time the formatting has to be / is being -checked. +- Format fix remaining README.md files. As of **16 October 2023** the entries of +years through 2013 and up through 2014/endoh1 have been checked. As for the +`YYYY/README.md` files years up through 2001 have had a first pass but some +things have to be done in those years. These things, such as dealing with old +email addresses and such, can likely be done with the typo pass (see below). + +- *AFTER* the README.md files have been format fixed: check for typos in +README.md files. Although I did up through I believe 2011 I have to do another +pass through all except that as of 12 July 2023 I went through 1984 and 1985. At +the same time the formatting has to be / is being checked. * UPDATE on 06 July 2023: some while back I noticed that _ALL_ years will have to be checked again but most of the years checked through 2011 (I think it is but I have this vague memory I did a couple more years - that will be @@ -45,9 +51,12 @@ checked. * UPDATE on 06 July 2023: note that this does NOT include the `YYYY/README.md` files! See the below item for that. -- Go through all year README.md files that is 1984/README.md, 1985/README.md and -so on. As of *Sun 30 Apr 2023 13:45:52 UTC* the following years have been -finished: 1984, 1985, 1986, 2004, 2005. +- Go through all year README.md files: that is 1984/README.md, 1985/README.md and +so on. As of **Mon 16 Oct 11:22:52 UTC 2023** the following years have had a +first pass: 1984 through 2001. However there are changes that are required +namely to do with email addresses that no longer exist. At this point it is not +determined if this will be done with the typo pass (what should be the final +pass) or not but it's very possible that it can be just to speed things along. - Verify which README.md files have not been checked for correct formatting and fix any issues.