つづき
DIM num(M+N,mxRC) !ヒント数字 MAT num=ZER RESTORE 10 FOR i=1 TO M !行 FOR j=1 TO R READ num(i,j) NEXT j NEXT i FOR i=1 TO N !列 FOR j=1 TO C READ num(i+M,j) NEXT j NEXT i DIM cnt(M+N) !ヒント数字の数 FOR i=1 TO M+N LET CntOfNum=0 FOR j=1 TO mxRC IF num(i,j)>0 THEN LET CntOfNum=CntOfNum+1 NEXT j LET cnt(i)=CntOfNum NEXT i DIM spc(M+N) !空白の数 FOR i=1 TO M+N LET CntOfSpc=0 FOR j=1 TO mxRC LET CntOfSpc=CntOfSpc+num(i,j) !パターンの長さ NEXT j IF i>M THEN !列の場合 LET mn=M ELSE !行の場合 LET mn=N END IF LET spc(i)=mn-(CntOfSpc+(cnt(i)-1)) !間には少なくとも1つの空白が必要である NEXT i DIM mtx$(M) !盤面 ※行を基準にしたビット列 FOR i=1 TO M LET mtx$(i)=REPEAT$("x",N) !0:0確定、1:1確定、x:未定 NEXT i DO !バックトラック CALL thinking(M,N,num,cnt,spc, mtx$, rc) !手を進める PRINT "rc=";rc IF rc=0 THEN !完成なら EXIT DO ELSEIF rc=1 THEN !矛盾なら CALL pop(stack_BOARD$,sp_BOARD, mtx$,M) !次の手 PRINT "次の手" ELSEIF rc=2 THEN !手詰まりなら FOR k=1 TO M !左上から順に未定箇所を探し、そこへ仮に置いてみる LET p=POS(mtx$(k),"x") IF p>0 THEN EXIT FOR NEXT k IF k>M THEN !すべて埋まっていたら PRINT "解答なし!" !※ヒントの数字に問題あり STOP END IF PRINT "(";k;",";p;")" LET mtx$(k)(p:p)="1" !「黒」(次の手)を保存しておく CALL push(stack_BOARD$,sp_BOARD, mtx$,M) LET mtx$(k)(p:p)="0" !まずは「白」から END IF LOOP PRINT "計算時間=";TIME-t0 PRINT PRINT "完成!" END
|