Merge pull request #109 from xexyl/hints

Address references to *.hint with some exceptions
This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-03-21 15:43:13 -07:00
commit 38cfa3d185
9 files changed
+142 -143

No files matched your search

+1 -1
View File
@@ -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
+1 -1
View File
@@ -166,7 +166,7 @@ ENTRY= dorssel
PROG= ${ENTRY}
#
OBJ= ${PROG}.o
DATA= dorssel.hint2
DATA= dorssel.hint
TARGET= ${PROG}
#
ALT_OBJ=
+52 -50
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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:
+1 -3
View File
@@ -447,9 +447,7 @@ Now, Microsoft makes AT&amp;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
View File
@@ -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>