• 締切済み

有限体GF(4)上の同次方程式で不定方程式

連立方程式の解法ですが、手計算だとうまくいくのにプログラムにしようとするとうまくいきません。 さらに不定方程式なので解がないといわれてしまいます。誰かわかる方がいらしたらプログラムを 見て直していただきたいです。プログラムは以下の通り。 #define N 4 #define T 6 unsigned char gf[4]={0,1,2,3},fg[4]={0,1,2,3}; unsigned char gf[4]={0,1,2,3},fg[4]={0,1,2,3}; unsigned char ad[4][4]; /* 答えは 1,1,2 */ unsigned char s[3][3]={{1,3,1},{3,3,0},{1,0,3}}; /* 答えはzを不定として1と置き、x=z=1;y=0;になる筈だがならない */ //unsigned char s[][]={{2,2,2},{2,0,2},{2,2,2}} int add(int x,int y){ return ad[x][y]; } int mlt(int x, int y){ if(x==0||y==0) return 0; return ((x+y-2)%(N-1))+1; } int mltn(int n,int x){ int i,j; if(n==0) return 1; i=x; for(j=0;j<n-1;j++) i=mlt(i,x); return i; } int div(int x,int y){ if(x==0) return 0; return ((x-y+(N-1))%(N-1))+1; } void syn(){ int i,j,k,l,n; for(i=0;i<3;i++){ for(j=0;j<3;j++){ if(i==j){ if(s[i][j]==1){ for(l=0;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); printf("%d ",s[l][k]); } printf("\n"); } } // exit(1); if(s[i][j]!=1){ printf("%da \n",s[i][j]); n=div(1,s[i][j]); if(n==0){ printf("%d =\n",fg[s[i][j]]); exit(1); } for(k=0;k<3;k++){ if(s[0][0]==0){printf("%d?\n",s[0][0]); exit(1);} s[i][k]=mlt(n,s[i][k]); printf("%d ",s[i][k]); } printf("\n"); for(l=i;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); // printf("%d ",s[l][k]); } printf("\n"); } printf("\n"); for(l=0;l<3;l++){ for(k=0;k<3;k++) printf("%d ",s[l][k]); printf("\n"); } // exit(1); if(s[i][j]==0){ while(s[i][j]==0){ j++; } printf("i-j==%d\n",s[i+1][j]); if(s[i][j]!=0){ if(s[i][j]==1){ for(l=0;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); printf("%d ",s[l][k]); } printf("\n"); } } // exit(1); if(s[i][j]!=1){ printf("%da \n",s[i][j]); n=div(1,s[i][j]); if(n==0){ printf("%d =\n",fg[s[i][j]]); exit(1); } for(k=0;k<3;k++){ if(s[0][0]==0){printf("%d?\n",s[0][0]); exit(1);} s[i][k]=mlt(n,s[i][k]); printf("%d ",s[i][k]); } printf("\n"); for(l=i;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); // printf("%d ",s[l][k]); } printf("\n"); } printf("\n"); for(l=0;l<3;l++){ for(k=0;k<3;k++) printf("%d ",s[l][k]); printf("\n"); } }} // i++;j++; //exit(1); } } } } } for(i=0;i<3;i++){ for(j=0;j<3;j++) printf("%2d ",s[i][j]); printf("\n"); } } int main(){ int i,j; for(i=0;i<N;i++){ for(j=0;j<N;j++) ad[i][j]=fg[gf[i]^gf[j]]; } syn(); }

みんなの回答

  • myuki1232
  • ベストアンサー率57% (97/170)
回答No.1

とりあえず全体的にプログラムの表示が意味不明です。 解がないといわれてしまいますとはどこのことですか?

