Простая криптографическая головоломка
Я ищу способ решить эту арифметическую проблему:
ROBERT + GERALD = DONALD
и, возможно, другие, где каждая буква представляет цифру.
Как бы вы решили решить это вручную и как это связано с программным решением?
заранее спасибо
1 ответ
Вы можете фактически решить это как сумму:
robert
+ gerald
------
= donald
и использовать базовые математические знания.
Например, в правом столбце (6) нет переноса, и мы имеем T + D = D
, Это означает T
должно быть ноль.
Аналогично, для столбца 5 нет переноса из столбца 6 и R + L = L
средства R
также равен нулю и не переносится в столбец 4.
То же самое с колонкой 4, E + A = A
так E
это ноль.
Итак, теперь у нас есть:
0ob000
+ g00ald
------
= donald
Отсюда мы можем вывести из столбцов 3 и 1, что b==n
а также g==d
и они (вместе с o/a/l/d
) может быть любым значением, так как каждая цифра добавляется к нулю, поэтому вероятность переноса в любом месте отсутствует. Итак, давайте просто сделаем их всех одним:
011000
+ 100111
------
= 111111
На самом деле, вы могли бы сделать их все ноль и в конечном итоге 000000 + 000000 = 000000
,
Но это вряд ли связано с программированием, поэтому давайте сделаем так:
#include <stdio.h>
int main (void) {
int robert, gerald, donald;
for (int r = 0; r < 10; r++) {
for (int o = 0; o < 10; o++) {
for (int b = 0; b < 10; b++) {
for (int e = 0; e < 10; e++) {
for (int t = 0; t < 10; t++) {
for (int g = 0; g < 10; g++) {
for (int a = 0; a < 10; a++) {
for (int l = 0; l < 10; l++) {
for (int d = 0; d < 10; d++) {
for (int n = 0; n < 10; n++) {
robert = r * 100000 + o * 10000 + b * 1000 + e * 100 + r * 10 + t;
gerald = g * 100000 + e * 10000 + r * 1000 + a * 100 + l * 10 + d;
donald = d * 100000 + o * 10000 + n * 1000 + a * 100 + l * 10 + d;
if (robert + gerald == donald) {
printf (" %06d\n", robert);
printf ("+ %06d\n", gerald);
printf (" ------\n");
printf ("= %06d\n", donald);
printf ("........\n");
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
Это даст вам целый ряд решений.
И до того, как вы пожалуетесь, что у вас не может быть повторяющихся цифр, в этом случае не существует решения, поскольку математически T
а также R
должен быть равен нулю, как показано в исходных рассуждениях выше. И вы можете доказать это эмпирически с помощью:
#include <stdio.h>
int main (void) {
int robert, gerald, donald;
for (int r = 0; r < 10; r++) {
for (int o = 0; o < 10; o++) {
if (o==r) continue;
for (int b = 0; b < 10; b++) {
if ((b==r) || (b==o)) continue;
for (int e = 0; e < 10; e++) {
if ((e==r) || (e==o) || (e==b)) continue;
for (int t = 0; t < 10; t++) {
if ((t==r) || (t==o) || (t==b) || (t==e)) continue;
for (int g = 0; g < 10; g++) {
if ((g==r) || (g==o) || (g==b) || (g==e) || (g==t)) continue;
for (int a = 0; a < 10; a++) {
if ((a==r) || (a==o) || (a==b) || (a==e) || (a==t) || (a==g)) continue;
for (int l = 0; l < 10; l++) {
if ((l==r) || (l==o) || (l==b) || (l==e) || (l==t) || (l==g) || (l==a)) continue;
for (int d = 0; d < 10; d++) {
if ((d==r) || (d==o) || (d==b) || (d==e) || (d==t) || (d==g) || (d==a) || (d==l)) continue;
for (int n = 0; n < 10; n++) {
if ((n==r) || (n==o) || (n==b) || (n==e) || (n==t) || (n==g) || (n==a) || (n==l) || (n==d)) continue;
robert = r * 100000 + o * 10000 + b * 1000 + e * 100 + r * 10 + t;
gerald = g * 100000 + e * 10000 + r * 1000 + a * 100 + l * 10 + d;
donald = d * 100000 + o * 10000 + n * 1000 + a * 100 + l * 10 + d;
if (robert + gerald == donald) {
printf (" %06d\n", robert);
printf ("+ %06d\n", gerald);
printf (" ------\n");
printf ("= %06d\n", donald);
printf ("........\n");
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
который не дает никаких решений.
Сейчас DONALD + GERALD = ROBERT
это другой вопрос, но вы можете решить это, просто слегка изменив приведенный выше код, сделав if
утверждение в:
if (donald + gerald == robert) {
printf (" %06d\n", donald);
printf ("+ %06d\n", gerald);
printf (" ------\n");
printf ("= %06d\n", robert);
printf ("........\n");
}
и вы получите единственное решение:
526485
+ 197485
------
= 723970