Untitled

mail@pastecode.io avatar
unknown
plain_text
21 days ago
3.5 kB
1
Indexable
Never

import itertools

def foo(a,b,c):

    # a - всегда самая длинная из а и b, так удобней
    ab_swap = False
    if len(a) < len(b):
        ab_swap = True
        a, b = b, a

    # если с длиньше самой длинной строки (a) больше чем на 1 символ
    # значит ответа нет
    if len(c) > len(a)+1:
        print("UNSOLVABLE")
        return

    # если с меньше самой длинной строки (a)
    # значит ответа нет
    if len(c) < len(a):
        print("UNSOLVABLE")
        return

    alphabet = set(a+b+c)

    # если разных букв во всех строках больше 10
    # значит ответа нет
    if len(alphabet) > 10:
        print("UNSOLVABLE")
        return

    # переворачиваем строки, так удобнее, перевернем обратно в конце
    a = a[::-1]
    b = b[::-1]
    c = c[::-1]

    # itertools.permutations(l, r) перебирает все перестановки из l по r
    for perm in itertools.permutations(list(range(10)), len(alphabet)):

        # мапа буква -> цифра
        m = dict()

        # заполняем мапу
        i = 0
        to_next_perm = False
        for ch in a+b+c:
            if ch not in m:
                m[ch] = perm[i]
                # избегаем случаев когда первой букве в строке достался 0, ведущих нулей нет по условию
                if perm[i] == 0:
                    if a[-1] == ch or b[-1] == ch or c[-1] == ch:
                        to_next_perm = True
                        break
                i += 1
        if to_next_perm:
            continue

        reminder = 0
        for i in range(len(a)):
            a_current = m[a[i]]
            # т.к. с >= a то не боимся выйти за пределы строки
            c_current = m[c[i]]
            # т.к. b <= a то заменяем b_current на 0 если вышли за пределы b
            b_current = m[b[i]] if i < len(b) else 0

            s = a_current + b_current + reminder
            c_predict = s % 10
            reminder = s // 10

            if c_current != c_predict:
                break
        else:
            # если закончили цикл без брейков
            if len(a) == len(c) and reminder == 0 or len(a) != len(c) and reminder == m[c[-1]]:
                # если а и с одинаковой длины и остатка не осталось
                # или если с длинне чем а (может быть длинее только на 1 символ) то проверяем что он равен остатку, если ок то рисуем ответ
                if ab_swap:
                    a, b = b, a
                print_result(m,a,b,c)
                return

                # если цикл прервался на break пробуем следующую перестановку

    # перебрали все перестановки, ответа нет
    print("UNSOLVABLE")


def string_to_num(s, m):
    return "".join(str(m[ch]) for ch in s)

def print_result(m, *strings):
    for s in strings:
        print(string_to_num(s[::-1], m))


# foo('abc', 'def', 'ghi') # 6823 6823 13646

foo('abcabcabca', 'defdefdefd', 'hijhijhijk') # 1421421421 7637637637 9059059058
Leave a Comment