Format fix and other updates to 2014/endoh1
Add make rake and rake.sh script that runs the rake command and then runs prog (if all okay). If rake is not installed it reports this and checks that gem is installed (as gem installs rake) and if gem is not installed it reports that and tells one how to get it and what to run after that. If rake is not installed and gem is it tells the user what to do as well. After this it tells the user to run the rule or rake.sh again. If rake is installed but it fails to work it suggests to install a specific gem (that the author noted in the spoilers file) and then trying again. An important note on the check for gem is it does not tell one how to install it but rather use it so if it's run again and for some reason rake is not installed then it will report the same issue again. The reason it is done this way is because the ruby file the README.md file suggests to be executed has an error in it, at least in macOS. This script should in any event simplify the usage of the entry. The read_me.md file was renamed to spoilers.md to be clearer in purpose: it contains spoilers and just having it be read_me.md is not clear. Updated the todo: now entries up through all of 2013 and up through 2014/endoh1 have had the first pass of the README.md files: the format fixes. These files will have to be typo checked next. Also YYYY/README.md files have been checked through 2001 with the caveat that some changes have to be done with them namely to do with email addresses (and UUCP addresses) that no longer exist. These things are now noted and it's noted that format fixes is a prerequisite of typo checks.
This commit is contained in:
1 parent
7f28d5586c
commit
b032564f30
9 files changed
+278
-166
No files matched your search
@@ -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
|
||||
@@ -139,6 +139,9 @@ main.c: prog
|
||||
${RM} -f $@
|
||||
./${PROG} > $@
|
||||
|
||||
rake: Rakefile rake.sh
|
||||
@./rake.sh
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: data ${ALT_TARGET}
|
||||
|
||||
+31
-5
@@ -1,8 +1,9 @@
|
||||
# Most square (YODA award)
|
||||
|
||||
Yusuke Endoh
|
||||
<mame@ruby-lang.org>
|
||||
<https://github.com/mame/>
|
||||
Yusuke Endoh<br>
|
||||
<mame@ruby-lang.org><br>
|
||||
<https://github.com/mame/>
|
||||
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:
|
||||
|
||||
|
||||
Executable
+44
@@ -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
|
||||
@@ -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[]="<main code>int main() { <VM code> }";
|
||||
int main() { <VM code>; }
|
||||
|
||||
* `<VM code>` : An own VM implementation (written in C) that executes the main code
|
||||
* `<main code>` : An object code of quine and QR code encoder (written in the assembly language of the VM)
|
||||
|
||||
`<main code>` (about 1100 bytes) appears once
|
||||
and `<VM code>` (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 `<main code>` and `<VM code>`.
|
||||
|
||||
* 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 `<VM code>`,
|
||||
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.
|
||||
@@ -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[]="<main code>int main() { <VM code> }";
|
||||
int main() { <VM code>; }
|
||||
```
|
||||
|
||||
* `<VM code>` : An own VM implementation (written in C) that executes the main code
|
||||
* `<main code>` : An object code of quine and QR code encoder (written in the assembly language of the VM)
|
||||
|
||||
`<main code>` (about 1100 bytes) appears once and `<VM code>` (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 `<main
|
||||
code>` and `<VM code>`.
|
||||
|
||||
* 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 `<VM code>`, 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.
|
||||
@@ -1,8 +1,9 @@
|
||||
# Best use of bioinformatics
|
||||
|
||||
Yusuke Endoh
|
||||
<mame@ruby-lang.org>
|
||||
<https://github.com/mame/>
|
||||
Yusuke Endoh<br>
|
||||
<mame@ruby-lang.org><br>
|
||||
<https://github.com/mame/><br>
|
||||
Mastodon: [@mame@ruby.social](https://ruby.social/@mame)
|
||||
|
||||
## To build:
|
||||
|
||||
|
||||
+16
-1
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user