Перебор с бэктрекингом
Задача - имеется три слова, первые два - слогаемые, третье - сумма. Подобрать кодировку для букв, чтобы равенство было верно.
Логика такая же, как в задаче с 8 ферзями - имеется поле с размерами: по вертикали имеется диапазон с 10 числами от нуля до девяти, по горизонтали диапазон в размере уникальных символов.
Перебор заключается в том, что начиная с первого символа "фишку" необходимо попытаться поставить как можно ближе к нулю на незанятый ряд (при этом учитывая, что если символ является первым в одном из слов - он не может быть равен нулю).
Когда последний символ уже некуда ставить, возвращаем его в -1 и возвращаемся к предудущему символу, двигаем его вперед и начинаем снова перебирать последний символ.
Когда предпоследний символ дошёл до крайнего значения, возвращаем его в null и сдвигаем предыдущий по счету символ и начинаем снова перебирать предпоследний символ и так далее.
Когда все символы одновременно дошли до превого значения - перебор закончен. Если в какой-то момент перебора было удовлетворено условие равенства - сохраняем набор значений ключей в массив.
Бэктрекинг заключается в том, что когда перебраны все элементы следующего уровня, мы возвращаемся на предыдущий и берем следующий элемент.
Логика функции для перебора значений выглядит так:
решалка { индекс буквы в массиве = 0; пока индекс буквы >= 0 { если значение символа < 9 { значение символа ++; если значение не занято другими символами { если индекс буквы < количества букв { перейти к следующей букве; } еще если текущее состояние значений является решением { .. сделать что требовалось сделать ..; } } } в ином случае { вернуть значение символа в начальное положение; вернуться к предыдущй букве; } } }
Для проверки, не занято ли значение для символа каким-либо из других символов существует отдельная фукнция.
цифра не занята { если цифра является первой и текущее значение равно нулю занято для каждой предыдущей буквы в массиве { если значение предыдущей буквы равно значению текущей буквы вернуть занято } вернуть свободно }