master
1<<-DOC
2A top secret message containing uppercase letters from 'A' to 'Z' has been encoded as numbers using the following mapping:
3
4'A' -> 1
5'B' -> 2
6...
7'Z' -> 26
8You are an FBI agent and you need to determine the total number of ways that the message can be decoded.
9
10Since the answer could be very large, take it modulo 10^9 + 7.
11
12Example
13
14For message = "123", the output should be
15
16mapDecoding(message) = 3.
17
18"123" can be decoded as "ABC" (1 2 3), "LC" (12 3) or "AW" (1 23), so the total number of ways is 3.
19
20Input/Output
21
22[time limit] 4000ms (rb)
23[input] string message
24
25A string containing only digits.
26
27Guaranteed constraints:
28
290 ≤ message.length ≤ 105.
30
31[output] integer
32
33The total number of ways to decode the given message.
34DOC
35
36describe "map_decoding" do
37 <<-THINK
38 "abc"
39
40 |1|2|3|
41 1|a|b|c|
42 2|L|W|-|
43 3|-|-|-|
44
45 |1|2|3|
46 |2|2|1|
47
48 10122110
49 10|12|21|10
50 10|12|2|1|10
51 10|1|22|1|10
52 10|1|2|21|10
53 10|1|2|2|1|10
54
55 [1, 2, 3]
56
57 [1], [2, 3] [1, 2, 3]
58 [2], [3] [2], [3]
59 [3] [3]
60
61
62 THINK
63 def map_decoding(message)
64 puts [message].inspect
65 if message.size == 1
66 return (0..26).include?(message[0].to_i - 1) ? 1 : 0
67 end
68
69 count = 0
70 results = []
71 (message.size - 1).downto(0) do |i|
72 tail = message[i].to_i
73 combined = message[i-1..i].to_i
74 head = message[i - 1].to_i
75
76 if tail == 0
77 return 0 if combined < 0 || combined >= 26
78 results.push(combined)
79 else
80 if head >= 0 && head < 26
81 count += 1
82 results << tail
83 end
84 end
85 puts results.inspect
86
87 i += 1
88 end
89
90 modulo = (10 ** 9) + 7
91 count % modulo
92 end
93
94 def decode(chars, rest = [])
95 #puts [chars, rest].inspect
96 return chars if rest.empty?
97
98 results = []
99 first = rest[0]
100 results.push(decode([first], rest[1..rest.size]))
101
102 second = rest[1]
103 results.push(decode([first + second], rest[2..rest.size])) if second
104 results
105 end
106
107 def map_decoding(message)
108 decode([], message.chars)
109 end
110
111 # dp[n] = dp[n - 1] + dp[n - 2] if [x,y] <= 26
112 # dp[n] = dp[n - 1]
113 def map_decoding(message)
114 puts message.inspect
115 dp = [1]
116
117 return message[0].to_i > 0 ? 1 : 0 if message.size == 1
118
119 1.upto(message.size - 1) do |n|
120 x, y = message[n - 1], message[n]
121 z = (x + y).to_i
122 puts [x, y].join.inspect
123 if x != "0" && z <= 26
124 dp[n] = dp[n - 1] + dp[n - 2]
125 else
126 if y.to_i > 0
127 dp[n] = dp[n - 1]
128 else
129 dp[n] = 0
130 end
131 end
132 puts dp.inspect
133 end
134 modulo = (10 ** 9) + 7
135 dp.last % modulo
136 end
137
138 [
139 { message: "123", expected: 3 },
140 { message: "12", expected: 2 },
141 { message: "0", expected: 0 },
142 { message: "1", expected: 1 },
143 { message: "11", expected: 2 },
144 { message: "301", expected: 0 },
145 { message: "1001", expected: 0 },
146 { message: "10122110", expected: 5 },
147 { message: "", expected: 1 },
148 { message: "11115112112", expected: 104 },
149 { message: "2871221111122261", expected: 233 },
150 { message: "1221112111122221211221221212212212111221222212122221222112122212121212221212122221211112212212211211", expected: 782204094 },
151 ].each do |x|
152 it do
153 expect(map_decoding(x[:message])).to eql(x[:expected])
154 end
155 end
156end