ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

魔方陣についてコミュの4方陣 全探索のプログラム。

  • mixiチェック
  • このエントリーをはてなブックマークに追加
下記内容で、4方陣全通りの探索が2.26GHzのPCで
10分かからないですみました。

  重複解も含めてtotal=7040 という
  解(880の8倍)が得られました。
   
探索範囲を示す変数の値
 (as,ae, bs,be cs,ce ・・・など)を書き換えて使えば
任意の範囲の4方陣を調べることができます。

次の a,b,c,e,f,g,i,kの場所に入る数字の範囲を指定できます。

a b c *
e f g *
i * k *
* * * *

下記内容をテキストファイルとしてコピーして、
ファイル名末尾を.htmlとして使用ください。

途中で Continue? の問いには OKを、
 中断しますか?の警告がでたら いいえ を
選べば、探索が続行されます。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<TITLE>4方陣の探索プログラム</TITLE>
</HEAD>
<BODY>
<script language="javascript">
<!-- //

N1=17;
SUM=34;


//探索手順: a,b,c,e,f,g,i,k についてのしらみつぶし探索:
// 残りは次の様に求める。
// a b c D  D=34-a-b-c; L=34-i-k-J= 34-i-k-(34-f-g-k)= f+g-i;
// e f g H  H=34-e-f-g; N=34-b-f-J= 34-b-f-(34-f-g-k)= g+k-b;
// i J k L  J=34-f-g-k; O=34-k-g-c;
// M N O P  M=34-a-e-i; P=34-a-f-k;

//■■■■■■■ここを書き換えれば任意の範囲を探せます■■■■■■■
as=1; ae=N1;
bs=1; be=N1;
cs=1; ce=N1;
es=1; ee=N1;
fs=1; fe=N1;
gs=1; ge=N1;
is=1; ie=N1;
ks=1; ke=N1;

//探索範囲の指定方法: 例えば aの探索範囲は as<= a < ae までを探索する。
//           (asはaのStart aeは aのEndの意:他も同様)
// aの値を固定するには asを特定の値とし, ae=as+1;と すること。

// 例えば A年 B月 C日 の組み合わせを探したいならば:
// 上の3行分を下記のように書き換える
// as=A; ae=as+1; //(ここでA,B,Cは実際は1から16までの定数)
// bs=B; be=bs+1;
// cs=C; ce=cs+1;

//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■



function PUT(x){ // xが使えるなら使用中にする。
if((x<1) || (x>16) || (checkdata&(1<<x))!=0) {
return 0; //使えない
}else{
checkdata|=(1<<x); return 1; //使用中にする。
}
}

function PUT2(x,y){ //部分和がxのところに、yとz=SUM-x-yが置けるかを判定
z=SUM-x-y;
if((z<N1) && (z>0) && (z!=y)){
if( ((1<<z)&checkdata)==0 && ((1<<y)&checkdata)==0 ){
checkdata|=((1<<y)|(1<<z));
return z;
}
}
return 0; //置けない時の判定用の戻り値
}

// 置いた数字を、元の未使用状態に戻すための関数
function REMOVE(x){ checkdata &= ~(1<<x);}
function REMOVE2(x,y){ checkdata &= ~((1<<x)|(1<<y));}

total=0;
GOAL=(1<<17)-2; //1から16まで全使用時のcheckdataの値

for(a=as; a<ae; a++){
checkdata=0;
if(PUT(a)==0) continue;
if(confirm("Continue? "+a+" total= "+total)!=true) break;

for(b=bs; b<be; b++){
if(PUT(b)==0) continue;

for(c=cs; c<ce; c++){
ab=a+b;
if(ab+c>=SUM) break;
D=PUT2(ab,c);
if(D==0) continue;

for(e=es; e<ee; e++){
if(PUT(e)==0) continue;

for(f=fs; f<fe; f++){
if(PUT(f)==0) continue;

for(g=gs; g<ge; g++){
ef=e+f;
if(ef+g>=SUM) break;
H=PUT2(ef,g);
if(H==0) continue;

for(i=is; i<ie; i++){
ae=a+e; if(ae+i>=SUM)break;
M=PUT2(ae,i);
if(M==0) continue;
L=f+g-i;
if(PUT(L)==0) {REMOVE2(i,M);continue;}

for(k=ks; k<ke; k++){
J=SUM-f-g-k; if(J<1) break;
if(J>16) continue;
O=SUM-c-g-k; if(O<1) break;
if(O>16) continue;
af=a+f; if(af+k>=SUM) break;
P=PUT2(af,k);
if(P==0) continue;
N=g+k-b; if((N<1)||(N>16)){ REMOVE2(k,P); continue;}

// N,O,Jは重複なく置けるかをチェックするのみ:PUT,REMOVEしない
if( (checkdata|(1<<N)|(1<<O)|(1<<J))!= GOAL){REMOVE2(k,P); continue;}

//ここまでくれば完成
document.write(a+","+b+","+c+","+D+"<br>");
document.write(e+","+f+","+g+","+H+"<br>");
document.write(i+","+J+","+k+","+L+"<br>");
document.write(M+","+N+","+O+","+P+"<br><br>");
++total;

REMOVE2(k,P);
}
REMOVE(L);REMOVE2(i,M);
}
REMOVE2(g,H);
}
REMOVE(f);
}
REMOVE(e);
}
REMOVE2(c,D);
}
REMOVE(b);
}
REMOVE(a);
}

alert("FINISHED: total="+total);

//-->
</script>
</BODY>
</HTML>


コメント(0)

mixiユーザー
ログインしてコメントしよう!

魔方陣について 更新情報

魔方陣についてのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング