抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

据说Google出过一道题目:WWWDOT - GOOGLE = DOTCOM。
其中每个字母代表一个数字,数字不能重复,而且最高位的数字不能为0。

像这样的谜题被称为cryptarithms或者字母算术(alphametics)。字母可以拼出实际的单词,而如果你把每一个字母都用0–9中的某一个数字代替后, 也同样可以拼出一个算术等式。关键的地方是找出每个字母都映射到了哪个数字。每个字母所有出现的地方都必须映射到同一个数字,数字不能重复, 并且“单词”不能以0开始。

最著名的字母算术谜题是SEND + MORE = MONEY。

Raymond Hettinger写过一个令人难以置信的Python程序,这个程序只用14行代码来解决任何字母算术谜题。
代码见:http://woodpecker.org.cn/diveintopython3/advanced-iterators.html

不过该代码是python 3.x版本的,下面是我改过的可以在2.x版运行的代码:

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
# -*- coding:utf-8 -*-
# Copyright (c) 2009, Raymond Hettinger, All rights reserved.
# Ported to Python 2.x and modified by poboke.com

import re
import itertools
import string

def solve(puzzle):

#匹配出所有字母,转为大写
words = re.findall('[A-Z]+', puzzle.upper())

#将字母放到集合里
unique_chars = set(''.join(words))

#因为数字只有10个,所以如果字母大于10个就会出错
assert len(unique_chars) <= 10, 'Too many letters'

#将式子的首字母排到前面,方便判断首字母是否为0
first_letters = {word[0] for word in words}
n = len(first_letters)
sorted_chars = ''.join(first_letters) + \
''.join(unique_chars - first_letters)

#所有数字
digits = '0123456789'
zero = digits[0]

#获取所有数字的全排列
for guess in itertools.permutations(digits, len(sorted_chars)):

#所有式子的首字母都不能为0
if zero not in guess[:n]:

#将字母替换为数字
trans = string.maketrans(sorted_chars, ''.join(guess))
equation = puzzle.translate(trans)

#如果数字式子的计算结果正确
if eval(equation):
print equation


if __name__ == '__main__':
import sys
for puzzle in sys.argv[1:]:
print(puzzle)
solve(puzzle)

执行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ python alphametics.py "WWWDOT - GOOGLE == DOTCOM"
WWWDOT - GOOGLE == DOTCOM
777589 - 188103 == 589486
777589 - 188106 == 589483

$ python alphametics.py "WWWDOT - POBOKE == DOTCOM"
WWWDOT - POBOKE == DOTCOM
666435 - 231397 == 435038
666435 - 231398 == 435037
666180 - 485893 == 180287
666180 - 485897 == 180283

$ python alphametics.py "SEND + MORE == MONEY"
SEND + MORE == MONEY
9567 + 1085 == 10652

$ python alphametics.py "SIX + SEVEN + SEVEN == TWENTY"
SIX + SEVEN + SEVEN == TWENTY
650 + 68782 + 68782 == 138214

评论