The portland erlang group is considering some of the ruby quizzes to dive into erlang. If you're not used to programming recursively, you'll probably want to start with simpler problems like implementing the
Here's a sequential, recursive solution in erlang to ruby quiz #121: morse code. It's not *tail* recursive so it could maybe blow out some stack given a really long morse code word. (I assume morse code is translated one word at a time, with spaces between words.)
A tail recursive implementation... hmm... would be a bit more complicated. The two "stacks" are the dots and dashes yet to be decoded and the codes to be considered with each undecoded substring. So one way would be to manage the stacks explicitly in one recursive "loop". Another way would be to use continuation passing style.
Here's (I think) a fairly straight-forward recursive style, morse.erl...
member
function, factorial
, or
-module(morse).
-export([codes/0, decode/1]).
-import(lists, [prefix/2, reverse/1]).
-import(string, [len/1, substr/2]).
%% http://www.rubyquiz.com/quiz121.html
%%
%% decode/1 when given a string of dots and dashes returns a list of
%% all possible decodings using morse code.
%%
%% Examples:
%%
%% morse:decode(".-").
%% ["ET","A"]
%%
%% lists:member("SOFIA", morse:decode("...---..-....-")).
%% true
%%
%% lists:member("SOPHIA", morse:decode("...---..-....-")).
%% false
%%
%% lists:member("EUGENIA", morse:decode("...---..-....-")).
%% true
%%
%% length(morse:decode("...---..-....-")).
%% 5104
codes() ->
[{$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, "--.."}].
decode("") ->
[];
decode(String) when is_list(String) ->
decode(String, "", [], codes()).
decode("", "", Results, _Codes) ->
Results;
decode("", PartialDecoding, Results, _Codes) ->
[reverse(PartialDecoding) | Results];
decode(_String, _PartialDecoding, Results, []) ->
Results;
decode(String, PartialDecoding, Results, [{Char, Code} | Rest]) ->
MoreResults =
case prefix(Code, String) of
true ->
decode(substr(String, 1 + len(Code)), [Char | PartialDecoding], Results, codes());
false ->
Results
end,
decode(String, PartialDecoding, MoreResults, Rest).
"I have a mind like a steel... uh... thingy." Patrick Logan's weblog.
Search This Blog
Saturday, September 08, 2007
Morse Codes in Erlang
Subscribe to:
Post Comments (Atom)
Blog Archive
-
►
2011
(19)
- ► 12/04 - 12/11 (2)
- ► 08/21 - 08/28 (5)
- ► 07/17 - 07/24 (1)
- ► 04/03 - 04/10 (3)
- ► 03/27 - 04/03 (5)
- ► 03/20 - 03/27 (1)
- ► 03/13 - 03/20 (1)
- ► 03/06 - 03/13 (1)
-
►
2010
(2)
- ► 11/07 - 11/14 (2)
-
►
2009
(40)
- ► 06/07 - 06/14 (2)
- ► 05/31 - 06/07 (1)
- ► 05/17 - 05/24 (1)
- ► 04/05 - 04/12 (2)
- ► 03/22 - 03/29 (7)
- ► 03/15 - 03/22 (1)
- ► 03/08 - 03/15 (4)
- ► 03/01 - 03/08 (2)
- ► 02/22 - 03/01 (1)
- ► 02/15 - 02/22 (5)
- ► 02/08 - 02/15 (1)
- ► 02/01 - 02/08 (7)
- ► 01/25 - 02/01 (2)
- ► 01/04 - 01/11 (4)
-
►
2008
(402)
- ► 12/28 - 01/04 (12)
- ► 12/14 - 12/21 (3)
- ► 12/07 - 12/14 (10)
- ► 11/30 - 12/07 (14)
- ► 11/23 - 11/30 (7)
- ► 11/16 - 11/23 (14)
- ► 11/09 - 11/16 (7)
- ► 11/02 - 11/09 (11)
- ► 10/26 - 11/02 (14)
- ► 10/19 - 10/26 (10)
- ► 10/12 - 10/19 (11)
- ► 10/05 - 10/12 (16)
- ► 09/28 - 10/05 (26)
- ► 09/21 - 09/28 (16)
- ► 09/14 - 09/21 (3)
- ► 09/07 - 09/14 (9)
- ► 08/31 - 09/07 (8)
- ► 08/24 - 08/31 (10)
- ► 08/17 - 08/24 (12)
- ► 08/10 - 08/17 (4)
- ► 08/03 - 08/10 (5)
- ► 07/27 - 08/03 (10)
- ► 07/20 - 07/27 (6)
- ► 07/13 - 07/20 (7)
- ► 07/06 - 07/13 (3)
- ► 06/29 - 07/06 (8)
- ► 06/22 - 06/29 (6)
- ► 06/15 - 06/22 (5)
- ► 06/08 - 06/15 (10)
- ► 06/01 - 06/08 (4)
- ► 05/25 - 06/01 (5)
- ► 05/18 - 05/25 (6)
- ► 05/11 - 05/18 (3)
- ► 05/04 - 05/11 (7)
- ► 04/27 - 05/04 (7)
- ► 04/20 - 04/27 (7)
- ► 04/13 - 04/20 (6)
- ► 04/06 - 04/13 (9)
- ► 03/30 - 04/06 (7)
- ► 03/23 - 03/30 (5)
- ► 03/16 - 03/23 (15)
- ► 03/09 - 03/16 (7)
- ► 03/02 - 03/09 (5)
- ► 02/24 - 03/02 (4)
- ► 02/17 - 02/24 (2)
- ► 02/10 - 02/17 (3)
- ► 02/03 - 02/10 (1)
- ► 01/27 - 02/03 (8)
- ► 01/20 - 01/27 (4)
- ► 01/13 - 01/20 (3)
- ► 01/06 - 01/13 (7)
-
▼
2007
(388)
- ► 12/30 - 01/06 (11)
- ► 12/16 - 12/23 (5)
- ► 12/09 - 12/16 (3)
- ► 12/02 - 12/09 (5)
- ► 11/25 - 12/02 (5)
- ► 11/18 - 11/25 (4)
- ► 11/11 - 11/18 (4)
- ► 11/04 - 11/11 (11)
- ► 10/28 - 11/04 (11)
- ► 10/21 - 10/28 (3)
- ► 10/14 - 10/21 (6)
- ► 10/07 - 10/14 (5)
- ► 09/30 - 10/07 (18)
- ► 09/23 - 09/30 (13)
- ► 09/16 - 09/23 (9)
- ► 09/09 - 09/16 (12)
-
▼
09/02 - 09/09
(15)
- Things from Phil Windley
- Morse Codes in Erlang
- Secure Enterprise-grade Persistent Group Chat
- Just a Router
- Parallel Jars of Formaldehyde
- (Re)New Web
- Naming and Synchronization in a Decentralized Comp...
- It's Simply Different
- It's Already On
- My Agile Failed - pause - NOT
- Delaying The Inevitable
- PDX.erl
- The Race Is On, Or Is That Off?
- Phil Windley on the Microwulf
- Rob Pike on Concurrency and Message passing in New...
- ► 08/26 - 09/02 (2)
- ► 08/19 - 08/26 (8)
- ► 08/12 - 08/19 (25)
- ► 08/05 - 08/12 (7)
- ► 07/29 - 08/05 (8)
- ► 07/22 - 07/29 (2)
- ► 07/15 - 07/22 (4)
- ► 07/08 - 07/15 (11)
- ► 07/01 - 07/08 (3)
- ► 06/24 - 07/01 (8)
- ► 06/17 - 06/24 (4)
- ► 06/10 - 06/17 (17)
- ► 06/03 - 06/10 (6)
- ► 05/27 - 06/03 (12)
- ► 05/20 - 05/27 (5)
- ► 05/13 - 05/20 (15)
- ► 05/06 - 05/13 (10)
- ► 04/29 - 05/06 (14)
- ► 04/22 - 04/29 (5)
- ► 04/15 - 04/22 (6)
- ► 04/08 - 04/15 (16)
- ► 04/01 - 04/08 (8)
- ► 03/25 - 04/01 (5)
- ► 03/18 - 03/25 (3)
- ► 03/11 - 03/18 (3)
- ► 03/04 - 03/11 (5)
- ► 02/25 - 03/04 (1)
- ► 02/18 - 02/25 (4)
- ► 02/04 - 02/11 (10)
- ► 01/28 - 02/04 (11)
- ► 01/21 - 01/28 (2)
- ► 01/14 - 01/21 (1)
- ► 01/07 - 01/14 (7)
-
►
2006
(261)
- ► 12/31 - 01/07 (7)
- ► 12/24 - 12/31 (13)
- ► 12/17 - 12/24 (6)
- ► 12/10 - 12/17 (7)
- ► 12/03 - 12/10 (6)
- ► 11/26 - 12/03 (1)
- ► 11/19 - 11/26 (5)
- ► 11/05 - 11/12 (2)
- ► 10/29 - 11/05 (4)
- ► 10/22 - 10/29 (5)
- ► 10/15 - 10/22 (2)
- ► 10/08 - 10/15 (3)
- ► 10/01 - 10/08 (9)
- ► 09/24 - 10/01 (8)
- ► 09/17 - 09/24 (1)
- ► 09/10 - 09/17 (5)
- ► 09/03 - 09/10 (6)
- ► 08/27 - 09/03 (2)
- ► 08/13 - 08/20 (9)
- ► 08/06 - 08/13 (6)
- ► 07/30 - 08/06 (6)
- ► 07/23 - 07/30 (6)
- ► 07/16 - 07/23 (3)
- ► 07/09 - 07/16 (2)
- ► 07/02 - 07/09 (2)
- ► 06/25 - 07/02 (10)
- ► 06/18 - 06/25 (9)
- ► 06/11 - 06/18 (10)
- ► 06/04 - 06/11 (6)
- ► 05/28 - 06/04 (9)
- ► 05/21 - 05/28 (9)
- ► 05/14 - 05/21 (3)
- ► 05/07 - 05/14 (4)
- ► 04/30 - 05/07 (10)
- ► 04/23 - 04/30 (1)
- ► 04/16 - 04/23 (2)
- ► 04/09 - 04/16 (4)
- ► 04/02 - 04/09 (4)
- ► 03/19 - 03/26 (9)
- ► 03/12 - 03/19 (11)
- ► 03/05 - 03/12 (1)
- ► 02/26 - 03/05 (5)
- ► 02/19 - 02/26 (14)
- ► 02/12 - 02/19 (2)
- ► 02/05 - 02/12 (1)
- ► 01/29 - 02/05 (1)
- ► 01/22 - 01/29 (2)
- ► 01/01 - 01/08 (8)
-
►
2005
(335)
- ► 12/25 - 01/01 (9)
- ► 12/18 - 12/25 (4)
- ► 11/27 - 12/04 (1)
- ► 11/20 - 11/27 (1)
- ► 11/13 - 11/20 (1)
- ► 10/23 - 10/30 (1)
- ► 10/16 - 10/23 (2)
- ► 10/09 - 10/16 (3)
- ► 10/02 - 10/09 (11)
- ► 09/18 - 09/25 (4)
- ► 09/11 - 09/18 (4)
- ► 09/04 - 09/11 (1)
- ► 08/28 - 09/04 (7)
- ► 08/21 - 08/28 (10)
- ► 08/14 - 08/21 (6)
- ► 08/07 - 08/14 (2)
- ► 07/31 - 08/07 (16)
- ► 07/24 - 07/31 (5)
- ► 07/17 - 07/24 (6)
- ► 07/10 - 07/17 (5)
- ► 06/19 - 06/26 (1)
- ► 05/29 - 06/05 (7)
- ► 05/22 - 05/29 (7)
- ► 05/15 - 05/22 (16)
- ► 05/08 - 05/15 (10)
- ► 05/01 - 05/08 (8)
- ► 04/24 - 05/01 (6)
- ► 04/03 - 04/10 (7)
- ► 03/27 - 04/03 (19)
- ► 03/20 - 03/27 (15)
- ► 03/13 - 03/20 (27)
- ► 03/06 - 03/13 (7)
- ► 02/27 - 03/06 (16)
- ► 02/20 - 02/27 (7)
- ► 02/13 - 02/20 (10)
- ► 02/06 - 02/13 (23)
- ► 01/30 - 02/06 (4)
- ► 01/23 - 01/30 (12)
- ► 01/16 - 01/23 (15)
- ► 01/09 - 01/16 (2)
- ► 01/02 - 01/09 (17)
-
►
2004
(534)
- ► 12/26 - 01/02 (18)
- ► 12/19 - 12/26 (5)
- ► 12/12 - 12/19 (5)
- ► 12/05 - 12/12 (25)
- ► 11/28 - 12/05 (8)
- ► 11/21 - 11/28 (3)
- ► 11/14 - 11/21 (4)
- ► 11/07 - 11/14 (7)
- ► 10/31 - 11/07 (13)
- ► 10/24 - 10/31 (7)
- ► 10/17 - 10/24 (10)
- ► 10/10 - 10/17 (15)
- ► 10/03 - 10/10 (1)
- ► 09/19 - 09/26 (9)
- ► 09/12 - 09/19 (4)
- ► 09/05 - 09/12 (4)
- ► 08/29 - 09/05 (9)
- ► 08/08 - 08/15 (11)
- ► 08/01 - 08/08 (4)
- ► 07/11 - 07/18 (12)
- ► 07/04 - 07/11 (19)
- ► 06/27 - 07/04 (12)
- ► 06/20 - 06/27 (7)
- ► 06/13 - 06/20 (5)
- ► 06/06 - 06/13 (1)
- ► 05/30 - 06/06 (8)
- ► 05/23 - 05/30 (27)
- ► 05/16 - 05/23 (16)
- ► 05/09 - 05/16 (36)
- ► 05/02 - 05/09 (31)
- ► 04/25 - 05/02 (13)
- ► 04/18 - 04/25 (25)
- ► 04/11 - 04/18 (15)
- ► 03/28 - 04/04 (9)
- ► 03/21 - 03/28 (12)
- ► 03/14 - 03/21 (9)
- ► 03/07 - 03/14 (7)
- ► 02/29 - 03/07 (16)
- ► 02/22 - 02/29 (11)
- ► 02/15 - 02/22 (6)
- ► 02/08 - 02/15 (8)
- ► 02/01 - 02/08 (9)
- ► 01/25 - 02/01 (18)
- ► 01/18 - 01/25 (12)
- ► 01/11 - 01/18 (14)
- ► 01/04 - 01/11 (14)
-
►
2003
(286)
- ► 12/28 - 01/04 (7)
- ► 12/21 - 12/28 (10)
- ► 12/14 - 12/21 (5)
- ► 11/30 - 12/07 (5)
- ► 11/23 - 11/30 (5)
- ► 11/16 - 11/23 (2)
- ► 11/09 - 11/16 (3)
- ► 10/26 - 11/02 (6)
- ► 10/19 - 10/26 (9)
- ► 10/12 - 10/19 (8)
- ► 10/05 - 10/12 (5)
- ► 09/28 - 10/05 (3)
- ► 09/21 - 09/28 (3)
- ► 09/14 - 09/21 (4)
- ► 09/07 - 09/14 (3)
- ► 08/31 - 09/07 (6)
- ► 08/24 - 08/31 (12)
- ► 08/17 - 08/24 (3)
- ► 08/10 - 08/17 (6)
- ► 08/03 - 08/10 (8)
- ► 07/27 - 08/03 (9)
- ► 07/20 - 07/27 (5)
- ► 07/13 - 07/20 (8)
- ► 07/06 - 07/13 (15)
- ► 06/29 - 07/06 (12)
- ► 06/22 - 06/29 (5)
- ► 06/15 - 06/22 (6)
- ► 06/08 - 06/15 (1)
- ► 06/01 - 06/08 (5)
- ► 05/18 - 05/25 (7)
- ► 05/11 - 05/18 (9)
- ► 05/04 - 05/11 (13)
- ► 04/27 - 05/04 (9)
- ► 04/20 - 04/27 (4)
- ► 04/13 - 04/20 (10)
- ► 04/06 - 04/13 (15)
- ► 03/30 - 04/06 (7)
- ► 03/23 - 03/30 (13)
- ► 03/16 - 03/23 (9)
- ► 03/09 - 03/16 (3)
- ► 03/02 - 03/09 (8)
About Me
- Patrick Logan
- Portland, Oregon, United States
- I'm usually writing from my favorite location on the planet, the pacific northwest of the u.s. I write for myself only and unless otherwise specified my posts here should not be taken as representing an official position of my employer. Contact me at my gee mail account, username patrickdlogan.
4 comments:
Interesting! I wish I'd known of the lists:prefix method - that would have made life easier for me. For some reason I didn't think you could do f(g()) in Erlang. I've been writing X = g(), f(X). The -import syntax is handy too.
"All possible decodings"
That's the assumption which is incorrect. Properly transmitted morse code has an inter-character "space" which prevents, operator (or computerized sender) willing, two characters from being interpreted as a third, i.e.
. + .. != ...
de VE7WV
"For some reason I didn't think you could do f(g()) in Erlang."
The one place, oddly, that function calls do not work at all is the "if" expression. That uses "guards" which cannot be function calls. So...
B = function_returning_boolean(Foo),
if
B ->
do_something_true();
true ->
do_something_false()
end.
I don't like that so much, which is why I used the "case" expression in the morse code example.
'Properly transmitted morse code has an inter-character "space"'
Yeah, but that's no fun. :-)
Post a Comment