понедельник, 17 февраля 2014 г.

Python: Числовые ребусы

Программка для разгадывания числовых ребусов. Методом грубой силы (т.е. простым перебором).

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import sys

#equation = u'удар+удар==драка'
#equation = u'кошка+кошка+кошка==собака'
#equation = u'кто+умён+тот==силён'
#equation = u'где*где-всюду==везде'
equation = u'масло+ноль==омлет'

def replace_all(text, srch, repl):
    for i in range(0, len(srch)):
        text = text.replace(srch[i], repl[i])
    return text

letters = []

for l in equation:
    if l not in ('+', '=', '-', '*'):
        if l not in letters:
            letters.append(l)

tops, counters = [], []
for i in range(0, len(letters)):
    tops.append(10 - i)
    counters.append(0)

canExit = False
while(not(canExit)):

    numbers = ['0','1','2','3','4','5','6','7','8','9']
    substs = []
    for i in range(0, len(tops)):
        substs.append(numbers[counters[i]])
        del numbers[counters[i]]

    text = replace_all(equation, letters, substs)
    try:
        if eval( text ):
            print text
    except:
        None

    N = 0
    inc = 1
    while (N < len(counters) and inc > 0):
        counters[N] += inc
        inc = 0
        if (counters[N] == tops[N]):
            counters[N] = 0
            inc = 1
            N += 1

    canExit = True
    for i in range(0, len(tops)):
        canExit &= (counters[i] == tops[i]-1)

2 комментария:

  1. А не замечали, что варианты и неправильные выдаются? Вот на эту же "масло+ноль==омлет":
    35604+7408==43012
    37604+5408==43012
    36054+7458==43512
    37054+6458==43512
    02761+9163==10684 *
    06231+7134==10359 *
    28153+4356==32509
    24153+8356==32509
    06451+7159==10528 *
    27143+5346==32489
    25143+7346==32489
    17692+4293==21985
    14692+7293==21985
    02761+9164==10685 *
    Такое ощущение, что функцию 'eval' первый значащий ноль сбивает с толку. Не говоря уже о том, что такое решение математически верно, но не совсем подходит под условие (вместо него можно написать "асло+ноль==омлет")...

    Кстати, видели ли Вы эту публикацию, а конкретнее эту ветку комментариев: https://habrahabr.ru/company/infopulse/blog/260809/#comment_8477501 ?

    ОтветитьУдалить
    Ответы
    1. Да, спасибо за замечание и за ссылку. Я как-то упустил из виду, что 0123 в питоне - это число в восьмеричной записи, так что при вычислении получаются всякие чудеса.

      Удалить