Merge pull request #385 from xexyl/1992-imc

Format fixes in 1992/imc/README.md
This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-04-09 13:42:57 -07:00
commit 2ee849e55d
10 files changed
+441 -320

No files matched your search

+92 -71
View File
@@ -1,36 +1,51 @@
Most Obfuscated Algorithm:
# Most Obfuscated Algorithm:
Sean Barrett
Software Construction Company
430 Southwest Parkway, #1906
College Station, TX 77840
USA
Sean Barrett
Software Construction Company
430 Southwest Parkway, #1906
College Station, TX 77840
USA
## To build:
make all
```sh
make all
```
## To run
./buzzard.1 0 10
./buzzard.1 56 720
./buzzard.1 1 521
```sh
./buzzard.1 num num
## Judges' comments
```
NOTE: this program will crash without two args.
## Try:
```sh
./buzzard.1 0 10
./buzzard.1 56 720
./buzzard.1 1 521
```
## Judges' comments:
To see good C Preprocessor buzzard.1, try:
make babble.cppcb
cat babble.cppcb
```sh
make babble.cppcb
cat babble.cppcb
```
Notice how many statements it takes to do anything useful?
## Author's comments;
## Author's comments:
What you shouldn't think about buzzard.1:
What you shouldn't think about `buzzard.1`:
`buzzard.1` doesn't just do a mass of #defines as its obfuscation.
`buzzard.1` doesn't just do a mass of `#define`s as its obfuscation.
### What you should be glad about:
@@ -75,8 +90,8 @@ error message.
`buzzard.1` is a translator from a pseudo-assembly language into a subset of C
suitable for execution on Charles Babbage's Analytical Engine. Or rather, the
`#define`s in `buzzard.1` are that translator. The rest of buzzard.1 is a
buzzard.1 program. If you run the whole mess through CPP and a beautifier, you
`#define`s in `buzzard.1` are that translator. The rest of `buzzard.1` is a
`buzzard.1` program. If you run the whole mess through CPP and a beautifier, you
will see that all you have is a loop that runs until a variable is not 0, and a
sequence of assignment statements. The assignment statements are all of the
form `a op= b` or `a = b`. The Engine actually allowed 'a = b op c'. Only `+`,
@@ -102,58 +117,56 @@ themselves to it.
### Theoretical observations:
The simulated comparison operations only work with a certain
range of numbers; numbers that are too large will cause the
output code to fail to simulate the input code. This means
that this implementation of buzzard.1 would not be Turing-complete,
even if the AE could process indefinitely-sized numbers.
However, this is actually a constraint that no actual computer
can meet, either, so we can conclude that if an AE, with
card bins connected as suggested above, were hooked up to
a memory unit of sufficient size, it would be as Turing
complete as any existing machine (or, for those who
interpret that excessively critically, i.e. "not at all" for
both, we can simply say that the AE could simulate any
existing machine--although not quickly). This would be a
good place to site some references on the AE, but I don't
have any.
The simulated comparison operations only work with a certain range of numbers;
numbers that are too large will cause the output code to fail to simulate the
input code. This means that this implementation of `buzzard.1` would not be
Turing-complete, even if the AE could process indefinitely-sized numbers.
However, this is actually a constraint that no actual computer can meet, either,
so we can conclude that if an AE, with card bins connected as suggested above,
were hooked up to a memory unit of sufficient size, it would be as Turing
complete as any existing machine (or, for those who interpret that excessively
critically, i.e. "not at all" for both, we can simply say that the AE could
simulate any existing machine--although not quickly). This would be a good
place to site some references on the AE, but I don't have any.
### Definition of the input language to buzzard.1 (OR What Exactly Do All The Macros Do?):
[Don't read this unless you're stumped!]
MACRO FUNCTION MNEMONIC
```
V begin variable declarations Variable
C begin program Code
MACRO FUNCTION MNEMONIC
Q(b,a) let b = a eQuals
A(c,a,b) let c = a + b Add
S(c,a,b) let c = a - b Subtract
D(c,a,b) let c = a / b, where b is a *constant* Divide
U(c,a,b) let c = a / b, where b is anything Unknown
M(c,a,b) let c = a * b Multiply
V begin variable declarations Variable
C begin program Code
O(c,a,b) let c = a boolean-or b (a,b are 0 or 1) Or
B(b, a) let b = boolean value of a Boolean
P(b, a) let b = 1 if a>0, else 0. Positive
Q(b,a) let b = a eQuals
A(c,a,b) let c = a + b Add
S(c,a,b) let c = a - b Subtract
D(c,a,b) let c = a / b, where b is a *constant* Divide
U(c,a,b) let c = a / b, where b is anything Unknown
M(c,a,b) let c = a * b Multiply
l emit next sequential label Label
J(x) goto label #x Jump
O(c,a,b) let c = a boolean-or b (a,b are 0 or 1) Or
B(b, a) let b = boolean value of a Boolean
P(b, a) let b = 1 if a>0, else 0. Positive
Z(a,d) if a is 0 goto d (a is 0 or 1) Zero
E(a,d) if a is 1 goto d (a is 0 or 1) Else
l emit next sequential label Label
J(x) goto label #x Jump
H halt Haly
Z(a,d) if a is 0 goto d (a is 0 or 1) Zero
E(a,d) if a is 1 goto d (a is 0 or 1) Else
K(x) let x = number of cmd line arguments Kount
G(x,y) let x = the value if the yth argument Get argument
H halt Haly
T end of code; begin output section Terminate
X(y) print out hexadecimal value of y heXadecimal
T end of output section and program Terminate
K(x) let x = number of cmd line arguments Kount
G(x,y) let x = the value if the yth argument Get argument
T end of code; begin output section Terminate
X(y) print out hexadecimal value of y heXadecimal
T end of output section and program Terminate
```
You can figure out the other macros yourself. In the sample program, I've
actually implemented subroutines by saving a return address in a variable and
@@ -168,32 +181,40 @@ programs is the conditional (given that we have loops).
Since all you can do in the given operation output set is
assignment, we implement "conditional assignment":
if (x) y = z;
```
if (x) y = z;
```
To implement this, we constrain x to be either 0 or 1, and
simply compute:
y = (z * x) + (y * (1-x));
```
y = (z * x) + (y * (1-x));
```
This is more obscured by factoring out common terms and restricting
ourselves to two operand operations:
temp = z; (temp == z)
temp -= y; (temp == z-y)
temp *= x; (temp == (z-y)*x)
y += temp; (y == (z-y)*x + y)
( == z*x - y*x + y)
( == z*x + y*(1-x))
```
temp = z; (temp == z)
temp -= y; (temp == z-y)
temp *= x; (temp == (z-y)*x)
y += temp; (y == (z-y)*x + y)
( == z*x - y*x + y)
( == z*x + y*(1-x))
```
Next we imagine we have a pc. "I'm supposed to execute statement
pc next", says our emulator. But suppose we're not currently
coming up on statement pc. To handle this, we simply make every
operation conditional on the pc having the correct value:
Next we imagine we have a [pc](https://en.wikipedia.org/wiki/Program_counter).
"I'm supposed to execute statement pc next", says our emulator. But suppose
we're not currently coming up on statement pc. To handle this, we simply make
every operation conditional on the pc having the correct value:
if (pc == some_constant) y = z;
```
if (pc == some_constant) y = z;
```
To combine this with other operations, we simply multiply by our
(`pc == some_constant`) flag right after the above 'temp `*= x'`.
(`pc == some_constant`) flag right after the above `temp *= x`.
To evaluate `pc == some_constant` requires one more trick. We assume that
numbers can only be in some limited range. Then we use successive additions and
+144 -129
View File
@@ -1,58 +1,73 @@
# Best Language Tool:
Sean Barrett
Software Construction Company
430 Southwest Parkway, #1906
College Station, TX 77840
USA
Sean Barrett
Software Construction Company
430 Southwest Parkway, #1906
College Station, TX 77840
USA
## To build:
make all
```sh
make all
```
## To run:
First:
make first
```sh
make first
```
Second:
echo help | cat third help.th - | ./first
cat third demo5.th | ./first
```sh
echo help | cat third help.th - | ./first
cat third demo5.th | ./first
```
Third:
cat third help.th - | ./first
```sh
cat third help.th - | ./first
```
NOTE: Wait until Ok is printed and the type:
NOTE: Wait until 'Ok' is printed and the type:
2 3 + . cr
Yes you should really type the 2 letters: cr.
```
2 3 + . cr
```
Yes you should really type the 2 letters: `cr`.
Fourth:
Sorry, this is third!
```
Sorry, this is third!
```
## Alternate code:
An alternate version of this entry, `buzzard.2.alt.c`, is provided. This alternate code
does not contain a fix that the author notes below.
An alternate version of this entry, [buzzard.2.alt.c](buzzard.2.alt.c), is
provided. This alternate code does not contain a fix that the author notes
below.
To compile this alternate version:
make alt
```sh
make alt
```
Use `buzzard.2.alt` as you would `buzzard.2` above.
## Judges' comments
## Judges' comments:
Have fun!
## Author's comments
## Author's comments:
What it does:
### What it does:
`first` implements a relatively primitive stack machine. How
primitive? It supplies 13 visible primitives: 3 arithmetic,
@@ -88,152 +103,152 @@ included, but it only works on ASCII systems.
Do not expect to be able to do anything interesting with first.
To do something interesting, you need to feed first the file
third first. In unix, you can do
[third](third) first. In unix, you can do
% cat third help.th - | ./first
```sh
% cat third help.th - | ./first
```
to do this. Hopefully most operating systems will provide a
way to do this. It may take some time for this to complete
(I seem to remember it taking several minutes on an 8086 PC);
THIRD will prompt you when it is finished. The file third has
not been obfuscated, due to sheer kindness on the author's part.
to do this. Hopefully most operating systems will provide a way to do this. It
may take some time for this to complete (I seem to remember it taking several
minutes on an 8086 PC); `THIRD` will prompt you when it is finished. The file
[third](third) has not been obfuscated, due to sheer kindness on the author's
part.
For more information on what you can do once you've piped
THIRD into first, type 'help' and consult FORTH manuals for
further reference. Six sample THIRD programs are included
in the files demo[1-6].th. buzzard.2.README has more
information.
For more information on what you can do once you've piped [third](third) into
first, type 'help' and consult FORTH manuals for further reference. Six sample
THIRD programs are included in the files demo[1-6].th.
[buzzard.2.README.md](buzzard.2.README.md) has more information.
Keep in mind that you are still running first, and
are for the most part limited by first's tokenizer
(notably, unknown words will attempt to be parsed as
integers.) It is possible to build a new parser that
parses by hand, reading a single character at a time;
however, such a parser cannot easily use the existing
dictionary, and so would have to implement its own,
thus requiring reimplementing all of first and third
a second time--I did not care to tackle this project.
Keep in mind that you are still running first, and are for the most part limited
by `first`'s tokenizer (notably, unknown words will attempt to be parsed as
integers.) It is possible to build a new parser that parses by hand, reading a
single character at a time; however, such a parser cannot easily use the
existing dictionary, and so would have to implement its own, thus requiring
reimplementing all of first and third a second time--I did not care to tackle
this project.
### Compiling:
`first` is reasonably portable. You may need to adjust the
size of the buffers on smaller machines; `m[]` needs to be
at least 2000 long, though.
`first` is reasonably portable. You may need to adjust the size of the buffers
on smaller machines; `m[]` needs to be at least 2000 long, though.
I say `first` is portable mainly because it uses native types.
Unlike FORTH, which traditionally allows byte and multi-byte
operations, all operations are performed on C `int`s. That
means first code is only as portable as the same code would
be in C. As in C, the result of dividing -1 by 2 is machine
(or rather compiler) dependent.
I say `first` is portable mainly because it uses native types. Unlike
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language), which
traditionally allows byte and multi-byte operations, all operations are
performed on C `int`s. That means first code is only as portable as the same
code would be in C. As in C, the result of dividing -1 by 2 is machine (or
rather compiler) dependent.
### How is first obfuscated?
`first` is obfuscated in several ways. Some minor obfuscations
like `&w[&m[1]][s]` for `s+m[w+1]` were in the original source
but are no longer because, apparently, ANSI doesn't allow it
(gcc -ansi -pedantic doesn't mind it, though.)
Other related obfuscations are still present. The top of the
stack is cached in a variable, which increases performance
massively if the compiler can figure out to keep it in a register;
it also obfuscates the code. (Unfortunately, the top of stack
is a global variable and neither gcc nor most bundled compilers
seem to register allocate it.)
`first` is obfuscated in several ways. Some minor obfuscations like
`&w[&m[1]][s]` for `s+m[w+1]` were in the original source but are no longer
because, apparently, ANSI doesn't allow it (gcc -ansi -pedantic doesn't mind it,
though.)
More significant are the design obfuscations. `m[0]` is the
"dictionary pointer", used when compiling words, and `m[1]` is
the return stack index. Both are used as integer offsets into
m. Both are kept in m, instead of as separate pointers,
because they are then accessible to first programs, which is a
crucial property of first. Similarly the way words are stored
in the dictionary is not obvious, so it can be difficult to
follow exactly what the compiler words are doing.
Other related obfuscations are still present. The top of the stack is cached in
a variable, which increases performance massively if the compiler can figure out
to keep it in a register; it also obfuscates the code. (Unfortunately, the top
of stack is a global variable and neither gcc nor most bundled compilers seem to
register allocate it.)
Assuming you've waded through all that, you still have
to penetrate the most significant obfuscation. Traditionally,
the question is whether a reader can answer the question "what
will this do when I run it". A reader who has deciphered first
to this point may think they know the answer to this question,
but they may not know the answer to the more important question,
"what will this program do when given the right input?" FORTH
aficionados, and especially FORTH implementers, may recognize
the similarity of the internal compiler format to many FORTH
internal representations, and, being aware that FORTH interpreters
can often by self-compiling, may be suspicious that this program
can compile FORTH, or a significant subset of it, or at least be
capable of doing so if fed the right input. Of course, the name
"THIRD" should be a dead giveaway, if the name "first" wasn't.
(These numbers were largely chosen because they were five letters
long, like "FORTH", and would not require truncation to five
letters, which would be a dead giveaway. Besides, THIRD represents
a step backwards, in more ways than one.)
More significant are the design obfuscations. `m[0]` is the "dictionary
pointer", used when compiling words, and `m[1]` is the return stack index. Both
are used as integer offsets into `m`. Both are kept in `m`, instead of as
separate pointers, because they are then accessible to first programs, which is
a crucial property of first. Similarly the way words are stored in the
dictionary is not obvious, so it can be difficult to follow exactly what the
compiler words are doing.
Assuming you've waded through all that, you still have to penetrate the most
significant obfuscation. Traditionally, the question is whether a reader can
answer the question "what will this do when I run it". A reader who has
deciphered first to this point may think they know the answer to this question,
but they may not know the answer to the more important question, "what will this
program do when given the right input?" FORTH aficionados, and especially FORTH
implementers, may recognize the similarity of the internal compiler format to
many FORTH internal representations, and, being aware that FORTH interpreters
can often be self-compiling, may be suspicious that this program can compile
FORTH, or a significant subset of it, or at least be capable of doing so if fed
the right input. Of course, the name "THIRD" should be a dead giveaway, if the
name "first" wasn't. (These numbers were largely chosen because they were five
letters long, like "FORTH", and would not require truncation to five letters,
which would be a dead giveaway. Besides, THIRD represents a step backwards, in
more ways than one.)
### What exactly is `first`, then?
`first` is a tiny interpreter which implements a sufficient
pseudo-subset of FORTH to allow it to bootstrap a relatively
complete version of FORTH (based loosely on forth79), which
I call THIRD. Complete relative to what, I'm not sure.
`first` is a tiny interpreter which implements a sufficient pseudo-subset of
FORTH to allow it to bootstrap a relatively complete version of FORTH (based
loosely on forth79), which I call THIRD. Complete relative to what, I'm not
sure.
I believe first is close to the smallest amount of code possible
to get this effect *using forth-style primitives*, and still have
some efficiency (it is possible to get by without multiplication
if you have addition, obviously). In the design file, design,
I give a justification for why each primitive in first was included.
I believe first is close to the smallest amount of code possible to get this
effect *using forth-style primitives*, and still have some efficiency (it is
possible to get by without multiplication if you have addition, obviously). In
the design file, design, I give a justification for why each primitive in first
was included.
THIRD is sorta slow, because first has so few primitives that
many things that are primitives in FORTH (like swap) take a
significant amount of time in THIRD.
THIRD is sorta slow, because first has so few primitives that many things that
are primitives in FORTH (like swap) take a significant amount of time in THIRD.
When you get the 'Ok.' message from third, try out some sample
FORTH code (first has no way of knowing if keyboard input is
waiting, so it can't actually prompt you in a normal way. It
only prints 'Ok.' after you define a word).
When you get the 'Ok.' message from third, try out some sample FORTH code (first
has no way of knowing if keyboard input is waiting, so it can't actually prompt
you in a normal way. It only prints 'Ok.' after you define a word).
2 3 + . cr ( add 2 and 3, and print it and a newline.)
```sh
2 3 + . cr
```
and THIRD responds
(which adds 2 and 3, and print the result and a newline.)
5
THIRD responds:
```
5
```
Now try:
: test 11 1 do i . loop cr ;
test
```
: test 11 1 do i . loop cr ;
test
```
and THIRD responds
1 2 3 4 5 6 7 8 9 10
```
1 2 3 4 5 6 7 8 9 10
```
When in THIRD, you can see how much space you're currently
using by typing
When in `THIRD`, you can see how much space you're currently
using by typing:
here .
```
here .
```
The number THIRD replies is the number of machine words (ints)
that the dictionary (the first code) takes up, plus the
512 ints for the return stack. If you compile the basic
THIRD system without the help word (strings take up one
int per character in the string!), you should find that
you're using around 1000 ints (plus the return stack).
The number THIRD replies with is the number of machine words (ints) that the
dictionary (the first code) takes up, plus the 512 ints for the return stack.
If you compile the basic THIRD system without the help word (strings take up one
int per character in the string!), you should find that you're using around 1000
ints (plus the return stack).
Thus THIRD gives you a relatively complete FORTH system in
less than 700 chars of C source + about 1000 ints of
memory--and it's portable too (you could copy over the
THIRD memory dump to another machine, in theory). If the
above numbers seem to you to be mixing apples and oranges
(C source and compiled THIRD code), note that you should
in theory be able to stick the compiled THIRD code into
the C source.
Thus THIRD gives you a relatively complete FORTH system in less than 700 chars
of C source + about 1000 ints of memory--and it's portable too (you could copy
over the THIRD memory dump to another machine, in theory). If the above numbers
seem to you to be mixing apples and oranges (C source and compiled THIRD code),
note that you should in theory be able to stick the compiled THIRD code into the
C source.
Software Construction Company gets credit for rekindling
my interest in FORTH and thus indirectly inspiring me
to write this program.
Software Construction Company gets credit for rekindling my interest in FORTH
and thus indirectly inspiring me to write this program.
## Copyright and CC BY-SA 4.0 License:
@@ -3,11 +3,16 @@ buzzard.2.design description of FIRST (design documentation of THIRD)
third implementation of THIRD in FIRST
help.th online listing of THIRD primitives
FIRST demos: use 'first < {demo}'
# FIRST demos:
Use `first < {demo}`.
demo1.1st prints Hello World! assuming ASCII
THIRD demos: use 'cat third {demo} | first'
# THIRD demos:
Use `cat third {demo} | first`.
demo1.th prints Hello World! regardless of character set
demo2.th demonstrates a simple loop
@@ -16,7 +21,9 @@ demo4.th recursive factorial calculating on the way up
demo5.th recursive factorial calculating on the way down
demo6.th demonstrates switching from compiler to execution mode
Interactive THIRD: use 'cat third - | first'.
# Interactive THIRD:
To include the primitive on-line help, use
'cat third help.th - | first'.
Use `cat third - | first`.
To include the primitive on-line help, use
`cat third help.th - | first`.
+1
View File
@@ -1,2 +1,3 @@
gson
ag
words
+51 -31
View File
@@ -1,18 +1,22 @@
# Most Humorous Output:
Andreas Gustafsson
Helsinki University of Technology
Arentikuja 1 D 305 (home address)
00410 Helsinki
FINLAND
Andreas Gustafsson
Helsinki University of Technology
Arentikuja 1 D 305
00410 Helsinki
Finland
## To build:
make all
```sh
make all
```
## To run:
./ag word word2 word3 < /path/to/dictionary
```sh
./ag word word2 word3 < /path/to/dictionary
```
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) changed the buffer size
in such a way that gets() should be safe (theoretically) as it comes from the
@@ -30,58 +34,74 @@ to be read (in case the `gets()` was not used in a loop). Thank you Cody for
your assistance!
## Judges' comment:
## Try:
Determine where your system dictionary is located. You may find
it located in one of the following places:
```
/usr/share/dict/words
/usr/share/lib/spell/words
/usr/ucblib/dict/words
/dev/null # <-- for machines with nothing to say
```
Then using the proper dictionary:
./ag free software foundation < /usr/share/dict/words
./ag obfuscated c contest < /usr/share/dict/words
./ag unix international < /usr/share/dict/words
./ag george bush < /usr/share/dict/words
./ag bill clinton < /usr/share/dict/words
./ag ross perot < /usr/share/dict/words
./ag paul e tsongas < /usr/share/dict/words
```sh
./ag free software foundation < /usr/share/dict/words
./ag obfuscated c contest < /usr/share/dict/words
./ag unix international < /usr/share/dict/words
./ag george bush < /usr/share/dict/words
./ag bill clinton < /usr/share/dict/words
./ag ross perot < /usr/share/dict/words
./ag paul e tsongas < /usr/share/dict/words
```
## Judges' comment:
Recently some newspapers printed amusing anagrams of one of the
names listed above. Run this program to find the anagrams they
weren't allowed to print!
The author provided an obfuscated script that can be used to construct
dictionaries which has been put in as [mkdict.sh](mkdict.sh). To use try:
```sh
cat README.md | ./mkdict.sh > words
```
Then try using the program as shown above with the file `words`.
## Author's comments:
The name of the game:
AG is short for either Anagram Generator or simply AnaGram.
It might also be construed to mean Alphabet Game, and by pure
coincidence it happens to be the author's initials.
AG is short for either Anagram Generator or simply AnaGram. It might also be
construed to mean Alphabet Game, and by pure coincidence it happens to be the
author's initials.
### What it does:
AG takes one or more words as arguments, and tries to find
anagrams of those words, i.e. words or sentences containing
exactly the same letters.
AG takes one or more words as arguments, and tries to find anagrams of those
words, i.e. words or sentences containing exactly the same letters.
### How to use it:
To run AG, you need a dictionary file consisting of distinct words
in the natural language of your choice, one word on each line. If
your machine doesn't have one already, you can make your own
dictionary by concatenating a few hundred of your favourite Usenet
articles and piping them through the following obfuscated shell
script:
To run AG, you need a dictionary file consisting of distinct words in the
natural language of your choice, one word on each line. If your machine doesn't
have one already, you can make your own dictionary by concatenating a few
hundred of your favourite Usenet articles and piping them through the following
obfuscated shell script:
```sh
#!/bin/sh
z=a-z];tr [A-Z\] \[$z|sed s/[\^$z[\^$z*/_/g|tr _ \\012|grep ..|sort -u
```
#!/bin/sh
z=a-z];tr [A-Z\] \[$z|sed s/[\^$z[\^$z*/_/g|tr _ \\012|grep ..|sort -u
Using articles from alt.folklore.computers is likely to make
a more professional-looking dictionary than rec.arts.erotica.
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
z=a-z];tr [A-Z\] \[$z|sed s/[\^$z[\^$z*/_/g|tr _ \\012|grep ..|sort -u
+57 -37
View File
@@ -1,23 +1,27 @@
# Best Output:
Ian Collier
Oxford University
The Queen's College
High Street
OXFORD
OX1 4AW
ENGLAND
Ian Collier
Oxford University
The Queen's College
High Street
Oxford
OX1 4AW
England
## To build:
make all
```sh
make all
```
## To run:
# text mode
./imc -text
```sh
# text mode
./imc -text
./imc
./imc
```
## Judges' comments:
@@ -31,9 +35,9 @@ NOTE: The original winning source assumed that exit() returned a value which cau
problems for some systems where exit() returns a void. The file [imc.c](imc.c) has been
modified to avoid this problem.
## Author's comments
## Author's comments:
### Portability
### Portability:
This program depends upon the ASCII character set, and makes certain
assumptions about the architecture. It naughtily declares the first
@@ -49,9 +53,9 @@ program runs happily without any parameters. If you supply an incorrect
parameter, an obfuscated error message results! :-) Should you want to
run the program without knowing what it does, then supplying the single
letter t as a parameter is a good move. Otherwise, direct the output
into a file. The resulting file is most useful on Sun OS, where the
into a file. The resulting file is most useful on SunOS, where the
`file` command will tell you what to do with it. For best results with
the t option, you may want to change the definition of the I macro :-)
the `t` option, you may want to change the definition of the `I` macro :-)
Details appear later, though the formatting of the code is a large clue.
All the code in this program appears between the `;` and `)` in
@@ -65,7 +69,7 @@ complex ones are best left as macros, because they have well-defined and
nontrivial (IMHO) functions. These macros help to give the program's
parameter format its flexibility. The parameters are sorted out in a
unique way (based on an idea by Pete Bevin) which hides very effectively
their identities (and I think that using a variable called _ adds a nice
their identities (and I think that using a variable called `_` adds a nice
touch to the illegibility of the code). In this section of the code, the
data types of the numbers checked against is varied, and just because
you see a `,` doesn't mean it has anything to do with commas! So I hope
@@ -78,19 +82,22 @@ contains eight 4-byte integers, the byte order in which depends upon the
machine. On Sun workstations they are stored MSB first].
The program may be asked to produce text output instead of a raster
file. Then the characters defined in the I macro will be used to create
file. Then the characters defined in the `I` macro will be used to create
up to 16 different shades of grey. Quite a respectable picture can be
gained by printing a 130x110 output on a dot matrix 132 column printer
gained by printing a `130x110` output on a dot matrix 132 column printer
with the linefeed set to 7 points. Text output also gives a good picture
when used in an X window with small characters having a square aspect
ratio.
The options accepted by the program follow. Each option is a letter; it
may be preceded with a minus sign (or any character in `[!-/]`) and may be
followed by other letters, so for example
followed by other letters, so for example:
m -m mask *mail
- m
- \-m
- mask
- \*mail
all mean the same thing. Most options may be followed by one or two
@@ -98,7 +105,10 @@ numbers. These numbers may be separated from each other and from the
option by a space, or may be joined to each other with a comma, or may
be appended to the single-letter option, so
-s100,200 size 100,200 -size123 100 200 s100 200
- \-s100,200
- size 100,200
- \-size123 100 200
- s100 200
all mean the same (note that in `-size123` all characters following the
initial `s` are ignored). Numbers need not be specified, as each has a
@@ -107,22 +117,30 @@ appears before `t`, specifying an option without numbers has no effect.
(specifying `-s -t` has the effect of producing text with the default
raster size; not a good idea!).
### Options
### Options:
The options of this program are:
-centre x y (float x,y) Centre the picture at x+iy in the complex
plane (default x=0 y=0)
-factor f (float f) Use f pixels per unit of the plane (default
f=x/4 where x is the width)
-julia x y (float x,y) Draw a julia set. Use x+iy as the constant
to add after squaring (default x=0 y=0)
-limit l (int l) Use l iterations maximum (default l=128)
-mask m (int m) Use m as a mask in deciding the colour of each
pixel (see below) (default m=1)
-size x y (int x,y) Produce an x-by-y output (default for raster
x=768 y=768; default for text x=63 y=23)
-text Produce text instead of raster.
`-centre x y` (float x,y) Centre the picture at `x+iy` in the complex
plane (default `x=0 y=0`)
`-factor f` (float f) Use `f` pixels per unit of the plane (default
`f=x/4` where `x` is the width)
`-julia x y` (float x,y) Draw a julia set. Use `x+iy` as the constant
to add after squaring (default `x=0 y=0`)
`-limit l` (int l) Use `l` iterations maximum (default `l=128`)
`-mask m` (int m) Use `m` as a mask in deciding the colour of each
pixel (see below) (default `m=1`)
`-size x y` (int x,y) Produce an x-by-y output (default for raster
`x=768 y=768`; default for text `x=63 y=23`)
`-text` Produce text instead of raster.
The colour of each point is determined by taking the bit-and of the
number of iterations and the mask. For a raster, the point is black
@@ -137,12 +155,14 @@ bits (e.g. 8).
While the program is creating your picture, it displays dots on the
standard error to indicate its progress (one dot per pixel line).
### Example pictures to try
### Example pictures to try:
Here are a couple of good pictures to draw:
./imc -s 512,512 -f 600000 -l 512 -m 16 -c.00805,.74274 > screen1.ras
./imc -s512,512 -j-.523,-.535 > screen2.ras
```sh
./imc -s 512,512 -f 600000 -l 512 -m 16 -c.00805,.74274 > screen1.ras
./imc -s512,512 -j-.523,-.535 > screen2.ras
```
## Copyright and CC BY-SA 4.0 License:
+30 -21
View File
@@ -1,30 +1,36 @@
# Best of Show:
Vern Paxson
Lawrence Berkeley Laboratory
Computer Systems Engineering
Bldg. 46A, Room 1123
Lawrence Berkeley Laboratory
1 Cyclotron Rd.
Berkeley, CA 94720 USA
Vern Paxson
Lawrence Berkeley Laboratory
Computer Systems Engineering
Bldg. 46A, Room 1123
Lawrence Berkeley Laboratory
1 Cyclotron Rd.
Berkeley, CA 94720 USA
## To build:
make all
```sh
make all
```
## To run:
./vern 3 # <-- default is 2
```sh
./vern 3 # <-- default is 2
```
## Try:
You might start off by giving the following input:
63 43
76 55
71 52
67 57 (this may take a while)
```
63 43
76 55
71 52
67 57 # (this may take a while)
```
## Judges' comments:
@@ -33,10 +39,13 @@ suggested above. :-)
For a real quick game try:
./vern
```sh
./vern
65 55
66 46
65 55
66 46
```
NOTE: Move values must be restricted to the range 00 to 77.
@@ -49,10 +58,10 @@ This program plays chess. You play the white pieces and the program
the black pieces. Moves are entered as a two-digit number specifying
the coordinates of the piece to be moved followed by another two-digit
number specifying the coordinates of where to move it. Rows and
columns are numbered starting with (0,0) for the upper-lefthand corner
(black's queen's rook) and going to (7,7) for the lower-righthand
columns are numbered starting with (0,0) for the upper-left-hand corner
(black's queen's rook) and going to (7,7) for the lower-right-hand
corner (white's king's rook). For example, the PK4 opening for white
is indicated as "64 44". Moves are read using scanf() so care should
is indicated as "64 44". Moves are read using `scanf()` so care should
be taken to not enter the wrong number of fields.
If the move you enter is illegal then you are just prompted again to
@@ -80,7 +89,7 @@ There are a few limitations on play:
- the board-position-repeated-three-times and fifty-moves stalemates are not
recognized.
If you checkmate the computer it prints "Rats!" and exits. If your own
If you checkmate the computer it prints "Rats!" and exits. If your own
checkmate is imminent it prints "Har har." but doesn't exit so it can
rub your nose in defeat (which may be a move or two away if you're
playing at a high "ply" - see the next paragraph). Stalemates are not
@@ -101,7 +110,7 @@ blunders but also immediately stupid moves altogether. A ply of 4
will find all mate-in-two's.
### Obfuscation
### Obfuscation:
This program is obfuscated in a number of ways. First, it abuses the
contest rule regarding ';', '{', and '}' in the source not counting
+42 -26
View File
@@ -1,16 +1,17 @@
# Best Small Program:
Brian Westley (aka Merlyn LeRoy)
Digi International
1026 Blair Ave.
St. Paul, MN 55104
USA
http://www.westley.org
Brian Westley (aka Merlyn LeRoy)
Digi International
1026 Blair Ave.
St. Paul, MN 55104
USA
<http://www.westley.org>
## To build:
make all
```sh
make all
```
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed this for clang by
@@ -24,11 +25,15 @@ in the author's comments below). Thank you Cody for your assistance!
If lost:
make whereami
```sh
make whereami
```
Then run:
./whereami lat long
```sh
./whereami lat long
```
Where lat and long correspond to your latitude and longitude.
@@ -37,15 +42,19 @@ show correctly!
## Try:
./whereami 47 -122 (- means west of meridian)
./whereami 47 122
```sh
./whereami 47 -122 (- means west of meridian)
./whereami 47 122
```
### Alternative code:
The author provided a version for the USA. To build:
make alt
```sh
make alt
```
Use `westley.alt` as you would `whereami` above.
@@ -56,8 +65,9 @@ NOTE: this alternative version also needs a terminal that wraps at 80 columns.
To find the approximate place where this entry was judged, type:
./whereami 37 -122 (- means west of meridian)
```sh
./whereami 37 -122 (- means west of meridian)
```
## Author's comments:
@@ -76,7 +86,7 @@ The program requires the ASCII character set, putchar(), atoi(),
and a display that auto-wraps at 80 characters(!). If your display
does not work this way, you will have to massage the output;
for example, you can pipe it to a file and edit it with vi,
which will do autowrap for you.
which will do auto-wrap for you.
Lint complains that main() returns a random value and I'm not
checking the value that putchar() returns. Scandalous!
@@ -88,14 +98,14 @@ don't exist and characters before a string constant.
### How it works:
The map is printed as one long string of ' ' and '!' characters,
with the autowrap used to stack up slices of 80. The map data is
with the auto-wrap used to stack up slices of 80. The map data is
a string; the first character is how many '!'s are printed
('A'=1, 'B'=2, etc), the second character is how many ' 's, the
third is how many '!'s, etc. ASCII characters less than 'A'
print no characters but still change the polarity, so any map
of ' 's and '!'s is possible. This is done in the putchar()
argument as "33^l&1", where l is the character position+4; if
l is odd, ' ' is printed, if l is even, '!' is printed.
argument as `33^l&1`, where `l` is the character `position+4`; if
`l` is odd, ' ' is printed, if `l` is even, '!' is printed.
The position of latitude & longitude is changed into a single
character position within the one long string via the first
@@ -122,13 +132,19 @@ is reasonably accurate.
### Here are some cities you might like to try:
New York 41 -74 Los Angeles 34 -118
London 52 0 Paris 45 2
Moscow 56 38 Beijing 40 116
New Delhi 29 77 Rio de Janeiro -23 -43
Sydney -34 151 Tokyo 36 140
- New York 41 -74
- London 52 0
- Moscow 56 38
- New Delhi 29 77
- Sydney -34 151
- Los Angeles 34 -118
- Paris 45 2
- Rio de Janeiro -23 -43
- Beijing 40 116
- Tokyo 36 140
For a domestic (USA) version with higher resolution, try:
```c
main(l,a,n,d)char**a;{for(d=atoi(a[1])/2*80-atoi(a[2])-2043;
n="bnaBCOCXdBBHGYdAP[A M E R I C A].AqandkmavX|ELC}BOCd"
@@ -141,7 +157,7 @@ joined together as one 160-character line and listed. You should see:
main(l,a,n,d)...
[A M E R I C A]...
...going down the left edge if your terminal autowraps at 80 characters.
...going down the left edge if your terminal auto-wraps at 80 characters.
## Copyright and CC BY-SA 4.0 License:
+8
View File
@@ -498,6 +498,14 @@ This program crashes. This will be worked on in the near future.
# 1992
## [1992/buzzard.1](1992/buzzard.1/buzzard.1.c) ([README.md](1992/buzzard.1/README.md))
## STATUS: INABIAF - please **DO NOT** fix
This entry will crash without enough args (2). At this time this is not
considered a bug to fix so it should not be fixed.
## [1992/lush](1992/lush/lush.c) ([README.md](1992/lush/README.md))
## STATUS: doesn't work with some compilers - please provide alternative code