Merge pull request #191 from xexyl/1998-schweikh2

Formatting fixes in 1998/schweikh2/README.md
This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-03-28 14:36:55 -07:00
commit 45e679c147
1 file changed
+93 -58
+93 -58
View File
@@ -14,27 +14,46 @@
make all make all
NOTE: Almost every compiler is supposed to be able to accept the code in NOTE: Almost every compiler is supposed to be able to accept the code in
schweikh2.c; try compiling schweikh2.alt.c to see if your compiler `schweikh2.c`; try compiling `schweikh2.alt.c` to see if your compiler
is fully standard-compliant. is fully standard-compliant.
### To run ## To run:
To use: To use:
./schweikh2 ./schweikh2
<some number>
or or
./schweikh2 integer_number ./schweikh2 integer_number
## Judges' comments ## Try:
Run the program with a small argument, like 5 or 10, several times. ./schweikh2 5
Are the results different? Why? ./schweikh2 5
Some non-gcc compilers that are not fully ANSI standard do not ./schweikh2
compile this entry correctly. 5
At the time this hint file was written, some gcc and egcs What is the difference here?
implementations ran into problem when building the original entry:
What happens if you don't put in any number like the below?
./schweikh2
<ENTER>
## Judges' comments:
Run the program with a small argument, like 5 or 10, several times. Are the
results different? Why?
Some non-gcc compilers that are not fully ANSI standard do not compile this
entry correctly.
At the time this hint file was written, some gcc and egcs implementations ran
into problem when building the original entry:
make schweikh2.alt make schweikh2.alt
@@ -61,14 +80,14 @@ is fully standard-compliant.
and the lone " after the #.file line results in an assembler syntax error. and the lone " after the #.file line results in an assembler syntax error.
In some cases one must compile using 'gcc -g': In some cases one must compile using `gcc -g`:
make schweikh2.alt CFLAGS=-g make schweikh2.alt CFLAGS=-g
to trigger this error. to trigger this error.
And with the proper text beyond the \012, it may be possible to have And with the proper text beyond the `\012`, it may be possible to have
all kinds of fun adding ``inline assembly'' via #line directives. :-) all kinds of fun adding `inline assembly` via #line directives. :-)
For extra credit: For extra credit:
If your compiler has this bug, transform the line in the C If your compiler has this bug, transform the line in the C
@@ -77,10 +96,14 @@ is fully standard-compliant.
If you are able to do the above, try adding assembly instructions If you are able to do the above, try adding assembly instructions
so that it will compile, execute and do something interesting. so that it will compile, execute and do something interesting.
If you succeed in doing this (especially on FreeBSD, Linux or Sparc), If you succeed in doing this (especially on FreeBSD, Linux or Sparc),
email the author for a free pat on the back. email the author for a free pat on the back.
## Author's comments NOTE: the author submitted the program as yarng so when trying the examples
below change `yarng` to `./schweikh2`.
## Author's comments:
What this program does What this program does
---------------------- ----------------------
@@ -91,62 +114,74 @@ is fully standard-compliant.
mechanical events that build up the hardware as well as some other mechanical events that build up the hardware as well as some other
non-deterministic factors. Here's how it works: non-deterministic factors. Here's how it works:
1) an alarm is scheduled to be delivered in a second 1. an alarm is scheduled to be delivered in a second
2) an infinite loop is entered that just increments a counter 2. an infinite loop is entered that just increments a counter
3) on delivery of the alarm signal, the counter's LSB is printed. 3. on delivery of the alarm signal, the counter's LSB is printed.
4) while some other counter is not zero, go to 1) 4. while some other counter is not zero, go to 1)
5) exit 5. exit
The yarng therefore produces output at a rate of 1 baud. The number of The yarng therefore produces output at a rate of 1 baud. The number of
bits may be specified by an argument and defaults either to UINT_MAX bits may be specified by an argument and defaults either to `UINT_MAX`
(least likely) or UINT_MAX+1 (most likely). Extra credit: why the (least likely) or `UINT_MAX+1` (most likely). Extra credit: why the
different values? How long would you need for an empirical test? different values? How long would you need for an empirical test?
For example: For example:
```sh
$ yarng 32 $ yarng 32
10111001010101110110010101001111 10111001010101110110010101001111
$ yarng 5 $ yarng 5
10011 10011
```
Why I think this is obfuscated Why I think this is obfuscated
------------------------------ ------------------------------
- Ever seen a 'do for ... while' loop? - Ever seen a 'do for ... while' loop?
- I avoided 'int' like the plague. Instead I used storage class specifiers - I avoided 'int' like the plague. Instead I used storage class specifiers
(register, auto) to get implicit int. The Standard allows implicit int (register, auto) to get implicit int. The Standard allows implicit int even in
even in casts as you can see in '(void(*)(register))main'. Where implicit casts as you can see in `(void(*)(register))main`. Where implicit int is
int is impossible, like in the 'int main' declaration I have int split impossible, like in the `int main` declaration I have int split across two
across two lines. All indent programs I use insert space at the beginning lines. All indent programs I use insert space at the beginning of the
of the continuation line and thereby introduce a syntax error. continuation line and thereby introduce a syntax error.
-main (ab)used as a signal handler. Shocking. Yeah, this leads to undefined
behaviour. I have yet to see a system where it does not work. If it - `main` (ab)used as a signal handler. Shocking. Yeah, this leads to undefined
doesn't work for you, I'd appreciate if you mail me about it. behaviour. I have yet to see a system where it does not work. If it doesn't work
Uh-oh, schweikh did it, uttered "Works for me". Don't quote me on that! for you, I'd appreciate if you mail me about it. Uh-oh, schweikh did it,
uttered "Works for me". Don't quote me on that!
- Even if you know how the program works, you just can't predict the output. - Even if you know how the program works, you just can't predict the output.
-Chained use of token pasting operators ## with shuffled arguments
-So you think you can't assign to __LINE__ and __FILE__? Not so. The - Chained use of token pasting operators ## with shuffled arguments.
#line preprocessor directive does the trick. But saying '#line 10 "01\n"'
is a little lame and I came up with '??=line 10 ONE(O(1,1,2,6,0,6))' - So you think you can't assign to `__LINE__` and `__FILE__`? Not so. The `#line`
-__LINE__ is used as the signal number argument to signal(). If indenting preprocessor directive does the trick. But saying `#line 10 "01\n"` is a little
or other editing changes the number of lines the program is likely to be lame and I came up with `??=line 10 ONE(O(1,1,2,6,0,6))`.
killed after one second... Thanks to POSIX for specifying SIGALRM as 14.
You're SOL if your system does not conform. Get a real OS. - `__LINE__` is used as the signal number argument to signal(). If indenting or
-All strings (or characters) needed are crammed into __FILE__ using other editing changes the number of lines the program is likely to be killed
octal notation and then extracted using pointer + offset notation. after one second... Thanks to POSIX for specifying SIGALRM as 14. You're SOL if
-Use of a # (null) preprocessor directive (hidden as a %: digraph) your system does not conform. Get a real OS.
Delete this line and prepare for a core dump.
-Identifiers reused with different capitalization: one, One, ONE, zero, - All strings (or characters) needed are crammed into `__FILE__` using octal
Zero. ONE is particularly nasty because it appears as a macro taking notation and then extracted using pointer + offset notation.
an arg and as a plain identifier in main's parameters. The rule is that
whenever ONE is followed by '(' it must be the macro. - Use of a `#` (null) preprocessor directive (hidden as a `%:` digraph) Delete
-A quote from Kernighan and Plauger, "The Elements of Programming Style", this line and prepare for a core dump.
2nd Ed., page 21: "A useful way to decide if some piece of code is
clear or not is the ``telephone test.'' If someone could understand your - Identifiers reused with different capitalization: `one`, `One`, `ONE`, `zero`,
code when read aloud over the telephone, it's clear enough. If not then `Zero`. `ONE` is particularly nasty because it appears as a macro taking an arg
it needs rewriting." and as a plain identifier in `main`'s parameters. The rule is that whenever
Now try the telephone test for 'one = zero = atoi (ONE[zero-1])' `ONE` is followed by `(` it must be the macro.
-Don't you love the aesthetics of symmetry: write (1, 1+__FILE__+1, 1)
- A quote from Kernighan and Plauger, "The Elements of Programming Style", 2nd
Ed., page 21: "A useful way to decide if some piece of code is clear or not is
the 'telephone test.' If someone could understand your code when read aloud
over the telephone, it's clear enough. If not then it needs rewriting." Now try
the telephone test for 'one = zero = atoi (ONE[zero-1])'.
- Don't you love the aesthetics of symmetry: `write (1, 1+__FILE__+1, 1)`
(telephone test this as well; is it 1, One, ONE, one? Maybe won?). (telephone test this as well; is it 1, One, ONE, one? Maybe won?).
Where does the randomness come from? Where does the randomness come from?
@@ -156,10 +191,10 @@ is fully standard-compliant.
executed between two calls of the signal handler. But what determines executed between two calls of the signal handler. But what determines
this number? this number?
+ The accuracy of the clock driving the CPU - The accuracy of the clock driving the CPU.
+ The accuracy of the clock driving the timer responsible for alarm signals - The accuracy of the clock driving the timer responsible for alarm signals.
+ On multitasking OS's: The total time the process is scheduled - On multitasking OS's: The total time the process is scheduled to run between
to run between successive invocations of the signal handler. successive invocations of the signal handler.
How about the randomness of the yarng? To measure these properties I How about the randomness of the yarng? To measure these properties I
counted the number of bit sequences and compared them to what I would counted the number of bit sequences and compared them to what I would
@@ -170,8 +205,8 @@ is fully standard-compliant.
than or equal to rand()'s. Randomness however tends to degrade under than or equal to rand()'s. Randomness however tends to degrade under
high load averages on my system (Linux). This could be avoided by high load averages on my system (Linux). This could be avoided by
allowing the process one second of execution time instead of wall allowing the process one second of execution time instead of wall
clock time (using the SIGVTALRM sent by the virtual timer clock time (using the `SIGVTALRM` sent by the virtual timer
instead of SIGALRM). instead of `SIGALRM`).
I'm not surprised. Yarng in the end depends on fluctuations of the I'm not surprised. Yarng in the end depends on fluctuations of the
electrical field and the heat distribution in the oscillators, the electrical field and the heat distribution in the oscillators, the