1. Morse

Anyone want to post a smaller, more efficient and/or more 'Euphoric' way to do this?

 
constant morse =  
{"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--..", 
 "1.----","2..---","3...--","4....-","5.....", 
 "6-....","7--...","8---..","9----.","0-----", 
 "..-.-.-","\\--..--","  "} 
 
constant EOM = ".-.-." 
 
include std/console.e   -- for display  
include std/text.e      -- for lower  
include std/sequence.e  -- for vslice 
include std/search.e    -- for lookup  
 
integer key = 0 
object index = vslice(morse,1) 
object code 
 
while key != 27 do 
    key = lower(wait_key()) 
    if key = 27 then exit 
    else 
        code = lookup(key,index,morse,"?") 
        display(code[2..$]&' ',,0) 
    end if 
end while 
 
display(EOM) 
new topic     » topic index » view message » categorize

2. Re: Morse

Well, it's not smaller, but it is probably more efficient and more Euphoria-like. Storing the codes in a table indexed by ASCII character should be more efficient than using vslice() and lookup(). I'm a bit rusty on my time complexity theory, but I believe it's the difference of O(1) vs O(n) or O(log n). I haven't examined the underlying code, so I don't know if lookup() uses a binary search or linear search. I would imagine it's binary, which is O(log n) complex.

-- morse.e 
 
public constant 
    STARTING_SIGNAL         =  1, 
    END_OF_MESSAGE          =  4, 
    INVITATION_TO_TRANSMIT  =  5, 
    UNDERSTOOD              =  6, 
    ERROR                   = 21, 
    WAIT                    = 22, 
    END_OF_WORK             = 23, 
$ 
 
public sequence MORSE = repeat( "", 127 ) 
 
MORSE[ERROR]                    = "........" 
MORSE[END_OF_MESSAGE]           = ".-.-." 
MORSE[END_OF_WORK]              = "...-.-" 
MORSE[INVITATION_TO_TRANSMIT]   = "-.-" 
MORSE[STARTING_SIGNAL]          = "-.-.-" 
MORSE[UNDERSTOOD]               = "...-." 
MORSE[WAIT]                     = ".-..." 
MORSE['!']  = "-.-.--" 
MORSE['\"'] = ".-..-." 
MORSE['$']  = "...-..-" 
MORSE['&']  = ".-..." 
MORSE['\''] = ".----." 
MORSE['(']  = "-.--." 
MORSE[')']  = "-.--.-" 
MORSE['+']  = ".-.-." 
MORSE[',']  = "--..--" 
MORSE['-']  = "-....-" 
MORSE['.']  = ".-.-.-" 
MORSE['/']  = "-..-." 
MORSE['0']  = "-----" 
MORSE['1']  = ".----" 
MORSE['2']  = "..---" 
MORSE['3']  = "...--" 
MORSE['4']  = "....-" 
MORSE['5']  = "....." 
MORSE['6']  = "-...." 
MORSE['7']  = "--..." 
MORSE['8']  = "---.." 
MORSE['9']  = "----." 
MORSE[':']  = "---..." 
MORSE[';']  = "-.-.-." 
MORSE['=']  = "-...-" 
MORSE['?']  = "..--.." 
MORSE['@']  = ".--.-." 
MORSE['A']  = ".-" 
MORSE['B']  = "-..." 
MORSE['C']  = "-.-." 
MORSE['D']  = "-.." 
MORSE['E']  = "." 
MORSE['F']  = "..-." 
MORSE['G']  = "--." 
MORSE['H']  = "...." 
MORSE['I']  = ".." 
MORSE['J']  = ".---" 
MORSE['K']  = "-.-" 
MORSE['L']  = ".-.." 
MORSE['M']  = "--" 
MORSE['N']  = "-." 
MORSE['O']  = "---" 
MORSE['P']  = ".--." 
MORSE['Q']  = "--.-" 
MORSE['R']  = ".-." 
MORSE['S']  = "..." 
MORSE['T']  = "-" 
MORSE['U']  = "..-" 
MORSE['V']  = "...-" 
MORSE['W']  = ".--" 
MORSE['X']  = "-..-" 
MORSE['Y']  = "-.--" 
MORSE['Z']  = "--.." 
MORSE['_']  = "..--.-" 
MORSE['a']  = ".-" 
MORSE['b']  = "-..." 
MORSE['c']  = "-.-." 
MORSE['d']  = "-.." 
MORSE['e']  = "." 
MORSE['f']  = "..-." 
MORSE['g']  = "--." 
MORSE['h']  = "...." 
MORSE['i']  = ".." 
MORSE['j']  = ".---" 
MORSE['k']  = "-.-" 
MORSE['l']  = ".-.." 
MORSE['m']  = "--" 
MORSE['n']  = "-." 
MORSE['o']  = "---" 
MORSE['p']  = ".--." 
MORSE['q']  = "--.-" 
MORSE['r']  = ".-." 
MORSE['s']  = "..." 
MORSE['t']  = "-" 
MORSE['u']  = "..-" 
MORSE['v']  = "...-" 
MORSE['w']  = ".--" 
MORSE['x']  = "-..-" 
MORSE['y']  = "-.--" 
MORSE['z']  = "--.." 
 
