6ae6663a1fc5b44960f27be9d4a6f19c

I'm trying to improve my Ruby skills. I wrote this as an exercise. I would like some suggestions on making this cleaner.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
$LETTER = Hash[*%w/
A .- N -.
B -... O ---
C -.-. P .--.
D -.. Q --.-
E . R .-.
F ..-. S ...
G --. T -
H .... U ..-
I .. V ...-
J .--- W .--
K -.- X -..-
L .-.. Y -.--
M -- Z --..
/]

$CODE = $LETTER.invert

def encode(message)
  encoded_message = []
  words = message.split(" ")
  words.each do |word|
    encoded_word = ""
    word.split(//).each do |letter|
      if $LETTER.has_key?(letter.upcase)
        encoded_word << $LETTER[letter.upcase]
        encoded_word << " "
      end
    end
    encoded_message << encoded_word 
  end
  puts encoded_message.join("| ")
end

def decode(message)
  decoded_message = ""
  words = message.split("|")
  words.each do |word|
    word.split(/\s/).each do |letter|
      if $CODE.has_key?(letter)
        decoded_message << $CODE[letter]
      end
    end
    decoded_message << " "
  end
  puts decoded_message
end

def encode_file(f)
  File.open(f).each do |line|
    encode(line)
  end
end

def decode_file(f)
  File.open(f).each do |line|
    decode(line)
  end
end

Refactorings

No refactoring yet !

A8d3f35baafdaea851914b17dae9e1fc

Adam

September 29, 2008, September 29, 2008 18:51, permalink

3 ratings. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
module Morse
  CODES = Hash[*%w/
    A .-    N -.
    B -...  O ---
    C -.-.  P .--.
    D -..   Q --.-
    E .     R .-.
    F ..-.  S ...
    G --.   T -
    H ....  U ..-
    I ..    V ...-
    J .---  W .--
    K -.-   X -..-
    L .-..  Y -.--
    M --    Z --..
    \  |
  /]
  
  def self.file_helper(method)
    module_eval %{
      def self.#{method}_file(filename)
        File.readlines(filename).map { |line| #{method}(line) }.join("\n")
      end
    }
  end
  
  def self.encode(message)
    message.upcase.split(//).map { |char| CODES[char] }.join(' ')
  end
  file_helper :encode

  def self.decode(message)
    message.split(' ').map { |code| CODES.invert[code] }.join
  end
  file_helper :decode
end
6ae6663a1fc5b44960f27be9d4a6f19c

Druwerd

September 30, 2008, September 30, 2008 00:36, permalink

No rating. Login to rate!

Thanks Adam.
This is very helpful. Looks concise and elegant.

B397b498cc02503a2d86c86176f7fd3e

Magnus Holm

October 1, 2008, October 01, 2008 12:49, permalink

4 ratings. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module Morse;A=[19,189,192,63,6,165,66,162,18,175,64,171,22,21,67,174,199,57,
54,7,55,163,58,190,193,198];B=proc{|c|A[c-65].to_s(3)[1..-1].tr('10','-.')}
C=proc{|m|(A.index(("2"+m.tr('-.','10')).to_i(3))||return)+65}

def self.encode(str);str.upcase.split(//).map{|c|(65..
  90)===(c=c[0])?B[c]:c==32?'|':nil}.compact.join(' ')
end

def self.decode(str);str.split(' ').map{|m|m[0]==?|?' ':(m=C[m])&&m.chr}.join
end

self.methods(false).map{|m|class<<self;self;end.send(:define_method,m+"_file"
){|f|File.readlines(f).map{|l|send(m,l)}.join $/}}

end

# >> Morse.encode("Concise and elegant")
# => "-.-. --- -. -.-. .. ... . | .- -. -.. | . .-.. . --. .- -. -"
# >> Morse.decode("-.-. --- -. -.-. .. ... . | .- -. -.. | . .-.. . --. .- -. -")
# => "CONCISE AND ELEGANT"
# >> Morse.encode_file("somefile.txt")
# >> Morse.decode_file("somefile.txt")
6ae6663a1fc5b44960f27be9d4a6f19c

Druwerd

October 1, 2008, October 01, 2008 18:45, permalink

No rating. Login to rate!

Magnus,
I don't understand your approach at all, but it sure looks concise!
Could you explain how it works?

2fa67a053f1bb83dca069df3c9f51a8a

lel

October 18, 2008, October 18, 2008 15:25, permalink

No rating. Login to rate!

Juggling ascii-numbers, base 3 and single letter constant names? Is this "obfuscatemycode.com" :-)

1
2
3
4
5
6
7
8
9
# The idea is that each morse code is encoded as a number: 
# "a" is mapped to 19, which in base 3 is 201, the 2 works as a dummy to keep leading 0's in place, so the real value is "01" which maps to the morse code ".-"
# "b" is mapped to 189, which in base 3 is 21000, remove the 2 and the real value is "1000" which maps to the mores code "-..."
# and so on.
# 
# I don't see why not, but the codes could have been encoded in base 2 as well:
# "a" would map to 5, which in base 2 is "101", the first digit is always a dummy, so the real value is "01" which maps to ".-"
# "b" would map to 24, which in base 2 is "11000", skip the first digit and we get "1000" which maps to "-..."
#
B397b498cc02503a2d86c86176f7fd3e

Magnus Holm

October 19, 2008, October 19, 2008 18:28, permalink

3 ratings. Login to rate!

lel: You're absolutely right. This can be solved in a much simpler way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
module                    Morse

 A,B,C=proc{M.tr(' ','').gsub(/#{$/}+/,$/).split($/).map{|x|
x[/(.)(.+)(.).*\1\2\3/,2].to_i(16)}},proc{|c|A[][c-65].to_s(2
    )[1..-1].tr('10','-.')},proc{|m|(A[].index(("1"+m.tr(
              '-.','10')).to_i(2))||return)+65}              

def                  self.encode(str)
         str.upcase.split(//).map{|c|(65..90)===
      (c=c[0])?B[c]:c==32?'|':nil}.compact.join(' ')
                                                          end

def                  self.decode(str)
 str.split(' ').map{|m|m[0]==?|?' ':(m=C[m])&&m.chr}.join
                                                          end

                   self.methods(false).
               map{|m|class<<self;self;end.
            send(:define_method,m+"_file"){|f|
      File.readlines(f).map{|l|send(m,l)}.join $/}}


M =              <<-'LETS GO MORSING!'
   3DC5D1BBFBE596573E0EE011500C2959ED1469891C5D9120EA8
   D18A6BF9C806A8A15A77A5788575BD18A0233578435B20884FE
                          
                       A1AAAAAA1AA 
                   BCD             BCD
                   123             123
              412C127               140C127
                      87EB9557EB757      
   
         7103B03517D082301871039DD318B6ABEB04981
         2A44EFBD92A0B694FE1ECC094F42E7F7DF37AF7
         9781      765A3C96E24326A0F58      1764
         2D3C        3399D0D588D492D        3A95
         AB74          D14522116D1          45E3
         6833      7     A807B37     A      F32E
         BD57      4F      C61      EC      613F
         07EF      733E     F     7DEA      540F
         E285      04F691       656291      6595
         85EC      1D8343A     C1D82A1      9F95
         F5A3      7F8D02D25A357BEDC75      4958
         86C8      61F6679FFEB2DF19CEC      8673
         0706      DC3C81C810CBEBA76FC      CC3C 
         32B7      91791ADFE02C7664F6E      7D51
         1111      656B15AA24FF66461FD      1111
         0BD60F270C533AE418A5A99E65950BD26D003CF
         1BC023CDEBA3CE19D0CF7E0B50607C7E19DD396
   
   
   11B878DCDAEAE1AE136657420A26AF87356FCD6DA11B80CDD4F
   22C2201C00354CD948A67CAAA92566A7E4515CAADADC8FA01C0
                     LETS GO MORSING!
                                                          end
Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

October 19, 2008, October 19, 2008 22:13, permalink

No rating. Login to rate!

awesome Magnus!

Your refactoring





Format Copy from initial code

or Cancel