Merge pull request #109 from xexyl/hints
Address references to *.hint with some exceptions
This commit is contained in:
9 files changed
+142
-143
No files matched your search
+1
-1
@@ -40,7 +40,7 @@ The ideal 3rd judge would have all of the following:
|
||||
|
||||
* thorough knowledge of the C language (ANSI and K&R)
|
||||
* thorough knowledge of common C libs (libc, libm, libcurses, ...)
|
||||
* reasonable written communication skills (able to write *.hint files)
|
||||
* reasonable written communication skills (able to write README.md files)
|
||||
* appreciation for well-written non-obfuscated code
|
||||
* willing to devote ~4 weekend days in January (starting Jan 96) for judging
|
||||
* located in the San Francisco (California, USA) Bay Area, or
|
||||
|
||||
@@ -166,7 +166,7 @@ ENTRY= dorssel
|
||||
PROG= ${ENTRY}
|
||||
#
|
||||
OBJ= ${PROG}.o
|
||||
DATA= dorssel.hint2
|
||||
DATA= dorssel.hint
|
||||
TARGET= ${PROG}
|
||||
#
|
||||
ALT_OBJ=
|
||||
|
||||
+52
-50
@@ -10,84 +10,86 @@
|
||||
|
||||
make all
|
||||
|
||||
### To run
|
||||
### To run:
|
||||
|
||||
echo Simple as 123 | ./dorssel
|
||||
echo '.... --- .-- -.. --- . ... .. - -.. --- - .... .- -' | ./dorssel
|
||||
|
||||
## Judges' comments
|
||||
## Judges' comments:
|
||||
|
||||
How does the program decide which way to convert?
|
||||
How does the program decide which way to convert?
|
||||
|
||||
What obsolescent feature are we talking about? (No, it's not a
|
||||
C language feature.)
|
||||
What obsolescent feature are we talking about? (No, it's not a
|
||||
C language feature.)
|
||||
|
||||
The author suggests that you try to answer the following questions:
|
||||
The author suggests that you try to answer the following questions:
|
||||
|
||||
- Which character in the initializing string is totally irrelevant?
|
||||
- Which two relevant characters in the initializing string may be
|
||||
exchanged without altering the behavior?
|
||||
- Which characters in the initializing string are somewhat irrelevant,
|
||||
and to what values may they be changed without altering the behavior?
|
||||
- Which characters may be used to enlarge the initializing string by
|
||||
one without altering the behavior ?
|
||||
- Which character in the initializing string is totally irrelevant?
|
||||
|
||||
Extra credit: Change the program so that it does not SHOUT IN ALL CAPS.
|
||||
- Which two relevant characters in the initializing string may be exchanged
|
||||
without altering the behavior?
|
||||
|
||||
You might also want to read the dorssel.hint2 file.
|
||||
- Which characters in the initializing string are somewhat irrelevant, and to
|
||||
what values may they be changed without altering the behavior?
|
||||
|
||||
## Author's comments
|
||||
- Which characters may be used to enlarge the initializing string by one without
|
||||
altering the behavior ?
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
This program converts ASCII to Morse code, and vice versa.
|
||||
Extra credit: Change the program so that it does not SHOUT IN ALL CAPS.
|
||||
|
||||
The program reads in lines from standard input and writes its result to
|
||||
standard output. The direction of conversion is determined on a per
|
||||
line basis. Each line must consist of a maximum of 952 characters
|
||||
followed by a new line character, they must not contain any NUL
|
||||
characters. Otherwise, some characters may be lost in the conversion.
|
||||
You might also want to read the [dorssel.hint](dorssel.hint) file.
|
||||
|
||||
- Encoding to Morse code:
|
||||
The program knows the Morse codes for all Latin letters (a-z, case
|
||||
insensitive) and decimal digits (0-9). Any other characters are
|
||||
replaced by an ASCII space ' '. Morse code per converted character is
|
||||
written as a sequence of '.' and '-' characters, each sequence
|
||||
followed by a space.
|
||||
## Author's comments:
|
||||
|
||||
- Decoding from Morse code:
|
||||
Morse code should be typed as sequences of '.' and '-' characters,
|
||||
separated by a space. Extra spaces will be echoed back (to separate
|
||||
words). Unknown sequences will be converted to a '?' character.
|
||||
Usage
|
||||
=====
|
||||
|
||||
Notes
|
||||
=====
|
||||
This program converts ASCII to Morse code, and vice versa.
|
||||
|
||||
The program assumes both source and execution character sets to be
|
||||
ASCII. As far as I can tell, the program is conforming and does not
|
||||
invoke undefined behavior.
|
||||
The program reads in lines from standard input and writes its result to
|
||||
standard output. The direction of conversion is determined on a per
|
||||
line basis. Each line must consist of a maximum of 952 characters
|
||||
followed by a new line character, they must not contain any NUL
|
||||
characters. Otherwise, some characters may be lost in the conversion.
|
||||
|
||||
Hints
|
||||
=====
|
||||
- Encoding to Morse code: The program knows the Morse codes for all Latin
|
||||
letters (a-z, case insensitive) and decimal digits (0-9). Any other characters
|
||||
are replaced by an ASCII space ' '. Morse code per converted character is
|
||||
written as a sequence of '.' and '-' characters, each sequence followed by a
|
||||
space.
|
||||
|
||||
- Try
|
||||
- Decoding from Morse code: Morse code should be typed as sequences of '.' and
|
||||
'-' characters, separated by a space. Extra spaces will be echoed back (to
|
||||
separate words). Unknown sequences will be converted to a '?' character.
|
||||
|
||||
Notes
|
||||
=====
|
||||
|
||||
The program assumes both source and execution character sets to be
|
||||
ASCII. As far as I can tell, the program is conforming and does not
|
||||
invoke undefined behavior.
|
||||
|
||||
Hints
|
||||
=====
|
||||
|
||||
Try
|
||||
|
||||
./dorssel < dorssel.c | ./dorssel
|
||||
|
||||
to see what variables, numbers, and functions are used. (Does a
|
||||
better job than most C beautifiers).
|
||||
to see what variables, numbers, and functions are used. (Does a
|
||||
better job than most C beautifiers).
|
||||
|
||||
- Filter your text twice (as in the previous sample) to obtain a version
|
||||
of your text that can be reversibly morsified, i.e.
|
||||
- Filter your text twice (as in the previous sample) to obtain a version of your
|
||||
text that can be reversibly morsified, i.e.
|
||||
|
||||
./dorssel | ./dorssel | ./dorssel | ./dorssel
|
||||
|
||||
is the same as
|
||||
is the same as
|
||||
|
||||
./dorssel | ./dorssel
|
||||
|
||||
- The file "dorssel.hint2" contains all the information needed to
|
||||
understand this program. For an obfuscated spoiler, try
|
||||
- The file "dorssel.hint" contains all the information needed to understand this
|
||||
program. For an obfuscated spoiler, try
|
||||
|
||||
./dorssel < dorssel.hint2
|
||||
./dorssel < dorssel.hint
|
||||
File renamed without changes.
+81
-82
@@ -13,18 +13,18 @@
|
||||
|
||||
make all
|
||||
|
||||
NOTE: This may take a while. Some systems may have problems building
|
||||
this entry because of the system resources it requires.
|
||||
NOTE: This may take a while. Some systems may have problems building
|
||||
this entry because of the system resources it requires.
|
||||
|
||||
### To run
|
||||
## To run
|
||||
|
||||
./fanf
|
||||
|
||||
## Judges' comments
|
||||
|
||||
To use:
|
||||
Enter an expression on standard input. Here are some
|
||||
sample expressions that you can use:
|
||||
### To use:
|
||||
|
||||
Enter an expression on standard input. Here are some
|
||||
sample expressions that you can use:
|
||||
|
||||
((\a(\b(\c(d)))) e)
|
||||
|
||||
@@ -46,74 +46,73 @@
|
||||
)
|
||||
)
|
||||
|
||||
This program translares lambda expressions into combinator
|
||||
expressions. But you do not need to know Lambda Calculus to be
|
||||
impressed by this program!
|
||||
## Judges' comments:
|
||||
|
||||
See the file:
|
||||
This program translates lambda expressions into combinator
|
||||
expressions. But you do not need to know Lambda Calculus to be
|
||||
impressed by this program!
|
||||
|
||||
fanf.lambda
|
||||
See the file [fanf.lambda](fanf.lambda) for more examples of lambda calculus
|
||||
source.
|
||||
|
||||
for more examples of lambda calculus source.
|
||||
Notice how large the code grows from the fanf.c into the final
|
||||
fanftmp2.c C program. Take a look at that final C program again,
|
||||
can you begin to understand what it is doing?
|
||||
|
||||
Notice how large the code grows from the fanf.c into the final
|
||||
fanftmp2.c C program. Take a look at that final C program again,
|
||||
can you begin to understand what it is doing?
|
||||
|
||||
Look at the first stage of the C pre-processing:
|
||||
Look at the first stage of the C pre-processing:
|
||||
|
||||
cc fanf.c -E > fanftmp1.c
|
||||
|
||||
Skip to the bottom of fanftmp1.c (after all of the #include header
|
||||
stuff ... look for a line of the form: # 2 "fanf.c" near the bottom)
|
||||
and look at the resulting code. This code, when C pre-processed
|
||||
will expand into over 342 times the original code (ignoring #include
|
||||
headers) to produce fanftmp2.c. That program in turn, when compiled
|
||||
translates a single lambda expression on standard input into
|
||||
combinator expressions on standard output.
|
||||
Skip to the bottom of fanftmp1.c (after all of the #include header
|
||||
stuff ... look for a line of the form: # 2 "fanf.c" near the bottom)
|
||||
and look at the resulting code. This code, when C pre-processed
|
||||
will expand into over 342 times the original code (ignoring #include
|
||||
headers) to produce fanftmp2.c. That program in turn, when compiled
|
||||
translates a single lambda expression on standard input into
|
||||
combinator expressions on standard output.
|
||||
|
||||
Extra credit question:
|
||||
### Extra credit question:
|
||||
|
||||
What do you have to do to make this program work with an
|
||||
old non-ANSI C preprocessor?
|
||||
What do you have to do to make this program work with an old non-ANSI C
|
||||
preprocessor?
|
||||
|
||||
## Author's comments
|
||||
## Author's comments:
|
||||
|
||||
My program is a demonstration of some practical applications of
|
||||
theoretical computer science. The application it implements is a program
|
||||
for translating lambda expressions into combinator expressions.
|
||||
My program is a demonstration of some practical applications of
|
||||
theoretical computer science. The application it implements is a program
|
||||
for translating lambda expressions into combinator expressions.
|
||||
|
||||
|
||||
What the program does
|
||||
=====================
|
||||
What the program does
|
||||
=====================
|
||||
|
||||
The syntax of lambda expressions recognised by the program is as
|
||||
follows: The basic atoms are variables which are single characters other
|
||||
than backslash or parentheses, e.g. `a' or `b' or `@'. Variables are
|
||||
combined by function application which is written e.g. `(f a)' which is
|
||||
the function `f' applied to the argument `a'. Application groups to the
|
||||
left, so `(f a b c)' is equivalent to `(((f a) b) c)'. Functions are
|
||||
created from lambda terms which are written in the form `\a(expr)' which
|
||||
is the function taking argument `a' and having value `expr'. Lambda is
|
||||
spelt `\' because ASCII isn't good enough. Lambda binds tightly, so
|
||||
`\a\bcd' is equivalent to `((\a(\b(c))) d)'. Whitespace is ignored.
|
||||
The syntax of lambda expressions recognised by the program is as
|
||||
follows: The basic atoms are variables which are single characters other
|
||||
than backslash or parentheses, e.g. `a` or `b` or `@`. Variables are
|
||||
combined by function application which is written e.g. `(f a)` which is
|
||||
the function `f` applied to the argument `a`. Application groups to the
|
||||
left, so `(f a b c)` is equivalent to `(((f a) b) c)`. Functions are
|
||||
created from lambda terms which are written in the form `\a(expr)` which
|
||||
is the function taking argument `a` and having value `expr`. Lambda is
|
||||
spelt `\` because ASCII isn't good enough. Lambda binds tightly, so
|
||||
`\a\bcd` is equivalent to `((\a(\b(c))) d)`. Whitespace is ignored.
|
||||
|
||||
For example, the identity function, called `I', is written `\x(x)'. A
|
||||
simple expression is `(I a)' which is equivalent to `(\x(x) a)', which
|
||||
has the value `a'. Another function called `K' is defined as `\x\y(x)'
|
||||
and it evaluates as follows:
|
||||
For example, the identity function, called `I`, is written `\x(x)`. A
|
||||
simple expression is `(I a)` which is equivalent to `(\x(x) a)`, which
|
||||
has the value `a`. Another function called `K` is defined as `\x\y(x)`
|
||||
and it evaluates as follows:
|
||||
|
||||
K p q
|
||||
-> \x\y(x) p q
|
||||
-> \y(p) q
|
||||
-> p
|
||||
|
||||
Another function of interest is `S', defined as `\f\g\x((f x) (g x))'.
|
||||
My program demonstrates the fact that any lambda expression can be
|
||||
translated into an equivalent "combinator expression" which involves
|
||||
only `S', `K', `I' (the combinators), and application, with no
|
||||
variables or lambda abstractions. In fact, even `I' is unnecessary,
|
||||
since it is equivalent to `S K K':
|
||||
Another function of interest is `S`, defined as `\f\g\x((f x) (g x))`.
|
||||
My program demonstrates the fact that any lambda expression can be
|
||||
translated into an equivalent "combinator expression" which involves
|
||||
only `S`, `K`, `I` (the combinators), and application, with no
|
||||
variables or lambda abstractions. In fact, even `I` is unnecessary,
|
||||
since it is equivalent to `S K K`:
|
||||
|
||||
I z
|
||||
-> \a(a) z
|
||||
@@ -125,41 +124,41 @@
|
||||
-> \x\y(x) z (K z)
|
||||
-> z
|
||||
|
||||
The algorithm for translating lambda expressions into combinator
|
||||
expressions works as follows. There are three forms of lambda expression
|
||||
to consider: variables, applications, and abstractions.
|
||||
The algorithm for translating lambda expressions into combinator
|
||||
expressions works as follows. There are three forms of lambda expression
|
||||
to consider: variables, applications, and abstractions.
|
||||
|
||||
trans `v' -> `v' (variable)
|
||||
trans `a b' -> (trans `a') (trans `b') (application)
|
||||
trans `\ab' -> abs a (trans `b') (abstraction)
|
||||
trans `v` -> `v` (variable)
|
||||
trans `a b` -> (trans `a`) (trans `b`) (application)
|
||||
trans `\ab` -> abs a (trans `b`) (abstraction)
|
||||
|
||||
There are a further three cases to consider for the body of lambda
|
||||
expressions, where we need to do the magic that transforms away the
|
||||
variables.
|
||||
There are a further three cases to consider for the body of lambda
|
||||
expressions, where we need to do the magic that transforms away the
|
||||
variables.
|
||||
|
||||
abs a `f x' -> `S' (abs a `f') (abs a `x')
|
||||
abs a `b' -> `K b' (b != a)
|
||||
abs a `a' -> `I'
|
||||
abs a `f x` -> `S` (abs a `f`) (abs a `x`)
|
||||
abs a `b` -> `K b` (b != a)
|
||||
abs a `a` -> `I`
|
||||
|
||||
E.g. suppose we had combinator expressions for `+' and `3' and we wanted
|
||||
to see what the combinator expression for doubling 3 looked like:
|
||||
E.g. suppose we had combinator expressions for `+` and `3` and we wanted
|
||||
to see what the combinator expression for doubling 3 looked like:
|
||||
|
||||
trans `\x(+ x x) 3'
|
||||
-> (trans `\x(+ x x)') (trans `3')
|
||||
-> (abs x (trans `+ x x')) `3'
|
||||
-> (abs x `+ x x') `3'
|
||||
-> `S' (abs x `+ x') (abs x `x') `3'
|
||||
-> `S' (`S' (abs x `+') (abs x `x')) `I' `3'
|
||||
-> `S' (`S' (`K +') `I') `I' `3'
|
||||
-> `S (S (K +) I) I 3'
|
||||
trans `\x(+ x x) 3`
|
||||
-> (trans `\x(+ x x)`) (trans `3`)
|
||||
-> (abs x (trans `+ x x`)) `3`
|
||||
-> (abs x `+ x x`) `3`
|
||||
-> `S` (abs x `+ x`) (abs x `x`) `3`
|
||||
-> `S` (`S` (abs x `+`) (abs x `x`)) `I` `3`
|
||||
-> `S` (`S` (`K +`) `I`) `I` `3`
|
||||
-> `S (S (K +) I) I 3`
|
||||
|
||||
We can then check that this evaluates to the expected result:
|
||||
We can then check that this evaluates to the expected result:
|
||||
|
||||
S (S (K +) I) I 3
|
||||
-> S (K +) I 3 (I 3)
|
||||
-> K + 3 (I 3) (I 3)
|
||||
-> + (I 3) (I 3)
|
||||
-> + 3 3
|
||||
S (S (K +) I) I 3
|
||||
-> S (K +) I 3 (I 3)
|
||||
-> K + 3 (I 3) (I 3)
|
||||
-> + (I 3) (I 3)
|
||||
-> + 3 3
|
||||
|
||||
It is possible to perform a slightly more compact translation with a
|
||||
couple of simple optimisations. For example, note that `K (a b)' is the
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
-- multi-character identifiers and uses ` instead of \ because that's
|
||||
-- easier to enter inside a Haskell string). It also contains the Haskell
|
||||
-- code I used to translate the lambda calculus into combinators using
|
||||
-- the fully optimising algorithm described in the .hint file.
|
||||
-- the fully optimising algorithm described in the README.md file.
|
||||
--
|
||||
-- Tony Finch <dot@dotat.at>
|
||||
--
|
||||
|
||||
+4
-4
@@ -102,7 +102,7 @@ syntax changing as we did to get old programs to compile on strict
|
||||
ANSI C compilers.
|
||||
|
||||
Last, read the judges' comments/spoilers on the program. Hints
|
||||
for `foo.c' are given in `foo.hint'. Often they will contain suggested
|
||||
for `foo.c` are given in `README.md`. Often they will contain suggested
|
||||
arguments or recommended data to use.
|
||||
|
||||
If you do gain some understanding of how a program works, go back to
|
||||
@@ -114,12 +114,12 @@ Regarding the source archive:
|
||||
|
||||
Each sub-directory contains all the entries for a single year. Often
|
||||
the file names match one of the last names of the author. Judges'
|
||||
hints are given in files of the form ``*.hint''.
|
||||
hints are given in files of the form `README.md`.
|
||||
|
||||
You may need to tweak the Makefile to get everything to compile correctly.
|
||||
Read the hint files for suggestions.
|
||||
Read the README.md files for suggestions.
|
||||
|
||||
The rules for a given year are given in the file named ``rules''. Each
|
||||
The rules for a given year are given in the file named `rules.txt`. Each
|
||||
archive contains a copy of the rules for the upcoming contest.
|
||||
|
||||
The following URL is the official archive of the winning entries:
|
||||
|
||||
@@ -447,9 +447,7 @@ Now, Microsoft makes AT&T look mild and kind in comparison. :-( (IMHO) ).
|
||||
|
||||
BTW:
|
||||
See the story about the ''
|
||||
<A
|
||||
HREF="/1993/mills/mills.hint">Bill
|
||||
Gates</A>'' award. :-)
|
||||
<A HREF="/1993/mills/README.md">Bill Gates</A>'' award. :-)
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
|
||||
+1
-1
@@ -2261,7 +2261,7 @@ Contest </I></FONT></CENTER>
|
||||
<UL TYPE=square>
|
||||
<LI><A HREF="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1998/dorssel/Makefile">Makefile</A>
|
||||
<LI><A HREF="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1998/dorssel/dorssel.c">dorssel.c</A>
|
||||
<LI><A HREF="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1998/dorssel/dorssel.hint2">dorssel.hint2</A>
|
||||
<LI><A HREF="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1998/dorssel/dorssel.hint">dorssel.hint</A>
|
||||
<LI><A HREF="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1998/dorssel/README.md">README.md</A>
|
||||
</UL>
|
||||
<A NAME="1998_fanf"></A>
|
||||
|
||||
Reference in new issue
Block a user