Решаем числовые ребусы с помощью Python

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

1. Что такое числовой ребус?

Ребус - это зашифрованный пример, где каждая цифра заменена какой-то буквой. Одна и та же цифра в примере обязательно должна быть заменена одной и той же буквой. И наоборот - две разных цифры не могут быть заменены на одну и ту же букву.

И последнее правило: в примере, который мы хотим превратить в ребус, ни одно число не может начинаться с 0.

Примеры ребусов:

  • EIN + EIN + EIN + EIN = VIER (1+1+1+1 = 4, нем.);

  • ЛОДКА + ЛОДКА + ЛОДКА + ЛОДКА = РЕГАТА;

  • КНИГА + КНИГА + КНИГА = НАУКА;

  • SEND + MORE = MONEY (Посылайте больше денег, англ.);

  • КОТ + КТО = ТОК

И все их с лёгкостью будет решать наша программа!

2. Структура нашей программы

Я понимаю, что вам важен один лишь результат, поэтому вы можете сразу посмотреть в конец блога. Однако, не обижайтесь, если вы там ничего не поймёте и поэтому не сможете пользоваться. А мы продолжим.

Итак, программа должна:

  1. Узнавать ребус;

  2. Перебирать все возможные значения букв;

  3. Проверить, какие из них подходят;

  4. Выдать результаты.

Всё это довольно легко, но давайте начнём со самого сложного - перебора и проверки, так как 1-й и 4-й пункт будут занимать всего одну строчку, если знать, как осуществеляется вывод и ввод в Python. Но давайте всё по порядку.

2.1. Перебор.

Я решил использовать для перебора рекурсию. Поясню для начала, что такое рекурсия. Рекурсивная функция - это функция, которая в процессе её выполнения вызывает саму себя. Например, перебор всех ходов в шахматах - это рекурсия, потому что мы перебираем всевозможные свои ходы и для каждого своего хода заново вызываем ту же функцию оценки для следующих возможных ходов.

Вёрнемся к нашему перебору. Его структура должна выглядеть примерно так:

Функция перебор(пример):
    Найти букву в примере, которую ещё не заменили на цифру;
    ЕСЛИ такой буквы нету, ТО пример готов и должен проверяться, а перебор закончен ИНАЧЕ:
    Для каждой цифры от 0 до 9 выполнить:
            Если такая цифра уже используется в примере, она нам не подходит; взять следующию цифру;
            Каждую букву в примере заменить на эту цифру;
            Вызвать перебор для нового примера

А теперь перепишем это на питон:

def get_comb(s):
    print(s + '\r', end='')
    letter = ''
    for i in s:
        if (i.isalpha()): # i.isalpha() показывает, является ли буквой переменная i
                letter = i
                break
    if (not letter):
        check(s)
        return # заканчивает перебор, если пример готов
    for n in range(10):
        n = str(n)
        if (s.find(n) > -1): continue
        s2 = s.replace(letter, n)
        get_comb(s2)

Эта функция заменяет буквы в ребусе на числа, не пропуская ни одного варианта. Нам остаётся только написать функцию check(), которая будет проверять пример на правильность.

2.2. Функция check()

К счастью, нам не придётся писать длинную функцию, для того чтобы расшифровать наш пример и проверить его на правильность. Ведь для питона строка "10+29=39", это все равно что обычный набор символов, он его не поймёт.

Так вот, существует в питоне функция eval(). Эта функция назначена как раз для вычисления примеров и равенств (ведь 10+29=39 по сути своей, не пример, а равенство).

С этой чудестной утилитой функция check() будет занимать всего лишь 4 строчки:

def check(s):
    try:
        b = eval(s.replace("=", "=="))
    except: return
    if (b): print(s)

Эта функция проверяет, верное ли равенство мы собрали. Если там возникает ошибка (когда вначале числа стоит 0, eval() выдаёт ошибку), то мы считаем, что равенство неверно (и правильно делаем, ведь это нарушает правила числового ребуса).

Если же равенство собрано, то мы нашли решение ребуса и можем его вывести на экран.
Итак, осталось только собрать всё вместе и добавить ввод ребуса.

3. Программа целиком.

Теперь, вот вам весь наш код:

def check(s):
    try:
       b = eval(s.replace("=", "=="))
    except: return 
    if (b): print(s)

def get_comb(s):
    print(s + '\r', end='')
    letter = ''
    for i in s:
        if (i.isalpha()):
            letter = i
            break
    if (not letter):
        check(s)
        return
    for n in range(10):
        n = str(n)
        if (s.find(n) > -1): continue
        s2 = s.replace(letter, n)
        get_comb(s2)

s = (input("Введите ребус: ")).replace(" ", "") # убираем пробелы с ребуса
get_comb(s)

Я также застраховал этот код : вы можете вводить ребус, делая пробелы, например, вводя кто + кот = ток вместо кто+кот=ток.

Итак, теперь вы можете очень быстро решать ребусы и даже придумывать свои, если, конечно, вы установили Python и ваш компьютер не слишком медленный (например, у меня на компьютере некоторые ребусы занимают минуту-две времени).

Удачи!

Источник: https://habr.com/ru/articles/764562/


Интересные статьи

Интересные статьи

Любой алгоритмический процесс может быть автоматизирован, обычно для автоматизации рутинных задач пишутся скрипты, которые принимают определённые параметры, делают определённые действия, и возвращают ...
Особенности Python,  о которых я даже не подозревалАвтор оригинала: Чарудатта Манваткар В последнее время у меня появилось новое хобби – чтение документации Pytho...
Иногда к программистам приходят изменения от бизнеса. И программисты должны доработать код. Как понять - у нас хорошая архитектура кода, или плохая? Для этого можно испол...
Каждому service mesh-фреймворку абсолютно необходимо уметь обрабатывать сбои в межсервисном взаимодействии. К ним также относятся таймауты и HTTP-коды ошибок. Я покажу, как с помощью ...
Есть у меня один Python-скрипт с расчётами. Там был цикл примерно на 2000 итераций, каждая из которых считалась несколько минут. И решил я, чтобы ловчее отлаживать тот скрипт, выводить гра...