Convert string to morse code

A task

The shortest code by the number of characters that will enter a string using only alphabetic characters (upper and lower case), numbers, commas, periods and a question mark and returns a string representation in Morse code. The Morse code output should consist of a dash ( - , ASCII 0x2D) for a long beep (AKA 'dah') and a dot ( . , ASCII 0x2E) for a short beep (AKA 'dit').

Each letter must be separated by a space ( ' ' , ASCII 0x20), and each word must be separated by a slash ( / , ASCII 0x2F).

Morse Code Table:

alt text http://liranuna.com/junk/morse.gif

Test examples:

 Input: Hello world Output: .... . .-.. .-.. --- / .-- --- .-. .-.. -.. 



 Input: Hello, Stackoverflow. Output: .... . .-.. .-.. --- --..-- / ... - .- -.-. -.- --- ...- . .-. ..-. .-.. --- .-- .-.-.- 

The number of codes includes input / output (i.e. a complete program).

+57
language-agnostic code-golf
Aug 29 '09 at 22:54
source share
32 answers
  • one
  • 2

C (131 characters)

Yes, 13 1 !

 main(c){for(;c=c?c:(c=toupper(getch())-32)? "•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5" [c-12]-34:-3;c/=2)putch(c/2?46-c%2:0);} 

I highlighted a few more characters by combining the logic from the while and for loops into one for loop and moving the declaration of the variable c to the definition of main as an input parameter. This last method that I borrowed from answered another call .




For those trying to test a program using GCC or with ASCII editors, you may need the following, slightly longer version:

 main(c){for(;c=c?c:(c=toupper(getchar())-32)?c<0?1: "\x95#\x8CKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5" [c-12]-34:-3;c/=2)putchar(c/2?46-c%2:32);} 

This version is 17 characters longer (weighs about 148), due to the following changes:

  • +4: getchar() and putchar() instead of getch() and putch()
  • +6: escape codes for two characters instead of non-ASCII characters
  • +1: 32 instead of 0 for space character
  • +6: added " c<0?1: " to suppress garbage from characters smaller than ASCII 32 (namely, from '\n' ). You still get garbage from any of !"#$%&'()*+[\]^_ _` {|}~ Or anything above ASCII 126.

This should make the code fully portable. Compile with:

  gcc -std = c89 -funsigned-char morse.c 

-std=c89 is optional. However, -funsigned-char is required, or you will get garbage for a comma and a complete stop.




135 characters

 c;main(){while(c=toupper(getch()))for(c=c-32? "•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5" [c-44]-34:-3;c;c/=2)putch(c/2?46-c%2:0);} 

In my opinion, this latest version is much more visually appealing. And no, it is not portable, and it is no longer protected from input outside the limits. It also has a pretty bad interface, accepting character input and converting it to Morse code and not having an exit condition (you need to press Ctrl + Break ). But a portable, reliable code with a nice interface was not required.

