zoukankan      html  css  js  c++  java
  • 字母算术的python算法

    据说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版运行的代码:

    # -*- 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)

    这个是python2的代码,如果是python3,需要修改
    string.maketrans 为 str.maketrans
    print加括号

    执行结果如下:

    poboke$ python alphametics.py "WWWDOT - GOOGLE == DOTCOM"
    WWWDOT - GOOGLE == DOTCOM
    777589 - 188103 == 589486
    777589 - 188106 == 589483
    
    poboke$ python alphametics.py "WWWDOT - POBOKE == DOTCOM"
    WWWDOT - POBOKE == DOTCOM
    666435 - 231397 == 435038
    666435 - 231398 == 435037
    666180 - 485893 == 180287
    666180 - 485897 == 180283
    
    poboke$ python alphametics.py "SEND + MORE == MONEY"
    SEND + MORE == MONEY
    9567 + 1085 == 10652
    
    poboke$ python alphametics.py "SIX + SEVEN + SEVEN == TWENTY"
    SIX + SEVEN + SEVEN == TWENTY
    650 + 68782 + 68782 == 138214


  • 相关阅读:
    Tennix — 开源的网球游戏
    Tile Racer — 3D 赛车游戏
    51CTO网管生活
    分割图片的例子 回复 "小熊宝" 的问题
    图解 CSS (5): font 字体
    图解 CSS (9): 列表
    图解 CSS (11): 理解样式表的逻辑
    图解 CSS (8): 浮动、显示、隐藏
    图解 CSS (10): 链接、继承、放缩、鼠标指针、其他(待补充...)
    多线程编程(2) 从 CreateThread 说起
  • 原文地址:https://www.cnblogs.com/cute/p/10298102.html
Copyright © 2011-2022 走看看