数学パズル問2
「プログラマ脳を鍛える数学パズル」の問2をまたまたC言語で実装。
答えを見たところ、C言語では逆ポーランド記法で実装すると書いてあったが、evalと同じく
ふつうpopenとかコンソールでやる方が簡単だと思う・・・。
本には逆ポーランド記法での解法について「初心者向けの練習問題でよく見かける」とあるが、
逆ポーランド記法を実装し始めるのは初心者じゃない気が・・・。K&Rの影響?
ネストが深いが、まあ、一回だけの実装なので勘弁。
問21000〜9999の数値で各桁の間に四則演算子を入れ計算した結果、
元の数の桁を逆から並べた数字と同じになるものは何か。
演算子を入れない場所があっても構わないが、最低でも1つは入れるものとする。
解答:5931(5 * 9 * 31 = 1395)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NUM_LEN 20 int judge_palindrome(int,int); int main(int argc,char *argv[]){ FILE *fp; char buf2[256]; char ope[] = {'+', '*', '-', '/', ' '}; int in_num; for(int i = 1000; i < 9999; i++){ printf("%d\n",i); char c_tmp[5] = {'\0'}; char cmd[256] = {'\0'}; char buf[256]; sprintf(c_tmp, "%d", i); /*全演算子を試行*/ for(int j = 0; j < 5; j ++){ for(int k = 0; k < 5; k++){ for(int l = 0; l < 5; l++){ /*1つ以上の演算子を含むので、全て空白の時は除外*/ if( j == 4 && k == 4 && l == 4){ } else{ char *find_pos; /*コマンド生成*/ sprintf(cmd, "echo \"%c %c %c %c %c %c %c\" | bc",c_tmp[0],ope[j],c_tmp[1],ope[k],c_tmp[2],ope[l],c_tmp[3]); /*ゼロの除算を除く*/ if (strstr(cmd, "/ 0") == NULL){ /*空白を詰めて数値にする*/ find_pos = strstr(cmd, " "); if( find_pos == NULL){ } else { char tmp[256]; char *p; strcpy(buf,cmd); while ((p = strstr(buf, " ")) != NULL) { *p = '\0'; p += strlen(" "); strcpy(tmp, p); strcat(buf, ""); strcat(buf, tmp); } } char *cmdline = buf; /*コマンド実行*/ if((fp = popen(cmdline, "r")) == NULL){ perror("error"); exit(1); } fgets(buf2, sizeof(buf2), fp); in_num = atoi(buf2); if(in_num == 0){ } else{ /*回文判定*/ if(judge_palindrome(in_num,i) == 0){ printf("resutl : %d\n", i); exit(0); } } pclose(fp); } } } } } } return 0; } /*回文判定*/ int judge_palindrome(int in_num, int org_in_num){ int num_len = 0; int tmp_len = in_num; int flag = 0; char rev_num[MAX_NUM_LEN] = {'\0'}; char org_num[MAX_NUM_LEN] = {'\0'}; int count = 0; sprintf(org_num, "%d", in_num); while(tmp_len != 0){ tmp_len = tmp_len / 10; num_len++; } while(in_num != 0){ int tmp; char c_tmp[MAX_NUM_LEN] = {'\0'}; count++; tmp = in_num % 10; in_num = in_num / 10; sprintf(c_tmp, "%d", tmp); strcat(rev_num,c_tmp); } sprintf(org_num, "%d", org_in_num); flag = strcmp(rev_num,org_num); return flag; }