The following is a brief description of the code:

 main(c){ while(c = toupper(getch())) /* well, *sort of* an exit condition */ for(c = c - 32 ? // effectively: "if not space character" "•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"[c - 44] - 34 /* This array contains a binary representation of the Morse Code * for all characters between comma (ASCII 44) and capital Z. * The values are offset by 34 to make them all representable * without escape codes (as long as chars > 127 are allowed). * See explanation after code for encoding format. */ : -3; /* if input char is space, c = -3 * this is chosen because -3 % 2 = -1 (and 46 - -1 = 47) * and -3 / 2 / 2 = 0 (with integer truncation) */ c; /* continue loop while c != 0 */ c /= 2) /* shift down to the next bit */ putch(c / 2 ? /* this will be 0 if we're down to our guard bit */ 46 - c % 2 /* We'll end up with 45 (-), 46 (.), or 47 (/). * It very convenient that the three characters * we need for this exercise are all consecutive. */ : 0 /* we're at the guard bit, output blank space */ ); } 

Each character in a long line of code contains Morse code for one text character. Each bit of an encoded character represents either a dash or a period. One represents a dash, and zero represents a dot. The smaller bit is the first stroke or dot in the Morse code. The final “guard” bit determines the length of the code. That is, the most significant bit in each encoded character represents the end of the code and is not printed. Without this guard bit, endpoint characters cannot be printed correctly.

For example, the letter “L” is “ .-.. ” in Morse code. To represent this in binary, we need 0, 1, and two more 0s, starting with the least significant bit: 0010. Drop one more on the protection bit, and we have our Morse code encoded: 10010 or decimal 18. Add an offset +34 to get 52, which is the ASCII value of the character "4". Thus, the encoded character array has “4” as the 33rd character (index 32).

This method is similar to the one used to encode characters in ACoolie , strager's (2) Miles's , pingw33n's , Alec and, but a bit simpler, requiring only one operation per bit (offset / division), and not two (offset / division and decrement )

EDIT:
Looking through the rest of the implementations, I see that Alec and Anon came up with this coding scheme - using the watchdog bit - before I did it. Anon's solution is particularly interesting, using the Python bin function and separating the "0b" prefix and the protection bit from [3:] , rather than looping, changing, and moving around, as Alec and I did.

As a bonus, this version also handles hyphens ( -....- ), slashes ( -..-. ), -..-. ( ---... ), semicolons ( -.-.-. ), -.-.-. to ( -...- ), but with the sign ( .--.-. ). As long as 8-bit characters are allowed, these characters do not require additional bytes of code to support. No character can be supported with this version without adding length to the code (unless Morse codes have more / less characters).

Since I find that the old implementations are still interesting, and there are some warnings in the text that apply to this version, I left the previous content of this post below.




Well, presumably the user interface can suck, right? So, borrowing from strager , I replaced gets() , which provides buffered echo input, with getch() , which provides unbuffered, unshielded character input. This means that every character you enter is immediately translated into Morse code on the screen. Maybe it's cool. It no longer works with either the stdin argument or the command line, but this is pretty damn small.

I kept the old code below, however, for reference. Here is a new one.

New border checking code, 171 characters:

 W(i){i?W(--i/2),putch(46-i%2):0;}c;main(){while(c=toupper(getch())-13) c=c-19?c>77|c<31?0:W("œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE" [c-31]-42):putch(47),putch(0);} 

Enter terminates the loop and exits the program.

New code without border checks, 159 characters:

 W(i){i?W(--i/2),putch(46-i%2):0;}c;main(){while(c=toupper(getch())-13) c=c-19?W("œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"[c-31]-42): putch(47),putch(0);} 

Following is the old code 196/177 with some explanation:

 W(i){i?W(--i/2),putch(46-i%2):0;}main(){char*p,c,s[99];gets(s); for(p=s;*p;)c=*p++,c=toupper(c),c=c-32?c>90|c<44?0:W( "œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"[c-44]-42): putch(47),putch(0);} 

This is based on the answer of Andrea Python , using the same method for generating Morse code as in this answer. But instead of storing coding characters one by one and finding their indices, I stored the indices one by one and looked at them by character (similar to my earlier answer ). This prevents lengthy gaps at the end that caused problems for earlier developers.

As before , I used a character that is larger than 127. Converting it to ASCII-only adds 3 characters. The first character of the long string should be replaced with \x9C . An offset is necessary this time, otherwise a large number of characters will be less than 32 and must be represented by escape codes.

As before, processing the command line argument adds 2 characters instead of stdin, and using a real space character between codes adds 1 character.

On the other hand, some of the other routines here do not deal with input outside the valid range [, .0-9 \ A-Za-z]. If such processing was removed from this procedure, then 19 characters can be deleted, resulting in a total of 177 characters. But if this is done, and an invalid input is transferred to this program, it can work and burn.

The code in this case can be:

 W(i){i?W(--i/2),putch(46-i%2):0;}main(){char*p,s[99];gets(s); for(p=s;*p;p++)*p=*p-32?W( "œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE" [toupper(*p)-44]-42):putch(47),putch(0);} 
+70
Aug 31 '09 at 2:41
source share

Using the Morse Font Font ?

 Console.Write(params[0]); 
+48
Aug 29 '09 at 23:01
source share

Perl, 170 characters (with a little help from an experienced golfer mauke ). Wrapped for clarity; All newlines are removable.

 $_=uc<>;y,. ,|/,;s/./$& /g;@m{A..Z,0..9,qw(| , ?)}= ".-NINNN..]IN-NII..AMN-AI---.M-ANMAA.I.-].AIAA-NANMMIOMAOUMSMSAH.B.MSOIONARZMIZ" =~/../g;1while s![]\w|,?]!$m{$&}!;print 

Explanation:

  • Extract the morse dictionary. Each character is defined as two characters, which can be either literal dots, or a dash, or a reference to the value of another specific char. E and T contain dummy characters to avoid decoding the decoder; we will delete them later.
  • Read and format the input. "Hello world" becomes "HELLO / WORLD"
  • The next step depends on the fact that the input and output dictionaries are different, so rotate the points at the entrance to an unused char (vertical bar, | )
  • Replace any char with the input that occurs in the morse dictionary with its value in the dictionary until a replacement occurs.
  • Remove the dummy char specified in step 1.
  • Print the output.

In the final version, the dictionary is optimized for efficient execution:

  • All characters with one character (E and T) and two-character characters (A, I, M, and N) are determined directly and decoded in a single pass.
  • All characters with three characters are defined in terms of a two-character character and a literal character, two-pass decoding.
  • All characters with four characters are defined in two characters with two characters, decoding in two passes with three replacements.
  • Five- and six-character characters (numbers and punctuation) are decoded in three passes with four or five replacements, respectively.

Since the golf code only replaces one character per cycle (to save one code character!) The number of cycles is limited to five times the input length (three times the input length if only alphabets are used), but adding the operation g to s/// , the number of cycles is limited to three (two if only alphabets are used).

Conversion Example:

 Hello 123 HELLO / 1 2 3 II .] AI AI M- / AO UM SM .... . .-.. .-.. --- / .-M- .A-- I.-- .... . .-.. .-.. --- / .---- ..--- ...-- 
