2016-05-26 6 views
0

有名なパズルが続きます。 SEND + MORE = MONEYMore Money Puzzle in Python

追加が正しいように、式の各文字を1〜9の整数(重複なし)で置き換えます。このパズルを解くプログラムを書く。ヒント:ブルートフォースはうまくいく(すべての可能性を試す)。

はここで、これまでに私のコードです:

def solution(): 
    letters = ('s', 'e', 'n', 'd', 'm', 'o', 'r', 'y') 
    for s in range(9, 0, -1): 
     for e in range(9, -1, -1): 
      for n in range(9, -1, -1): 
       for d in range(9, -1, -1): 
        for m in range(9, 0, -1): 
         for o in range(9, -1, -1): 
          for r in range(9, -1, -1): 
           for y in range(9, -1, -1): 
            if len(set((letters))) != len(letters): 
             send = 1000 * s + 100 * e + 10 * n + d 
             more = 1000 * m + 100 * o + 10 * r + e 
             money = 10000 * m + 1000 * o + 100 * n + 10 * e + y 

             if send + more == money: 
              return send, more, money 

print(solution()) 

しかし、それは動作しません。それは出力を与えません。これをどうすれば解決できますか?

+1

'len(set((letters)))!= len(letters)'は不変で、決して真です。それはなんのためですか? – kevmo314

+0

@Shankarしかし、それは起こっていない。 – Veedrac

+0

@Shankar - このような文字列の乗算は行われません。 – TigerhawkT3

答えて

0

セットへのキャスティングリストは、ユニークでない要素がある場合にのみ長さが変更されます。セットがどのように動作するか チェック:https://docs.python.org/2/library/sets.html

community guidelinesから:

は、あなたがそれを自分で解決するからあなたを妨げてきたあらゆる困難をあなたが解決しようとしている問題が発生し、 方法を説明。あなたの質問の最初の段落 は、ほとんどの読者が を参照する2番目のものです。できるだけ魅力的で有益なものにしてください。

一意性要件に
3

、すべてのソリューションを検索:

def solutions(): 
    # letters = ('s', 'e', 'n', 'd', 'm', 'o', 'r', 'y') 
    all_solutions = list() 
    for s in range(9, -1, -1): 
     for e in range(9, -1, -1): 
      for n in range(9, -1, -1): 
       for d in range(9, -1, -1): 
        for m in range(9, 0, -1): 
         for o in range(9, -1, -1): 
          for r in range(9, -1, -1): 
           for y in range(9, -1, -1): 
            if len(set([s, e, n, d, m, o, r, y])) == 8: 
             send = 1000 * s + 100 * e + 10 * n + d 
             more = 1000 * m + 100 * o + 10 * r + e 
             money = 10000 * m + 1000 * o + 100 * n + 10 * e + y 

             if send + more == money: 
              all_solutions.append((send, more, money)) 
    return all_solutions 

print(all_solutions) 
+0

これは素晴らしい動作です!問題の可能なすべてのソリューションを返すために、最後にforループを追加するにはどうすればよいですか? – anon

+0

編集されたレスポンスを参照してください(但し、1つの解決策のみが見つかりました) –

1

を私が前にパズルの聞いたことがないので、私はもう少し簡潔なブルートフォースソリューションを書くために抵抗することができませんでした。私はここにS -> 0またはM -> 0の可能性を排除しなかった

from itertools import combinations, permutations 

a, b, c = 'SEND', 'MORE', 'MONEY' 

for comb in combinations(range(10), 8): 
    for perm in permutations(comb): 
     d = dict(zip('SENDMORY', perm)) 
     f = lambda x: sum(d[e] * 10**i for i, e in enumerate(x[::-1])) 
     if f(a) + f(b) == f(c): 
      print "{} + {} = {}".format(f(a), f(b), f(c)) 

注意。

EDIT:同様のものですが、ジェネレータを使用し、先行ゼロにつながる置換を無視します。 siwica @

from itertools import combinations, permutations 

def replacements(): 
    for comb in combinations(range(10), 8): 
     for perm in permutations(comb): 
      if perm[0] * perm[1] != 0: 
       yield dict(zip('SMENDORY', perm)) 

a, b, c = 'SEND', 'MORE', 'MONEY' 

for replacement in replacements(): 
    f = lambda x: sum(replacement[e] * 10**i for i, e in enumerate(x[::-1])) 
    if f(a) + f(b) == f(c): 
     print('{} + {} = {}'.format(f(a), f(b), f(c))) 
0

:あなたの「速い」ソリューションは、複数の結果のリストを提供し、私はあなたの最後から二番目の行の変更を提案する:

そう
if (f(a) + f(b) == f(c)) & (len(a) == len(str(f(a)))) & (len(b) == len(str(f(b)))): 

、私はコメントする一切の権限を持っていない、これは私はこれをなぜ書くのですか?

+0

私は 'M - > 0'が有効な置換えであると想定していたので、この問題は、このオプションを明確に排除していませんでした。 先行ゼロが許可されていない場合は、提案した時点ではなく、ループの始めにこのケースをチェックします。 また、私のコードは高速だとは言わなかったが、それは簡潔であるということだけである。それらの用語は必ずしも関連していません。 –