• ベストアンサー

小町算

#include<stdio.h> #define KETA 9 #define SIN_SU 3 #define GOOD 100 int next(int symbol[]); void int_set(int symbol[]); void myprint(int symbol[]); int check(int symbol[]); main() { int symbol[KETA]; int_set(symbol); do{ if(check(symbol)) myprint(symbol); }while(next(symbol)); } int next(int symbol[]) { int i=KETA; do { if(++symbol[i]<SIN_SU) return symbol; symbol[i]=0; }while(i--); return 0; } void int_set(int symbol[]) { int i; symbol[0]=1; for(i=1;i<KETA;i++) symbol[i]=0; } void myprint(int symbol[]) { int i; for(i=0;i<KETA;i++) { if(symbol[0]==1) ; else if(symbol[i]==1) printf("+"); else if(symbol[i]==2) printf("-"); printf("%d",i+1); } } int cheak(int symbol[]) { int num=0; int result=0; int i; for(i=0;i<KETA;i++) { if(symbol[i]==0) num=10*num+(i+1); else{ if(symbol[i]==2) { result+=-1*num; num=i+1; } else { result+=symbol[i]*num; num=i+1; } } } if(result==GOOD) return 1; else return 0; } このプログラムの関数nextのところのreturn symbolが 思うとおりに動きません。どなたか教えていただけないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

