这是emacs中的一个小游戏:给一个用大写字母表示的乘法算式,计算出每个大写字母代表的数字。例如,以下的乘法竖式:
B I D
x D J
-------
A B H D
H J I D
---------
H D A I D
在这个式子中, BID = 475,DJ = 53,ABHD = 1425,HJID = 2375,HDAID = 25175。现在写一个程序,根据给定的算式计算每一个大写字母代表的数字。因为在emacs的这个小游戏中,所有算式都有相同的特点:被乘数3位数,乘数2位数,中间结果都是4位数,最终结果都是5位数。所以,专门针对emacs的小游戏的这个程序的一个非常简单的思路就是:枚举所有三位数和两位数相乘的式子,检测它们是否与给定的字母表示相容,如果有冲突,继续枚举下一个式子,否则就找到了解。如何判断找到的式子是否与给定的字母表示相容呢?假设A, B是任意两个字母表示,a,b是枚举出来的与A,B对应的数字值。不相容有两种情况:A==B但a!=b,或者A!=B但a==b,即flag = (A == B && a != b) || (A != B && a == b),当flag为1时,表示有冲突。从flag的表达式很容易能看出flag的表达式可以简写为:flag = (A == B) ^ (a == b)。下面是源代码:
#include <stdio.h>
#include <string.h>
#define print(cnt, format, array) for(i = 0; i < cnt; i++) printf(format, *(array+i))
int main() {
int op1, op2, a, b;
char all[32], temp[32];
int i, j, flag;
*all = 0;
puts("input op1:"); scanf("%s", all + strlen(all));
puts("input op2:"); scanf("%s", all + strlen(all));
puts("input median result and final result line by line:");
scanf("%s", all + strlen(all)); /* get first median resutl */
scanf("%s", all + strlen(all)); /* get second median resutl */
scanf("%s", all + strlen(all)); /* get final result */
for(op1 = 100; op1 <= 999; op1++) {
for(op2 = 10; op2 <= 99; op2++) {
a = op2 % 10;
b = op2 / 10;
if(op1 * a < 1000 || op1 * b < 1000) continue;
memset(temp, 0, sizeof(temp));
sprintf(temp, "%d%d%d%d%d", op1, op2, op1 * a, op1 * b, op1 * op2);
flag = 1;
if(strlen(all) != strlen(temp)) { flag = 0; break; }
for(i = 0; i < strlen(all); i++) {
for(j = 0; j < i; j++) {
if((all[i] == all[j]) ^ (temp[i] == temp[j])) {
flag = 0; break;
}
}
if(flag == 0) break;
}
if(flag) {
print(3, "%c", all); printf(" = "); print(3, "%c", temp); printf("/n");
print(2, "%c", all + 3); printf(" = ");print(2, "%c", temp + 3); printf("/n");
print(4, "%c", all + 5); printf(" = ");print(4, "%c", temp + 5); printf("/n");
print(4, "%c", all + 9); printf(" = ");print(4, "%c", temp + 9); printf("/n");
printf("%s = %s/n", all + 13, temp + 13);
return 0;
}
}
}
return 0;
}
例如对一开始的例子运行,输入:
#include <string.h>
#define print(cnt, format, array) for(i = 0; i < cnt; i++) printf(format, *(array+i))
int main() {
int op1, op2, a, b;
char all[32], temp[32];
int i, j, flag;
*all = 0;
puts("input op1:"); scanf("%s", all + strlen(all));
puts("input op2:"); scanf("%s", all + strlen(all));
puts("input median result and final result line by line:");
scanf("%s", all + strlen(all)); /* get first median resutl */
scanf("%s", all + strlen(all)); /* get second median resutl */
scanf("%s", all + strlen(all)); /* get final result */
for(op1 = 100; op1 <= 999; op1++) {
for(op2 = 10; op2 <= 99; op2++) {
a = op2 % 10;
b = op2 / 10;
if(op1 * a < 1000 || op1 * b < 1000) continue;
memset(temp, 0, sizeof(temp));
sprintf(temp, "%d%d%d%d%d", op1, op2, op1 * a, op1 * b, op1 * op2);
flag = 1;
if(strlen(all) != strlen(temp)) { flag = 0; break; }
for(i = 0; i < strlen(all); i++) {
for(j = 0; j < i; j++) {
if((all[i] == all[j]) ^ (temp[i] == temp[j])) {
flag = 0; break;
}
}
if(flag == 0) break;
}
if(flag) {
print(3, "%c", all); printf(" = "); print(3, "%c", temp); printf("/n");
print(2, "%c", all + 3); printf(" = ");print(2, "%c", temp + 3); printf("/n");
print(4, "%c", all + 5); printf(" = ");print(4, "%c", temp + 5); printf("/n");
print(4, "%c", all + 9); printf(" = ");print(4, "%c", temp + 9); printf("/n");
printf("%s = %s/n", all + 13, temp + 13);
return 0;
}
}
}
return 0;
}
例如对一开始的例子运行,输入:
BID
DJ
ABHD
HJID
HDAID
程序就会输出结果:
BID = 475
DJ = 53
ABHD = 1425
HJID = 2375