関連するQ&A

  • ガウスのの単純消去法のプログラムです。

    ガウスのの単純消去法のプログラムです。 前進消去の第k段階が終わった段階でaij,biが表示されるようにしたいんですがどうすればいいでしょうか↓ よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<math.h> #define ERROR -1 #define EPS 1.0e-15 int gausssimp(double *, double *, double *, int); int main(void) { double *a,*b,*x,val; char s[32]; int i,j,n,result; printf("Input size n="); gets(s); sscanf(s,"%d",&n); if((a=(double *)calloc(n*n,sizeof(double)) ) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } if((b=(double *)calloc(n,sizeof(double))) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } if((x=(double *)calloc(n,sizeof(double))) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } /* A,b の成分を入力 */ printf("----- A -----\n"); for(i=0; i<n; i++){ for(j=0; j<n; j++){ printf("a(%2d,%2d)=",i+1,j+1); gets(s); sscanf(s,"%lf",&val); a[n*i+j]=val; } } printf("\n----- b -----\n"); for(i=0; i<n; i++){ printf("b(%2d)=",i+1); gets(s); sscanf(s,"%lf",&val); b[i]=val; } /* Gaussの単純消去法による求解 */ result = gausssimp(x,a,b,n); /* 解の表示 */ if(result == ERROR){ printf("ERROR occurs. pivot 0\n"); } else { printf("\n----- solution -----\n"); for(i=0; i<n; i++){ printf("x(%2d)=%.8e\n",i+1, x[i]); } } free(a); free(b); free(x); return 0; } int gausssimp(double *x, double *a, double *b, int n) { int i,j,k; double tmp,p,sum; /* step 1: 前進消去 */ /**** 追加 ****/ /* 前進消去の各段階を終えるごとに,式がどのように変化しているかわかるように表示する */ /**************/ for(k=0; k<n-1;k++){ if(a[n*k+k] == 0.0) { /* ピボットの値が0.割り算でエラーが起きる.*/ return ERROR; } else { /* k+1番目以降の式から x[k] の項を消去 */ for(i=k+1; i<n; i++){ p=a[n*i+k]/a[n*k+k]; for(j=0; j<n; j++){ a[n*i+j]=a[n*i+j]-p*a[n*k+j]; } b[i]=b[i]-p*b[k]; printf("a[%d %d]=%d b[%d]=%d",i,j,a[n*i+j]-p*a[n*k+j],i,b[i]-p*a[n*k+j]); ↑これではできませんでした。。。 } /**********************************/ } printf("k=%d\n",k); } /* step 2: 後退代入 */ for(k=n-1; k>=0; k--){ if(fabs(a[n*k+k]) < EPS) return(ERROR); sum=0.0; for(j=k+1; j<n; j++) sum+=a[n*k+j]*x[j]; x[k]=(b[k] - sum)/a[k*n+k]; } return 0; }

  • すいません。。改めて質問!!

    #include<stdio.h> #define NMAX 200 int n; int a[NMAX], x[NMAX]; void yomikomi() { for(n=0; scanf("%d%d",&a[n],&x[n])!=EOF;n++); return; } void hyouzi() { int i; for(i=0;i<n;i++) printf("%5d %5d\n",a[i],x[I]); return; } void seiretu() { int i,j,max,k,w; for(i=0;i<n-1;i++){ max=x[i];k=i; for(j=i+1;j<n;j++) if(x[j]>max){ max=x[j];k=j; } w=a[k];a=[k]=a[i];a[i]=w; x[k]=x[i]; x[i]=max; } return; } main() { printf("sorting\n"); yomikomi(); printf(\nInput data\n"); hyouzi(); seiretu(); printf(\nSorted data\n); hyouzi(); return(0); } これを改良して偶数と奇数に分けてソートするプログラムがわかればいいのですが。。まだ慣れないものですいませんでした。

  • Gaussの消去法のプログラムなんですがこれを利用して、消去法による行

    Gaussの消去法のプログラムなんですがこれを利用して、消去法による行列式の計算プログラムをつくりたいのですが難しくてよくわかりません。。。 教えていただきたいです。 困ってるのでよろしくお願いします。 int gauss(double *x, double *a, double *b, int n) { int i,j,k,m; double tmp,p,sum; for(k=0; k<n-1;k++){ printf("---- Step %d ----\n",k+1); printf("-- before --\n"); for( m = k;m < n;m++){ printf("%lf\n",a[n * m + k]); } printf("-- --\n"); j = pivot(a,n,k); if(j == ERROR) { return ERROR; } else { if(j != k) { for(i=0; i<n; i++){ tmp = a[n*k+i]; a[n*k+i] = a[n*j+i]; a[n*j+i] = tmp; } tmp=b[j]; b[j]=b[k]; b[k]=tmp; } } printf("-- after --\n"); for( m = k;m < n;m++){ printf("%lf \n",a[n * m + k]); } for(i=k+1; i<n; i++){ p=a[n*i+k]/a[n*k+k]; for(j=0; j<n; j++){ a[n*i+j]=a[n*i+j]-p*a[n*k+j]; printf("a[%d %d]=%lf",i,j,a[n*i+j]); } b[i]=b[i]-p*b[k]; printf("b[%d]=%lf\n",i,b[i]); } printf("k=%d\n",k); /*--------------------------------------------------------------------------*/ } /* step 2: 後退代入 */ for(k=n-1; k>=0; k--){ if(fabs(a[n*k+k]) < EPS){ return(ERROR); } sum=0.0; for(j=k+1; j<n; j++){ sum+=a[n*k+j]*x[j]; } x[k]=(b[k] - sum)/a[k*n+k]; } return 0; } int pivot(double *a, int n, int k) { int i,m; double d; /* ピボットの探索 */ m = k; d = fabs(a[k*n+k]); for(i=k+1; i<n; i++){ if(fabs(a[n*i+k]) > d){ m = i; d = fabs(a[n*i+k]); } } if(fabs(d) < EPS) { return ERROR; } else { return m; } }

  • C言語 エラー表示 break の位置が誤っている(関数 main ) 

    #include<stdio.h> int main(void){ int n,i,j,k; char c='*'; printf("正の整数:"); scanf("%d",&n); if(n>0){ for(i=1;i<=n;i++){ printf("%d",i); for(j=1;j<=n+1-i;j++){ if(j==1){ if(i-1>0){ for(k=i-1;k>0;k--){ printf(" "); } } } printf("%c",c); } printf("\n"); } } break; return 0; } これをコンパイルすると「break の位置が誤っている(関数 main )」と表示されるのですが何でですか? 困ってます↓

  • C *での三角形描画

    課題で*を使って三角形を描画するプログラムを作るんですが、ネットで見たかぎり、 #include<stdio.h> int main() { int n, i, j, k, l; printf("段数を入力してください:"); scanf("%d", &n); for(i = 0; i < n; i ++) { for(j = 0; j < n; j ++) { for(k = 0; k < n*n-i*n-j-1; k ++) printf(" "); for(k = 0; k < i; k ++) { for(l = 0; l < j*2+1; l ++) printf("*"); for(; l < n*2; l ++) printf(" "); } for(k = 0; k < j*2+1; k ++) printf("*"); printf("\n"); } } return 0; } となっているのが、  段数を入力してください:2     *    ***   *   *  *** *** という風に表示されるので、これを  段数を入力してください:2     *    *** という形に表示させられるよう変更すべき箇所を教えてください。

  • C言語の問題です!!

    すみません。 詳細表示をする際に、未ソート部の先頭要素の上に記号文字「*」を表示し、未ソート部の最小要素の上に記号文字「+」を表示したいと思い、以下のソースプログラムを作成したのですが、結果が何か違う気がします…。どこが違うのか、教えていただけませんか? また、プログラムを修正していただけませんか? #include<stdio.h> #include<stdlib.h> #include<time.h> #define swap(type,x,y) do{type t=x;x=y;y=t;}while(0) /*--- 単純選択ソート ---*/ void selection(int a[], int n) { int i, j,k,flg; char *disp[]={" ","[* ]","[ +]","[*+]"}; for (i = 0; i < n - 1; i++) { int min = i; for (j = i + 1; j < n; j++) { if (a[min] > a[j]) { min = j; } } for (k = 0; k < n; k++) { flg=0; if(k==i) flg|=1; if(k==min) flg|=2; printf("%s",disp[flg]); } printf("\n"); for (k = 0; k < n; k++) printf("[%2d]", a[k]); printf("\n"); swap(int, a[i], a[min]); } } int main(void) { int i, nx; int *x; printf("要素数 : "); scanf("%d", &nx); x = calloc(nx, sizeof(int)); srand(time(NULL)); for (i = 0; i < nx; i++) { x[i] = rand() % 100; printf("x[%d] = %d\n", i, x[i]); } selection(x, nx); for (i = 0; i < nx; i++) printf("x[%d] = %d\n", i, x[i]); free(x); return 0; }

  • お願いします!!!プログラミングについて。

    お願いします!!!プログラミングについて。 次の文が実行されると何がどのようにプリントされるか。何もプリントされない時は「なし」と記せ。 また、途中に「ブランク」が入る場合は、”b”と記せ。 (1) printf("i=%d j=%lf\n", 1/2,1/3); (2) x = 0.5; y= 1e0/3e0; printf("x = %7.3f, y = %12.5e\n", x, y); */ (3) i = 2; j = 3; printf("%d", i==2); (4) int sum1(i){ int s = 0; return s += i; } int sum2(i){ static int s = 0; return s += i; } main(){ int s1, s2, i; for(i=1;i<=10;i++){ s1 =sum1(i); s2 = sum2(i);} printf("%d %d\n",s1,s2); } (5) int mtx[4][3] = {{1,2,3},{4,5,6},{7,8,9},{-1,-2,-3}}; int i,j,rtot,ctot[3]={0,0,0},stot=0; for(i=0,i<4,i++){ rtot = 0; for(j=0;j<3;j++){ rtot += mtx[i][j] ctot[j] += mtx[i][j]; stot += mtx[i][j]; printf("%3d ",mtx[i][j]); } printf(" %3d\n",rtot); } printf("\n"); for(j=0;j<3;j++) printf("%3d ",ctot[j]); printf(" %3d\n",rtot); この5問をプログラミングに詳しい方教えてください!切実です。。 一つだけでも構いません!よろしくお願いします。

  • お願いします!!!プログラミングについて。

    お願いします!!!プログラミングについて。 次の文が実行されると何がどのようにプリントされるか。何もプリントされない時は「なし」と記せ。 また、途中に「ブランク」が入る場合は、”b”と記せ。 (1) printf("i=%d j=%lf\n", 1/2,1/3); (2) x = 0.5; y= 1e0/3e0; printf("x = %7.3f, y = %12.5e\n", x, y); */ (3) i = 2; j = 3; printf("%d", i==2); (4) int sum1(i){ int s = 0; return s += i; } int sum2(i){ static int s = 0; return s += i; } main(){ int s1, s2, i; for(i=1;i<=10;i++){ s1 =sum1(i); s2 = sum2(i);} printf("%d %d\n",s1,s2); } (5) int mtx[4][3] = {{1,2,3},{4,5,6},{7,8,9},{-1,-2,-3}}; int i,j,rtot,ctot[3]={0,0,0},stot=0; for(i=0,i<4,i++){ rtot = 0; for(j=0;j<3;j++){ rtot += mtx[i][j] ctot[j] += mtx[i][j]; stot += mtx[i][j]; printf("%3d ",mtx[i][j]); } printf(" %3d\n",rtot); } printf("\n"); for(j=0;j<3;j++) printf("%3d ",ctot[j]); printf(" %3d\n",rtot); この5問をプログラミングに詳しい方教えてください!切実です。。1問だけでも構いませんのでよろしくお願いします。

  • n次の奇数魔方陣をつくるプログラム

    どうしてもエラーが出てしまいます。少なくとも、「int mahojin[n+1][n+1],i,j,k;」あたりの行が間違っているらしいのですが、なぜだかわかりません。アドバイスお願いします!!(スペースが上手く入らなくて、全角スペースを使ってますが気にしないでください。) #include<stdio.h> int main(void) {  int n;  printf("n(ただし、nは奇数)=?");scanf("%d",&n);  int mahojin[n+1][n+1],i,j,k;  j=(n+2)/2;i=0;  for(k=1;k<=n*n;k++){     if((k%n)==1)      i++;     else {      i--;j++;     }     if(i==0)      i=n;     if(j>n)      j=1;     mahojin[i][j]=k;   }   printf(" %d次の魔方陣 \n",n);   for(i=1;i<=n;i++){     for(j=1;j<=n;j++)      printf("%4d",mahojin[i][j]);     printf("\n");   }   return 0; }

  • 以前も同じ質問したのですがもう一度お願いします

    以前も同じ質問したのですがもう一度お願いします プログラミングで3行3列の行列Aに対しAの2乗、Aの3乗を求めるプログラムを作成したいのですが下記のプログラムでは3行3列まで表示できません どこが間違えているのか修正していただけないでしょうか? #include <stdio.h> int main(){ int z[3][3]; int w[3][3]; int x[3][3]={1,2,3,4,5,6,7,8,9}; int n,m; int i,j,k; printf("z[3][3] : \n"); for(i=0;i<3;i++) { for(j=0;j<3;j++) {printf("z[%d][%d] = ",i,j); scanf ("%d",&z[i][j]); } } printf("m for [z]^m ="); scanf ("%d",&m); for(n=0;n<m;n++) { for(i=0;i<3;i++) { for(j=0;j<3;j++) { w[i][j] = 0; for(k=0;k<3;k++) { w[i][j] += x[i][k]*z[k][j]; } } } for(i=0;i<3;i++) { for(j=0;j<3;j++) { x[i][j] = w[i][j]; } } printf("[z]^%d\n",n+1); for(i=0;i<3;i++) { for(j=0;j<3;j++) { printf(" %9d",x[i][j]); }printf("\n"); }printf("\n"); } return 0; }