+23
Aug 29 '09 at 23:25
source share

Understanding Python List, 159 Character Single Line

 for c in raw_input().upper():print c<","and"/"or bin(ord("•ƒwTaQIECBRZ^`šŒ#S#n|':<.$402&9/6)(18?,*%+3-;=>"[ord(c)-44])-34)[3:].translate(" "*47+"/.-"+" "*206), 

Uses a similar packing of P Daddy C data, but does not store bits in reverse order and uses bin() to retrieve data, not arithmetic. Note also that gaps are detected using inequality; he believes that each character “less than a comma” is space.

Python for loop, 205 characters, including newlines

 for a in raw_input().upper(): q='_ETIANMSURWDKGOHVF_L_PJBXCYZQ__54_3___2__+____16=/_____7___8_90'.find(a);s='' while q>0:s='-.'[q%2]+s;q=~-q/2 print['/','--..--','..--..','.-.-.-',''][' ,?.'.find(a)]+s, 
+16
Aug 29 '09 at 23:23
source share

I talked about compact character encoding, but I don’t see if it works better than implicit trees that are already in use, so I present the encoding here if someone else can use it.

Consider the line:

  --..--..-.-.-..--...----.....-----.--/ 

which contains all the necessary sequences as substrings. We could encode characters with offset and length as follows:

  ET RRRIIGGGJJJJ --..--..-.-.-..--...----.....-----.--/ CCCC DD WWW 00000 ,,,,,, AALLLL BBBB 11111 --..--..-.-.-..--...----.....-----.--/ ?????? KKK MMSSS 22222 FFFF PPPP 33333 --..--..-.-.-..--...----.....-----.--/ UUU XXXX 44444 NN PPPP OOO 55555 --..--..-.-.-..--...----.....-----.--/ ZZZZ 66666 77777 YYYY --..--..-.-.-..--...----.....-----.--/ ...... 88888 HHHH 99999 VVVV QQQQ --..--..-.-.-..--...----.....-----.--/ 

with space (ie, word boundary) starting and ending on a finite character ("/"). Feel free to use it if you see a good way.

Most short characters have, of course, several possible encodings.




P Daddy found a shorter version of this trick (and now I see at least some redundancy here) and made a good implementation of c. Alec implemented a python implementation with the first (error and incomplete) version. Hobbs made a fairly compact version of perl , which I don't understand at all.

+7
Aug 30 '09 at 1:40
source share

J, 124 130 134 characters

 '.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~ai')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~aitoupper 

J beats C! Fine!

Using:

  '.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~ai')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~aitoupper 'Hello World' .... . .-.. .-.. --- / .-- --- .-. .-.. -.. '.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~ai')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~aitoupper 'Hello, Stackoverflow.' .... . .-.. .-.. --- .-.-.- / ... - .- -.-. -.- --- ...- . .-. ..-. .-.. --- .-- --..-- 
+6
May 11 '10 at 16:53
source share

Python 3 One liner: 172 characters

 print(' '.join('/'if c==' 'else''.join('.'if x=='0'else'-'for x in bin(ord("ijÁĕÁÿïçãáàðøüþÁÁÁÁÁČÁÅ×ÚÌÂÒÎÐÄ×ÍÔÇÆÏÖÝÊÈÃÉÑËÙÛÜ"[ord(c)-44])-192)[3:])for c in input().upper())) 

(Encoding the translation table in Unicode code points. It works well, and they display fine in my test on my Windows Vista machine.)

Edited up to 184 characters, removing unnecessary spaces and brackets (creating a comps gen exps list).

Edit again: more deleted spaces that I didn't even know were possible before seeing other answers here - until 176.

Change again to 172 (woo woo!) Using ".join instead of" .join and make spaces separately. (Spirit!)

+5
Aug 31 '09 at 1:49
source share

C # 266 characters

Solution 131 char C translated into C # yields 266 characters:

 foreach(var i in Encoding.ASCII.GetBytes(args[0].ToUpper())){var c=(int)i;for(c=(c-32!=0)?Encoding.ASCII.GetBytes("•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5")[c-44]-34:-3;c!=0;c/=2)Console.Write(Encoding.ASCII.GetChars(new byte[]{(byte)((c/2!=0)?46-c%2:0)}));} 

