Write the shortest program to transform the standard input into Morse code. Characters not in the table should be printed as they are.

|
Write the shortest program to transform the standard input into Morse code. Characters not in the table should be printed as they are.
|
|||||||||||||
|
Golfscript - 74 charsThis answer supports only uppercase and digits. The letters are separated by newlines and words are separated by 2 newlines
Analysis
{ }% as usual works like a map over the array
. push a copy of the char onto the stack
" ETIAN..." this is a lookup table for the uppercase characters
? like a string.find returns the index of the char in the string
or -1 if it is not found (ie it's a digit)
) increment that index so E=>2 T=>3 I=>4 etc. notice that if the
char is not an uppercase letter or space this is now 0 (False)
"?/'#!..." this is a lookup table for the digits. it will be used in the
reverse way to the other lookup table.
@ pull that copy we made of the char to the top of the stack
))%10 convert ascii digit to a number by adding 2 and taking mod 10.
It's important to do it this way because all the uppercase
letters hit this code too, and we need to make sure they fall
in the range 0..9 or the next step will fail.
= pull the nth char from the string eg "Hello"1= gives "e"
or remember if the uppercase lookup fails we have a 0 result, so
the digit lookup will be used
2base convert to base 2 so E=>[1 0], T=>[1 1], I=>[1 0 0] etc.
(; pop the front of the list and throw it away so E=>[0], T=>[1]
{!45+}% negate each bit and add 45, this gives ascii value of . and -
n newline separates each word. this could be 32 if you wanted to
separate the words with spaces for a cost of 1 stroke
Golfscript - 85 chars This is shorter than my SO answer due to the relaxed requirements here The input must be uppercase/digits and the punctuation characters ".,?"
Since the punctuation is not even required here, I may shorten the answer even more My answer from SO newline at the end of the input is not supported, so use something like this
Letters are a special case and converted to lowercase and ordered in their binary positions. Everything else is done by a translation table
|
|||||||||
|
|
C# (213 characters) I'm sure this wont stand long, but at least I got the technique here first!
And in readable format:
For a brief explanation, the string of characters is a heap in which the left child is a dot and the right child is a dash. To build the letter, you traverse back up and reverse the order. |
|||||||||||
|
tr + sed (347)
|
|||||||||||||||||||
|
Haskell —
|
Just checked the question referenced by @dmckee "Code Golf: Morse code" and didn't find a Haskell version. I think, shorter than 314 would be possible. – Yasir Arsanukaev Jan 28 '11 at 17:33 |
|
fromJust.elemIndex c can be written as head.findIndices(==c). That is one character more, but you can then get rid of import Data.Maybe, so you'll save 17 characters total. You can also save two characters by removing the space in front of the string each time you call intercalate. And another few characters by doing i=intercalate at the beginning and replacing the two calls to intercalate with i. – sepp2k Feb 1 '11 at 16:25 |
|
@sepp2k: Nice idea! Thanks. I also played with intercalate and have saved another 6 characters! :-) – Yasir Arsanukaev Feb 1 '11 at 16:54 |
|
You can also do w=words, which saves one character if I'm not mistaken. And instead of l c=... and map l, you should do map\c->... (you don't even need parens around the lambda since there's already a closing paren afterwards anyway). – sepp2k Feb 1 '11 at 17:02 |
|
@sepp2k: Inlining of l c=... did save me 1 character, but I couldn't put it without parens, only as map(\c->...). GHC version 6.12.3. – Yasir Arsanukaev Feb 1 '11 at 17:15 |
|
Lisp (
This encodes lower case letters, and morse code sequences are printed with a trailing space |
||||
|
|
|
Perl6 (238)
Readable version
|
|||
|
|
|
Ruby (161)
Encodes each digit into a single char, where 1 is dash, 0 is dot, with a leading 1 as a marker bit (+ an offset to keep it printable. Uses ASCII math to use the input chars as lookup indices. |
|||
|
|
|
In Java, 475 characters.
Translates a-z, A-Z and 0-9. Edit: Or in 447 characters, if you don't mind Java throwing an error after the translation.
|
||||
|
|
|
Postscript Combined numbers and letters with a ternary encoding. 5 ternary digits fit in a byte! This eliminates those silly difference loops, and special-casing numbers entirely. ASCII85 cuts 1/3 of each table. And simplifying the code (finally!) gets back under 400!
Sample output Luser Dr00g! . --- . . . . --- . . . . . --- . --- . . . --- . --- --- --- --- --- --- --- --- --- --- --- --- . ! Ungolfed and commented. I'm very proud of this one. I feel it's elegant, making the numbers do the work. :)
The tables (33)+(13)=(46) Here's how the strings encode the table. Each byte represents a 5-digit ternary number. And the bytes are further encoded in ASCII85 (which postscript can automagically decode).
|
||||
|
|
Perl (489 chars)
Can be executed via command line like so.
Edit: Thanks @tobyodavies for pointing out that my original solution had the translation backwards! |
|||||
|
PHP, 474 characters
Its 462 characters if all input is in uppercase:
|
|||
|
|