ライブラリ libncurses5-dev が必要
$ sudo apt-get install libncurses5-dev
だったかな
$ gcc -o fuku7 fuku7.c
$ ./fuku7
で実行。計算が長いので、qボタンかESCボタンで中断
$ ./fuku7
で中断したところから再開
実行結果は、fuku7.txtを見ること
計算が最後まで終わり、再び最初からはじめたい場合は
$ rm fuku7.try
($ rm fuku7.txt)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <termios.h> /* ライブラリ libncurses5-dev が必要 */
#include <term.h>
enum {FALSE,TRUE};
#define N 10
#define T42 111 /* 20〜111までいろいろ値を変えてみよう */
/* 中断データは終わったら削除すること */
/* qボタン、ESCボタンを押すと中断、実行ファイルで再開 */
char txt[20]="fuku7.txt"; /* セーブするファイル名 */
char ttry[20]="fuku7.try"; /* 中断データを入れるファイル名 */
/*
覆面算
参考資料:
技術評論社 奥村晴彦 著
C言語による最新アルゴリズム事典 2330円+税
P238〜239より引用・改変
*/
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard();
void close_keyboard();
int kbhit();
int readch();
int imax,jmax,solution,ch;
int word[ N][128],digit[ 256];
int word1[N][128],digit1[256];
int low[256],ok[256];
unsigned char nn[128][128];
FILE *fp;
void found();
void found1();
void try(int sum);
void input(int i,unsigned char buffer[128]);
void found(){
int i,j,c;
++solution;
if(solution>1) return;
for(i=0;i<=imax;i++){
for(j=jmax;j>=0;j--){
c=word1[i][j]=word[i][j];
if(c) digit1[c]=digit[c];
else digit1[c]=' ';
}
}
}
void found1(){
int i,j,c;
fp=fopen(txt,"a");
if(fp==NULL){
printf("fail\n");
exit(1);
}
printf("\33[2J\33[0;0H");
printf("\n 唯一解 \n");
fprintf(fp,"\n 唯一解 \n");
for(i=0;i<=imax;i++){
for(j=jmax;j>=0;j--){
c=word1[i][j];
if(c){
printf("%c",c);
fprintf(fp,"%c",c);
}
else{
printf(" ");
fprintf(fp," ");
}
}
printf("\n");
fprintf(fp,"\n");
}
printf("\n");
fprintf(fp,"\n");
for(i=0;i<=imax;i++){
for(j=jmax;j>=0;j--){
c=word1[i][j];
if(c){
printf("%d",digit1[c]);
fprintf(fp,"%d",digit1[c]);
}
else{
printf(" ");
fprintf(fp," ");
}
}
printf("\n");
fprintf(fp,"\n");
}
printf("\n");
fprintf(fp,"\n");
fclose(fp);
}
void try(int sum){
static int i=0,j=0,carry;
int c,d;
c=word[i][j];
if(i<imax){
i++;
if((d=digit[c])<0){
for(d=low[c];d<=9;d++){
if(ok[d]){
digit[c]=d; ok[d]=FALSE;
try(sum+d); ok[d]=TRUE;
}
}
digit[c]=-1;
}
else try(sum+d);
i--;
}
else{
j++; i=0; d=sum%10; carry=sum/10;
if(digit[c]==d){
if(j<=jmax) try(carry);
else if(carry==0) found();
}
else if(digit[c]<0&&ok[d]&&d>=low[c]){
digit[c]=d; ok[d]=FALSE;
if(j<=jmax) try(carry);
else if(carry==0) found();
digit[c]=-1; ok[d]=TRUE;
}
j--; i=imax;
}
}
main(){
int i,j,k,c,p,q,r,s,t,u,z;
static unsigned char buffer[128];
strcpy(nn[0],"zero");
strcpy(nn[1],"one");
strcpy(nn[2],"two");
strcpy(nn[3],"three");
strcpy(nn[4],"four");
strcpy(nn[5],"five");
strcpy(nn[6],"six");
strcpy(nn[7],"seven");
strcpy(nn[8],"eight");
strcpy(nn[9],"nine");
strcpy(nn[10],"ten");
strcpy(nn[11],"eleven");
strcpy(nn[12],"twelve");
strcpy(nn[13],"thirteen");
strcpy(nn[14],"fourteen");
strcpy(nn[15],"fifteen");
strcpy(nn[16],"sixteen");
strcpy(nn[17],"seventeen");
strcpy(nn[18],"eighteen");
strcpy(nn[19],"nineteen");
strcpy(nn[20],"twenty");
strcpy(nn[21],"twentyone");
strcpy(nn[22],"twentytwo");
strcpy(nn[23],"twentythree");
strcpy(nn[24],"twentyfour");
strcpy(nn[25],"twentyfive");
strcpy(nn[26],"twentysix");
strcpy(nn[27],"twentyseven");
strcpy(nn[28],"twentyeight");
strcpy(nn[29],"twentynine");
strcpy(nn[30],"thirty");
strcpy(nn[31],"thirtyone");
strcpy(nn[32],"thirtytwo");
strcpy(nn[33],"thirtythree");
strcpy(nn[34],"thirtyfour");
strcpy(nn[35],"thirtyfive");
strcpy(nn[36],"thirtysix");
strcpy(nn[37],"thirtyseven");
strcpy(nn[38],"thirtyeight");
strcpy(nn[39],"thirtynine");
strcpy(nn[40],"forty");
strcpy(nn[41],"fortyone");
strcpy(nn[42],"fortytwo");
strcpy(nn[43],"fortythree");
strcpy(nn[44],"fortyfour");
strcpy(nn[45],"fortyfive");
strcpy(nn[46],"fortysix");
strcpy(nn[47],"fortyseven");
strcpy(nn[48],"fortyeight");
strcpy(nn[49],"fortynine");
strcpy(nn[50],"fifty");
strcpy(nn[51],"fiftyone");
strcpy(nn[52],"fiftytwo");
strcpy(nn[53],"fiftythree");
strcpy(nn[54],"fiftyfour");
strcpy(nn[55],"fiftyfive");
strcpy(nn[56],"fiftysix");
strcpy(nn[57],"fiftyseven");
strcpy(nn[58],"fiftyeight");
strcpy(nn[59],"fiftynine");
strcpy(nn[60],"sixty");
strcpy(nn[61],"sixtyone");
strcpy(nn[62],"sixtytwo");
strcpy(nn[63],"sixtythree");
strcpy(nn[64],"sixtyfour");
strcpy(nn[65],"sixtyfive");
strcpy(nn[66],"sixtysix");
strcpy(nn[67],"sixtyseven");
strcpy(nn[68],"sixtyeight");
strcpy(nn[69],"sixtynine");
strcpy(nn[70],"seventy");
strcpy(nn[71],"seventyone");
strcpy(nn[72],"seventytwo");
strcpy(nn[73],"seventythree");
strcpy(nn[74],"seventyfour");
strcpy(nn[75],"seventyfive");
strcpy(nn[76],"seventysix");
strcpy(nn[77],"seventyseven");
strcpy(nn[78],"seventyeight");
strcpy(nn[79],"seventynine");
strcpy(nn[80],"eighty");
strcpy(nn[81],"eightyone");
strcpy(nn[82],"eightytwo");
strcpy(nn[83],"eightythree");
strcpy(nn[84],"eightyfour");
strcpy(nn[85],"eightyfive");
strcpy(nn[86],"eightysix");
strcpy(nn[87],"eightyseven");
strcpy(nn[88],"eightyeight");
strcpy(nn[89],"eightynine");
strcpy(nn[90],"ninety");
strcpy(nn[91],"ninetyone");
strcpy(nn[92],"ninetytwo");
strcpy(nn[93],"ninetythree");
strcpy(nn[94],"ninetyfour");
strcpy(nn[95],"ninetyfive");
strcpy(nn[96],"ninetysix");
strcpy(nn[97],"ninetyseven");
strcpy(nn[98],"ninetyeight");
strcpy(nn[99],"ninetynine");
strcpy(nn[100],"onehundred");
strcpy(nn[101],"onehundredandone");
strcpy(nn[102],"onehundredandtwo");
strcpy(nn[103],"onehundredandthree");
strcpy(nn[104],"onehundredandfour");
strcpy(nn[105],"onehundredandfive");
strcpy(nn[106],"onehundredandsix");
strcpy(nn[107],"onehundredandseven");
strcpy(nn[108],"onehundredandeight");
strcpy(nn[109],"onehundredandnine");
strcpy(nn[110],"onehundredandten");
strcpy(nn[111],"onehundredandeleven");
init_keyboard();
printf("\33[2J\33[0;0H");
jmax=0;
imax=4;
printf("行数は?: %d",imax); imax--;
fp=fopen(ttry,"r");
if(fp==NULL){
printf("中断データはありません\n");
fp=fopen(txt,"a");
if(fp==NULL){
printf("fail\n");
exit(1);
}
/*fprintf(fp,"中断データはありません\n");*/
fclose(fp);
}
else{
fscanf(fp,"%d,%d,%d",&p,&q,&r);
r++;
fclose(fp);
fp=fopen(txt,"a");
if(fp==NULL){
printf("fail\n");
exit(1);
}
printf( "p=%d q=%d r=%d から再開します\n",p,q,r);
fprintf(fp,"p=%d q=%d r=%d から再開します\n",p,q,r);
fclose(fp);
goto SAIKAI;
}
jmax=0;
imax=4;
printf("行数は?: %d",imax); imax--;
for(p=0;p<=T42;p++){
for(q=p;q<=T42;q++){
for(r=q;r<=T42;r++){
SAIKAI:
if(p+q+r<=111){
z++;
if(z%256==0) printf("\33[0;0Hp=%d q=%d r=%d \n",p,q,r);
for(j=0;j<N;j++)
for(i=0;i<128;i++) word[j][i]=0;
for(i=0;i<256;i++) digit[i]=0;
for(i=0;i<256;i++) low[i]=0;
for(i=0;i<256;i++) ok[i]=0;
input(0,nn[p]);
input(1,nn[q]);
input(2,nn[r]);
input(3,nn[p+q+r]);
for(i=0;i<=9;i++) ok[i]=TRUE;
solution=0; try(0);
if(solution==1) found1();
if(kbhit()){
ch = readch();
if(ch=='q'||ch==0x1b){
fp=fopen(ttry,"w");
if(fp==NULL){
printf("fail\n");
exit(1);
}
printf( "p=%d q=%d r=%d で中断します\n",p,q,r);
fprintf(fp,"%d,%d,%d\n",p,q,r);
fclose(fp);
close_keyboard();
exit(0);
}
}
}
}}
}
fp=fopen(ttry,"w");
if(fp==NULL){
printf("fail\n");
exit(1);
}
printf( "p=%d q=%d r=%d で終了しました\n",p,q,r);
fprintf(fp,"%d,%d,%d\n",p,q,r);
fclose(fp);
close_keyboard();
}
void input(int i,unsigned char buffer[128]){
int k,j,c;
low[buffer[0]]=1;
k=strlen((char *)buffer)-1;
if(k>jmax) jmax=k;
for(j=0;j<=k;j++){
c=word[i][j]=buffer[k-j];
if(isalpha(c)) digit[c]=-1;
else if(isdigit(c)) digit[c]=c-'0';
}
}
void init_keyboard()
{
tcgetattr(0, &initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 0;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &initial_settings);
}
void close_keyboard()
{
tcsetattr(0, TCSANOW, &initial_settings);
}
int kbhit()
{
char ch;
int nread;
if(peek_character != -1)
return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0, &ch, 1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1) {
peek_character = ch;
return 1;
}
return 0;
}
int readch()
{
char ch;
if(peek_character != -1) {
ch = peek_character;
peek_character = -1;
return ch;
}
read(0, &ch, 1);
return ch;
}