Here are some additive cryptarithms (also called "alphametics"). The program below will find the unique letter substitutions (assuming that the first digit is not zero) that work in these
- examples
- A + CHILLY + LADY = GODIVA ALL + ALPHA + METICS + SEEM = SIMPLE BROWN + YELLOW = PURPLE CARBON + COBALT + BORON = ELEMENT CROSS + ROADS = DANGER EASY + AS + ONE + TWO = THREE FIRST + THREE + HORSES = TRIPLE GEE + TAM + SEE + THEM = WEEDS ICY + NORTH + OCEAN = ARCTIC LET + THERE + BE = LIGHT MARTIN + GARDNER = RETIRES NACL + KCL + LICL = SALT OH + YES + SHE = SAYS PAPER + PENCIL + AND + AN = ERASER RIDER + DROPS + REINS + HORSE = LOSES SPANISH + SAILING + SHIP = GALLEON SEND + MORE = MONEY THE + LATE + THE + FUTURE = ARTHUR WE + WANT + NO + NEW + ATOMIC = WEAPON
Here are some double-meaning examples from Journals from 1980 to 1984
- that fit
TWELVE + TWELVE + NINE + NINE + NINE + NINE + FIVE + FIVE = SEVENTY SIXTEEN + TWENTY + TWENTY + TEN + TWO + TWO = SEVENTY SIXTEEN + TWELVE + TWELVE + TWELVE + NINE + NINE = SEVENTY THREE + NINE + NINE + NINE + TWENTY + THIRTY = EIGHTY FIFTY + EIGHT + EIGHT + TEN + TWO + TWO = EIGHTY FIVE + FIVE + TEN + TEN + TEN + TEN + THIRTY = EIGHTY THREE + THREE + THREE + THREE + THREE + THREE + THREE + FIVE + FIVE + FIVE + FIVE + FIVE + ELEVEN + ELEVEN + ELEVEN + ELEVEN = NINETY SIXTY + EIGHT + THREE + NINE + TEN = NINETY EIGHT + EIGHT + THREE + THREE + ONE + ONE + ONE + ONE + ONE + ONE + ONE
- ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE =
FORTY
- In Roman numerals
- I + IV + XIV + XLIV + XXII = LXXXV DCL + DLIX + CDII = MDCXI LIV + CCXIV + DCCI + MDCI = MDLX
- In languages other than English
- AONO + AHIKU + AIWA + AWALU + UMI = KANAHA JEDEN + JEDEN + JEDEN + JEDEN = CZTERY SIETE + SIETE + TRECE + TRECE + VEINTE + TREINTA = NOVENTA ZEVEN + TWEE + EEN + EEN + EEN = TWAALF
- If numbers not made up a single word are allowed
- NINETEEN + THIRTEEN + SIXTEEN + THREE + THREE + ONE + ONE + ONE + ONE + ONE + ONE + ONE = SIXTYONE THIRTEEN + THIRTEEN + THIRTEEN + THIRTEEN + NINE + ONE + ONE + ONE + ONE + ONE = SIXTYSIX
- And for a really long one
- HUNDRED + HUNDRED + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + THREE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE + ONE = THOUSAND
Here are some multiplicative cryptarithms, that the program will not
- solve without extensions (so we give the solutions)
KISS x KISS = PASSION 2033 x 2033 = 4133089
MIN x NIE = MOUSE 321 x 124 = 39804
----------------------------------cut here----------------------------
- include <stdio.h>
- include <stdlib.h>
/*
- Tom Magliery
- National Center for Supercomputing Applications
- 605 E. Springfield
- Champaign, IL 61820
- email: mag@ncsa.uiuc.edu
*
- Generates a C program which will solve a given cryptarithm (is that what
- what they're called?). Anyway, I mean puzzles like this:
*
- s e n d
- + m o r e
- m o n e y
*
- where each letter stands for a different digit. That particular
- puzzle has 1 "interesting" solution (neither m nor s=0), and 24
- "uninteresting" ones.
*
- The input is a character string of the form "send + more = money".
- It may have any number of addends (including 1 or 0, in which case
- the appropriate '+' and '=' are omitted). There must be exactly one
- space on either side of each '+' and '='. Strange, unpredictable,
- and most importantly, incorrect, behavior will probably result if
- you don't follow these rules.
*
- The generated program runs with no arguments. It tries every possible
- combination of digits and prints all that work, including ones with
- leading zeroes in the addends and/or sum.
*
- The generated program is printed to standard output. Redirect it to
- a file with a ".c" extension and compile it. Both this program and
- the generated program are ANSI C. It (they) may require some hacking
- to work with a non-ANSI compiler.
*
- /
typedef struct {
char symbols[11?; int num_of_addends; char** addends; char* sum;
} REC;
void parseInput (char*, REC*); void printHeader (REC*); void printMain (REC*); void printMatch (REC*); void printPrint (REC*); int index_of (char, char*);
main (int argc, char**argv) {
REC* pzl = (REC*) malloc (sizeof (REC));
if (argc<2)
fprintf (stderr, "No problem. ;-)\n");
else {
parseInput (argv[1?, pzl); printHeader (pzl); printMain (pzl); printMatch (pzl); printPrint (pzl); }
}
void parseInput (char* problem, REC* pzl) {
char** words; int i, index, length = strlen(problem), spaces=0;
/* record the different symbols used in the problem */ for (i=0; i<11; i++) pzl->symbols[i? = '\0'; for (i=0; i<length; i++)
if (problem[i? != ' ' && problem[i? != '+' && problem[i? != '=')
if (index_of(problem[i?, pzl->symbols) == -1) {
if (strlen(pzl->symbols) == 10) {
printf ("Error -- too many symbols in problem.\n"); exit (37); }
/* count the spaces */ for (i=0; i<length; i++)
if (problem[i?==' ') spaces++;
/* there is one more word than the number of spaces / / WARNING: not robust -- assumes no two consecutive spaces / words = (char**) malloc ((spaces+1)*sizeof(char));
/* set pointers to individual words */ words[0? = problem; index = 1; for (i=0; i<length; i++)
if (problem[i? == ' ')
/* make words null-terminated */ for (i=0; i<length; i++)
if (problem[i? == ' ')
problem[i? = '\0';
/* # of addends is always half # of spaces */ pzl->num_of_addends = spaces/2;
/* construct the list of addends / pzl->addends = (char**) malloc (pzl->num_of_addends * sizeof(char)); for (i=0; i<pzl->num_of_addends; i++)
/* sum is the last 'word' on the list */ pzl->sum = words[spaces?;
}
void printHeader (REC* pzl) {
int i; printf ("/*\n"); printf (" * Automatically-generated program to solve the"); printf (" following cryptarithm:\n"); printf (" * "); for (i=0; i<pzl->num_of_addends; i++) {
printf ("%s", pzl->addends[i?); printf ("%s", i<pzl->num_of_addends-1 ? " + " : " = "); }
printf ("%s\n", pzl->sum); printf (" */\n");
}
void printMain(REC* pzl) {
printf ("#include <stdio.h>\n"); printf ("#include <stdlib.h>\n"); printf ("#define M %d\n", strlen(pzl->symbols)); printf ("int tuple[10?;\n"); printf ("int Used[10? = {0,0,0,0,0,0,0,0,0,0};\n"); printf ("void perm(int*, int);\n"); printf ("int match();\n"); printf ("void print();\n"); printf ("main () {\n"); printf (" perm (Used, M);\n"); printf ("}\n"); printf ("void perm (int Used[10?, int Size) {\n"); printf ("int i;\n"); printf ("if (Size == 1) {\n"); printf (" for (i=0; i<10; i++)\n"); printf (" if (!Used[i?) {\n"); printf (" tuple[M-Size? = i;\n"); printf (" if (match()) print();\n"); printf (" }\n"); printf (" }\n"); printf ("else {\n"); printf (" for (i=0; i<10; i++) {\n"); printf (" if (!Used[i?) {\n"); printf (" Used[i? = 1;\n"); printf (" tuple[M-Size? = i;\n"); printf (" perm (Used, Size-1);\n"); printf (" Used[i? = 0;\n"); printf (" }\n"); printf (" }\n"); printf (" }\n"); printf ("}\n");
}
void printMatch(REC* pzl) {
int a, i, len=strlen(pzl->sum), multiplier=1;
printf ("int match () {\n"); printf ("return !("); for (i=0; i<len; i++) {
if (i>0) printf (" "); printf ("%10d*(", multiplier); for (a=0; a<pzl->num_of_addends; a++) {
if (i<strlen(pzl->addends[a?)) {
printf ("tuple[["); printf ("%d",
index_of(pzl->addends[a?[strlen(pzl->addends[[a?)-i-1],
pzl->symbols));
}
else
printf (" ");
if (a < pzl->num_of_addends-1)
printf ("%s", i<strlen(pzl->addends[a?) ? "]+" : " ");
else
printf ("%s", i<strlen(pzl->addends[a?) ? "]" : " ");
}
printf ("-tuple[len-i-1?, pzl->symbols)); printf ("])"); printf ("%s", i<len-1 ? "+\n" : ");\n"); multiplier *= 10; }
printf ("}\n");
}
void printPrint(REC* pzl) {
int i, j; char* current_addend;
printf ("void print () {\n");
printf ("printf (\""); current_addend = pzl->addends[0?; for (i=0; i < pzl->num_of_addends; i++) {
for (j=0; j<strlen(pzl->addends[i?); j++)
printf ("%%d");
printf ("%s", i<pzl->num_of_addends-1 ? " + " : " = "); }
for (j=0; j<strlen(pzl->sum); j++)
printf ("%%d");
printf ("\\n\",\n ");
for (i=0; i<pzl->num_of_addends; i++) {
for (j=0; j<strlen(pzl->addends[i?); j++)
printf ("tuple[%d?, ", index_of(pzl->addends[i?[j?,pzl->symbols));
printf ("\n "); }
for (j=0; j<strlen(pzl->sum); j++) {
printf ("tuple[%d?", index_of(pzl->sum[j?, pzl->symbols)); printf ("%s", j<strlen(pzl->sum)-1 ? ", " : ");\n"); }
printf ("return;\n}\n");
}
int index_of (char ch, char* str) {
int i, len = strlen(str); for (i=0; i<len; i++)
if (str[i? == ch)
return i;
return -1;
}
