Merge pull request #1354 from xexyl/smr1994
This commit is contained in:
3 files changed
+57
-56
No files matched your search
+17
-17
@@ -30,12 +30,14 @@ For more detailed information see [1994 shapiro in bugs.md](/bugs.md#1994-shapir
|
||||
^Z
|
||||
bg
|
||||
ps x
|
||||
fg
|
||||
^C
|
||||
|
||||
./shapiro_t1
|
||||
```
|
||||
|
||||
Notice what you see in the output of `ps`!
|
||||
Notice what you see in the output of `ps`! Observe too that after you bring it
|
||||
back to the foreground what happens.
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
@@ -60,29 +62,27 @@ The basic theme (pun) of this program is:
|
||||
> ~~~~
|
||||
|
||||
|
||||
My entry ([shapiro.c](shapiro.c)) is mostly comment, formatted in the shape of a\
|
||||
clock. If you strip out the comments and look at the code you will\
|
||||
quickly realize that the comments were the important part and that\
|
||||
the code does very little (see pun above). It writes (to stdout)\
|
||||
another C program ([shapiro_t2.c](shapiro_t2.c)). This is the first level of\
|
||||
My entry ([shapiro.c](shapiro.c)) is mostly comments, formatted in the shape of a
|
||||
clock. If you strip out the comments and look at the code you will
|
||||
quickly realize that the comments were the important part and that
|
||||
the code does very little (see pun above). It writes (to `stdout`)
|
||||
another C program ([shapiro_t2.c](shapiro_t2.c)). This is the first level of
|
||||
obfuscation.
|
||||
|
||||
The second program ([shapiro_t2.c](shapiro_t2.c) if you use the Makefile
|
||||
The second program ([shapiro_t2.c](shapiro_t2.c) (use `make everything` first)
|
||||
prints a clock in the upper right hand corner of your VTxxx/ANSI display.
|
||||
|
||||
Most of the surface obfuscation in the second program
|
||||
([shapiro_t2.c](shapiro_t2.c))\
|
||||
was an attempt to make it as small as possible. You should be able to\
|
||||
see around this with cb(1) and some more intelligent variable names.\
|
||||
Once you get past this you will realize that the third level of\
|
||||
obfuscation is a six member client/server hierarchy.\
|
||||
(See the [shapiro.md](shapiro.md) file for a detailed description of the
|
||||
algorithm.)
|
||||
([shapiro_t2.c](shapiro_t2.c)) was an attempt to make it as small as possible.
|
||||
You should be able to see around this with `cb(1)` and some more intelligent
|
||||
variable names. Once you get past this you will realize that the third level of
|
||||
obfuscation is a six member client/server hierarchy. (See the
|
||||
[shapiro.md](shapiro.md) file for a detailed description of the algorithm.)
|
||||
|
||||
`lint` complains about: precedence confusion, `K` may be used before set,
|
||||
main() returns random value to invocation environment, value type used\
|
||||
inconsistently, value type declared inconsistently, function argument\
|
||||
(number) used inconsistently, function returns value which is always\
|
||||
`main()` returns random value to invocation environment, value type used
|
||||
inconsistently, value type declared inconsistently, function argument
|
||||
(number) used inconsistently, function returns value which is always
|
||||
ignored, function returns value which is sometimes ignored.
|
||||
All of which are harmless (famous last words).
|
||||
|
||||
|
||||
+32
-31
@@ -1,6 +1,6 @@
|
||||
# HINTS
|
||||
|
||||
For the first program (prog.c):
|
||||
For the first program ([shapiro.c](shapiro.c)):
|
||||
|
||||
|
||||
This is a very simple program:
|
||||
@@ -20,15 +20,14 @@ This is a very simple program:
|
||||
12. exit(0);}
|
||||
```
|
||||
|
||||
Lines 1-5 are basic stuff. Line 6 opens the source code for input. Line 7
|
||||
is the loop. Line 8 is read in each character in the file (placed in `L`)
|
||||
while not `EOF` (usually `-1`). Line 9 is an if expression which filters out all
|
||||
characters not between `J` and `J + 15`. Line 10 uses `M` to execute two different
|
||||
paths the first just stores the character in `K`. The second path combines
|
||||
the last two characters read in as high and low nibbles of a byte and
|
||||
outputs them. In effect this is a very poor ASCII to binary decoder.
|
||||
The last line is necessary so that make will not stop when it executes
|
||||
this program.
|
||||
Lines 1-5 are basic stuff. Line 6 opens the source code for input. Line 7 is the
|
||||
loop. Line 8 reads in each character in the file (placed in `L`) while not >= 0.
|
||||
Line 9 is an `if` expression which filters out all characters not between `J`
|
||||
and `J + 15`. Line 10 uses `M` to execute two different paths; the first just
|
||||
stores the character in `K` and the second path combines the last two characters
|
||||
read in as high and low nibbles of a byte and outputs them. In effect this is a
|
||||
very poor ASCII to binary decoder. The last line is necessary so that make will
|
||||
not stop when it executes this program.
|
||||
|
||||
The second program is encoded into this format and then included (mostly)
|
||||
as a comment.
|
||||
@@ -38,6 +37,7 @@ contiguous ASCII characters free for the encoding. Because of this the
|
||||
second program is mostly included as a comment. However, some of the
|
||||
characters of the encoded program are also source code for the decoder.
|
||||
|
||||
|
||||
### For the second program (with time.h):
|
||||
|
||||
```
|
||||
@@ -72,37 +72,38 @@ characters of the encoded program are also source code for the decoder.
|
||||
|
||||
```
|
||||
|
||||
Lines 1 and 2 have to be. Think of `o` in line 3 as send message with
|
||||
`j`,`k` and `m` as where, format and what. Lines 4 and 5 are all the text
|
||||
strings. Line 6 is the offsets into the time string for the hours,
|
||||
minutes and seconds. Lines 7-13 are basic stuff. Line 14 is the crux of
|
||||
the biscuit. 14 forks off `f` (6) processes each of which is connected to
|
||||
the ones above and below it with a Unix pipe. It was too difficult to
|
||||
recover the actual FD numbers for the pipe ends in line 14 so I regenerate
|
||||
them and `fdopen()` them (for use with the standard C library functions) on lines
|
||||
15 and 16. Now we have six almost identical processes. Each of which has
|
||||
two files open `h` and `i` (up and down). The only difference in each process
|
||||
is the value of `f` (`0 <= f < 6`). The five processes where `f !=0` are the
|
||||
slave processes and `f == 0` is the master. Line 17 says we are going to do
|
||||
this forever. Lines 18 and 23 differentiate between the master and the
|
||||
slaves.
|
||||
Lines 1 and 2 have to be there. Think of `o` in line 3 as send message with
|
||||
`j`,`k` and `m` as where, format and what. Lines 4 and 5 are all the text
|
||||
strings. Line 6 is the offsets into the time string for the hours, minutes and
|
||||
seconds. Lines 7-13 are basic stuff. Line 14 is the crux of the biscuit. 14
|
||||
forks off `f` (6) processes each of which is connected to the ones above and
|
||||
below it with a Unix pipe. It was too difficult to recover the actual FD numbers
|
||||
for the pipe ends in line 14 so I regenerate them and `fdopen()` them (for use
|
||||
with the standard C library functions) on lines 15 and 16. Now we have six
|
||||
almost identical processes each of which has two files open, `h` and `i` (up and
|
||||
down). The only difference in each process is the value of `f` (`0 <= f < 6`).
|
||||
The five processes where `f !=0` are the slave processes and `f == 0` is the
|
||||
master. Line 17 says we are going to do this forever. Lines 18 and 23
|
||||
differentiate between the master and the slaves.
|
||||
|
||||
Lines 19 to 22 are the slave code. Here we read in a line of text from
|
||||
`i` (down)(line 19) and remove the end of line char (line 20). On line
|
||||
`i` (down, line 19) and remove the newline char (line 20). On line
|
||||
21 if this message is for us (if the first character is our number, `f`,
|
||||
in ASCII) we do two things:
|
||||
|
||||
1. We copy the text of the message to `*c` which is really argv[0]. If you are
|
||||
1. We copy the text of the message to `*c` which is really `argv[0]`. If you are
|
||||
on the correct flavor of Unix this will change the output of the `ps(1)` command
|
||||
to the string we just put there.
|
||||
2. We send the message (not including the number) to stdout with format number 6
|
||||
2. We send the message (not including the number) to `stdout` with format number 6
|
||||
(`"\0337\033[%d;65;H%s\0338"`) If you can read VTxxx (and I read books printed
|
||||
as ANSI/VTxxx codes for fun :-) ) you know this is the sequence for:
|
||||
|
||||
remember where we are,
|
||||
go somewhere else,
|
||||
print the message,
|
||||
and return to where we started.
|
||||
```
|
||||
remember where we are,
|
||||
go somewhere else,
|
||||
print the message,
|
||||
and return to where we started.
|
||||
```
|
||||
|
||||
Line 22 says if this message is not for us (the number is bigger than ours)
|
||||
send it to `h` (up).
|
||||
|
||||
+8
-8
@@ -21,17 +21,17 @@ make all
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
Nearly every year, one or more people would submit what they claimed\
|
||||
Nearly every year, one or more people would submit what they claimed
|
||||
was the world's smallest self reproducing program. While the sizes
|
||||
of these submissions varied, a quick glance would reveal that they
|
||||
were too big, until this entry came along.
|
||||
|
||||
While strictly speaking, smr.c is not a valid C program, it is
|
||||
not an invalid C program either! Some C compilers will compile
|
||||
an empty file into a program that does nothing. But even if your
|
||||
compiler can't, the build instructions supplied with this entry
|
||||
will produce an executable file. On most systems, the stdout
|
||||
from the executable will exactly match original source.
|
||||
While strictly speaking, [smr.c](smr.c) is not a valid C program, it is not an
|
||||
invalid C program either! Some C compilers will compile an empty file into a
|
||||
program that does nothing. But even if your compiler can't, the build
|
||||
instructions supplied with this entry will produce an executable file. On most
|
||||
systems, the `stdout` from the executable will exactly match the original
|
||||
source.
|
||||
|
||||
In the future, the contest rules will specify a minimum size that is one
|
||||
character larger than this entry, forever eliminating this sort of program from
|
||||
@@ -41,7 +41,7 @@ the contest. After all, how many variations can one make on this entry? :-)
|
||||
## Author's remarks:
|
||||
|
||||
The world's smallest self-replicating program. Guaranteed.
|
||||
Produces a listing of itself on stdout.
|
||||
Produces a listing of itself on `stdout`.
|
||||
|
||||
|
||||
## Copyright and CC BY-SA 4.0 License:
|
||||
|
||||
Reference in new issue
Block a user