简单的加密拼图

时间:2013-09-11 09:50:13

标签: cryptarithmetic-puzzle

我正在寻找一种解决此隐藏算术问题的方法:

ROBERT +  GERALD =  DONALD

也可能是其他人,其中每个字母代表一个数字。

你将如何手动解决这个问题?这与以编程方式解决它有什么关系?

提前谢谢

1 个答案:

答案 0 :(得分:4)

你实际上可以将其作为总和:

  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==ng==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;
}

这将为您提供一系列解决方案。

而且,在你抱怨你不能重复数字之前,如果是这种情况,那么没有解决方案,因为数学上TR 必须< / em>为零,如上面的原始推理所示。你可以凭经验证明这一点:

#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