public function morse( object s ) -- s = string 
     
    if atom( s ) then 
         
        s = and_bits( s, #FF ) 
        return MORSE[s] 
         
    end if 
     
    sequence m = "" -- m = message 
     
    for i = 1 to length( s ) do 
         
        sequence c = morse( s[i] ) -- c = code 
         
        if length( c ) > 0 and length( m ) > 0 then 
            m &= " " 
        end if 
         
        m &= c 
         
    end for 
     
    return m 
end function 
-- morse.ex 
 
include std/console.e 
include morse.e 
 
sequence cmd = command_line() 
 
for i = 3 to length( cmd ) do 
    sequence code = morse( cmd[i] & END_OF_MESSAGE ) 
    printf( 1, "%s\n", {code} ) 
end for 

> eui morse.ex "Hello, world!" 
.... . .-.. .-.. --- --..-- .-- --- .-. .-.. -.. -.-.-- .-.-. 
 
> eui morse.ex "The quick brown fox jumps over the lazy dog." 
- .... . --.- ..- .. -.-. -.- -... .-. --- .-- -. ..-. --- -..- .--- ..- -- .--. ... --- ...- . .-. - .... . .-.. .- --.. -.-- -.. --- --. .-.-.- .-.-. 

-Greg

new topic     » goto parent     » topic index » view message » categorize

3. Re: Morse

Hi,
AFAIK (I learnt Morse in the military) Its not case sensitive, so why not use lower() and shorten the lookup table?
BTW, we never used @ and a few others you have, but its nice to know that they are there.
Brings back 35 year old memories :)
Cheers, Alan

new topic     » goto parent     » topic index » view message » categorize

4. Re: Morse

fizzpopsoft said...

AFAIK (I learnt Morse in the military) Its not case sensitive, so why not use lower() and shorten the lookup table?

You're right, it's not case-sensitive. I am sacrificing the extra few bytes of memory for the sake of speed. Passing everything through lower() takes time. Indexing everything directly is faster. If we simply "copy" the values from A-Z to a-z, it should use less memory (due to Euphoria's copy-on-write sequence management). Although if we add it all up, we're probably only saving about 400 bytes of memory.

MORSE['a']  = MORSE['A'] 
MORSE['b']  = MORSE['B'] 
MORSE['c']  = MORSE['C'] 
MORSE['d']  = MORSE['D'] 
MORSE['e']  = MORSE['E'] 
MORSE['f']  = MORSE['F'] 
MORSE['g']  = MORSE['G'] 
MORSE['h']  = MORSE['H'] 
MORSE['i']  = MORSE['I'] 
MORSE['j']  = MORSE['J'] 
MORSE['k']  = MORSE['K'] 
MORSE['l']  = MORSE['L'] 
MORSE['m']  = MORSE['M'] 
MORSE['n']  = MORSE['N'] 
MORSE['o']  = MORSE['O'] 
MORSE['p']  = MORSE['P'] 
MORSE['q']  = MORSE['Q'] 
MORSE['r']  = MORSE['R'] 
MORSE['s']  = MORSE['S'] 
MORSE['t']  = MORSE['T'] 
MORSE['u']  = MORSE['U'] 
MORSE['v']  = MORSE['V'] 
MORSE['w']  = MORSE['W'] 
MORSE['x']  = MORSE['X'] 
MORSE['y']  = MORSE['Y'] 
MORSE['z']  = MORSE['Z'] 
fizzpopsoft said...

BTW, we never used @ and a few others you have, but its nice to know that they are there.
Brings back 35 year old memories :)

Wikipedia has a pretty comprehensive list of Letters, numbers, punctuation, prosigns and non-English variants for Morse code, which is what I used as a reference.

-Greg

new topic     » goto parent     » topic index » view message » categorize

5. Re: Morse

Morse Code Conversion Utility

 
/* Wikipedia: "Letter frequency" 

 
"No exact letter frequency distribution underlies a given language, since all writers write slightly differently.  
Linotype machines assumed the letter order, from most to least common, to be etaoin shrdlu cmfwyp vbgkjq xz  
based on the experience and custom of manual compositors. 
 
Likewise, Modern International Morse code encodes the most frequent letters with the shortest symbols;  
arranging the Morse alphabet into groups of letters that require equal amounts of time to transmit, and  
then sorting these groups in increasing order, yields e it san hurdm wgvlfbk opjxcz yq." 
*/  
 
