假设我们有一个翻译莫尔斯符号的函数:
.
- > -.
-
- > ...-
如果我们应用这个函数两次,我们得到例如:
.
- > -.
- > ...--.
给定输入字符串和多次重复,想知道最终字符串的长度。 (来自Flemish Programming Contest VPW的问题1,摘自these slides,它提供了Haskell中的解决方案)。
对于给定的输入文件
4
. 4
.- 2
-- 2
--... 50
我们期待解决方案
44
16
20
34028664377246354505728
由于我不知道Haskell,这是我在Python中提出的递归解决方案:
def encode(msg, repetition, morse={'.': '-.', '-': '...-'}):
if isinstance(repetition, str):
repetition = eval(repetition)
while repetition > 0:
newmsg = ''.join(morse[c] for c in msg)
return encode(newmsg, repetition-1)
return len(msg)
def problem1(fn):
with open(fn) as f:
f.next()
for line in f:
print encode(*line.split())
适用于前三个输入,但在最后一次输入时出现内存错误。
你会如何以更有效的方式重写这个?
修改
根据给出的评论重写:
def encode(p, s, repetition):
while repetition > 0:
p,s = p + 3*s, p + s
return encode(p, s, repetition-1)
return p + s
def problem1(fn):
with open(fn) as f:
f.next()
for line in f:
msg, repetition = line.split()
print encode(msg.count('.'), msg.count('-'), int(repetition))
关于风格和进一步改进的评论仍然欢迎
答案 0 :(得分:7)
考虑到你实际上不必输出结果字符串,只输出它的长度。还要考虑'。'的顺序。字符串中的' - '不影响最终长度(例如“.- 3”和“ - 。3”产生相同的最终长度)。
因此,我会放弃存储整个字符串而是存储'。'的数量。和' - '作为整数。
答案 1 :(得分:2)
在您的起始字符串中,计算点数和破折号。然后申请:
repetitions = 4
dots = 1
dashes = 0
for i in range(repetitions):
dots, dashes = dots + 3 * dashes, dashes + dots
想一想为什么会这样。
答案 2 :(得分:2)
Per @Hammar(我有同样的想法,但他解释得比我能做的更好; - ):
from sympy import Matrix
t = Matrix([[1,3],[1,1]])
def encode(dots, dashes, reps):
res = matrix([dashes, dots]) * t**reps
return res[0,0] + res[0,1]
答案 3 :(得分:1)
你将点数计算为破折号,并在每次迭代中将破折号计数为点数......
def encode(dots, dashes, repetitions):
while repetitions > 0:
dots, dashes = dots + 3 * dashes, dots + dashes
repetitions -= 1
return dots + dashes
def problem1(fn):
with open(fn) as f:
count = int(next(f))
for i in xrange(count):
line = next(f)
msg, repetition = line.strip().split()
print encode(msg.count('.'), msg.count('-'), int(repetition))