which is more readable as:

 foreach (var i in Encoding.ASCII.GetBytes(args[0].ToUpper())) { var c = (int)i; for (c = ((c - 32) != 0) ? Encoding.ASCII.GetBytes("•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5")[c - 44] - 34 : -3 ; c != 0 ; c /= 2) Console.Write(Encoding.ASCII.GetChars(new byte[] { (byte)((c / 2 != 0) ? 46 - c % 2 : 0) })); } 
+5
Oct 11 '09 at 22:56
source share

Golfscript - 106 characters - NO FUNNY CHARS :)

newline at the end of input is not supported, so use something like this

echo -n Hello, Stackoverflow| ../golfscript.rb morse.gs

 ' '/{{.32|"!etianmsurwdkgohvf!l!pjbxcyzq"?)"UsL?/'#! 08<>"@".,?0123456789"?=or 2base(;>{'.-'\=}%' '}%}%'/'* 

Letters are a special case and are converted to lowercase letters and ordered in their binary positions.
Everything else is done by the translation table.

+5
Nov 09 '09 at 21:40
source share

Python

Incomplete solution, but maybe someone can make a complete solution out of it. Does not process numbers or punctuation, but weighs only 154 characters.

 def e(l): i='_etianmsurwdkgohvf_l_pjbxcyzq'.find(l.lower());v='' while i>0:v='-.'[i%2]+v;i=(i-1)/2;return v or '/' def enc(s):return ' '.join(map(e,s)) 
+4
Aug 30 '09 at 0:46
source share

Here is my contribution as a console application to VB.Net

 Module MorseCodeConverter Dim M() As String = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."} Sub Main() Dim I, O Dim a, b While True I = Console.ReadLine() O = "" For Each a In I b = AscW(UCase(a)) If b > 64 And b < 91 Then O &= M(b - 65) & " " ElseIf b > 47 And b < 58 Then O &= M(b - 22) & " " ElseIf b = 46 Then O &= ".-.-.- " ElseIf b = 44 Then O &= "--..-- " ElseIf b = 63 Then O &= "..--.. " Else O &= "/" End If Next Console.WriteLine(O) End While End Sub End Module 