constant alpha = { 'e', 'i', 't', 's', 'a', 'n', 'h', 'u', 'r', 'd', 'm', 'w', 'g', 'v', 'l', 'f', 'b',  
'k', 'o', 'p', 'j', 'x', 'c', 'z',  'y', 'q', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.', ' '  }  
 
constant morse = { ".", "..", "-", "...", ".-", "-.", "....", "..-", ".-.", "-..", "--", ".--", "--.", "...-",  
".-..",  "..-.",  "-...", ".-.", "---", ".--.", ".---", "-..-", "-.-.", "--..", "-.--", "--.-",  ".----", 
"..---","...--","....-",".....",  "-....","--...","---..","----.","-----",  ".-.-.-", "       " }  
 
/* Space between words is taken as 'seven time moments'.  

Not all characters have been encoded yet. */ 
 
 
include std/text.e 
  
procedure signal( sequence msg ) 
   for i=1 to length(msg) do 
		object char = msg[i] 
		if atom(char) then 
    		char = { lower(char) } 
   			puts(1, morse[ match(char, alpha) ] & " | " ) 
		else 
			puts(1, alpha[ find(char, morse) ]  ) 
	    end if	 
	end for   
    puts(1, "\n\n" )   
end procedure 
 
 
/* Assumes the argument has no typing errors. */ 
 
signal( "Hello world" ) 
signal( "The quick brown fox jumps over the lazy dog." ) 
signal( { "--", "---", ".-.", "...", ".", "       ", "-.-.", "---", "-..", "." } ) 
 
 
/* 

.... | . | .-.. | .-.. | --- |         | .-- | --- | .-. | .-.. | -.. |  
 
- | .... | . |         | --.- | ..- | .. | -.-. | .-. |         | -... | .-. | --- | .-- | -. |         | ..-. | --- | -..- |         | .--- | ..- | -- | .--. | ... |         | --- | ...- | . | .-. |         | - | .... | . |         | .-.. | .- | --.. | -.-- |         | -.. | --- | --. | .-.-.- |  
 
morse code 
*/ 
 
 

_tom

new topic     » goto parent     » topic index » view message » categorize

6. Re: Morse

ghaberek said...

Wikipedia has a pretty comprehensive list of Letters, numbers, punctuation, prosigns and non-English variants for Morse code, which is what I used as a reference.

I thought it might be "fun" to encode that tree picture thing, see what it turned out like.

sequence morse = repeat(0,255) 
 
    morse[' '] = "    " 
 
procedure ext(string root, object data) 
object dot, dash 
    if sequence(data) then 
        {data,dot,dash} = data 
        ext(root,data) 
        ext(root&'.',dot) 
        ext(root&'-',dash) 
    elsif data!=0 then 
        morse[data] = root 
--      printf(1,"morse['%c']:=%s\n",{data,root}) 
    end if 
end procedure 
 
      ext("",{0,{'E',{'I',{'S',{'H','5','4'}, 
                               {'V',{0,{0,0,'$'},0},'3'}}, 
                          {'U','F',{0,{0,'?','_'},'2'}}}, 
                     {'A',{'R',{'L','&',{0,'"',0}}, 
                               {0,{'+',0,'.'},0}}, 
                          {'W',{'P',0,{0,'@',0}}, 
                               {'J',0,{'1','\'',0}}}}}, 
                {'T',{'N',{'D',{'B',{'6',0,'-'},'='}, 
                               {'X','/',0}}, 
                          {'K',{'C',0,{0,';','!'}}, 
                               {'Y',{'(',0,')'},0}}}, 
                     {'M',{'G',{'Z','7',{0,0,','}}, 
                               'Q'}, 
                          {'O',{0,{'8',':',0},0}, 
                               {0,'9','0'}}}}}) 

Amazingly it works. (Obviously I use Phix so you might need to change that {data,dot,dash} = data to dash = data[3] dot = data[2] data = data[1], not tested on OpenEu.)

I think the word you're looking for is "ugly".

Pete

new topic     » goto parent     » topic index » view message » categorize

7. Re: Morse

petelomax said...

(Obviously I use Phix so you might need to change that {data,dot,dash} = data to dash = data[3] dot = data[2] data = data[1], not tested on OpenEu.)

Tested and works. Although your multiple assignment statement may not even be necessary. I just passed the values directly to ext().

if sequence( data ) then  
     
--  {data,dot,dash} = data  
--  ext( root, data )  
--  ext( root & '.', dot )  
--  ext( root & '-', dash )  
     
    ext( root, data[1] )  
    ext( root & '.', data[2] )  
    ext( root & '-', data[3] )  
     
elsif data != 0 then  
     
    morse[data] = root  
    printf(1,"morse['%s']:=%s\n",{data,root})  
     
end if  
petelomax said...

I think the word you're looking for is "ugly".

Indeed. Efficiency isn't always pretty. smile

-Greg

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu