「C-assign-2009-03-13」の編集履歴(バックアップ)一覧はこちら

C-assign-2009-03-13」(2009/02/28 (土) 20:19:35) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

*問1 4つの4、4に対して様々な演算子を働かせて数を作る。 結果的にこれで済むことが判明した。どうせ最適化される。 #codehighlight(c){{ #include <stdio.h> #include <ctype.h> #include <math.h> #include <string.h> #define LENGTH_OF_ARRAY(x) (sizeof(x)/sizeof((x)[0])) #define PUT_ERROR(x) fprintf(stderr, (x)) #define ROUND(x) (floor((x) + 0.5)) #define IPOW0(x) 1 #define IPOW1(x) (x) #define IPOW2(x) ((x)*(x)) #define IPOW3(x) ((x)*(x)*(x)) #define IPOW4(x) ((x)*(x)*(x)*(x)) #define IPOW5(x) ((x)*(x)*(x)*(x)*(x)) #define IPOW6(x) ((x)*(x)*(x)*(x)*(x)*(x)) #define IPOW7(x) ((x)*(x)*(x)*(x)*(x)*(x)*(x)) //#define IPOW7(x) ((x)*(x)*(x)*(x)*(x)*(x)*(x)*(x)) #define STACK_SIZE 64 #define STR_LENGTH 128 double factorial(double x); int isBinOp(char c); void d_init(void); double calc(char *const str); void s_init(void); void s_push(char *const str); char* s_pop(); void toInfix(char *const exp, char *const target); int makeRPNExp(char *const exp); void search(char result[][STR_LENGTH]); const double ERROR_NUM = 1000000.0; const char* ERROR_OVFLOW = "STACK overflow.\n"; const char* ERROR_NOBODY = "Nakani daremo imasen yo.\n"; const char* STR_NODATA = "Data Empty"; const int SEARCH_RANGE = 31; //114; const char bin_op[] = "*/+-"; const char uni_op[] = "_sm!.n"; //除く // m:minus, s:sqrt // 4.4や4.44 can't be in Z // .4~==4/9 so n:devide with 9 //const char* const EXP_TYPE[] = { // "4 4 %c 4 %c 4 %c " // ,"4 4 %c 4 4 %c %c " // ,"4 4 4 %c %c 4 %c " // ,"4 4 4 %c 4 %c %c " // ,"4 4 4 4 %c %c %c " //}; const char* const EXP_TYPE[] = { "4 4 %c 4 %c 4 %c " ,"4 4 %c 4 4 %c %c " ,"4 4 4 %c %c 4 %c " ,"4 4 4 %c 4 %c %c " ,"4 4 4 4 %c %c %c " }; int ipower(int x, int p) { int a=1; for(; p; --p) a *= x; return a; } double factorial(double x) { int i, ix; double result = 1.0; ix = (int)ROUND(x); for(i=1; i<=ix; ++i) result *= i; return result; } int isBinOp(char c) { char const *ptr; for(ptr = bin_op; *ptr; ++ptr) if(*ptr==c) return 1; return 0; } //this should be template typedef struct DOUBLE_STACK{ double stack[STACK_SIZE]; unsigned int index; } d_stack; d_stack ds; #define D_INIT ds.index = 0 void d_push(double x) { /*if(ds.index < STACK_SIZE)*/ ds.stack[(ds.index)++] = x; /*else PUT_ERROR(ERROR_OVFLOW);*/ } //#define d_push(x) (ds.stack[(ds.index)++] = (x)) //#define D_POP ((ds.index) ? ds.stack[--(ds.index)] : (PUT_ERROR(ERROR_NOBODY),ERROR_NUM)) double d_pop(void) { return (ds.stack[--(ds.index)]); } double calc(char *const str) { char *c; double op; D_INIT; for(c = str; *c; ++c) { if(isdigit(*c)) d_push((double)(*c-'0')); else{ op = d_pop(); switch(*c) { case '+': d_push(d_pop() + op); break; case '-': d_push(d_pop() - op); break; case '*': d_push(d_pop() * op); break; case '/': if(op == 0.0) return ERROR_NUM; d_push(d_pop() / op); break; case 'm': d_push(-op); break; case 's': if(op==4.0) d_push(2.0); else if(op > 0.0) d_push(sqrt(op)); else return ERROR_NUM; break; case '!': if(op==4.0) d_push(24.0); else if(op>0.0 && ROUND(op) == op) d_push(factorial(op)); else return ERROR_NUM; break; case 'n': if((int)ROUND(op) == op && op==4) d_push(op/9.0); else return ERROR_NUM; break; case '.': if((int)ROUND(op) == 4) d_push(op/10.0); else return ERROR_NUM; break; default: d_push(op); break; } } } return d_pop(); } typedef struct STR_STACK{ char stack[STACK_SIZE][STR_LENGTH]; unsigned int index; } s_stack; s_stack ss; void s_init(void) { ss.index = 0; } void s_push(char *const str) { if(ss.index < STACK_SIZE) sprintf(ss.stack[(ss.index)++], "%s", str); else PUT_ERROR(ERROR_OVFLOW); } char* s_pop() { return (ss.index) ? ss.stack[--(ss.index)] : (PUT_ERROR(ERROR_NOBODY), (char *)NULL); } void toInfix(char *const exp, char *const target) { char temp[STR_LENGTH]; char *c; // pointer for char[] exp s_init(); for(c = exp; *c; ++c) { if(isdigit(*c)) sprintf(temp, "%c", *c); else if(isBinOp(*c)) sprintf(temp, "(%s %c %s)", s_pop(), *c, s_pop()); else if(*c == '.') sprintf(temp, "%c%s", *c, s_pop()); else if(*c == 'm') sprintf(temp, "-%s", s_pop()); else if(*c == 's') sprintf(temp, "sqrt(%s)", s_pop()); else if(*c == '!') sprintf(temp, "%s%c", s_pop(), *c); else if(*c == 'n') sprintf(temp, ".%s~", s_pop()); else strcpy(temp, s_pop()); s_push(temp); } strcpy(target, temp); } int makeRPNExp(char *const exp) { #define LNB (LENGTH_OF_ARRAY(bin_op)-1) static int idx_bin, idx_uni, idx_exp; // init with zero const static int ln_b = LNB; const static int ln_max = (LNB)*(LNB)*(LNB) - 1; #undef LNB #define LNU (LENGTH_OF_ARRAY(uni_op)-1) //there are 3 bin-ops in exp is the reason why LNB is powered with 3 //int i; //const static int ln_exp = strlen(EXP_TYPE[0])/2; if(idx_exp==LENGTH_OF_ARRAY(EXP_TYPE)) ++idx_uni, idx_exp = 0; if(idx_uni==IPOW7(LNU) - 1) ++idx_bin, idx_uni = 0; //二項演算子の代入 sprintf(exp, EXP_TYPE[idx_exp] , bin_op[idx_bin%ln_b], bin_op[(idx_bin / ln_b) % ln_b], bin_op[(idx_bin / ln_b / ln_b) % ln_b]); //単項演算子の挿入 #define INPUT_SINGLE(x) (exp[(x)*2+1] = uni_op[(idx_bin / IPOW##x(LNU)) % LNU]) INPUT_SINGLE(0); INPUT_SINGLE(1); INPUT_SINGLE(2); INPUT_SINGLE(3); INPUT_SINGLE(4); INPUT_SINGLE(5); INPUT_SINGLE(6); #undef INPUT_SINGLE ++idx_exp; return (idx_bin == ln_max && idx_uni==IPOW7(LNU) - 1 && idx_exp==LENGTH_OF_ARRAY(EXP_TYPE)) ? 0 : 1; #undef LNU } void search(char result[][STR_LENGTH]) { char rpn_exp[STR_LENGTH]; // Reverse Polish Notation Expression char inf_exp[STR_LENGTH]; // Infix notation Expression double answer; int i_answer; int fill_counter=SEARCH_RANGE; while(makeRPNExp(rpn_exp) && fill_counter) { answer = calc(rpn_exp); i_answer = (int)ROUND(answer); if(answer == i_answer && 0 <= i_answer && i_answer < SEARCH_RANGE && result[i_answer][0] == STR_NODATA[0] ){ toInfix(rpn_exp, inf_exp); strcpy(result[i_answer], inf_exp); --fill_counter; printf("%d:%s,%s\n", i_answer, rpn_exp, inf_exp); } } } void test(char *a) { char b[256]; double x; x = calc(a); toInfix(a, b); printf("RPN:%s\n" "INF:%s\n" "RESULT:%f\n", a, b, x); } int main(int argc, char* argv[]) { #if 0 test("44*4+"); test("44+4/"); test("11-4+"); test("44/4*"); test("4!"); test("4m"); test("4ms"); test("4s"); test("4."); test("4n"); printf("4! = %f", factorial(4.0)); #endif #if 0 test("4!4_4s4_-_*_/_"); test("4s4!4!/_-_4_-_"); test("4_4!4s*_-_4_/_"); test("4!4s4_-_4_/_*_"); test("4!4s-m4_4_/_+_"); test("4s4_4!4_/_*_-_"); test("4!4s4s4_-_/_/_"); #endif #if 1 char result[SEARCH_RANGE][STR_LENGTH]; int i; for(i=0; i<SEARCH_RANGE; ++i) strcpy(result[i], STR_NODATA); search(result); for(i=0; i<SEARCH_RANGE; ++i) printf("%2d : %s\n",i, result[i]); #endif return 0; } }}
*問1 4つの4、4に対して様々な演算子を働かせて数を作る。 計算を手抜きした版を上に、実直な版を下に添える。 #codehighlight(c){{ #include <stdio.h> #include <ctype.h> #include <math.h> #include <string.h> #define LENGTH_OF_ARRAY(x) (sizeof(x)/sizeof((x)[0])) #define PUT_ERROR(x) fprintf(stderr, (x)) #define ROUND(x) (floor((x) + 0.5)) #define IPOW0(x) 1 #define IPOW1(x) (x) #define IPOW2(x) ((x)*(x)) #define IPOW3(x) ((x)*(x)*(x)) #define IPOW4(x) ((x)*(x)*(x)*(x)) #define IPOW5(x) ((x)*(x)*(x)*(x)*(x)) #define IPOW6(x) ((x)*(x)*(x)*(x)*(x)*(x)) #define IPOW7(x) ((x)*(x)*(x)*(x)*(x)*(x)*(x)) //#define IPOW7(x) ((x)*(x)*(x)*(x)*(x)*(x)*(x)*(x)) #define STACK_SIZE 64 #define STR_LENGTH 128 double factorial(double x); int isBinOp(char c); void d_init(void); double calc(char *const str); void s_init(void); void s_push(char *const str); char* s_pop(); void toInfix(char *const exp, char *const target); int makeRPNExp(char *const exp); void search(char result[][STR_LENGTH]); const double ERROR_NUM = 1000000.0; const char* ERROR_OVFLOW = "STACK overflow.\n"; const char* ERROR_NOBODY = "Nakani daremo imasen yo.\n"; const char* STR_NODATA = "Data Empty"; const int SEARCH_RANGE = 114; const char numbers[] = "4SM?.N"; const char bin_op[] = "*/+-"; const char uni_op[] = "_s"; // m!除く // m:minus, s:sqrt // 4.4や4.44 can't be in Z // .4~==4/9 so n:devide with 9 struct EXP_BASE { int bin_position[3]; int num_position[4]; int uni_position[2]; }; const char * EXP_BASE_STRING[] ={ "44$@4$@4$", "444$@$@4$", "444$@4$@$", "4444$@$@$", "44$@44$@$", }; struct EXP_BASE exp_base[LENGTH_OF_ARRAY(EXP_BASE_STRING)]; void exp_base_init(const char *pstr[], int length, struct EXP_BASE *target) { int i, j; int c_n, c_u, c_b; const char *c; for(i = 0; i < length; ++i) { for(c = pstr[i], j = c_n = c_u = c_b = 0; c[j]; ++j) { switch(c[j]) { case '4': target[i].num_position[c_n++] = j; break; case '@': target[i].uni_position[c_u++] = j; break; case '$': target[i].bin_position[c_b++] = j; break; default: break; } } } } double factorial(double x) { int i, ix; double result = 1.0; ix = (int)ROUND(x); for(i=1; i<=ix; ++i) result *= i; return result; } int isBinOp(char c) { char const *ptr; for(ptr = bin_op; *ptr; ++ptr) if(*ptr==c) return 1; return 0; } //this should be template typedef struct DOUBLE_STACK{ double stack[STACK_SIZE]; unsigned int index; } d_stack; d_stack ds; #define D_INIT ds.index = 0 void d_push(double x) { /*if(ds.index < STACK_SIZE)*/ ds.stack[(ds.index)++] = x; /*else PUT_ERROR(ERROR_OVFLOW);*/ } //#define d_push(x) (ds.stack[(ds.index)++] = (x)) //#define D_POP ((ds.index) ? ds.stack[--(ds.index)] : (PUT_ERROR(ERROR_NOBODY),ERROR_NUM)) double d_pop(void) { return (ds.stack[--(ds.index)]); } double calc(char *const str) { char *c; double op; D_INIT; for(c = str; *c; ++c) { if(isdigit(*c)) d_push(4.0); else{ switch(*c) { case 'M': d_push(-4.0); /*dump*/ break; case 'S': d_push(2.0); /*dump*/ break; case '?': d_push(24.0); /*dump*/ break; case 'N': d_push(4.0/9.0); break; case '.': d_push(0.4); break; case 'm': d_push(-d_pop()); break; case 's': op = d_pop(); if( op < 0.0) return ERROR_NUM; else d_push(sqrt(op)); break; case '!': op = d_pop(); if(op != ROUND(op) || op < 0.0) return ERROR_NUM; else d_push(factorial(op)); break; case '+': d_push(d_pop() + d_pop()); break; case '-': op = d_pop(); d_push(d_pop() - op); break; case '*': d_push(d_pop() * d_pop()); break; case '/': op = d_pop(); if(op == 0.0) return ERROR_NUM; d_push(d_pop() / op); break; default: break; } } } return d_pop(); } typedef struct STR_STACK{ char stack[STACK_SIZE][STR_LENGTH]; unsigned int index; } s_stack; s_stack ss; void s_init(void) { ss.index = 0; } void s_push(char *const str) { if(ss.index < STACK_SIZE) sprintf(ss.stack[(ss.index)++], "%s", str); else PUT_ERROR(ERROR_OVFLOW); } char* s_pop() { return (ss.index) ? ss.stack[--(ss.index)] : (PUT_ERROR(ERROR_NOBODY), (char *)NULL); } void toInfix(char *const exp, char *const target) { char temp[STR_LENGTH]; char *c; // pointer for char[] exp s_init(); for(c = exp; *c; ++c) { if(isdigit(*c)) sprintf(temp, "%c", *c); else { switch(*c) { case '.': sprintf(temp, ".4"); break; case 'N': sprintf(temp, ".4~"); break; case 'M': sprintf(temp, "-4"); break; case 'S': sprintf(temp, "sqrt(4)"); break; case '?': sprintf(temp, "4!"); break; case 'm': sprintf(temp, "-(%s)", s_pop()); break; case 's': sprintf(temp, "sqrt(%s)", s_pop()); break; case '!': sprintf(temp, "(%s)%c", s_pop(), *c); break; default: if(isBinOp(*c)) sprintf(temp, "(%s %c %s)", s_pop(), *c, s_pop()); else strcpy(temp, s_pop()); break; } } s_push(temp); } strcpy(target, temp); } int makeRPNExp(char *const exp) { #define LNB (LENGTH_OF_ARRAY(bin_op)-1) static int idx_bin, idx_num, idx_exp; // init with zero static int idx_uni; const static int ln_b = LNB; const static int ln_max = IPOW3(LNB) - 1; //there are 3 bin-ops in exp is the reason why LNB is powered with 3 #undef LNB #define LNU (LENGTH_OF_ARRAY(uni_op) - 1) #define LNN (LENGTH_OF_ARRAY(numbers) - 1) if(idx_exp==LENGTH_OF_ARRAY(exp_base)) ++idx_num, idx_exp = 0; if(idx_num==IPOW4(LNN) - 1) ++idx_uni, idx_num = 0; if(idx_uni==IPOW2(LNU) - 1) ++idx_bin, idx_uni = 0; //二項演算子の代入 strcpy(exp, EXP_BASE_STRING[0]); //どうせ全ての項目を後で代入してしまうので、領域が確保されている以上strcpyが無駄。 //と思いきや\0の問題が…仕方ないのできまりきった文字列をコピペすることに //つまり、EXP_BASE::stringはお飾り #define INPUT_BINARY(x) exp[exp_base[idx_exp].bin_position[x]] = bin_op[(idx_bin / IPOW##x(ln_b)) % ln_b] INPUT_BINARY(0); INPUT_BINARY(1); INPUT_BINARY(2); #undef INPUT_BINARY //数字オブジェクトの挿入 #define INPUT_NUM(x) exp[exp_base[idx_exp].num_position[x]] = numbers[(idx_num / IPOW##x(LNN)) % LNN] INPUT_NUM(0); INPUT_NUM(1); INPUT_NUM(2); INPUT_NUM(3); #undef INPUT_NUM //単項演算子の代入 #define INPUT_SINGLE(x) exp[exp_base[idx_exp].uni_position[x]] = uni_op[(idx_uni / IPOW##x(LNU)) % LNU] //#define INPUT_SINGLE(x) exp[exp_base[idx_exp].uni_position[x]] = '_' INPUT_SINGLE(0); INPUT_SINGLE(1); #undef INPUT_SINGLE ++idx_exp; return (idx_bin == ln_max && idx_num == IPOW4(LNN) - 1 && idx_uni == IPOW2(LNU) - 1 && idx_exp==LENGTH_OF_ARRAY(exp_base)) ? 0 : 1; #undef LNU #undef LNN } void search(char result[][STR_LENGTH]) { char rpn_exp[STR_LENGTH]; // Reverse Polish Notation Expression char inf_exp[STR_LENGTH]; // Infix notation Expression double answer; int i_answer; int fill_counter=SEARCH_RANGE; while(makeRPNExp(rpn_exp) && fill_counter) { answer = calc(rpn_exp); i_answer = (int)ROUND(answer); if(answer == i_answer && 0 <= i_answer && i_answer < SEARCH_RANGE && result[i_answer][0] == STR_NODATA[0] ){ toInfix(rpn_exp, inf_exp); strcpy(result[i_answer], inf_exp); --fill_counter; printf("%d:%s,%s\n", i_answer, rpn_exp, inf_exp); } } } void test(char *a) { char b[256]; double x; x = calc(a); toInfix(a, b); printf("RPN:%s\n" "INF:%s\n" "RESULT:%f\n", a, b, x); } int main(int argc, char* argv[]) { exp_base_init(EXP_BASE_STRING, LENGTH_OF_ARRAY(EXP_BASE_STRING), exp_base); #if 0 test("44*4+"); test("44+4/"); test("11-4+"); test("44/4*"); test("4!"); test("4m"); test("4ms"); test("4s"); test("4."); test("4n"); printf("4! = %f", factorial(4.0)); #endif #if 0 test("4!4_4s4_-_*_/_"); test("4s4!4!/_-_4_-_"); test("4_4!4s*_-_4_/_"); test("4!4s4_-_4_/_*_"); test("4!4s-m4_4_/_+_"); test("4s4_4!4_/_*_-_"); test("4!4s4s4_-_/_/_"); #endif #if 1 char result[SEARCH_RANGE][STR_LENGTH]; int i; for(i=0; i<SEARCH_RANGE; ++i) strcpy(result[i], STR_NODATA); search(result); for(i=0; i<SEARCH_RANGE; ++i) printf("%2d : %s\n",i, result[i]); #endif return 0; } }} #codehighlight(c){{ #include <stdio.h> #include <ctype.h> #include <math.h> #include <string.h> #define LENGTH_OF_ARRAY(x) (sizeof(x)/sizeof((x)[0])) #define PUT_ERROR(x) fprintf(stderr, (x)) #define ROUND(x) (floor((x) + 0.5)) #define IPOW0(x) 1 #define IPOW1(x) (x) #define IPOW2(x) ((x)*(x)) #define IPOW3(x) ((x)*(x)*(x)) #define IPOW4(x) ((x)*(x)*(x)*(x)) #define IPOW5(x) ((x)*(x)*(x)*(x)*(x)) #define IPOW6(x) ((x)*(x)*(x)*(x)*(x)*(x)) #define IPOW7(x) ((x)*(x)*(x)*(x)*(x)*(x)*(x)) //#define IPOW7(x) ((x)*(x)*(x)*(x)*(x)*(x)*(x)*(x)) #define STACK_SIZE 64 #define STR_LENGTH 128 double factorial(double x); int isBinOp(char c); void d_init(void); double calc(char *const str); void s_init(void); void s_push(char *const str); char* s_pop(); void toInfix(char *const exp, char *const target); int makeRPNExp(char *const exp); void search(char result[][STR_LENGTH]); const double ERROR_NUM = 1000000.0; const char* ERROR_OVFLOW = "STACK overflow.\n"; const char* ERROR_NOBODY = "Nakani daremo imasen yo.\n"; const char* STR_NODATA = "Data Empty"; const int SEARCH_RANGE = 31; //114; const char bin_op[] = "*/+-"; const char uni_op[] = "_sm!.n"; //除く // m:minus, s:sqrt // 4.4や4.44 can't be in Z // .4~==4/9 so n:devide with 9 //const char* const EXP_TYPE[] = { // "4 4 %c 4 %c 4 %c " // ,"4 4 %c 4 4 %c %c " // ,"4 4 4 %c %c 4 %c " // ,"4 4 4 %c 4 %c %c " // ,"4 4 4 4 %c %c %c " //}; const char* const EXP_TYPE[] = { "4 4 %c 4 %c 4 %c " ,"4 4 %c 4 4 %c %c " ,"4 4 4 %c %c 4 %c " ,"4 4 4 %c 4 %c %c " ,"4 4 4 4 %c %c %c " }; int ipower(int x, int p) { int a=1; for(; p; --p) a *= x; return a; } double factorial(double x) { int i, ix; double result = 1.0; ix = (int)ROUND(x); for(i=1; i<=ix; ++i) result *= i; return result; } int isBinOp(char c) { char const *ptr; for(ptr = bin_op; *ptr; ++ptr) if(*ptr==c) return 1; return 0; } //this should be template typedef struct DOUBLE_STACK{ double stack[STACK_SIZE]; unsigned int index; } d_stack; d_stack ds; #define D_INIT ds.index = 0 void d_push(double x) { /*if(ds.index < STACK_SIZE)*/ ds.stack[(ds.index)++] = x; /*else PUT_ERROR(ERROR_OVFLOW);*/ } //#define d_push(x) (ds.stack[(ds.index)++] = (x)) //#define D_POP ((ds.index) ? ds.stack[--(ds.index)] : (PUT_ERROR(ERROR_NOBODY),ERROR_NUM)) double d_pop(void) { return (ds.stack[--(ds.index)]); } double calc(char *const str) { char *c; double op; D_INIT; for(c = str; *c; ++c) { if(isdigit(*c)) d_push((double)(*c-'0')); else{ op = d_pop(); switch(*c) { case '+': d_push(d_pop() + op); break; case '-': d_push(d_pop() - op); break; case '*': d_push(d_pop() * op); break; case '/': if(op == 0.0) return ERROR_NUM; d_push(d_pop() / op); break; case 'm': d_push(-op); break; case 's': if(op==4.0) d_push(2.0); else if(op > 0.0) d_push(sqrt(op)); else return ERROR_NUM; break; case '!': if(op==4.0) d_push(24.0); else if(op>0.0 && ROUND(op) == op) d_push(factorial(op)); else return ERROR_NUM; break; case 'n': if((int)ROUND(op) == op && op==4) d_push(op/9.0); else return ERROR_NUM; break; case '.': if((int)ROUND(op) == 4) d_push(op/10.0); else return ERROR_NUM; break; default: d_push(op); break; } } } return d_pop(); } typedef struct STR_STACK{ char stack[STACK_SIZE][STR_LENGTH]; unsigned int index; } s_stack; s_stack ss; void s_init(void) { ss.index = 0; } void s_push(char *const str) { if(ss.index < STACK_SIZE) sprintf(ss.stack[(ss.index)++], "%s", str); else PUT_ERROR(ERROR_OVFLOW); } char* s_pop() { return (ss.index) ? ss.stack[--(ss.index)] : (PUT_ERROR(ERROR_NOBODY), (char *)NULL); } void toInfix(char *const exp, char *const target) { char temp[STR_LENGTH]; char *c; // pointer for char[] exp s_init(); for(c = exp; *c; ++c) { if(isdigit(*c)) sprintf(temp, "%c", *c); else if(isBinOp(*c)) sprintf(temp, "(%s %c %s)", s_pop(), *c, s_pop()); else if(*c == '.') sprintf(temp, "%c%s", *c, s_pop()); else if(*c == 'm') sprintf(temp, "-%s", s_pop()); else if(*c == 's') sprintf(temp, "sqrt(%s)", s_pop()); else if(*c == '!') sprintf(temp, "%s%c", s_pop(), *c); else if(*c == 'n') sprintf(temp, ".%s~", s_pop()); else strcpy(temp, s_pop()); s_push(temp); } strcpy(target, temp); } int makeRPNExp(char *const exp) { #define LNB (LENGTH_OF_ARRAY(bin_op)-1) static int idx_bin, idx_uni, idx_exp; // init with zero const static int ln_b = LNB; const static int ln_max = (LNB)*(LNB)*(LNB) - 1; #undef LNB #define LNU (LENGTH_OF_ARRAY(uni_op)-1) //there are 3 bin-ops in exp is the reason why LNB is powered with 3 //int i; //const static int ln_exp = strlen(EXP_TYPE[0])/2; if(idx_exp==LENGTH_OF_ARRAY(EXP_TYPE)) ++idx_uni, idx_exp = 0; if(idx_uni==IPOW7(LNU) - 1) ++idx_bin, idx_uni = 0; //二項演算子の代入 sprintf(exp, EXP_TYPE[idx_exp] , bin_op[idx_bin%ln_b], bin_op[(idx_bin / ln_b) % ln_b], bin_op[(idx_bin / ln_b / ln_b) % ln_b]); //単項演算子の挿入 #define INPUT_SINGLE(x) (exp[(x)*2+1] = uni_op[(idx_bin / IPOW##x(LNU)) % LNU]) INPUT_SINGLE(0); INPUT_SINGLE(1); INPUT_SINGLE(2); INPUT_SINGLE(3); INPUT_SINGLE(4); INPUT_SINGLE(5); INPUT_SINGLE(6); #undef INPUT_SINGLE ++idx_exp; return (idx_bin == ln_max && idx_uni==IPOW7(LNU) - 1 && idx_exp==LENGTH_OF_ARRAY(EXP_TYPE)) ? 0 : 1; #undef LNU } void search(char result[][STR_LENGTH]) { char rpn_exp[STR_LENGTH]; // Reverse Polish Notation Expression char inf_exp[STR_LENGTH]; // Infix notation Expression double answer; int i_answer; int fill_counter=SEARCH_RANGE; while(makeRPNExp(rpn_exp) && fill_counter) { answer = calc(rpn_exp); i_answer = (int)ROUND(answer); if(answer == i_answer && 0 <= i_answer && i_answer < SEARCH_RANGE && result[i_answer][0] == STR_NODATA[0] ){ toInfix(rpn_exp, inf_exp); strcpy(result[i_answer], inf_exp); --fill_counter; printf("%d:%s,%s\n", i_answer, rpn_exp, inf_exp); } } } void test(char *a) { char b[256]; double x; x = calc(a); toInfix(a, b); printf("RPN:%s\n" "INF:%s\n" "RESULT:%f\n", a, b, x); } int main(int argc, char* argv[]) { #if 0 test("44*4+"); test("44+4/"); test("11-4+"); test("44/4*"); test("4!"); test("4m"); test("4ms"); test("4s"); test("4."); test("4n"); printf("4! = %f", factorial(4.0)); #endif #if 0 test("4!4_4s4_-_*_/_"); test("4s4!4!/_-_4_-_"); test("4_4!4s*_-_4_/_"); test("4!4s4_-_4_/_*_"); test("4!4s-m4_4_/_+_"); test("4s4_4!4_/_*_-_"); test("4!4s4s4_-_/_/_"); #endif #if 1 char result[SEARCH_RANGE][STR_LENGTH]; int i; for(i=0; i<SEARCH_RANGE; ++i) strcpy(result[i], STR_NODATA); search(result); for(i=0; i<SEARCH_RANGE; ++i) printf("%2d : %s\n",i, result[i]); #endif return 0; } }}

表示オプション

横に並べて表示:
変化行の前後のみ表示:
目安箱バナー