I left him empty space to make it readable. Only 1100 characters. It will read input from the command line, one line at a time and send the corresponding output back to the output stream. The compressed version is lower, only 632 characters.

 Module Q Dim M() As String={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."} Sub Main() Dim I,O,a,b:While 1:I=Console.ReadLine():O="":For Each a In I:b=AscW(UCase(a)):If b>64 And b<91 Then:O &=M(b-65)&" ":ElseIf b>47 And b<58 Then:O &=M(b-22)&" ":ElseIf b=46 Then:O &=".-.-.- ":ElseIf b=44 Then:O &="--..-- ":ElseIf b=63 Then:O &= "..--.. ":Else:O &="/":End IF:Next:Console.WriteLine(O):End While End Sub End Module 
+3
Aug 30 '09 at 2:28
source share

C (248 characters)

Another decision tree.

 #define O putchar char z[99],*t= " ETINAMSDRGUKWOHBL~FCPJVX~YZQ~~54~3~~~2~~+~~~~16=/~~.~~7,~~8~90";c,p,i=0; main(){gets(z);while(c=z[i++]){c-46?c-44?c:O(45):O(c);c=c>96?c-32:c;p=-1; while(t[++p]!=c);for(;p;p/=2){O(45+p--%2);}c-32?O(32):(O(47),O(c));}} 

There may be errors in the source tree because wikipedia seems to be wrong or maybe I didn’t understand something.

+3
Aug 30 '09 at 3:03
source share

F #, 256 characters

 let rec D i=if i=16 then" "else let x=int"U*:+F8c]uWjGbJ0-0Dnmd0BiC5?\4o`h7f>9[1E=pr_".[i]-32 if x>43 then"-"+D(x-43)else"."+D x let M(s:string)=s.ToUpper()|>Seq.fold(fun s c->s+match c with |' '->"/ "|','->"--..-- "|'.'->".-.-.- "|_->D(int c-48))"" 

for example

 M("Hello, Stack.") |> printfn "%s" 

gives

 .... . .-.. .-.. --- --..-- / ... - .- -.-. -.- .-.-.- 

I think my technique may be unique so far. The idea is this:

  • there is an ascii character range that covers most of what we want (0..Z)
  • 43 characters in this range
  • this way we can encode one bit (dash or dot) plus the “next character” in a range of 86 characters
  • the ascii range (32-117) is “printable” and can serve as an 86-char range
  • therefore, a string literal encodes a table along these lines

There's a bit more, but that's the point. The comma, period and space are not in the range 0..Z, so they are specially treated by "coincidence". Some "unused" characters in the range 0..Z (for example, ';') are used in the table as suffixes for other morse translations that are not “letters” in themselves.

+3
Aug 30 '09 at 20:58
source share

C (233 characters)

 W(n,p){while(n--)putch(".-.-.--.--..--..-.....-----..../"[p++]);}main(){ char*p,c,s[99];gets(s);for(p=s;*p;){c=*p++;c=toupper(c);c=c>90?35:c-32? "È#À#¶µ´³²±°¹¸·#####Ê#@i Že'J•aEAv„…`q!j"d‰ƒˆ"[c-44]:63;c-35? W(c>>5,c&31):0;putch(0);}} 

This enters data from stdin. Entering command line input adds 2 characters. Instead:

 ...main(){char*p,c,s[99];gets(s);for(p=s;... 

You get:

 ...main(int i,char**s){char*p,c;for(p=s[1];... 

I use the Windows-1252 code page for characters above 127, and I'm not sure how they will appear in other browsers. I noticed that in my browser at least (Google Chrome) two characters (between "@" and "i") are not displayed. If you copy from a browser and paste into a text editor, however, they appear, albeit in the form of small boxes.

It can be converted to ASCII-only, but it adds 24 characters, increasing the number of characters to 257. For this, I first shift each character in the line by -64, minimizing the number of characters that are more than 127. Then I replace the characters \x XX characters, when necessary. He changes this:

 ...c>90?35:c-32?"È#À#¶µ´³²±°¹¸·#####Ê#@i Že'J•aEAv„…`q!j"d‰ƒˆ"[c-44]:63; c-35?W(... 

:

 ...c>90?99:c-32?"\x88#\x80#vutsrqpyxw#####\x8A#\0PA)\xE0N%Q\nU!O\5\1\66DE 1 \xE1*S$ICH"[c-44]+64:63;c-99?W(... 

Here's a more nicely formatted and commented version of the code:

 /* writes `n` characters from internal string to stdout, starting with * index `p` */ W(n,p){ while(n--) /* warning for using putch without declaring it */ putch(".-.-.--.--..--..-.....-----..../"[p++]); /* dmckee noticed (http://tinyurl.com/n4eart) the overlap of the * various morse codes and created a 37-character-length string that * contained the morse code for every required character (except for * space). You just have to know the start index and length of each * one. With the same idea, I came up with this 32-character-length * string. This not only saves 5 characters here, but means that I * can encode the start indexes with only 5 bits below. * * The start and length of each character are as follows: * * A: 0,2 K: 1,3 U: 10,3 4: 18,5 * B: 16,4 L: 15,4 V: 19,4 5: 17,5 * C: 1,4 M: 5,2 W: 4,3 6: 16,5 * D: 9,3 N: 1,2 X: 9,4 7: 25,5 * E: 0,1 O: 22,3 Y: 3,4 8: 24,5 * F: 14,4 P: 4,4 Z: 8,4 9: 23,5 * G: 5,3 Q: 5,4 0: 22,5 .: 0,6 * H: 17,4 R: 0,3 1: 21,5 ,: 8,6 * I: 20,2 S: 17,3 2: 20,5 ?: 10,6 * J: 21,4 T: 1,1 3: 19,5 */ } main(){ /* yuck, but it compiles and runs */ char *p, c, s[99]; /* p is a pointer within the input string */ /* c saves from having to do `*p` all the time */ /* s is the buffer for the input string */ gets(s); /* warning for use without declaring */ for(p=s; *p;){ /* begin with start of input, go till null character */ c = *p++; /* grab *p into c, increment p. * incrementing p here instead of in the for loop saves * one character */ c=toupper(c); /* warning for use without declaring */ c = c > 90 ? 35 : c - 32 ? "È#À#¶µ´³²±°¹¸·#####Ê#@i Že'J•aEAv„…`q!j"d‰ƒˆ"[c - 44] : 63; /**** OR, for the ASCII version ****/ c = c > 90 ? 99 : c - 32 ? "\x88#\x80#vutsrqpyxw#####\x8A#\0PA)\xE0N%Q\nU!O\5\1\66DE 1\xE1" "*S$ICH"[c - 44] + 64 : 63; /* Here where it gets hairy. * * What I've done is encode the (start,length) values listed in the * comment in the W function into one byte per character. The start * index is encoded in the low 5 bits, and the length is encoded in * the high 3 bits, so encoded_char = (char)(length << 5 | position). * For the longer, ASCII-only version, 64 is subtracted from the * encoded byte to reduce the necessity of costly \xXX representations. * * The character array includes encoded bytes covering the entire range * of characters covered by the challenge, except for the space * character, which is checked for separately. The covered range * starts with comma, and ends with capital Z (the call to `toupper` * above handles lowercase letters). Any characters not supported are * represented by the "#" character, which is otherwise unused and is * explicitly checked for later. Additionally, an explicit check is * done here for any character above 'Z', which is changed to the * equivalent of a "#" character. * * The encoded byte is retrieved from this array using the value of * the current character minus 44 (since the first supported character * is ASCII 44 and index 0 in the array). Finally, for the ASCII-only * version, the offset of 64 is added back in. */ c - 35 ? W(c >> 5, c & 31) : 0; /**** OR, for the ASCII version ****/ c - 99 ? W(c >> 5, c & 31) : 0; /* Here that explicit check for the "#" character, which, as * mentioned above, is for characters which will be ignored, because * they aren't supported. If c is 35 (or 99 for the ASCII version), * then the expression before the ? evaluates to 0, or false, so the * expression after the : is evaluated. Otherwise, the expression * before the ? is non-zero, thus true, so the expression before * the : is evaluated. * * This is equivalent to: * * if(c != 35) // or 99, for the ASCII version * W(c >> 5, c & 31); * * but is shorter by 2 characters. */ putch(0); /* This will output to the screen a blank space. Technically, it not * the same as a space character, but it looks like one, so I think I * can get away with it. If a real space character is desired, this * must be changed to `putch(32);`, which adds one character to the * overall length. } /* end for loop, continue with the rest of the input string */ } /* end main */ 

, Python. , , . - , .

EDIT:

, , ASCII 44 ( ), . , 5 , :

 ...c>90?35:c-32?"... 

:

 ...c-32?c>90|c<44?35:"... 
+3
30 . '09 21:42
source share

REBOL (118 )

10-

 foreach c ask""[l: index? find" etinamsdrgukwohblzfcpövxäqüyj"c while[l >= 2][prin pick"-."odd? ll: l / 2]prin" "] 

: http://www.rebol.com/oneliners.html

( :/...)

+3
02 . '10 1:04
source share

Python 2; 171

, Andrea , , .

 for c in raw_input().lower():print"".join(".-"[int(d)]for d in bin( (' etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,' %(('',)*5)).find(c))[3:])or'/', 

( )

, bin() 2.6, 176:

 for c in raw_input():C=lambda q:q>0and C(~-q/2)+'-.'[q%2]or'';print C( (' etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,'% (('',)*5)).find(c.lower()))or'/', 

( , )

+2
30 . '09 3:02
source share

Python (210 )

, Alec one

 def e(l): i=(' etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,'%tuple('_'*5)).find(l.lower());v='' while i>0:v='-.'[i%2]+v;i=(i-1)/2 return v or '/' def enc(s):return ' '.join(map(e,s)) 
+2
30 . '09 13:43
source share

C, 338

338 :

 #define O putchar #define W while char*l="x@@@@@ppmmmmm@@FBdYcbcbSd[Kcd`\31(\b1g_<qCN:_'|\25D$W[QH0"; int c,b,o; main(){ W(1){ W(c<32) c=getchar()&127; W(c>96) c^=32; c-=32; o=l[c/2]-64; b=203+(c&1?o>>3:0); o=c&1?o&7:o>>3; W(o>6) O(47),o=0; c/=2; W(c--) b+=(l[c]-64&7)+(l[c]-64>>3); b=(((l[b/7]<<7)+l[b/7+1])<<(b%7))>>14-o; W(o--) O(b&(1<<o)?46:45); O(32); } } 

, . l 32 95 , . D - ... 3 E. 1. 011 001, 011001. , 64, 1011001 - 89, ASCII Y. 0. l ( \031 ) - , 1 0. ASCII, 7 /.

c , c ( o ), b , .

, , .

"7" a/ .

, , , , ...

+2
30 . '09 20:04
source share

# Linq (133 )

  static void Main() { Console.WriteLine(String.Join(" ", (from c in Console.ReadLine().ToUpper().ToCharArray() select m[c]).ToArray())); } 

, . ( , ):

  static Dictionary<char, string> m = new Dictionary<char, string>() { {'A', ".-"}, {'B', "-.."}, {'C', "-.-."}, {'D', "-.."}, {'E', "."}, {'F', "..-."}, {'G', "--."}, {'H', "...."}, {'I', ".."}, {'J', ".---"}, {'K', "-.-"}, {'L', ".-.."}, {'M', "--"}, {'N', "-."}, {'O', "---"}, {'P', ".--."}, {'Q', "--.-"}, {'R', ".-."}, {'S', "..."}, {'T', "-"}, {'U', "..-"}, {'V', "...-"}, {'W', ".--"}, {'X', "-..-"}, {'Y', "-.--"}, {'Z', "--.."}, {'0', "-----"}, {'1', ".----"}, {'2', "..---"}, {'3', "...--"}, {'4', "....-"}, {'5', "....."}, {'6', "-...."}, {'7', "--..."}, {'8', "---.."}, {'9', "----."}, {' ', "/"}, {'.', ".-.-.-"}, {',', "--..--"}, {'?', "..--.."}, }; 

, - #, ?

+2
31 . '09 4:37
source share

Perl, 206 , dmckee

, , , , . / . . dmckee, , . , "/ " , , char ( ), ( char 26- , ), , , , . ( , , ).

, 206 ; , .

 #!perl -lp ($a,@b)=unpack"b32C*", "\264\202\317\0\31SF1\2I.T\33N/G\27\308XE0=\x002V7HMRfermlkjihgx\207\205"; $a=~y/01/-./;@m{A..Z,0..9,qw(. , ?)}=map{substr$a,$_%23,1+$_/23}@b; $_=join' ',map$m{uc$_}||"/",/./g 

:

  • . ( "\264\202\317\0" ) 32 ( "--.-..-.-.-----.....--..--------" ), 26 . " ".
  • , - , (, ,... Z, 0, 1,... 9, ".", ",", "?" ). 23 * ( - 1) + pos, . - , , 22.
  • , , ( ) , $m{'a'} = '.-' et cetera, , , , ... shebang, perl , $_ , $_ .
+2
31 . '09 8:18
source share

C89 (293 )

.

EDIT: (yay).

 #define P putchar char t['~']="~ETIANMSURWDKGOHVF~L~PJBXCYZQ~~54~3",o,q[9],Q=10;main(c){for(;Q;)t[ "&./7;=>KTr"[--Q]]="2167890?.,"[Q];while((c=getchar())>=0){c-=c<'{'&c>96?32:0;c- 10?c-32?0:P(47):P(10);for(o=1;o<'~';++o)if(t[o]==c){for(;o;o/=2)q[Q++]=45+(o--&1 );for(;Q;P(q[--Q]));break;}P(32);}} 
+1
30 . '09 1:55
source share

, dmckee, , Python :

Python

244

 def h(l):p=2*ord(l.upper())-88;a,n=map(ord,"AF__GF__]E\\E[EZEYEXEWEVEUETE__________CF__IBPDJDPBGAHDPC[DNBSDJCKDOBJBTCND`DKCQCHAHCZDSCLD??OD"[p:p+2]);return "--..--..-.-.-..--...----.....-----.-"[a-64:a+n-128] def e(s):return ' '.join(map(h,s)) 

:

  • dmckee "Y", , . , "??" part "-"
  • '/' ; ,

, , , (), ASCII.

EDIT: Unicode, ASCII , , :

Python

240

 def h(l):a,n=divmod(ord(u'\x06_7_\xd0\xc9\xc2\xbb\xb4\xad\xa6\x9f\x98\x91_____\x14_AtJr2<s\xc1d\x89IQdH\x8ff\xe4Pz9;\xba\x88X_f'[ord(l.upper())-44]),7);return "--..--..-.-.-..--...----.....-----.-"[a:a+n] def e(s):return ' '.join(map(h,s)) 

, .

UTF-8, , 185 , Python Perl.: -)

+1
30 . '09 6:16
source share

, :

Python

232

 def d(c): o='';b=ord("Y_j_?><80 !#'/_____f_\x06\x11\x15\x05\x02\x15\t\x1c\x06\x1e\r\x12\x07\x05\x0f\x16\x1b\n\x08\x03\r\x18\x0e\x19\x01\x13"[ord(c.upper())-44]) while b!=1:o+='.-'[b&1];b/=2 return o e=lambda s:' '.join(map(d,s)) 

, . , , , , .

, .

+1
30 . '09 18:41
source share

Haskell

 type MorseCode = String program :: String program = "__5__4H___3VS__F___2 UI__L__+_ R__P___1JWAE" ++ "__6__=B__/_XD__C__YKN__7_Z__QG__8_ __9__0 OMT " decode :: MorseCode -> String decode = interpret program where interpret = head . foldl exec [] exec xs '_' = undefined : xs exec (x:y:xs) c = branch : xs where branch (' ':ds) = c : decode ds branch ('-':ds) = x ds branch ('.':ds) = y ds branch [] = [c] 

, decode "-- --- .-. ... . -.-. --- -.. ." "MORSE CODE" .

Fun .

+1
03 . '09 11:38
source share

Php

PHP , .:)

 $a=array(32=>"/",44=>"--..--",1,".-.-.-",48=>"-----",".----","..---","...--","....-",".....","-....","--...","---..","----.",63=>"..--..",1,".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."); foreach(str_split(strtoupper("hello world?"))as$k=>$v){echo $a[ord($v)]." ";} 

380 2 - .; D 1s - 2 , , .

. .:)

 array(20=>"data",22=>"more data"; array(20=>"data",1,"more data"; 

, , , , , .

: 578 , 380 (198 ~ 34,26% ).

+1
14 . '09 9:46
source share

Bash , a script, ( ), 1661 . :)

 #!/bin/sh txt='' res='' if [ "$1" == '' ]; then read -se txt else txt="$1" fi; len=$(echo "$txt" | wc -c) k=1 while [ "$k" -lt "$len" ]; do case "$(expr substr "$txt" $k 1 | tr '[:upper:]' '[:lower:]')" in 'e') res="$res"'.' ;; 't') res="$res"'-' ;; 'i') res="$res"'..' ;; 'a') res="$res"'.-' ;; 'n') res="$res"'-.' ;; 'm') res="$res"'--' ;; 's') res="$res"'...' ;; 'u') res="$res"'..-' ;; 'r') res="$res"'.-.' ;; 'w') res="$res"'.--' ;; 'd') res="$res"'-..' ;; 'k') res="$res"'-.-' ;; 'g') res="$res"'--.' ;; 'o') res="$res"'---' ;; 'h') res="$res"'....' ;; 'v') res="$res"'...-' ;; 'f') res="$res"'..-.' ;; 'l') res="$res"'.-..' ;; 'p') res="$res"'.--.' ;; 'j') res="$res"'.---' ;; 'b') res="$res"'-...' ;; 'x') res="$res"'-..-' ;; 'c') res="$res"'-.-.' ;; 'y') res="$res"'-.--' ;; 'z') res="$res"'--..' ;; 'q') res="$res"'--.-' ;; '5') res="$res"'.....' ;; '4') res="$res"'....-' ;; '3') res="$res"'...--' ;; '2') res="$res"'..---' ;; '1') res="$res"'.----' ;; '6') res="$res"'-....' ;; '7') res="$res"'--...' ;; '8') res="$res"'---..' ;; '9') res="$res"'----.' ;; '0') res="$res"'-----' ;; esac; [ ! "$(expr substr "$txt" $k 1)" == " " ] && [ ! "$(expr substr "$txt" $(($k+1)) 1)" == ' ' ] && res="$res"' ' k=$(($k+1)) done; echo "$res" 
+1
20 . '10 13:54
source share

C, 533

stdin. 70 .

 #include <stdio.h> #include <ctype.h> char *u[36] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."}; main(){ char*v;int x;char o; do{ o = toupper(getc(stdin));v=0;if(o>=65&&o<=90)v=u[o-'A'];if(o>=48&&o<=57)v=u[o-'0'+26];if(o==46)v=".-.-.-";if(o==44)v="--..--";if(o==63)v="..--..";if(o==32)v="/";if(v)printf("%s ", v);} while (o != EOF); } 
0
29 . '09 23:44
source share

C89 (388 )

, , .

 #define P putchar char q[10],Q,tree[]= "EISH54V 3UF 2ARL + WP J 1TNDB6=X/ KC Y MGZ7 QO 8 90";s2;e(x){q[Q++] =x;}p(){for(;Q--;putchar(q[Q]));Q=0;}T(int x,char*t,int s){s2=s/2;return s?*tx ?t[s2]-x?T(x,++t+s2,--s/2)?e(45):T(x,t,--s/2)?e(46):0:e(45):e(46):0;}main(c){ while((c=getchar())>=0){c-=c<123&&c>96?32:0;if(c==10)P(10);if(c==32)P(47);else T(c,tree,sizeof(tree)),p();P(' ');}} 

. ( #define, , ). , -7-.

0
30 . '09 0:16
source share

C (381 )

 char*p[36]={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."}; main(){int c;while((c=tolower(getchar()))!=10)printf("%s ",c==46?".-.-.-":c==44?"--..--":c==63?"..--..":c==32?"/":*(p+(c-97)));} 
0
30 . '09 1:10
source share

C , 448 cmdline:

 char*a[]={".-.-.-","--..--","..--..","/",".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."},*k=".,? ",*s,*p,x;main(int _,char**v){for(;s=*++v;putchar(10))for(;x=*s++;){p=strchr(k,x);printf("%s ",p?a[pk]:isdigit(x)?a[x-18]:isalpha(x=toupper(x))?a[x-61]:0);}} 

C , 416 stdin:

 char*a[]={".-.-.-","--..--","..--..","/",".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."},*k=".,? ",*p,x;main(){while((x=toupper(getchar()))-10){p=strchr(k,x);printf("%s ",p?a[pk]:isdigit(x)?a[x-18]:isalpha(x)?a[x-61]:0);}} 
0
30 . '09 1:13
source share
  • one
  • 2



All Articles