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
+320 -199

No files matched your search

+49 -28
View File
@@ -1,4 +1,4 @@
Most Obfuscated Algorithm: # Most Obfuscated Algorithm:
Sean Barrett Sean Barrett
Software Construction Company Software Construction Company
@@ -9,28 +9,43 @@ Most Obfuscated Algorithm:
## To build: ## To build:
```sh
make all make all
```
## To run ## To run
```sh
./buzzard.1 num num
```
NOTE: this program will crash without two args.
## Try:
```sh
./buzzard.1 0 10 ./buzzard.1 0 10
./buzzard.1 56 720 ./buzzard.1 56 720
./buzzard.1 1 521 ./buzzard.1 1 521
```
## Judges' comments ## Judges' comments:
To see good C Preprocessor buzzard.1, try: To see good C Preprocessor buzzard.1, try:
```sh
make babble.cppcb make babble.cppcb
cat babble.cppcb cat babble.cppcb
```
Notice how many statements it takes to do anything useful? 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: ### 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 `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 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 `#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 `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 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 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 `+`, form `a op= b` or `a = b`. The Engine actually allowed 'a = b op c'. Only `+`,
@@ -102,27 +117,24 @@ themselves to it.
### Theoretical observations: ### Theoretical observations:
The simulated comparison operations only work with a certain The simulated comparison operations only work with a certain range of numbers;
range of numbers; numbers that are too large will cause the numbers that are too large will cause the output code to fail to simulate the
output code to fail to simulate the input code. This means input code. This means that this implementation of `buzzard.1` would not be
that this implementation of buzzard.1 would not be Turing-complete, Turing-complete, even if the AE could process indefinitely-sized numbers.
even if the AE could process indefinitely-sized numbers. However, this is actually a constraint that no actual computer can meet, either,
However, this is actually a constraint that no actual computer so we can conclude that if an AE, with card bins connected as suggested above,
can meet, either, so we can conclude that if an AE, with were hooked up to a memory unit of sufficient size, it would be as Turing
card bins connected as suggested above, were hooked up to complete as any existing machine (or, for those who interpret that excessively
a memory unit of sufficient size, it would be as Turing critically, i.e. "not at all" for both, we can simply say that the AE could
complete as any existing machine (or, for those who simulate any existing machine--although not quickly). This would be a good
interpret that excessively critically, i.e. "not at all" for place to site some references on the AE, but I don't have any.
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?): ### Definition of the input language to buzzard.1 (OR What Exactly Do All The Macros Do?):
[Don't read this unless you're stumped!] [Don't read this unless you're stumped!]
```
MACRO FUNCTION MNEMONIC MACRO FUNCTION MNEMONIC
@@ -154,6 +166,7 @@ have any.
T end of code; begin output section Terminate T end of code; begin output section Terminate
X(y) print out hexadecimal value of y heXadecimal X(y) print out hexadecimal value of y heXadecimal
T end of output section and program Terminate T end of output section and program Terminate
```
You can figure out the other macros yourself. In the sample program, I've 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 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 Since all you can do in the given operation output set is
assignment, we implement "conditional assignment": 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 To implement this, we constrain x to be either 0 or 1, and
simply compute: 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 This is more obscured by factoring out common terms and restricting
ourselves to two operand operations: ourselves to two operand operations:
```
temp = z; (temp == z) temp = z; (temp == z)
temp -= y; (temp == z-y) temp -= y; (temp == z-y)
temp *= x; (temp == (z-y)*x) temp *= x; (temp == (z-y)*x)
y += temp; (y == (z-y)*x + y) y += temp; (y == (z-y)*x + y)
( == z*x - y*x + y) ( == z*x - y*x + y)
( == z*x + y*(1-x)) ( == z*x + y*(1-x))
```
Next we imagine we have a pc. "I'm supposed to execute statement Next we imagine we have a [pc](https://en.wikipedia.org/wiki/Program_counter).
pc next", says our emulator. But suppose we're not currently "I'm supposed to execute statement pc next", says our emulator. But suppose
coming up on statement pc. To handle this, we simply make every we're not currently coming up on statement pc. To handle this, we simply make
operation conditional on the pc having the correct value: 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 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 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 numbers can only be in some limited range. Then we use successive additions and
+124 -109
View File
@@ -8,51 +8,66 @@
## To build: ## To build:
```sh
make all make all
```
## To run: ## To run:
First: First:
```sh
make first make first
```
Second: Second:
```sh
echo help | cat third help.th - | ./first echo help | cat third help.th - | ./first
cat third demo5.th | ./first cat third demo5.th | ./first
```
Third: Third:
```sh
cat third help.th - | ./first 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 2 3 + . cr
```
Yes you should really type the 2 letters: cr. Yes you should really type the 2 letters: `cr`.
Fourth: Fourth:
```
Sorry, this is third! Sorry, this is third!
```
## Alternate code: ## Alternate code:
An alternate version of this entry, `buzzard.2.alt.c`, is provided. This alternate code An alternate version of this entry, [buzzard.2.alt.c](buzzard.2.alt.c), is
does not contain a fix that the author notes below. provided. This alternate code does not contain a fix that the author notes
below.
To compile this alternate version: To compile this alternate version:
```sh
make alt make alt
```
Use `buzzard.2.alt` as you would `buzzard.2` above. Use `buzzard.2.alt` as you would `buzzard.2` above.
## Judges' comments ## Judges' comments:
Have fun! Have fun!
## Author's comments ## Author's comments:
What it does: ### What it does:
`first` implements a relatively primitive stack machine. How `first` implements a relatively primitive stack machine. How
primitive? It supplies 13 visible primitives: 3 arithmetic, 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. Do not expect to be able to do anything interesting with first.
To do something interesting, you need to feed first the file 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
```sh
% cat third help.th - | ./first % cat third help.th - | ./first
```
to do this. Hopefully most operating systems will provide a to do this. Hopefully most operating systems will provide a way to do this. It
way to do this. It may take some time for this to complete may take some time for this to complete (I seem to remember it taking several
(I seem to remember it taking several minutes on an 8086 PC); minutes on an 8086 PC); `THIRD` will prompt you when it is finished. The file
THIRD will prompt you when it is finished. The file third has [third](third) has not been obfuscated, due to sheer kindness on the author's
not been obfuscated, due to sheer kindness on the author's part. part.
For more information on what you can do once you've piped For more information on what you can do once you've piped [third](third) into
THIRD into first, type 'help' and consult FORTH manuals for first, type 'help' and consult FORTH manuals for further reference. Six sample
further reference. Six sample THIRD programs are included THIRD programs are included in the files demo[1-6].th.
in the files demo[1-6].th. buzzard.2.README has more [buzzard.2.README.md](buzzard.2.README.md) has more information.
information.
Keep in mind that you are still running first, and Keep in mind that you are still running first, and are for the most part limited
are for the most part limited by first's tokenizer by `first`'s tokenizer (notably, unknown words will attempt to be parsed as
(notably, unknown words will attempt to be parsed as integers.) It is possible to build a new parser that parses by hand, reading a
integers.) It is possible to build a new parser that single character at a time; however, such a parser cannot easily use the
parses by hand, reading a single character at a time; existing dictionary, and so would have to implement its own, thus requiring
however, such a parser cannot easily use the existing reimplementing all of first and third a second time--I did not care to tackle
dictionary, and so would have to implement its own, this project.
thus requiring reimplementing all of first and third
a second time--I did not care to tackle this project.
### Compiling: ### Compiling:
`first` is reasonably portable. You may need to adjust the `first` is reasonably portable. You may need to adjust the size of the buffers
size of the buffers on smaller machines; `m[]` needs to be on smaller machines; `m[]` needs to be at least 2000 long, though.
at least 2000 long, though.
I say `first` is portable mainly because it uses native types. I say `first` is portable mainly because it uses native types. Unlike
Unlike FORTH, which traditionally allows byte and multi-byte [FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language), which
operations, all operations are performed on C `int`s. That traditionally allows byte and multi-byte operations, all operations are
means first code is only as portable as the same code would performed on C `int`s. That means first code is only as portable as the same
be in C. As in C, the result of dividing -1 by 2 is machine code would be in C. As in C, the result of dividing -1 by 2 is machine (or
(or rather compiler) dependent. rather compiler) dependent.
### How is first obfuscated? ### How is first obfuscated?
`first` is obfuscated in several ways. Some minor obfuscations `first` is obfuscated in several ways. Some minor obfuscations like
like `&w[&m[1]][s]` for `s+m[w+1]` were in the original source `&w[&m[1]][s]` for `s+m[w+1]` were in the original source but are no longer
but are no longer because, apparently, ANSI doesn't allow it because, apparently, ANSI doesn't allow it (gcc -ansi -pedantic doesn't mind it,
(gcc -ansi -pedantic doesn't mind it, though.) 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.)
More significant are the design obfuscations. `m[0]` is the Other related obfuscations are still present. The top of the stack is cached in
"dictionary pointer", used when compiling words, and `m[1]` is a variable, which increases performance massively if the compiler can figure out
the return stack index. Both are used as integer offsets into to keep it in a register; it also obfuscates the code. (Unfortunately, the top
m. Both are kept in m, instead of as separate pointers, of stack is a global variable and neither gcc nor most bundled compilers seem to
because they are then accessible to first programs, which is a register allocate it.)
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 More significant are the design obfuscations. `m[0]` is the "dictionary
to penetrate the most significant obfuscation. Traditionally, pointer", used when compiling words, and `m[1]` is the return stack index. Both
the question is whether a reader can answer the question "what are used as integer offsets into `m`. Both are kept in `m`, instead of as
will this do when I run it". A reader who has deciphered first separate pointers, because they are then accessible to first programs, which is
to this point may think they know the answer to this question, a crucial property of first. Similarly the way words are stored in the
but they may not know the answer to the more important question, dictionary is not obvious, so it can be difficult to follow exactly what the
"what will this program do when given the right input?" FORTH compiler words are doing.
aficionados, and especially FORTH implementers, may recognize
the similarity of the internal compiler format to many FORTH Assuming you've waded through all that, you still have to penetrate the most
internal representations, and, being aware that FORTH interpreters significant obfuscation. Traditionally, the question is whether a reader can
can often by self-compiling, may be suspicious that this program answer the question "what will this do when I run it". A reader who has
can compile FORTH, or a significant subset of it, or at least be deciphered first to this point may think they know the answer to this question,
capable of doing so if fed the right input. Of course, the name but they may not know the answer to the more important question, "what will this
"THIRD" should be a dead giveaway, if the name "first" wasn't. program do when given the right input?" FORTH aficionados, and especially FORTH
(These numbers were largely chosen because they were five letters implementers, may recognize the similarity of the internal compiler format to
long, like "FORTH", and would not require truncation to five many FORTH internal representations, and, being aware that FORTH interpreters
letters, which would be a dead giveaway. Besides, THIRD represents can often be self-compiling, may be suspicious that this program can compile
a step backwards, in more ways than one.) 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? ### What exactly is `first`, then?
`first` is a tiny interpreter which implements a sufficient `first` is a tiny interpreter which implements a sufficient pseudo-subset of
pseudo-subset of FORTH to allow it to bootstrap a relatively FORTH to allow it to bootstrap a relatively complete version of FORTH (based
complete version of FORTH (based loosely on forth79), which loosely on forth79), which I call THIRD. Complete relative to what, I'm not
I call THIRD. Complete relative to what, I'm not sure. sure.
I believe first is close to the smallest amount of code possible I believe first is close to the smallest amount of code possible to get this
to get this effect *using forth-style primitives*, and still have effect *using forth-style primitives*, and still have some efficiency (it is
some efficiency (it is possible to get by without multiplication possible to get by without multiplication if you have addition, obviously). In
if you have addition, obviously). In the design file, design, the design file, design, I give a justification for why each primitive in first
I give a justification for why each primitive in first was included. was included.
THIRD is sorta slow, because first has so few primitives that THIRD is sorta slow, because first has so few primitives that many things that
many things that are primitives in FORTH (like swap) take a are primitives in FORTH (like swap) take a significant amount of time in THIRD.
significant amount of time in THIRD.
When you get the 'Ok.' message from third, try out some sample When you get the 'Ok.' message from third, try out some sample FORTH code (first
FORTH code (first has no way of knowing if keyboard input is has no way of knowing if keyboard input is waiting, so it can't actually prompt
waiting, so it can't actually prompt you in a normal way. It you in a normal way. It only prints 'Ok.' after you define a word).
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.)
THIRD responds:
```
5 5
```
Now try: Now try:
```
: test 11 1 do i . loop cr ; : test 11 1 do i . loop cr ;
test test
```
and THIRD responds 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 When in `THIRD`, you can see how much space you're currently
using by typing using by typing:
```
here . here .
```
The number THIRD replies is the number of machine words (ints) The number THIRD replies with is the number of machine words (ints) that the
that the dictionary (the first code) takes up, plus the dictionary (the first code) takes up, plus the 512 ints for the return stack.
512 ints for the return stack. If you compile the basic If you compile the basic THIRD system without the help word (strings take up one
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
int per character in the string!), you should find that ints (plus the return stack).
you're using around 1000 ints (plus the return stack).
Thus THIRD gives you a relatively complete FORTH system in Thus THIRD gives you a relatively complete FORTH system in less than 700 chars
less than 700 chars of C source + about 1000 ints of of C source + about 1000 ints of memory--and it's portable too (you could copy
memory--and it's portable too (you could copy over the over the THIRD memory dump to another machine, in theory). If the above numbers
THIRD memory dump to another machine, in theory). If the seem to you to be mixing apples and oranges (C source and compiled THIRD code),
above numbers seem to you to be mixing apples and oranges note that you should in theory be able to stick the compiled THIRD code into the
(C source and compiled THIRD code), note that you should C source.
in theory be able to stick the compiled THIRD code into
the C source.
Software Construction Company gets credit for rekindling Software Construction Company gets credit for rekindling my interest in FORTH
my interest in FORTH and thus indirectly inspiring me and thus indirectly inspiring me to write this program.
to write this program.
## Copyright and CC BY-SA 4.0 License: ## 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 third implementation of THIRD in FIRST
help.th online listing of THIRD primitives help.th online listing of THIRD primitives
FIRST demos: use 'first < {demo}'
# FIRST demos:
Use `first < {demo}`.
demo1.1st prints Hello World! assuming ASCII 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 demo1.th prints Hello World! regardless of character set
demo2.th demonstrates a simple loop 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 demo5.th recursive factorial calculating on the way down
demo6.th demonstrates switching from compiler to execution mode demo6.th demonstrates switching from compiler to execution mode
Interactive THIRD: use 'cat third - | first'. # Interactive THIRD:
Use `cat third - | first`.
To include the primitive on-line help, use To include the primitive on-line help, use
'cat third help.th - | first'. `cat third help.th - | first`.
+1
View File
@@ -1,2 +1,3 @@
gson gson
ag ag
words
+35 -15
View File
@@ -2,17 +2,21 @@
Andreas Gustafsson Andreas Gustafsson
Helsinki University of Technology Helsinki University of Technology
Arentikuja 1 D 305 (home address) Arentikuja 1 D 305
00410 Helsinki 00410 Helsinki
FINLAND Finland
## To build: ## To build:
```sh
make all make all
```
## To run: ## To run:
```sh
./ag word word2 word3 < /path/to/dictionary ./ag word word2 word3 < /path/to/dictionary
```
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) changed the buffer size [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 in such a way that gets() should be safe (theoretically) as it comes from the
@@ -30,18 +34,21 @@ to be read (in case the `gets()` was not used in a loop). Thank you Cody for
your assistance! your assistance!
## Judges' comment: ## Try:
Determine where your system dictionary is located. You may find Determine where your system dictionary is located. You may find
it located in one of the following places: it located in one of the following places:
```
/usr/share/dict/words /usr/share/dict/words
/usr/share/lib/spell/words /usr/share/lib/spell/words
/usr/ucblib/dict/words /usr/ucblib/dict/words
/dev/null # <-- for machines with nothing to say /dev/null # <-- for machines with nothing to say
```
Then using the proper dictionary: Then using the proper dictionary:
```sh
./ag free software foundation < /usr/share/dict/words ./ag free software foundation < /usr/share/dict/words
./ag obfuscated c contest < /usr/share/dict/words ./ag obfuscated c contest < /usr/share/dict/words
./ag unix international < /usr/share/dict/words ./ag unix international < /usr/share/dict/words
@@ -49,38 +56,51 @@ Then using the proper dictionary:
./ag bill clinton < /usr/share/dict/words ./ag bill clinton < /usr/share/dict/words
./ag ross perot < /usr/share/dict/words ./ag ross perot < /usr/share/dict/words
./ag paul e tsongas < /usr/share/dict/words ./ag paul e tsongas < /usr/share/dict/words
```
## Judges' comment:
Recently some newspapers printed amusing anagrams of one of the Recently some newspapers printed amusing anagrams of one of the
names listed above. Run this program to find the anagrams they names listed above. Run this program to find the anagrams they
weren't allowed to print! 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: ## Author's comments:
The name of the game: The name of the game:
AG is short for either Anagram Generator or simply AnaGram. AG is short for either Anagram Generator or simply AnaGram. It might also be
It might also be construed to mean Alphabet Game, and by pure construed to mean Alphabet Game, and by pure coincidence it happens to be the
coincidence it happens to be the author's initials. author's initials.
### What it does: ### What it does:
AG takes one or more words as arguments, and tries to find AG takes one or more words as arguments, and tries to find anagrams of those
anagrams of those words, i.e. words or sentences containing words, i.e. words or sentences containing exactly the same letters.
exactly the same letters.
### How to use it: ### How to use it:
To run AG, you need a dictionary file consisting of distinct words To run AG, you need a dictionary file consisting of distinct words in the
in the natural language of your choice, one word on each line. If natural language of your choice, one word on each line. If your machine doesn't
your machine doesn't have one already, you can make your own have one already, you can make your own dictionary by concatenating a few
dictionary by concatenating a few hundred of your favourite Usenet hundred of your favourite Usenet articles and piping them through the following
articles and piping them through the following obfuscated shell obfuscated shell script:
script:
```sh
#!/bin/sh #!/bin/sh
z=a-z];tr [A-Z\] \[$z|sed s/[\^$z[\^$z*/_/g|tr _ \\012|grep ..|sort -u 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 Using articles from alt.folklore.computers is likely to make
a more professional-looking dictionary than rec.arts.erotica. 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
+45 -25
View File
@@ -4,20 +4,24 @@
Oxford University Oxford University
The Queen's College The Queen's College
High Street High Street
OXFORD Oxford
OX1 4AW OX1 4AW
ENGLAND England
## To build: ## To build:
```sh
make all make all
```
## To run: ## To run:
```sh
# text mode # text mode
./imc -text ./imc -text
./imc ./imc
```
## Judges' comments: ## 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 problems for some systems where exit() returns a void. The file [imc.c](imc.c) has been
modified to avoid this problem. modified to avoid this problem.
## Author's comments ## Author's comments:
### Portability ### Portability:
This program depends upon the ASCII character set, and makes certain This program depends upon the ASCII character set, and makes certain
assumptions about the architecture. It naughtily declares the first assumptions about the architecture. It naughtily declares the first
@@ -51,7 +55,7 @@ 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 letter t as a parameter is a good move. Otherwise, direct the output
into a file. The resulting file is most useful on SunOS, 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 `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. Details appear later, though the formatting of the code is a large clue.
All the code in this program appears between the `;` and `)` in 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 nontrivial (IMHO) functions. These macros help to give the program's
parameter format its flexibility. The parameters are sorted out in a parameter format its flexibility. The parameters are sorted out in a
unique way (based on an idea by Pete Bevin) which hides very effectively 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 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 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 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]. machine. On Sun workstations they are stored MSB first].
The program may be asked to produce text output instead of a raster 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 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 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 when used in an X window with small characters having a square aspect
ratio. ratio.
The options accepted by the program follow. Each option is a letter; it 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 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 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 option by a space, or may be joined to each other with a comma, or may
be appended to the single-letter option, so 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 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 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 (specifying `-s -t` has the effect of producing text with the default
raster size; not a good idea!). raster size; not a good idea!).
### Options ### Options:
The options of this program are: The options of this program are:
-centre x y (float x,y) Centre the picture at x+iy in the complex `-centre x y` (float x,y) Centre the picture at `x+iy` in the complex
plane (default x=0 y=0) 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 `-factor f` (float f) Use `f` pixels per unit of the plane (default
to add after squaring (default x=0 y=0) `f=x/4` where `x` is the width)
-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) `-julia x y` (float x,y) Draw a julia set. Use `x+iy` as the constant
-size x y (int x,y) Produce an x-by-y output (default for raster to add after squaring (default `x=0 y=0`)
x=768 y=768; default for text x=63 y=23)
-text Produce text instead of raster. `-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 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 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 While the program is creating your picture, it displays dots on the
standard error to indicate its progress (one dot per pixel line). 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: Here are a couple of good pictures to draw:
```sh
./imc -s 512,512 -f 600000 -l 512 -m 16 -c.00805,.74274 > screen1.ras ./imc -s 512,512 -f 600000 -l 512 -m 16 -c.00805,.74274 > screen1.ras
./imc -s512,512 -j-.523,-.535 > screen2.ras ./imc -s512,512 -j-.523,-.535 > screen2.ras
```
## Copyright and CC BY-SA 4.0 License: ## Copyright and CC BY-SA 4.0 License:
+14 -5
View File
@@ -10,21 +10,27 @@
## To build: ## To build:
```sh
make all make all
```
## To run: ## To run:
```sh
./vern 3 # <-- default is 2 ./vern 3 # <-- default is 2
```
## Try: ## Try:
You might start off by giving the following input: You might start off by giving the following input:
```
63 43 63 43
76 55 76 55
71 52 71 52
67 57 (this may take a while) 67 57 # (this may take a while)
```
## Judges' comments: ## Judges' comments:
@@ -33,11 +39,14 @@ suggested above. :-)
For a real quick game try: For a real quick game try:
```sh
./vern ./vern
65 55 65 55
66 46 66 46
```
NOTE: Move values must be restricted to the range 00 to 77. NOTE: Move values must be restricted to the range 00 to 77.
NOTE: Because some mailers have problems with the original winning source, NOTE: Because some mailers have problems with the original winning source,
@@ -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 black pieces. Moves are entered as a two-digit number specifying
the coordinates of the piece to be moved followed by another two-digit the coordinates of the piece to be moved followed by another two-digit
number specifying the coordinates of where to move it. Rows and number specifying the coordinates of where to move it. Rows and
columns are numbered starting with (0,0) for the upper-lefthand corner 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-righthand (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 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. be taken to not enter the wrong number of fields.
If the move you enter is illegal then you are just prompted again to If the move you enter is illegal then you are just prompted again to
@@ -101,7 +110,7 @@ blunders but also immediately stupid moves altogether. A ply of 4
will find all mate-in-two's. will find all mate-in-two's.
### Obfuscation ### Obfuscation:
This program is obfuscated in a number of ways. First, it abuses the This program is obfuscated in a number of ways. First, it abuses the
contest rule regarding ';', '{', and '}' in the source not counting contest rule regarding ';', '{', and '}' in the source not counting
+29 -13
View File
@@ -5,12 +5,13 @@
1026 Blair Ave. 1026 Blair Ave.
St. Paul, MN 55104 St. Paul, MN 55104
USA USA
<http://www.westley.org>
http://www.westley.org
## To build: ## To build:
```sh
make all make all
```
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed this for clang by [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: If lost:
```sh
make whereami make whereami
```
Then run: Then run:
```sh
./whereami lat long ./whereami lat long
```
Where lat and long correspond to your latitude and longitude. Where lat and long correspond to your latitude and longitude.
@@ -37,15 +42,19 @@ show correctly!
## Try: ## Try:
```sh
./whereami 47 -122 (- means west of meridian) ./whereami 47 -122 (- means west of meridian)
./whereami 47 122 ./whereami 47 122
```
### Alternative code: ### Alternative code:
The author provided a version for the USA. To build: The author provided a version for the USA. To build:
```sh
make alt make alt
```
Use `westley.alt` as you would `whereami` above. 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: To find the approximate place where this entry was judged, type:
```sh
./whereami 37 -122 (- means west of meridian) ./whereami 37 -122 (- means west of meridian)
```
## Author's comments: ## 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 and a display that auto-wraps at 80 characters(!). If your display
does not work this way, you will have to massage the output; 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, 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 Lint complains that main() returns a random value and I'm not
checking the value that putchar() returns. Scandalous! checking the value that putchar() returns. Scandalous!
@@ -88,14 +98,14 @@ don't exist and characters before a string constant.
### How it works: ### How it works:
The map is printed as one long string of ' ' and '!' characters, 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 string; the first character is how many '!'s are printed
('A'=1, 'B'=2, etc), the second character is how many ' 's, the ('A'=1, 'B'=2, etc), the second character is how many ' 's, the
third is how many '!'s, etc. ASCII characters less than 'A' third is how many '!'s, etc. ASCII characters less than 'A'
print no characters but still change the polarity, so any map print no characters but still change the polarity, so any map
of ' 's and '!'s is possible. This is done in the putchar() 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 argument as `33^l&1`, where `l` is the character `position+4`; if
l is odd, ' ' is printed, if l is even, '!' is printed. `l` is odd, ' ' is printed, if `l` is even, '!' is printed.
The position of latitude & longitude is changed into a single The position of latitude & longitude is changed into a single
character position within the one long string via the first 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: ### Here are some cities you might like to try:
New York 41 -74 Los Angeles 34 -118 - New York 41 -74
London 52 0 Paris 45 2 - London 52 0
Moscow 56 38 Beijing 40 116 - Moscow 56 38
New Delhi 29 77 Rio de Janeiro -23 -43 - New Delhi 29 77
Sydney -34 151 Tokyo 36 140 - 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: For a domestic (USA) version with higher resolution, try:
```c ```c
main(l,a,n,d)char**a;{for(d=atoi(a[1])/2*80-atoi(a[2])-2043; 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" 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)... main(l,a,n,d)...
[A M E R I C A]... [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: ## 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
## [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)) ## [1992/lush](1992/lush/lush.c) ([README.md](1992/lush/README.md))
## STATUS: doesn't work with some compilers - please provide alternative code ## STATUS: doesn't work with some compilers - please provide alternative code