Merge pull request #1397 from xexyl/dorssel98

Updates to 1998/dorssel
This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-11-12 13:38:42 -07:00
commit c8461850f0
4 files changed
+82 -28

No files matched your search

+23 -10
View File
@@ -18,11 +18,13 @@ echo text | ./dorssel
### Try:
```sh
echo Simple as 123 | ./dorssel
echo 'Binary as simple as 1, 10 11.' | ./dorssel
echo '.... --- .-- -.. --- . ... .. - -.. --- - .... .- -' | ./dorssel
echo 'HOW DOES IT DO THAT' | ./dorssel
echo 'HOW DOES IT DO THAT' | ./dorssel | ./dorssel
./try.sh
```
Also try:
```sh
./dorssel < dorssel.md
```
@@ -47,7 +49,17 @@ what values may they be changed without altering the behavior?
altering the behavior ?
Extra credit: Change the program so that it does not SHOUT IN ALL CAPS.
### Extra credit:
Try doing what the last part of the last command in [try.sh](try.sh) suggests.
As in, do the following:
```sh
echo ". -..- . .-. -.-. .. ... .
-.-. .... .- -. --. . - .... . .--. .-. --- --. .-. .- -- ... --- .. - -.. --- . ... -. --- - ... .... --- ..- -" | ./dorssel
```
and make the necessary adjustments.
You might also want to read the [dorssel.md](dorssel.md) file.
@@ -56,7 +68,8 @@ You might also want to read the [dorssel.md](dorssel.md) file.
### Usage
This program converts ASCII to Morse code, and vice versa.
This program converts ASCII to [Morse
code](https://en.wikipedia.org/wiki/Morse_code), and vice versa.
The program reads in lines from standard input and writes its result to
standard output. The direction of conversion is determined on a per
@@ -66,8 +79,8 @@ characters. Otherwise, some characters may be lost in the conversion.
- 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
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.
- Decoding from Morse code: Morse code should be typed as sequences of `.` and
@@ -108,7 +121,7 @@ is the same as
understand this program. For an obfuscated spoiler, try
```sh
./dorssel < dorssel.md\
./dorssel < dorssel.md
```
+18 -18
View File
@@ -1,7 +1,7 @@
# Information about this entry
Morse codes for letters and digits use sequences of 1 to 5 (inclusive)
Morse symbols (denoted as '.' or '-'), e.g.
Morse symbols (denoted as `.` or `-`), e.g.
```
E .
@@ -16,7 +16,7 @@ to be a bit set to 0, `.` to be a bit set to 1. Characters in C are at
least 8 bits, but they are either signed or unsigned. To be portable,
I've used only values from 0 to 127 (inclusive) (both in the encoding
of Morse codes, as well as in subexpressions in the program). Hence we
can use type char (using unsigned char for an extra bit would have made
can use type `char` (using `unsigned char` for an extra bit would have made
the source code excessively large ;-)
The least significant bit contains the first symbol of a Morse code, so
@@ -28,7 +28,7 @@ Z > 0...1100
3 > 0..00111
```
The dots have still to be determined. But we also need to encode the
The dots still have to be determined. But we also need to encode the
length of the sequence. Since there are only 4 different kind of lengths,
two bits would suffice, e.g.
@@ -60,7 +60,7 @@ length 4: 00.1xxxx Z > 00.11100
length 5: 0.1xxxxx 3 > 0.100111
```
With 1 bit still to be chosen freely (let's assume it is 0). Now we can do
with 1 bit still to be chosen freely (let's assume it is 0). Now we can do
```c
do {
@@ -95,8 +95,8 @@ do {
```
The last shift will always result in `00100010`, hence the test for `>35`.
Note that the calculation for the next value of `encoding` is done at int
precision, so that the actual value of the char remains `<= 127`.
Note that the calculation for the next value of `encoding` is done at `int`
precision, so that the actual value of the `char` remains `<= 127`.
The character `'-'` (ASCII 45) and `'.'` (ASCII 46) are conveniently in
sequence, so the putchar can simply be
@@ -106,9 +106,9 @@ putchar(45 + encoding % 2);
```
I used the modulo operator this time, because `+` takes precedence over `&`.
The assignment can be incorporated into the while control test, and a
do-while loop with a body of a single expression statement can be written
as a while loop with a comma operator in the test:
The assignment can be incorporated into the `while` control test, and a
`do-while` loop with a body of a single expression statement can be written
as a `while` loop with a comma operator in the test:
```c
while(putchar(45 + encoding % 2), encoding = encoding + 32 >> 1);
@@ -128,16 +128,16 @@ of the array initializer ! The test also stops when at most 5 symbols
have been shifted in.
The encoded character is then looked up in the encoding string with
`memchr()` (why `memchr()` is explained later). Either a `?` (when there are
`memchr(3)` (why `memchr(3)` is explained later). Either a `?` (when there are
more than 5 consecutive Morse symbols, or if the sequence is unknown)
or the decoded character is printed. Or a `' '` if there was an extra
space in the source line. Note the use of "or" in these last sentences,
as they explain the use of the conditional operator.
The `strspn` calls need either `" .-"` or `".-"` as argument. Of course they
The `strspn(3)` calls need either `" .-"` or `".-"` as argument. Of course they
are overlapped. I put these strings between the encodings for digits
and letters. This is OK, since neither of these characters, or the `'\0'`,
is a valid encoding ! We must, however, use `memchr()` instead of `strchr()` in
is a valid encoding ! We must, however, use `memchr(3)` instead of `strchr(3)` in
the decoding lookup because of this `'\0'`. Since it is far more obscure
this way, I hope you'll forgive me.
@@ -163,11 +163,11 @@ while (more lines) {
```
Because of the *two* `while(more characters)` loops are the same, I've
exchanged the `if(line is in morse)` and the two while loops (so there
is *single* while loop). However, we must now store the `if(line is in
exchanged the `if(line is in morse)` and the two `while` loops (so there
is *single* `while` loop). However, we must now store the `if(line is in
morse)` test for efficiency (it would be stupid to test the entire line
for every character). This is done in `l[0]` ! (the first encoding is
thus in `l[1]`). The `memchr()` decoding lookup is not disturbed, because the
thus in `l[1]`). The `memchr(3)` decoding lookup is not disturbed, because the
test is always `0` for Morse lines, and `'\0'` is not a possible encoding.
`l[0]` is also used as the temporary shift character while encoding a
line of text. This does not disturb the `if (line is in morse)` test,
@@ -191,15 +191,15 @@ l[35] - l[998] input line
---
Selected notes:
- We don't need to declare `isalnum()` (or include ctype.h) as its implicit
- We don't need to declare `isalnum(3)` (or include ctype.h) as its implicit
declaration is correct (int argument, int result). This is not so for
`strlen()`, `strspn()`, and `memchr()` as they use `size_t`.
`strlen(3)`, `strspn(3)`, and `memchr(3)` as they use `size_t`.
- During development, my gcc 2.7.2.3 had an internal compiler error (signal
6) on code that was correct !
- lclint 2.4b thinks that "the observer is modified" a couple of times,
whereas it is not. Well, it is, but there is a sequence point in between.
- lclint 2.4b parses line 13 as <error>, whereas it is correct code.
- lclint 2.4b is positive the second while loop is infinite, whereas it is
- lclint 2.4b is positive the second `while` loop is infinite, whereas it is
not.
---
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
#
# script to show 1998/dorssel
echo "$ echo 'Simple as 123' | ./dorssel" 1>&2
echo 'Simple as 123' | ./dorssel
echo "$ echo 'Binary as simple as 1, 10 11.' | ./dorssel" 1>&2
echo 'Binary as simple as 1, 10 11.' | ./dorssel
echo "$ echo '.... --- .-- -.. --- . ... .. - -.. --- - .... .- -' | ./dorssel" 1>&2
echo '.... --- .-- -.. --- . ... .. - -.. --- - .... .- -' | ./dorssel
echo "$ echo 'HOW DOES IT DO THAT' | ./dorssel" 1>&2
echo 'HOW DOES IT DO THAT' | ./dorssel
echo "$ echo 'HOW DOES IT DO THAT' | ./dorssel | ./dorssel" 1>&2
echo 'HOW DOES IT DO THAT' | ./dorssel | ./dorssel
echo "$ ./dorssel < dorssel.c | ./dorssel" 1>&2
./dorssel < dorssel.c | ./dorssel
echo "$ echo '
.. - .... .. -. -.- - .... .. ... ... .--. --- .. .-.. . .-. .. ... -- --- .-. . --- -... ..-. ..- ... -.-. .- - . -.. - .... .- -. - .... . .--. .-. --- --. .-. .- --
. -..- . .-. -.-. .. ... .
-.-. .... .- -. --. . - .... . .--. .-. --- --. .-. .- -- ... --- .. - -.. --- . ... -. --- - ... .... --- ..- -' | ./dorssel" 1>&2
echo "
.. - .... .. -. -.- - .... .. ... ... .--. --- .. .-.. . .-. .. ... -- --- .-. . --- -... ..-. ..- ... -.-. .- - . -.. - .... .- -. - .... . .--. .-. --- --. .-. .- --
. -..- . .-. -.-. .. ... .
-.-. .... .- -. --. . - .... . .--. .-. --- --. .-. .- -- ... --- .. - -.. --- . ... -. --- - ... .... --- ..- -" | ./dorssel
+5
View File
@@ -2048,6 +2048,11 @@ Cody added a call to `endwin()` to restore terminal sanity (echo etc.) when
exiting the program.
## [1998/dorssel](1998/dorssel/dorssel.c) ([README.md](1998/dorssel/README.md]))
Cody added the [try.sh](1998/dorssel/try.sh) script.
## [1998/fanf](1998/fanf/fanf.c) ([README.md](1998/fanf/README.md))
Cody fixed this to compile. The problem was the intermediate steps to get to the