No.2 です。 > いろいろと修正しましてコンパイルできるようになったのですが答えが3つずつ出てしまいます。原因がわかりません・・。どうしてでしょうか? int* next(int symbol[]) { int i=KETA - 1; が正解です。 ここ以外のところでは、symbol[0] から symbol[KETA - 1] までを使っていますよね? symbol[KETA] は、そのさらにひとつ下の桁です。 なので、この桁があふれるまで3回分かかるのです。 int symbol[KETA] で確保して、symbol[KETA] にアクセスすると、良くないことがおきそうですが、たまたま運良く(運悪く)実害が見えなかったのでしょう。

h9well3
質問者

お礼

いろいろとありがとうございます!無事コンパイルできました!

その他の回答 (4)

noname#30727
noname#30727
回答No.4

#3です。 訂正します。 >1~9の数字を for (i = 1; i <= KETA; i++) などのループで処理する事を考えると、symbol[0]を使用しない方が自然な形になるかもしれません。 これは無かった事にして下さい(笑

noname#30727
noname#30727
回答No.3

小町算は123456789の数字の間に空白または演算記号を入れるって事ですよね? そうすると、int symbol[KETA]; は int symbol[KETA-1]; と宣言するか、symbol[0]またはsymbol[KETA-1]は使用しない事になると思います。 1~9の数字を for (i = 1; i <= KETA; i++) などのループで処理する事を考えると、symbol[0]を使用しない方が自然な形になるかもしれません。 問題のnext関数ですがsymbolを返す必要はありません。symbolに1を加える典型的な方法を記しておきます。(要素数はKETAとしています) int next(int symbol[]) { int a = 1, i, n; for (i = 0; i < KETA; i++) { n = symbol[i] + a; symbol[i] = n % SIN_SU; a = n / SIN_SU; } return !a; }

回答No.2

int next(int symbol[]) { int i; symbol[KEKA]++; for (i = KETA; (i >= 2) && (symbol[i] >= SIN_SU); i--) { symbol[i] = 0; symbol[i - 1] ++; } if (symbol[0] != 1) return 0; return 1; } こんな感じでしょうか。(チェックしていません) 気持ちとしては、 ・9個の配列に なにもない、+、-をそれぞれ配置する。 ・この配列を更新するのが楽なように、それじれ、0, 1, 2にした。 ・100100100 なら、1+234+567 (でも、これだと、9桁めが0だと問題ですね) ・問題の next は、今の符号配置から次の符号配置を計算する。これを、3進数の多桁演算でやってみた。 ・多桁演算をして、桁がオーバーフローしなかったら配列を返す という感じですね。 まず、配列は、特殊な事情による、実質参照渡しになります。このため、関数側でいじった内容はそのまま帰ります。従って明示的に配列を返す必要はありません。(そもそも、next が返すのは、int のはず) また、もとの書き方では、「1桁でもOKの桁があれば直ちに終了」しますし、さらに、繰り上がりもしていません。 (その桁が3に達したら、その桁を0にしているだけで、次の桁をインクリメントしていない) というところでしょうか。 あと、「思うとおりに動きません」というのは、通常実行してみたら、動きがおかしいというレベルで使います。 もとのソースは、多分、コンパイルが通っていませんよね。 あと、特に check() の計算は面倒そうですね。

h9well3
質問者

補足

いろいろと修正しましてコンパイルできるようになったのですが答えが3つずつ出てしまいます。原因がわかりません・・。どうしてでしょうか? #include<stdio.h> #define KETA 9 #define SIN_SU 3 #define GOOD 100 #define TRUE 1 #define FALSE 0 int* next(int symbol[]); void int_set(int symbol[]); void myprint(int symbol[]); int check(int symbol[]); main() { int symbol[KETA]; int_set(symbol); do{ if(check(symbol)) myprint(symbol); }while(next(symbol)); } int* next(int symbol[]) { int i=KETA; do { if(++symbol[i]<SIN_SU) return symbol; symbol[i]=0; }while(i--); return 0; } void int_set(int symbol[]) { int i; symbol[0]=1; for(i=1;i<KETA;i++) symbol[i]=0; } void myprint(int symbol[]) { int i; for(i=0;i<KETA;i++) { if(symbol[i]==1) if(i==0); else printf("+"); else if(symbol[i]==2) printf("-"); printf("%d",i+1); } printf(" = %d\n",GOOD); } int check(int symbol[]) { int num=0; int result=0; int tmp=0; int i; for(i=0;i<KETA;i++) { if(symbol[i]==0) num=10*num+(i+1); else{ if(tmp==2) { result+=-1*num; tmp=symbol[i]; num=i+1; } else { result+=tmp*num; tmp=symbol[i]; num=i+1; } } } if(tmp==2) result +=-1*num; else result += tmp*num; if(result==GOOD) { return TRUE; } else return FALSE;

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

next関数の返り値を while(next(symbol)) と使っている所を見ると、0か非0(と言うか、TRUEかFALSE)を返すべき関数として作ったのですよね? なのに、何故 return symbol; などと「配列へのポインタ」を返そうとするのか、理解に苦しみます。 (ぶっちゃけ、何がしたいのか、理解に苦しみます) 「呼び出し元での関数の呼び方」と「関数が返すべき返り値」の整合性が取れておらず、全体の設計が出来ていないと思われます。 フローチャート図の書き方など、プログラムの設計方法の基礎から習得し直すべきです。

h9well3
質問者

お礼

返信ありがとうございます!まだ勉強をはじめたばかりで見苦しくて申し訳ありません。 next関数は100000000~222222222までを調べる関数なのです。これは1が+,2が-,0が何もないと思って内部データをあらわしています。そして最下位から1ずつインクリメントして調べようという関数のつもりで作りました。そこでreturnで配列を返すことによってこの範囲の中ならループを続けるとしたかったのです。 説明も下手で申し訳ありません。もう一度考え直してみます!ありがとうございました!

関連するQ&A

  • プログラミングCの質問です

    現在10×10の市松模様を表示させるというプログラムを作成しています。 #define文、IF文、for文の使用、printfを使って■と□を表示させることが条件です。 間違っているところの指摘をお願いします。 #include <stdio.h> #define N 10 int main(void) { for( i=1 ; i<=N ; ++i ) { for( j=1 ; j<=N ; ++j ) } if( (i+j) % 2 ){ printf("■"); }else printf("□"); } printf("\n"); i++; } return 0; }

  • return 1

    #include<stdio.h> int fact(int num); int main(void) { int i; printf("Input figure freely:"); scanf("%d", &i); printf("%d", fact(i)); return 0; } int fact(int num) { if(num>0){ return num * fact(num-1); }else{ return 1; } } -------------------------------------------- 上のプログラムは再帰呼び出しを使った階乗計算の プログラムです。 func()関数内のreturn 1の意味をどなたか教えて いただけないでしょうか?

  • 続・C言語について

    http://okwave.jp/qa5241461.html 先ほど、このような質問をして、いただいた回答を参考に下記のようなプログラムを作ってみたのですが、実行結果は、数値の入力と最後の"\n"しか反映していません…。 このプログラムのどの部分がマズイのか、お教えいただけたら幸いです。 よろしくお願いいたします。 #include <stdio.h> void draw_even(int, int); void draw_odd(int, int); int main(void) { int kazu; int gyou=1; printf("数字2~9を入力してください:"); scanf("%d", &kazu); while(kazu < 2 || kazu >9) { printf("※入力エラー!! 2~9を入力してください:"); scanf("%d", &kazu); } while(gyou <= kazu) { if(kazu = 2*(kazu/2)) { gyou = kazu+1; draw_even(kazu, gyou); } else { gyou = kazu; draw_odd(kazu, gyou); } gyou++; } } void draw_even(int kazu, int gyou) { int keta = 1; if(kazu!=(gyou+1)/2) { while(keta==kazu && keta==(gyou+1)/2 && keta==gyou-(kazu-1)) { printf("*"); } } else { for(keta=1; keta<=gyou; keta++) { if(keta!=(gyou+1)/2) { printf("*"); } else { printf(" "); } } } printf("\n"); } void draw_odd(int kazu, int gyou) { int keta = 1; if(kazu!=(gyou+1)/2) { while(keta==kazu && keta==(gyou+1)/2 && keta==gyou-(kazu-1)) { printf("*"); } } else { for(keta=1; keta<=gyou; keta++) { printf("*"); } } printf("\n"); }

  • C言語の質問です

    下記の素数か素数でないか調べるコードで、 (1)変数名にis_primeとありますが、isは何を意味しているのですか? (2)is_prime = 1;とするのがわかりません。 (3)以下、return 0; まで、どういう流れかわかりません よろしければコメント以下から1行ずつ教えてもらえるとうれしいです。 #include <stdio.h> int main(void) { int num, i, is_prime; printf("判定したい数を入力してください: "); scanf("%d", &num); /* 約数があるかどうか調べる */ is_prime = 1; for(i=2; i<=num/2; i=i+1) if((num%i)==0) is_prime = 0; if(is_prime==1 && num > 1) printf("素数です"); else if (num > 1) printf("素数ではありません"); return 0; }

  • 数独解答判定プログラム

    数独の解答判定プログラムを作成しているのですが、完成しません。下に僕の作ったプログラムを載せておくので間違い等の指摘をお願いします。 #include <stdio.h> #define row 9 #define column 9 int question[row][column]={ 915284376, 273916584, 468753912, 396178245, 742365891, 851492637, 629847153, 587631429, 134529768, }; int num; int singlenumber(void); int saferow(int, int); int safecolumn(int, int); int safebox(int, int, int); int main(void){ int judge; for(num = 1; num <= 9; num++){ int singlenumber(void); } if(judge == 0){ printf("おめでとう!! 正解です。"); }else{ printf("残念!! 不正解です。"); } return 0; } int singlenumber(void){ int i, j; int row_judge; int column_judge; int box_judge; int judge; for(i = 0; i < row; i++){ int saferow(int i, int num); } for(j = 0; j < column; j++){ int safecolumn(int j, int num); } for(i = 0; i < row; i++){ for(j = 0; j < column; j++){ int safebox(int i, int j, int num); } } if(row_judge == 0 && column_judge == 0 && box_judge == 0){ judge = 0; }else{ judge = 1; } return judge; } int saferow(int i, int num){ int k; int row_judge; for(k = 0; k < column; k++){ if(num == question[i][k]){ row_judge = 0; }else{ row_judge = 1; } } return row_judge; } int safecolumn(int j, int num){ int l; int column_judge; for(l = 0; l < row; l++){ if(num == question[l][j]){ column_judge = 0; }else{ column_judge = 1; } } return column_judge; } int safebox(int i, int j, int num){ int m, n; int box_judge01, box_judge02, box_judge03; int box_judge11, box_judge12, box_judge13; int box_judge21, box_judge22, box_judge23; int box_judge0, box_judge1, box_judge2, box_judge; for(m = 0; m < row ; m++){ if(m / 3 == 0){ for(n = 0; n < 3; n++){ if(num == question[m][n]){ box_judge01 = 0; }else{ box_judge01 = 1; } } for(n = 3; n < 6; n++){ if(num == question[m][n]){ box_judge02 = 0; }else{ box_judge02 = 1; } } for(n = 6; n < 9; n++){ if(num == question[m][n]){ box_judge03 = 0; }else{ box_judge03 = 1; } } } if(box_judge01 == 0 && box_judge02 == 0 && box_judge03 == 0){ box_judge0 = 0; }else{ box_judge0 = 1; } if(m / 3 == 1){ for(n = 0; n < 3; n++){ if(num == question[m][n]){ box_judge11 = 0; }else{ box_judge11 = 1; } } for(n = 3; n < 6; n++){ if(num == question[m][n]){ box_judge12 = 0; }else{ box_judge12 = 1; } } for(n = 6; n < 9; n++){ if(num == question[m][n]){ box_judge13 = 0; }else{ box_judge13 = 1; } } } if(box_judge11 == 0 && box_judge12 == 0 && box_judge13 == 0){ box_judge1 = 0; }else{ box_judge1 = 1; } if(m / 3 == 2){ for(n = 0; n < 3; n++){ if(num == question[m][n]){ box_judge21 = 0; }else{ box_judge21 = 1; } } for(n = 3; n < 6; n++){ if(num == question[m][n]){ box_judge22 = 0; }else{ box_judge22 = 1; } } for(n = 6; n < 9; n++){ if(num == question[m][n]){ box_judge23 = 0; }else{ box_judge23 = 1; } } } if(box_judge21 == 0 && box_judge22 == 0 && box_judge23 == 0){ box_judge2 = 0; }else{ box_judge2 = 1; } if(box_judge0 == 0 && box_judge1 == 0 && box_judge2 == 0){ box_judge = 0; }else{ box_judge = 1; } } return box_judge; }

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }

  • 困ってます…nCrを求めるC言語プログラミング

    nCr、つまりn個のうちr個を取り出すときの場合の数を求めるプログラミングを作りたいのですが、どうもうまくいきません。 関数combinationを作って求めるという指定もあり、自分で出来るとこまで作ってみたのですが訳がわからなくなってしまい、かなり困っています…; コンパイルは出来るのですが実行してもセグメントエラーが出るばかりで… すみませんがご指摘していただけないでしょうか…? #include<stdio.h> //階乗を計算する関数 int fact(int num){ int i; if(num < 0){ return -1; } else if(num == 0){ return 1; } else if(num == 1){ return 1; } else { i = num * fact(num - 1); return i; } } //コンビネーションを計算 int combination(int n, int r) { int fact(int num); int i; i=fact(n)/fact(r)/fact(n-r); return combination(n-1, r-1)-combination(n,r-1); } int main(void) { int n, r; while ( printf("n r を入力して下さい。"), scanf("%d%d", &n, &r) == 2 ) { printf("nCr(%d,%d)=%d\n", n, r, combination(n, r)); } return 0; }

  • スロット プルグラムについて

    今、スロットをC++で作っています。 しかし、確実に実行されません。 分かるかた、教えていただけないでしょうか? プログラムがめちゃくちゃなのは承知の上です。 優しい回答お願いします。 #include <stdio.h> #include <stdlib.h> #include <time.h> void r_dsp(int rel[3][3]); int r_han(int rel[3][3],int tc); main() { int co=100, r, i, j, kc,num ,rel[3][3]; srand(time(NULL)); while( co > 2 ){ printf("何枚コインを入れますか?(1~3):"); scanf("%d",&kc); if( kc == 99 ) break; if( kc < 1 || kc > 3 ){ continue; } co -= kc; for( i = 0 ; i < 3 ; i++ ){ for( j = 0 ; j < 3 ; j++ ){ r = (double)rand() / RAND_MAX * 10; rel[i][j] = r; } } r_dsp(rel); co += r_han(rel, kc); printf("残りコイン=%d枚\n", co); } } void r_dsp(int rel[3][3]) { char num[][3]={"0","1","2","3","4","5","6","7","8","9"}; int i, j; for( i = 0 ; i < 3 ; i++ ){ for( j = 0 ; j < 3 ; j++ ){ printf("%s ", num[rel[i][j]]); } printf("\n"); } } int r_han(int rel[3][3], int tc) { int i, hk=0; for( i = 0 ; i < 3 ; i++ ){ if( i == 1 || tc != 1 ) if( rel[i][0] == 7 ) if( rel[i][1] == 7 ) if( rel[i][2] == 7 ) hk += 100; else hk += 10; else hk += 2; } if( tc == 3 ){ if( rel[0][0] == 7 ){ if( rel[1][1] == 7 ) if( rel[2][2] == 7 ) hk += 100; else hk += 10; else hk += 2; } if( rel[2][0] == 7 ){ if( rel[1][1] == 7 ) if( rel[0][2] == 7 ) hk += 100; else hk += 10; else hk += 2; } } printf("払出し枚数=%d\n", hk); return hk; }

  • 初心者です。

    ループで、どうしてもわからないので、質問します。   1234567890123456789012345 と、いうように表示したいのですが、以下のソースでは、表示されません。教えてください。  ※ 読み込まれた整数値の個数は25とした場合です。 #include <stdio.h> int main(void) { int i = 0; int num; printf("整数を入力してください。:"); scanf("%d",&num); for (i = 0; i < num; i++){ printf("%d", i); if ( i <= 10 ){ i = 0; } } putchar('\n'); return(0); }

  • Cプログラミング 

    素数を判定するプログラミングの作成で以下のプログラミングを作成したのですが、すべて 素数でないとでてしまいます。どなたか間違いをおしえていただけませんでしょうか。 #include<stdio.h> int main(void) { int num,i; printf("Please input a number:"); scanf("%d",&num); for (i=2; i < num ; i++){num % i; if (num % i == 0) break; } if (num % i == 0) printf("%d is not prime. \n" ,num); else printf("%d is prime. \n" ,num); return 0; }

専門家に質問してみよう