Fix 2004/kopczynski and format fix README.md

The fix is that we cannot pass -ON to the compiler. With -ON it enters
an infinite loop as the variable l goes up, not down.

Format fix README.md.

Add kopczynski-a to show what happens when it's not a number.
This commit is contained in:
Cody Boone Ferguson committed 2023-04-26 04:38:26 -07:00
1 parent e44a1ec7a5
commit cfc8c6a412
3 files changed
+85 -72

No files matched your search

+1 -1
View File
@@ -66,7 +66,7 @@ CINCLUDE=
# Optimization # Optimization
# #
OPT= -O3 OPT=
# Default flags for ANSI C compilation # Default flags for ANSI C compilation
# #
+76 -71
View File
@@ -1,12 +1,8 @@
# Best one-liner # Best one-liner
Eryk Kopczynski Eryk Kopczynski
Faculty of Mathematics, Informatics and Mechanics Poland
ul. Banacha 2 <http://www.mimuw.edu.pl/~erykk/>
02-097 Warszawa
Poland
http://www.mimuw.edu.pl/~erykk/
## To build: ## To build:
@@ -20,6 +16,11 @@ make
./kopczynski < input_file ./kopczynski < input_file
``` ```
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) reported that this
entry cannot be optimised by the compiler if it's to work. He also added the
file [kopczynski-a](kopczynski-a) to demonstrate what happens when art more like
a letter is fed to the program. Thank you Cody!
## Try: ## Try:
```sh ```sh
@@ -31,6 +32,14 @@ make
./kopczynski < kopczynski-11 ./kopczynski < kopczynski-11
``` ```
Also try:
```sh
./kopczynski < kopczynski-a
```
What happens?
### Alternate code ### Alternate code
The judges modified the program to print its result. The original The judges modified the program to print its result. The original
@@ -47,7 +56,7 @@ Then try:
echo $? echo $?
``` ```
## Judges' remarks ## Judges' remarks:
What is in a line? A lot when you obfuscate the way Eryk Kopczynski What is in a line? A lot when you obfuscate the way Eryk Kopczynski
did it. This small one line program is an outstanding technical did it. This small one line program is an outstanding technical
@@ -69,10 +78,10 @@ Here is a related puzzle: how to continue the sequence:
1, 0, 0, 0, 0, 0, 1, 0, 2, 1, ... 1, 0, 0, 0, 0, 0, 1, 0, 2, 1, ...
With certain arguments, you can alter the exit value. Can you figure With certain arguments, you can alter the exit value / output. Can you figure
out how and why? out how and why?
## Author's remarks ## Author's remarks:
The program proves it is not as hard to recognize numbers. The current The program proves it is not as hard to recognize numbers. The current
one liner version should correctly recognize all numbers from 8 to 11. one liner version should correctly recognize all numbers from 8 to 11.
@@ -81,112 +90,108 @@ recognize negatives, zeros which have dots or slashes inside them,
digits should be separated, and numbers should be "complete".) digits should be separated, and numbers should be "complete".)
This program returns the number as its exit status. (In most shells, This program returns the number as its exit status. (In most shells,
you can see the exit status of the last command with 'echo $?' (or you can see the exit status of the last command with `echo $?` (or
just '$?').) just `$?`).)
[[NOTE: The judges altered the primary version to output a number.]] **NOTE: The judges altered the primary version to output a number.**
On the input, give numbers formed as a sequences of empty spaces and # On the input, give numbers formed as a sequences of empty spaces and #
signs (you can also use dots instead of spaces), ending with an empty signs (you can also use dots instead of spaces), ending with an empty
line. (No number has an empty line in it.) The program should return line. (No number has an empty line in it.) The program should return
the number from 8 to 11 that it thinks it is. the number from 8 to 11 that it thinks it is.
* The line is 131 bytes long (in 1986 165 bytes was OK, and the size * The line is 131 bytes long (in 1986, 165 bytes was OK, and the size
limit has grown from 1986...). limit has grown from 1986...).
* I have decided that it is better for this program to return the * I have decided that it is better for this program to return the
number, not to print it, but if you think otherwise, the change would number, not to print it, but if you think otherwise, the change would
cost 6 chars (plus a warning). Change 'return *' to 'printf("%d",*)'. cost 6 chars (plus a warning). Change `return *` to `printf("%d",*)`.
('$?' is shorter) (`$?` is shorter)
* I achieved some additional tightness by '-Dif=while', saved 9 chars * I achieved some additional tightness by `-Dif=while` which saved 9 chars of
of source for cost of 11 chars of build file. If I used '-DB=while', source for the cost of 11 chars of the [Makefile](Makefile). If I used
I would save 12 for 10, but I think the current version is slightly `-DB=while`, I would save 12 for 10, but I think the current version is slightly
more obfuscated. more obfuscated.
* A remark on portability: ### Portability
It only requires two's compliment arithmetics, as far as I It only requires two's complement arithmetics, as far as I know. The maximum
know. The maximum length of an input line is N-9, where length of an input line is `N-9`, where `N` is the size of `int` in bits
N is the size of int in bits (you can try to compile with (you can try to compile with an option `'-Dint=long long'` for longer
an option '-Dint=long long' for longer lines). lines).
-- Algorithm & Obfuscation -- ### Algorithm & Obfuscation
1. This program works by calculating the Euler characteristics of input, 1. This program works by calculating the [Euler
plus 9. It is the number of digits (i.e. separated #-regions) minus the characteristics](https://en.wikipedia.org/wiki/Euler_characteristic) of input,
number of holes in them. It turns out that this algorithm works plus 9. It is the number of digits (i.e. separated #-regions) minus the number
correctly for all numbers from 8 to 11. of holes in them. It turns out that this algorithm works correctly for all
numbers from 8 to 11.
2. We know that Euler characteristics is the number of "vertexes" 2. We know that [Euler
characteristics](https://en.wikipedia.org/wiki/Euler_characteristic) is the number of "vertexes"
# #
minus the number of "edges" minus the number of "edges"
## # #. .# ## # #. .#
# .# #. ('.' must be empty) # .# #. ('.' must be empty)
plus the number of "faces" plus the number of "faces"
## ##
## ##
3. If we fill all these patterns to 2x2 squares, 3. If we fill all these patterns to 2x2 squares,
#? ## #? #. .# ## #? ## #? #. .# ##
?? ?? #? .# #. ## ?? ?? #? .# #. ##
+1 -1 -1 -1 -1 +1 +1 -1 -1 -1 -1 +1
substitute all possible "values" of '?' and sum up, we get that it is substitute all possible "values" of `?` and sum them up, we get that it is
enough to calculate: enough to calculate:
#. .# ## #. .# ##
.. #. #. .. #. #.
+1 -1 -1 +1 -1 -1
Note now it is simple and obfuscated enough to be used as Note now it is simple and obfuscated enough to be used as
a "magic trick". a "magic trick".
4. I make a 16-character array; when indexed by 4-bit value which 4. I make a 16-character array; when indexed by 4-bit value which
represents the 2x2 squares, it will return a number to add/subtract represents the 2x2 squares, it will return a number to add/subtract
{-1,0,+1} `{-1,0,+1}`
5. We convert lines of input to bitmaps (N-bit integers). Additionally, 5. We convert lines of input to bitmaps (`N-bit` integers). Additionally, it is
it is heavily obfuscated by using negative numbers (two's compliment). heavily obfuscated by using negative numbers (two's complement). For example,
For example, it turns out that 6 in "z=6" in the only 1-digit number it turns out that `6` in `z=6` is the only 1-digit number which works here (and
which works here (and it's not only because we have "z>5" in the it's not only because we have `z>5` in the following `while`). The conversion
following while). The conversion routine also sets n=8 in an obfuscated routine also sets `n=8` in an obfuscated and concise way.
and concise way.
5. Since we always return the number from 8 to 11, we can calculate 6. Since we always return the number from 8 to 11, we can calculate modulo 4.
modulo 4. Instead of 16 {-1,0,+1} values, we use a 15-character string Instead of `16 {-1,0,+1}` values, we use a 15-character string which agrees
which agrees modulo 4 to the array in (4). (NUL fits very well as the modulo 4 to the array in (`4`). (`NUL` fits very well as the 16th character, so
16th character, so we use 15-character string.) we use 15-character string.)
6. Since the rule found in (3) did not produce any funny messages, I 7. Since the rule found in (3) did not produce any funny messages, I changed it until it did. (The `#` character to find vertexes is in the top right corner, not the top left one.) The following messages will also work instead of `has dirtiest IF`:
changed it until it did. (The # character to find vertexes is in the
top right corner, not the top left one.) The following messages will
also work instead of "has dirtiest IF":
HighlandYachter HighlandYachter
TestDirtiestTen TestDirtiestTen
has lintiest IF has lintiest IF
TighterLaughter TighterLaughter
HustlerDaughter HustlerDaughter
TighterDemoThen TighterDemoThen
They can be mixed, of course! They can be mixed, of course!
7. [[NOTE: Item 7 was removed by the judges so as to not spoil the 8. NOTE: item 8 was removed by the judges so as to not spoil the challenge of
challenge of figuring how arguments can be used to alter figuring how arguments can be used to alter the exit value.
the exit value.]]
8. The variable names are confusing. 9. The variable names are confusing.
9. Finally, the program tries to be as concise as possible. Some 10. Finally, the program tries to be as concise as possible. Some obfuscation
obfuscation comes from this. For additional obfuscation and comes from this. For additional obfuscation and conciseness, `if` means `while`.
conciseness, 'if' means 'while'.
## Copyright and CC BY-SA 4.0 License: ## Copyright and CC BY-SA 4.0 License:
+8
View File
@@ -0,0 +1,8 @@
####
######
## ##
### ###
##########
## ##
## ##