ブログトップ

電子工作やってみたよ

数独は奥が深いですねえ。
錆びかけた脳みそに油をさしながら頑張ってみたのですが、やっと ニコリの数独攻略ガイドの中級が解けるプログラムが出来ました。
解析手順は今までの2つの方法に新たに2つ追加して以下の4つの方法をグルグルと繰り返しています。

1、 空きマスを探して 縦、横、3X3ブロックの条件からそこに入力出来る数値を探す。
2、 1~9のなかで注目する数値を決めその数値がない3x3のブロックの中のどこに置くことが出来るか探す。
3、 1~9のなかで注目する数値を決めその数値がない縦の列の中のどこに置くことが出来るか探す。
4、 1~9のなかで注目する数値を決めその数値がない横の行の中のどこに置くことが出来るか探す。

言葉で言えばこれだけの事ですが、これをプログラムで表現しようとするとなかなうまく行きませんでした。
2~4においては、答えの場所を探すというよりは、置けないところを見つけてはじき出すという感じですね。
このなかでは、「先読み」や数値の「仮置き」は使っていません。

この次は「上級」の問題に挑戦してみます。


c0335218_19035428.jpg

ニコリ 数独攻略ガイド (中級) P52,53 No17,18
c0335218_10091709.jpg


ニコリ 数独攻略ガイド (中級)P52 No17
正常な答えがでました。

上半分は問題  下半分は回答です。 演算時間はみな5秒以内でした。
c0335218_10003189.jpg

ニコリ 数独攻略ガイド (中級)P53 No18
正常な答えが出ました。
上半分は問題  下半分は回答です。
c0335218_10003962.jpg


ニコリ 数独攻略ガイド (上級) P73 No26 上級の問題

c0335218_10100381.jpg


ニコリ 数独攻略ガイド (上級)P73 No26   
答えがまったく出ません。

上半分は問題  下半分は回答です。
c0335218_10004645.jpg




F-97 BASICで書いたプログラムリストです。

------------------------------
数独(ナンプレ) Ver SDOK_050N.BAS 2018-08-7
'基本テーブル配列の定義
dim AL(9,9) 
dim CHK(27)
dim INV1(20)
dim M_BUF(9)
'
'問題のテーブルデータの設定
gosub *TBL_ABCD
gosub *DISP3
gosub *ALBKCOPY
'stop
for AL_COUNT = 1 to 20
    ?" AL_COUNT=";AL_COUNT
gosub *MAIN_1
gosub *MAIN_2
gosub *MAIN_3
gosub *MAIN_4
next AL_COUNT
gosub *DISP3
?" ALL END"
stop
'=====================================================================================
'空欄を順に探してそこに入る可能性のある数値を、空欄のたて、横、ブロックのデータから類推する
*MAIN_1
'?" MAIN_1 ============================== "
X=1:Y=1
'空欄のマスをサーチする
for JJJ=1 to 20
for Y=1 to 9
for X=1 to 9
'?" X=";X;:?" Y=";Y;
if AL(X,Y)=0 then gosub *SHORI
next X
next Y
next JJJ

return
'
'=============================================================================
'空欄のたて、横、ブロックのデータを読み込む
*SHORI
'?" SHORI":'stop
for XXA=1 to 27
CHK(XXA)=0
next XXA
for XXB=1 to 9
' ?" XXB=";XXB;" Y=";Y
INV1(XXB)=AL(XXB,Y)
'stop
next XXB
'gosub *disp1:stop

'空欄に入る可能性データに変換する
for XX=1 to 9
INV2(XX)=XX
next XX

for YY=1 to 9
for XX=1 to 9
if INV2(XX)=INV1(YY) then INV2(XX)=0
next XX
next YY
for XX=1 to 9
CHK(XX)=INV2(XX)
next XX
'------------------------------------------------
'問題のテーブルから縦の列データをコピーする
for YY=1 to 9
INV1(YY)=AL(X,YY)
next YY
'gosub *disp1:stop
'空欄に入る可能性データに変換する
for XX=1 to 9
INV2(XX)=XX
next XX
'gosub *DISP2:stop
for YY=1 to 9
for XX=1 to 9
if INV2(XX)=INV1(YY) then INV2(XX)=0
next XX
next YY
'gosub *DISP2:stop
for XX=1 to 9
CHK(XX+9)=INV2(XX)
next XX
'gosub *DISP27:stop
'-------------------------------------------------
'問題のテーブルからブロックデータをINV1へコピーする
if (X<=3)and(Y<=3) then gosub *AAA:goto *BLKMOVEND
if (X>=4)and(X<=6)and(Y<=3) then gosub *BBB:goto *BLKMOVEND
if (X>=7)and(Y<=3) then gosub *CCC:goto *BLKMOVEND
if (X<=3)and(Y>=4)and(Y<=6)then gosub *DDD:goto *BLKMOVEND
if (X>=4)and(X<=6)and(Y>=4)and(Y<=6)then gosub *EEE:goto *BLKMOVEND
if (X>=7)and(Y>=4)and(Y<=6)then gosub *FFF:goto *BLKMOVEND
if (X<=3)and(Y>=7) then gosub *GGG:goto *BLKMOVEND
if (X>=4)and(X<=6)and(Y>=7)then gosub *HHH:goto *BLKMOVEND
if (X>=7)and(Y>=7) then gosub *III:goto *BLKMOVEND
?" ERR_blkend":stop
*BLKMOVEND
'空欄に入る可能性データに変換する
for XX=1 to 9
INV2(XX)=XX
next XX
'gosub *disp2:stop
for YY=1 to 9
for XX=1 to 9
if INV2(XX)=INV1(YY) then INV2(XX)=0
next XX
next YY
'gosub *disp2:stop
for XX=1 to 9
CHK(XX+18)=INV2(XX)
next XX
'gosub *disp27:stop
'-------------------------------------------------
for XX=1 to 9
BF(XX)=0
next XX
'gosub *DISP_BF
for M=1 to 9
KZ=0:GT=0
for T=1 to 27
if CHK(T)=M then KZ=KZ+1
if KZ>=3 then ANS=M:GT=1:BF(M)=1:T=27: '?"KZ";KZ;:?"GT=";GT;
next T
next M
OKCHK=0
for XX=1 to 9
OKCHK=OKCHK + BF(XX)
next XX
'gosub *DISP_BF
'?" OKCHK=";OKCHK,
'?" X="X;:?" Y=";Y
'stop
if OKCHK<>1 then goto *NON
AL(X,Y)=ANS
    '?" ANS=";ANS,
'?" X=";X,
'?" Y=";Y
*NON
return
'------------------------------------------------------------
'注目する数値を決めてからその注目値の無いブロックを探し、注目値がそのブロックのどこに当てはまるかを調べる。
*MAIN_2
'?" ":?" ":
'?" MAIN_2 ====================================================================== "
'stop
X=1:Y=1
'空欄のマスをサーチする
for ALOOP=1 to 20
for CHUMOKU=1 to 9
for BLKNO=1 to 9 ' *AA: 1 *BB: 2 ----
           '?" ":?" CHUMOKU=";CHUMOKU;  :?" BLKNO=";BLKNO;
'stop
gosub *BLOCK
next BLKNO
next CHUMOKU
next ALOOP
'?"  All end"
'gosub *DISP3B
'?" "
'gosub *DISP3
return
'------------------------------------------------------------
*BLOCK
if BLKNO=1 then BLKYUP=1:BLKXLF=1:gosub *AAA:goto *BLKXX
if BLKNO=2 then BLKYUP=1:BLKXLF=4:gosub *BBB:goto *BLKXX
if BLKNO=3 then BLKYUP=1:BLKXLF=7:gosub *CCC:goto *BLKXX
if BLKNO=4 then BLKYUP=4:BLKXLF=1:gosub *DDD:goto *BLKXX
if BLKNO=5 then BLKYUP=4:BLKXLF=4:gosub *EEE:goto *BLKXX
if BLKNO=6 then BLKYUP=4:BLKXLF=7:gosub *FFF:goto *BLKXX
if BLKNO=7 then BLKYUP=7:BLKXLF=1:gosub *GGG:goto *BLKXX
if BLKNO=8 then BLKYUP=7:BLKXLF=4:gosub *HHH:goto *BLKXX
if BLKNO=9 then BLKYUP=7:BLKXLF=7:gosub *III:goto *BLKXX
?" BLK ERR":stop
'------------------
*BLKXX
CNT=0
'このブロック(*AAA *BBB *CCC~) の中に注目している(CHUMOKU)数値があれば何もせずリターン
for XXX=1 to 9
CNT=CNT+1
'if INV1(XXX)=CHUMOKU then ?" ":?"M2 ブロック内に注目値あり":CNT=0:XXX=9:return
if INV1(XXX)=CHUMOKU then :CNT=0:XXX=9:return
next XXX

' ?" ":?"M2 ブロック内に注目値が無いので場所探しをする":stop
gosub *BK_Y_IV
gosub *BK_X_IV
gosub *XY_LNCK
gosub *CHUSET
return
'---------------------------------------------------------------
*AAA
'?"":?" AAA"
INV1(1)=AL(1,1): INV1(2)=AL(2,1): INV1(3)=AL(3,1)
INV1(4)=AL(1,2): INV1(5)=AL(2,2): INV1(6)=AL(3,2)
INV1(7)=AL(1,3): INV1(8)=AL(2,3): INV1(9)=AL(3,3)
gosub *BLKOUTCOPY
return
'----------------------------------------
*BBB
'?"":?" BBB"
INV1(1)=AL(4,1): INV1(2)=AL(5,1): INV1(3)=AL(6,1)
INV1(4)=AL(4,2): INV1(5)=AL(5,2): INV1(6)=AL(6,2)
INV1(7)=AL(4,3): INV1(8)=AL(5,3): INV1(9)=AL(6,3)
gosub *BLKOUTCOPY
return
'----------------------------------------
*CCC
'?"":?" CCC"
INV1(1)=AL(7,1): INV1(2)=AL(8,1): INV1(3)=AL(9,1)
INV1(4)=AL(7,2): INV1(5)=AL(8,2): INV1(6)=AL(9,2)
INV1(7)=AL(7,3): INV1(8)=AL(8,3): INV1(9)=AL(9,3)
gosub *BLKOUTCOPY
return
'----------------------------------------
*DDD
'?"":?" DDD"
INV1(1)=AL(1,4): INV1(2)=AL(2,4): INV1(3)=AL(3,4)
INV1(4)=AL(1,5): INV1(5)=AL(2,5): INV1(6)=AL(3,5)
INV1(7)=AL(1,6): INV1(8)=AL(2,6): INV1(9)=AL(3,6)
gosub *BLKOUTCOPY
return
'----------------------------------------
*EEE
'?"":?" EEE"
INV1(1)=AL(4,4): INV1(2)=AL(5,4): INV1(3)=AL(6,4)
INV1(4)=AL(4,5): INV1(5)=AL(5,5): INV1(6)=AL(6,5)
INV1(7)=AL(4,6): INV1(8)=AL(5,6): INV1(9)=AL(6,6)
gosub *BLKOUTCOPY
return
'----------------------------------------
*FFF
'?"":?" FFF"
INV1(1)=AL(7,4): INV1(2)=AL(8,4): INV1(3)=AL(9,4)
INV1(4)=AL(7,5): INV1(5)=AL(8,5): INV1(6)=AL(9,5)
INV1(7)=AL(7,6): INV1(8)=AL(8,6): INV1(9)=AL(9,6)
gosub *BLKOUTCOPY
return
'----------------------------------------
*GGG
'?"":?" GGG"
INV1(1)=AL(1,7): INV1(2)=AL(2,7): INV1(3)=AL(3,7)
INV1(4)=AL(1,8): INV1(5)=AL(2,8): INV1(6)=AL(3,8)
INV1(7)=AL(1,9): INV1(8)=AL(2,9): INV1(9)=AL(3,9)
gosub *BLKOUTCOPY
return
'----------------------------------------
*HHH
'?"":?" HHH"
INV1(1)=AL(4,7): INV1(2)=AL(5,7): INV1(3)=AL(6,7)
INV1(4)=AL(4,8): INV1(5)=AL(5,8): INV1(6)=AL(6,8)
INV1(7)=AL(4,9): INV1(8)=AL(5,9): INV1(9)=AL(6,9)
gosub *BLKOUTCOPY
return
'----------------------------------------
*III
'?"":?" III"
INV1(1)=AL(7,7): INV1(2)=AL(8,7): INV1(3)=AL(9,7)
INV1(4)=AL(7,8): INV1(5)=AL(8,8): INV1(6)=AL(9,8)
INV1(7)=AL(7,9): INV1(8)=AL(8,9): INV1(9)=AL(9,9)
gosub *BLKOUTCOPY
return
'---------------------------------------------------------
*BK_Y_IV
'?"ブロックを含むヨコ3行(1行9マス)の中に注目値を含む行が有るかチェック"
'?"YCHU(1)は1行目の9マスに注目値があったら1を入れる"
'?"YCHU(1)は2行目の9マスに注目値があったら1を入れる"
'?" "
YCHU(1)=0:YCHU(2)=0:YCHU(3)=0:
for BKJJ=0 to 2
'?"ブロックの上横1行9文字をINV1へコピーして注目値を調べる"
'?"注目値があればYCHU(1-3)に1が設定される"
'stop
for XX=1 to 9: INV1(XX)=AL(XX,BLKYUP+BKJJ): next XX
CNT=0
for XXX=1 to 9
CNT=CNT+1
'if INV1(XXX)=CHUMOKU then CNT=0:XXX=9:YCHU(BKJJ+1)=1:?"よこ3行に注目値が有り" '0, 1, 2 => 1, 2, 3
if INV1(XXX)=CHUMOKU then CNT=0:XXX=9:YCHU(BKJJ+1)=1: '0, 1, 2 => 1, 2, 3
next XXX
'stop
next BKJJ
return
'----------------------------------------------------------
*BK_X_IV
'?"M3 BK_X_IV ブロックを含む縦3列の中に注目値を含む列が有るかチェック"
'?"XCHU(1)は1列目の9マスに注目値があったら1を入れる"
'?"XCHU(2)は2列目の9マスに注目値があったら1を入れる"
'?" "
XCHU(1)=0:XCHU(2)=0:XCHU(3)=0:
for BKJJ=0 to 2
    '?"ブロックの左端縦の1列9文字をINV1へコピーして注目値を調べる"
'?"注目値があればXCHU(1-3)に1が設定される"
'stop
    for YY=1 to 9: INV1(YY)=AL(BLKXLF+BKJJ,YY): next YY
CNT=0
for YYY=1 to 9
CNT=CNT+1
'if INV1(YYY)=CHUMOKU then CNT=0:YYY=9:XCHU(BKJJ+1)=1:?"縦3列に注目値が有り" '0, 1, 2 => 1, 2, 3
if INV1(YYY)=CHUMOKU then CNT=0:YYY=9:XCHU(BKJJ+1)=1: '0, 1, 2 => 1, 2, 3
next YYY
'stop
next BKJJ
return
'------------------------------------------------------------------------------
*XY_LNCK
'?"注目数値のある行(9個)および列(9個)に関わるマスには使用不可の10を入れておく"
'?"INV1 をセーブしたBLKOUTからINV1へ戻す"
'?"BLKOUTとは現在作業中のブロックのデータを1列にしたもの"
'stop
for BLKX=1 to 9 
INV1(BLKX)=BLKOUT(BLKX)
next BLKX
if YCHU(1)=0 then goto *LBL200
INV1(1)=10:INV1(2)=10:INV1(3)=10
'?" YCHU INV(1-3)=10"
*LBL200
if YCHU(2)=0 then goto *LBL210
INV1(4)=10:INV1(5)=10:INV1(6)=10:
'?" YCHU INV(4-6)=10"
*LBL210
if YCHU(3)=0 then goto *LBL220
INV1(7)=10:INV1(8)=10:INV1(9)=10:
'?" YCHU INV(7-9)=10"
*LBL220
'stop
if XCHU(1)=0 then goto *LBL300
INV1(1)=10:INV1(4)=10:INV1(7)=10:
'?" XCHU INV(1,4,7)=10"
*LBL300
if XCHU(2)=0 then goto *LBL310
INV1(2)=10:INV1(5)=10:INV1(8)=10:
'?" XCHU INV(2,5,10)=10"
*LBL310
if XCHU(3)=0 then goto *LBL320
INV1(3)=10:INV1(6)=10:INV1(9)=10:
'?" XCHU INV(3,6,10)=10"
*LBL320
'stop
return
'--------------------------------------------------------------------
*CHUSET
'?"注目数値に対応する空きマスが1つの時そこに注目数値を入れる"
'?" 空きマスの数を数え2個以上あったらリターンする"
'?" 空きマスの場所をPOJに覚えておく"
WCHK=0:POJ=0
for III=1 to 9
if INV1(III)=0 then WCHK=WCHK+1:POJ=III
next III
'if WCHK>=2 then  ?"空マスが2個以上あったのでリターンする":return
if WCHK>=2 then return
'?"空マスが1個でした"
'?" 空きマスの位置の元のXY座標を求める"
if POJ<=3 then YY=1:XX=POJ:goto *MTRX
if (POJ>=4)and(POJ<=6)then YY=2:XX=POJ-3:goto *MTRX
if(POJ<=9) then YY=3: XX=POJ-6: goto *MTRX
?"ERR 5 ":stop
'stop
*MTRX
'?"ブロックNOとの組み合わせで大元のALテーブル上のXY座標を求め注目値を置く"
if BLKNO=1 then X=XX:Y=YY: goto *DTSET
if BLKNO=2 then X=XX+3:Y=YY: goto *DTSET
if BLKNO=3 then X=XX+6:Y=YY: goto *DTSET
if BLKNO=4 then X=XX:Y=YY+3: goto *DTSET
if BLKNO=5 then X=XX+3:Y=YY+3: goto *DTSET
if BLKNO=6 then X=XX+6:Y=YY+3: goto *DTSET
if BLKNO=7 then X=XX:Y=YY+6: goto *DTSET
if BLKNO=8 then X=XX+3:Y=YY+6: goto *DTSET
if BLKNO=9 then X=XX+6:Y=YY+6: goto *DTSET
?" ERROR 10 ": stop
*DTSET
AL(X,Y)=CHUMOKU
'?" ":?" X=";X," Y=";Y," DATA=";CHUMOKU,"WCHK=";WCHK
'stop
'gosub *DISP3
'?" ================ "
'stop
return
'----------------------------------------------------------------------------
----------------------------------------------------------------------------
'注目する数値を決めてからその注目値の無いヨコ行を探し、注目値がその行のどこに当てはまるかを調べる。
*MAIN_3
'?" MAIN_3 ============================== "
'stop
'空欄のマスをサーチする
X=1:Y=1
for ALOOP=1 to 20
'?"ALOOP=";ALOOP
'stop
for CHUMOKU = 1 to 9 '********************************************************************************
'stop
for X = 1 to 9 '********************************************************************************
'?"":?" MAIN3 CHU=";CHUMOKU; " 現在調査中の縦列 左から何列目の位置か X=";X
'stop
gosub *LINE_Y
next X
next CHUMOKU
next ALOOP
'?"  M3 All end"
'gosub *DISP3B
'?" "
'gosub *DISP3
'stop
return
'----------------------------------------------------------------------------
*LINE_Y
'?" ":?" M3 LINE_Y 01 TATE JYOUGE ============================================== "
'?"これから調べるメインの縦1列の中に注目値があったら何もせずリターンする"
'stop
for YY = 1 to 9
'?"注目値チェック 主調査の縦列に注目値があれば何もせずもどる"
'?" CHUMOKU=";CHUMOKU;
'?" X=";X; " YY=";YY; " マス値=";AL( X,YY)
'if AL( X,YY)=CHUMOKU then ?"M3 この縦列内に注目値あり":YY=9: ?"":return
if AL( X,YY)=CHUMOKU then :YY=9:return
next YY
'stop
'?"M3 この縦列内に注目値が無いので何処に入るか調査開始する
'?"ALテーブルから現在の縦列1行をメインバッファ(M_BUF)にコピーして表示"
'stop
'?" X=";X
for YY=1to 9
M_BUF(YY) = AL( X,YY)
next YY
'gosub *DISP_M_BUF
'stop
if (X<=3) then goto *LEF
if (X>=4)and(X<=6)then goto *SNT
if (X>=7) then goto *RGT
?"ERR ":stop
'-------------------------------
*LEF
'?" M3 LEF_1====================================== "
'?" 1列~3列の範囲なので一番上のブロックAAAに注目値があるかチェック"
'gosub *AAA: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 AAAに注目値なし ":goto *LEF3
gosub *AAA: gosub *BK_CHU_CK: if CHUFLG=0 then goto *LEF3
'?" AAAに注目値があるので空きマスを10で埋める "
for PT=1 to 3
M_BUF(PT)=10
next PT
'gosub *DISP_INV1:gosub *DISP_M_BUF
*LEF3
'?"":?" M3 LEF_3 "
'stop
'?" M3 1列~3列の範囲なので2段目のブロックDDDに注目値があるかチェック"
'gosub *DDD: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 DDDに注目値なし ": goto *LEF4
gosub *DDD: gosub *BK_CHU_CK: if CHUFLG=0 then : goto *LEF4
'?" DDDに注目値があるので空きマスを10で埋める "
for PT=4 to 6
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*LEF4
'?"":?"M3 LEF_4 *************************"
'?" M3 1列~3列の範囲なので上から3段目のブロックGGGに注目値があるかチェック"
'gosub *GGG: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 GGGに注目値なし ": goto *LEF5
gosub *GGG: gosub *BK_CHU_CK: if CHUFLG=0 then goto *LEF5
'?" GGGに注目値があるので空きマスを10で埋める "
for PT=7 to 9
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*LEF5
'?"":?"M3 LEF 5 "
'stop
gosub *LINE_Y_YOKO
'stop
return
'----------------------------------------------------------------
*SNT
'?"":?" M3 SNT_1============================== "
'stop
'?" 4列~6列の範囲なので一番上のブロックBBBに注目値があるかチェック"
'gosub *BBB: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 BBBに注目値なし ": goto *SNT3
gosub *BBB: gosub *BK_CHU_CK: if CHUFLG=0 then goto *SNT3
'?" BBBに注目値があるので空きマスを10で埋める "
for PT=1 to 3
'if INV1(PT)=0 then M_BUF(PT)=10:?" M_BUF(PT)=10を代入する "
M_BUF(PT)=10
next PT
'gosub *DISP_INV1:gosub *DISP_M_BUF
*SNT3
'?"":?" M3 SNT_3 "
'stop
'?" 4列~6列の範囲なので2段目のブロックEEEに注目値があるかチェック"
'gosub *EEE: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 EEEに注目値なし ":goto *SNT4
gosub *EEE: gosub *BK_CHU_CK: if CHUFLG=0 then goto *SNT4

'?" EEEに注目値があるので空きマスを10で埋める "
for PT=4 to 6
'if INV1(PT)=0 then M_BUF(PT)=10:?" M_BUF(PT)=10を代入する "
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*SNT4
'?"":?" M3 SNT_4 "
'stop
'?" 4列~6列の範囲なので3段目のブロックHHHに注目値があるかチェック"
'gosub *HHH: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 HHHに注目値なし":goto *SNT5
gosub *HHH: gosub *BK_CHU_CK: if CHUFLG=0 then goto *SNT5

'?" HHHに注目値があるので空きマスを10で埋める "
for PT=7 to 9
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*SNT5
'?"":?" M3 SNT 5 "
'stop
gosub *LINE_Y_YOKO
return
'------------------------------
*RGT
'?"":?" RGT_1============================== "
'stop
'?" 7列~9列の範囲なので一番上のブロックCCCに注目値があるかチェック"
'gosub *CCC: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 CCCに注目値なし":goto *RGT3
gosub *CCC: gosub *BK_CHU_CK: if CHUFLG=0 then goto *RGT3
'?" CCCに注目値があるので空きマスを10で埋める "
for PT=1 to 3
M_BUF(PT)=10
next PT
'gosub *DISP_INV1:gosub *DISP_M_BUF
*RGT3
'?"":?" M3 RGT_3 "
'stop
'?" 7列~9列の範囲なので2番目のブロックFFFに注目値があるかチェック"
'gosub *FFF: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 FFFに注目値なし":goto *RGT4
gosub *FFF: gosub *BK_CHU_CK: if CHUFLG=0 then goto *RGT4

'?" FFFに注目値があるので空きマスを10で埋める "
for PT=4 to 6
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*RGT4
'?"":?" M3 RGT_4 "
'stop
'?" 7列~9列の範囲なので3番目のブロックIIIに注目値があるかチェック"
'gosub *III: gosub *BK_CHU_CK: if CHUFLG=0 then ?"M3 CHUFLG=0 IIIに注目値なし":goto *RGT5
gosub *III: gosub *BK_CHU_CK: if CHUFLG=0 then goto *RGT5
'?" IIIに注目値があるので空きマスを10で埋める "
for PT=7 to 9
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*RGT5
'?"":?" M3 RGT 5 "
gosub *LINE_Y_YOKO
return
'----------------------------------------------------------------------------
*LINE_Y_YOKO
'?" *M3 LINE_Y_YOKO===================================================="
'?"調査中の縦列に存在する空きマスのヨコ1行をチェックして注目値があるか見る"
'stop
for YYY=1 to 9
'?" YYY=";YYY;:?" CHUMOKU=";CHUMOKU
'if M_BUF(YYY)<>0 then ?"M_BUF(YYY)<>0の時 ":goto *YOKO
    if M_BUF(YYY)<>0 then  goto *YOKO
'?"M_BUF(YYY)=0 空きマスなのでよこ1行に注目値があるかチェックする"
CNT=0
for XXX=1 to 9
'?" XXX=";XXX; " YYY=";YYY; " マス値=";AL(XXX,YYY)
'if AL( XXX,YYY)=CHUMOKU then M_BUF(YYY)=10: ?"M3 このよこ列内に注目値あり":XXX=9:
if AL( XXX,YYY)=CHUMOKU then M_BUF(YYY)=10:XXX=9:
            'gosub *DISP_M_BUF
'stop
next XXX
*YOKO
next YYY
'gosub *DISP_M_BUF
'stop
KARA=0:ZERO_Y=0
for YYY=1 to 9
if M_BUF(YYY)=0 then KARA=KARA+1:ZERO_Y=YYY
next YYY
'if KARA=1 then AL(X,ZERO_Y)=CHUMOKU:M_BUF(ZERO_Y)=CHUMOKU:?" KARA=1 SET OK  X,ZERO_Y=";:?X;ZERO_Y
if KARA=1 then AL(X,ZERO_Y)=CHUMOKU:M_BUF(ZERO_Y)=CHUMOKU
'?" X,ZERO_Y =";X;ZERO_Y
'?" KARA=";KARA;
'?" ZERO_Y=";ZERO_Y;
'?" CHUMOKU=";CHUMOKU
'gosub *DISP_INV1:gosub *DISP_M_BUF:gosub *DISP3
'?"M3 end M3 end M3 end"
'stop
return

'---------------------------------------------------------
*BK_CHU_CK
'?"":?"*BK_CHU_CK 01================================================= "
'?"通過するブロック(3*3)の中に注目値が含まれるかチェック"
'gosub *DISP_INV1
CHUFLG=0
CNT=0:CHUFLG=0
'   ?" CHUMOKU=";CHUMOKU;
for XXX=1 to 9
CNT=CNT+1
'if INV1(XXX)=CHUMOKU then CHUFLG=1:CNT=0:?" BK_CHU_CK 注目値あり ":XXX=9:goto *BK_CHU_CK03
if INV1(XXX)=CHUMOKU then CHUFLG=1:CNT=0:XXX=9:goto *BK_CHU_CK03
next XXX
'?" BK_CHU_CK 注目値無し "
*BK_CHU_CK03
return

'----------------------------------------------------------------------------
'注目する数値を決めてからその注目値の無いヨコ行を探し、注目値がその行のどこに当てはまるかを調べる。
*MAIN_4
'?" MAIN_4 ============================== "
'stop
'空欄のマスをサーチする
X=1:Y=1
for ALOOP = 1 to 20
'?"ALOOP=";ALOOP
'stop
for CHUMOKU = 1 to 9 '***********************************************
'stop
for Y = 1 to 9 ' **********************************************
'?" MAIN4 CHU=";CHUMOKU; " 現在調査中の横列 上から何行目の位置か Y=";Y
'stop
gosub *LINE_X ' Y => X
next Y ' X => Y
next CHUMOKU
next ALOOP
'?" M4 All end"
'gosub *DISP3B
'?" "
'gosub *DISP3
'stop
return
'----------------------------------------------------------------------------
*LINE_X ' Y => X
'?" ":?" M4 LINE_X 01============================================== "
'?" これから調べる横1行の中に注目値があったら何もせずリターンする"
'stop
for XX = 1 to 9                ' YY =>  XX
'?" 注目値チェック 主調査の横行に注目値があれば何もせずもどる"
'?" M4 CHUMOKU=";CHUMOKU;
'?" XX=";XX; " Y=";Y;" マス値=";AL( XX,Y)
'if AL( XX,Y)=CHUMOKU then ?" M4 この横行内に注目値あり ":XX=9:return :'stop
if AL( XX,Y)=CHUMOKU then XX=9:return :'stop
next XX

'?"この横行内に注目値が無いので何処に入るか調査開始する
'?"ALテーブルから現在の横行 1行をメインバッファ(M_BUF)にコピーして表示"
'stop
'?" M4  XX=";XX;" Y=";Y
for XX=1to 9 ' YY => XX
M_BUF(XX) = AL( XX,Y)
next XX ' YY => XX
'gosub *DISP_M_BUF
'stop
if (Y<=3) then goto *UP            ' X => Y           *LEF => *UP
if (Y>=4)and(Y<=6)then goto *MD ' X => Y *SNT => *MD
if (Y>=7) then goto *LO ' X => Y *RGT => *LO
?"ERR ":stop
'-------------------------------
*UP '*LEF => *UP
'?" M4 UP_1====================================================== "
'?" 1行~3行の範囲なので一番上のブロックAAAに注目値があるかチェック"
'gosub *AAA: gosub *BK_CHU_CK: if CHUFLG=0 then ?" M4 CHUFLG=0 ":goto *UP3
gosub *AAA: gosub *BK_CHU_CK: if CHUFLG=0 then goto *UP3
'?" AAAに注目値があるので空きマスを10で埋める "
for PT=1 to 3
M_BUF(PT)=10
next PT
'gosub *DISP_INV1:gosub *DISP_M_BUF
*UP3                                                  'LEF => UP
'?"":?" M4 UP_3 "
'stop
'?" M4 1行~3行の範囲なので2行目のブロックBBBに注目値があるかチェック"
gosub *BBB: gosub *BK_CHU_CK: if CHUFLG=0 then goto *UP4
'?" M4 BBBに注目値があるので空きマスを10で埋める"

for PT=4 to 6
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*UP4
'?"":?" M4 UP_4 ================================================"
'?" M4 1行~3行の範囲なので左から3行目のブロックCCCに注目値があるかチェック"
gosub *CCC: gosub *BK_CHU_CK: if CHUFLG=0 then goto *UP5
'?" CCCに注目値があるので空きマスを10で埋める "
for PT=7 to 9
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*UP5
'?"":?"M4 UP 5 "
'stop
gosub *LINE_X_TATE
'stop
return
'---------------------------------------------------------------
*MD ' SNT => MD
'?"":?" M4 MD_1 =============================== "
'stop
'?" 4行~6行の範囲なので一番左のブロックBBBに注目値があるかチェック"
gosub *DDD: gosub *BK_CHU_CK: if CHUFLG=0 then goto *MD3
'?" DDDに注目値があるので空きマスを10で埋める "
for PT=1 to 3
M_BUF(PT)=10
next PT
'gosub *DISP_INV1:gosub *DISP_M_BUF
*MD3
'?"":?" M4 MD_3 "
'stop
'?" 4行~6行の範囲なので左から2個目のブロックEEEに注目値があるかチェック"
gosub *EEE: gosub *BK_CHU_CK: if CHUFLG=0 then goto *MD4
'?" EEEに注目値があるので空きマスを10で埋める "
for PT=4 to 6
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*MD4
'?"":?" M4 SNT_4 "
'stop
'?" 4行~6行の範囲なので左から3個目のブロックFFFに注目値があるかチェック"
gosub *FFF: gosub *BK_CHU_CK: if CHUFLG=0 then goto *MD5
for PT=7 to 9
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*MD5
'?"":?"M4 MD 5 "
'stop
gosub *LINE_X_TATE               ' *LINE_Y_YOKO  =>  *LINE_X_TATE
'stop
return
'------------------------------
*LO 'RGT => LO
'?"":?" M4 LO_1========================= "
'?" 7行~9行の範囲なので左から2個目のブロックGGGに注目値があるかチェック"
'stop
gosub *GGG: gosub *BK_CHU_CK: if CHUFLG=0 then goto *LO3
'?" GGGに注目値があるので空きマスを10で埋める "
for PT=1 to 3
M_BUF(PT)=10
next PT
'gosub *DISP_INV1:gosub *DISP_M_BUF
*LO3
'?"":?" M4 LO_3 "
'stop
'?" 7行~9行の範囲なので一番左のブロックGGGに注目値があるかチェック"
gosub *HHH: gosub *BK_CHU_CK: if CHUFLG=0 then goto *LO4
'?" HHHに注目値があるので空きマスを10で埋める "
for PT=4 to 6
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*LO4
'?"":?" M4 LO_4 "
'stop
'?" 7行~9行の範囲なので左から2個目のブロックGGGに注目値があるかチェック"
gosub *III: gosub *BK_CHU_CK: if CHUFLG=0 then goto *LO5
'?" GGGに注目値があるので空きマスを10で埋める "
for PT=7 to 9
M_BUF(PT)=10
next PT
'gosub *DISP_INV1: gosub *DISP_M_BUF
*LO5
'?"":?" M4 LO 5 "
'stop
gosub *LINE_X_TATE 
'stop
return
'----------------------------------------------------------------------------
*LINE_X_TATE ' *LINE_Y_YOKO
'?" M4 LINE_X_TATE============================================= "
'?"調査中のMAINの横行に存在する空きマスのSUB縦1列をチェックして注目値があるか見る"
'stop
for XXX=1 to 9                            'YYY => XXX
'?" XXX=";XXX;:?" CHUMOKU=";CHUMOKU
'if M_BUF(XXX)<>0 then ?"M_BUF(XXX)<>0の時 ":goto *TATE
    if M_BUF(XXX)<>0 then goto *TATE 
CNT=0
'?"M_BUF(XXX)=0 空きマスなのでSUB_縦1列に注目値があるかチェックする"
CNT=0
for YYY=1 to 9
'?" XXX=";XXX;:?" YYY=";YYY;:?"値=";AL(XXX,YYY)
if AL( XXX,YYY)=CHUMOKU then M_BUF(XXX)=10:YYY=9:

'gosub *DISP_M_BUF
'stop
next YYY
*TATE
next XXX
'gosub *DISP_M_BUF
'stop
KARA=0:ZERO_X=0
for XXX=1 to 9
if M_BUF(XXX)=0 then KARA=KARA+1:ZERO_X=XXX
next XXX
if KARA=1 then AL(ZERO_X,Y)=CHUMOKU:M_BUF(ZERO_X)=CHUMOKU:?" KARA=1 SET OK  ZERO_X,Y=";:? ZERO_X;Y
'?" ZERO_X,Y =";ZERO_X;Y
'?" KARA=";KARA;
'?" ZERO_X=";ZERO_X;
'?" CHUMOKU=";CHUMOKU
'gosub *DISP_INV1:gosub *DISP_M_BUF:gosub *DISP3
'?"M4 end M4 end M4 end"
'stop
return
'----------------------------------------------------------------------------
 *BLKOUTCOPY
for BLKX=1 to 9
BLKOUT(BLKX)=INV1(BLKX)
next BLKX
return
'---------------------------------------
*ALBKCOPY
?" "
for YYY=1 to 9
for XXX=1 to 9
ALBK(XXX,YYY)=AL(XXX,YYY)
next XXX
next YYY
return

'--------------------------------------------------------------------------
*DISP_M_BUF
'?"":?" M_BUF=";
for YY=1to 9
'?M_BUF(YY);
next YY
'?" "
return
'----------------------------------------------------------------------------
*DISP_INV1
*DISP1
'?" INV1 =";
for KKK=1 to 9
'?INV1(KKK);
next kkk
return
'---------------------------------------
'*DISP2
'?" INV2(1~)=";
for KKK=1 to 9
'?INV2(KKK);
next kkk
return
'---------------------------------------
*DISP3
'?" "
for YYY=1 to 9
for XXX=1 to 9
?AL(XXX,YYY);
if XXX=3 then ?" ";
if XXX=6 then ?" ";
next XXX
if YYY=3 then ?" "
if YYY=6 then ?" "
?" "
next YYY
return
'---------------------------------------
*DISP3B
?" "
for YYY=1 to 9
for XXX=1 to 9
?ALBK(XXX,YYY);
if XXX=3 then ?" ";
if XXX=6 then ?" ";
next XXX
' if YYY=3 then ?" "
' if YYY=6 then ?" "
?" "
next YYY
return
'---------------------------------------
'*DISP27
for X12=1 to 27
? CHK(X12);
if X12=9 then ?" "
if X12=18 then ?" "
next X12
?" "
return
'-----------------------------------------
'*DISP_BF
?" "
?" BF(1~9)=";
for KKK=1 to 9
?BF(KKK);
next kkk
return
'---------------------------------------
'問題のテーブルデータの設定
'ニコリ 数独攻略ガイド P51 No16
'M1,2,3,4 全OK    20180804
*TBL_ABCD

data 2,0,1, 6,0,0, 0,0,9
data 0,0,0, 0,0,8, 2,0,0
data 3,0,0, 0,4,0, 0,5,0
data 9,0,0, 0,0,0, 0,2,0
data 0,0,8, 0,0,0, 3,0,0
data 0,4,0, 0,0,0, 0,0,6
data 0,3,0, 0,5,0, 0,0,8
data 0,0,9, 7,0,0, 0,0,0
data 6,0,0, 0,0,1, 4,0,5

for YY=1 to 9
for XX=1 to 9
read AL(XX,YY)
next XX
next YY
return



これで終わりです。




今年は、猛烈な暑さのため、スイカはみなひび割れてしまいました。
トウモロコシも半分以上のものが乾燥してダメでした。
この花だけは、毎年元気で咲いてくれています。

c0335218_09115141.jpg

朝顔も元気ですね。
c0335218_09112206.jpg

***************

++++++++++++++ 
-------------------------



by telmic-gunma | 2018-08-08 10:21 | HP電卓 | Trackback | Comments(2)

前回の4x4の解き方をそのまま9x9の拡張してやってみました。
しかし4x4ではうまく行っていた方法も9x9では単純な問題しか解くことができなくなりました。
そこで数独の解説書などを参考に新たな方法に挑戦してみました。
ここでも 人力で解くことは可能なのですが、それをプログラム化するところで四苦八苦してしまいました。
何とか出来上がったソフトでいろいろ試したのですが、やはりオールマイティーということはなくて、

限られた問題しか解けません。
やはり いろいろな問題を解くには、いろいろな方式のプログラムを作りそれを組み合わせていかなくてはならないようです。

今回の方式は、3x3の一つのブロックに注目しその中にない数値がどの場所ならば置くことが出来るかをさがしていく方法です。
これは ニコリの「全問解説数独」のP6に載っている方法をプログラム化したものです。

1) 1~9までの注目する数値を決める(実際は「1」から順番にやる)
2) その数値がない3x3のブロックを順に見つける。(今回は上の右端)
3) 横方向の行で注目数値「1」が入らないところを見つける。
   a行 b行には「1」が有るので入らない。
4) 縦方向で「1」が入らないのは I列です。
5) 上記より「1」の入る可能性はGcとHcです。
6) しかしHcはすでに「2」が入っている。
7) ゆえに残るのはGcだけなのでここに「1」が入ります。

表題に出している「HP電卓」はどうしたのと言われそうですが、ベーシックで問題が解けるようになったら、人間コンパイラになってHP電卓に書き直してみようと思います。
c0335218_19035428.jpg



この問題は 最初にやった4x4の延長の方式では解くことが出来ませんでした。
今回の各ブロックに注目してやる方法で解けました。
だけど この方式でも解けない問題がわんさか有ります。

c0335218_19045525.jpg



画面上側が問題です。  問題のブランクの所には、ゼロが入っています。
下側はパソコンが出した回答です。
Fベーシック97で3秒ほどかかりました。
デバッグのための途中経過を表示しているので、その時間がかかっていると思います。


c0335218_19042435.jpg





( Fベーシック97  富士通が作った20年前のBASIC言語をWinXPで動かしてます)


'数独(ナンプレ) SDOK9x9_30D 2018-06-20
'基本テーブル配列の定義
dim AL(9,9)
dim CHK(27)
dim INV1(9)
'
'問題のテーブルデータの設定
gosub *TBL_P6
gosub *DISP3
stop
'空欄のマスをサーチする
for ALOOP=1 to 10
for CHUMOKU=1 to 9
for BLKNO=1 to 9 ' *AA: 1 *BB: 2 ----
'          ?" CHUMOKU=";CHUMOKU;  :?" BLKNO=";BLKNO;
'stop
gosub *BLOCK
next BLKNO
next CHUMOKU
next ALOOP
?"  All end"
gosub *DISP3
stop:stop
'------------------------------------------------------------
*BLOCK
if BLKNO=1 then BLKYUP=1:BLKXLF=1:gosub *AAA:goto *BLKXX
if BLKNO=2 then BLKYUP=1:BLKXLF=4:gosub *BBB:goto *BLKXX
if BLKNO=3 then BLKYUP=1:BLKXLF=7:gosub *CCC:goto *BLKXX
if BLKNO=4 then BLKYUP=4:BLKXLF=1:gosub *DDD:goto *BLKXX
if BLKNO=5 then BLKYUP=4:BLKXLF=4:gosub *EEE:goto *BLKXX
if BLKNO=6 then BLKYUP=4:BLKXLF=7:gosub *FFF:goto *BLKXX
if BLKNO=7 then BLKYUP=7:BLKXLF=1:gosub *GGG:goto *BLKXX
if BLKNO=8 then BLKYUP=7:BLKXLF=4:gosub *HHH:goto *BLKXX
if BLKNO=9 then BLKYUP=7:BLKXLF=7:gosub *III:goto *BLKXX
?" BLK ERR":stop
'---------------------------------------------------------------
*BLKXX
CNT=0
'このブロックの中に注目している(CHUMOKU)数値があれば何もせずリターン
for XXX=1 to 9
CNT=CNT+1
if INV1(XXX)=CHUMOKU then CNT=0:XXX=9:?"同一文字有り":return
next XXX
'----------------------------------------
YCHU(1)=0:YCHU(2)=0:YCHU(3)=0:
for BKJJ=0 to 2
'ブロックの上横1行9文字をINV1へコピー
for XX=1 to 9: INV1(XX)=AL(XX,BLKYUP+BKJJ): next XX
CNT=0
for XXX=1 to 9
CNT=CNT+1
if INV1(XXX)=CHUMOKU then CNT=0:XXX=9:YCHU(BKJJ+1)=1
next XXX
next BKJJ
'-------------------------
XCHU(1)=0:XCHU(2)=0:XCHU(3)=0:
for BKJJ=0 to 2
'ブロックの左縦から1行9文字をINV1へコピー
for YY=1 to 9: INV1(YY)=AL(BLKXLF+BKJJ,YY): next YY
CNT=0
for YYY=1 to 9
CNT=CNT+1
if INV1(YYY)=CHUMOKU then CNT=0:YYY=9:XCHU(BKJJ+1)=1
next YYY
next BKJJ
'-------------------------------------------
for BLKX=1 to 9
INV1(BLKX)=BLKOUT(BLKX)
next BLKX
if YCHU(1)=0 then goto *LBL200
INV1(1)=10:INV1(2)=10:INV1(3)=10:
*LBL200
if YCHU(2)=0 then goto *LBL210
INV1(4)=10:INV1(5)=10:INV1(6)=10:
*LBL210
if YCHU(3)=0 then goto *LBL220
INV1(7)=10:INV1(8)=10:INV1(9)=10:
*LBL220
if XCHU(1)=0 then goto *LBL300
INV1(1)=10:INV1(4)=10:INV1(7)=10:
*LBL300
if XCHU(2)=0 then goto *LBL310
INV1(2)=10:INV1(5)=10:INV1(8)=10:
*LBL310
if XCHU(3)=0 then goto *LBL320
INV1(3)=10:INV1(6)=10:INV1(9)=10:
*LBL320
WCHK=0
for III=1 to 9
if INV1(III)=0 then WCHK=WCHK+1:POJ=III
next III
if WCHK>=2 then ?"空マスが2個以上あった":return
if POJ<=3 then YY=1:XX=POJ:goto *MTRX
if (POJ>=4)and(POJ<=6)then YY=2:XX=POJ-3:goto *MTRX
if(POJ<=9) then YY=3: XX=POJ-6: goto *MTRX
?"ERR 5 ":stop
*MTRX
if BLKNO=1 then X=XX:Y=YY: goto *DTSET
if BLKNO=2 then X=XX+3:Y=YY: goto *DTSET
if BLKNO=3 then X=XX+6:Y=YY: goto *DTSET
if BLKNO=4 then X=XX:Y=YY+3: goto *DTSET
if BLKNO=5 then X=XX+3:Y=YY+3: goto *DTSET
if BLKNO=6 then X=XX+6:Y=YY+3: goto *DTSET
if BLKNO=7 then X=XX:Y=YY+6: goto *DTSET
if BLKNO=8 then X=XX+3:Y=YY+6: goto *DTSET
if BLKNO=9 then X=XX+6:Y=YY+6: goto *DTSET
?" ERROR 10 ": stop
*DTSET
AL(X,Y)=CHUMOKU
ALLCNT=ALLCNT+1
?" ":?" X=";X," Y=";Y," DATA=";CHUMOKU,"ALL CNT=";ALLCNT
'gosub *DISP3
?" ================ "
return
'---------------------------------------------------------------
*AAA
INV1(1)=AL(1,1): INV1(2)=AL(2,1): INV1(3)=AL(3,1)
INV1(4)=AL(1,2): INV1(5)=AL(2,2): INV1(6)=AL(3,2)
INV1(7)=AL(1,3): INV1(8)=AL(2,3): INV1(9)=AL(3,3)
gosub *BLKOUTCOPY
return
*BBB
INV1(1)=AL(4,1): INV1(2)=AL(5,1): INV1(3)=AL(6,1)
INV1(4)=AL(4,2): INV1(5)=AL(5,2): INV1(6)=AL(6,2)
INV1(7)=AL(4,3): INV1(8)=AL(5,3): INV1(9)=AL(6,3)
gosub *BLKOUTCOPY
return
*CCC
INV1(1)=AL(7,1): INV1(2)=AL(8,1): INV1(3)=AL(9,1)
INV1(4)=AL(7,2): INV1(5)=AL(8,2): INV1(6)=AL(9,2)
INV1(7)=AL(7,3): INV1(8)=AL(8,3): INV1(9)=AL(9,3)
gosub *BLKOUTCOPY
return
*DDD
INV1(1)=AL(1,4): INV1(2)=AL(2,4): INV1(3)=AL(3,4)
INV1(4)=AL(1,5): INV1(5)=AL(2,5): INV1(6)=AL(3,5)
INV1(7)=AL(1,6): INV1(8)=AL(2,6): INV1(9)=AL(3,6)
gosub *BLKOUTCOPY
return
*EEE
INV1(1)=AL(4,4): INV1(2)=AL(5,4): INV1(3)=AL(6,4)
INV1(4)=AL(4,5): INV1(5)=AL(5,5): INV1(6)=AL(6,5)
INV1(7)=AL(4,6): INV1(8)=AL(5,6): INV1(9)=AL(6,6)
gosub *BLKOUTCOPY
return
*FFF
INV1(1)=AL(7,4): INV1(2)=AL(8,4): INV1(3)=AL(9,4)
INV1(4)=AL(7,5): INV1(5)=AL(8,5): INV1(6)=AL(9,5)
INV1(7)=AL(7,6): INV1(8)=AL(8,6): INV1(9)=AL(9,6)
gosub *BLKOUTCOPY
return
*GGG
INV1(1)=AL(1,7): INV1(2)=AL(2,7): INV1(3)=AL(3,7)
INV1(4)=AL(1,8): INV1(5)=AL(2,8): INV1(6)=AL(3,8)
INV1(7)=AL(1,9): INV1(8)=AL(2,9): INV1(9)=AL(3,9)
gosub *BLKOUTCOPY
return
*HHH
INV1(1)=AL(4,7): INV1(2)=AL(5,7): INV1(3)=AL(6,7)
INV1(4)=AL(4,8): INV1(5)=AL(5,8): INV1(6)=AL(6,8)
INV1(7)=AL(4,9): INV1(8)=AL(5,9): INV1(9)=AL(6,9)
gosub *BLKOUTCOPY
return
*III
INV1(1)=AL(7,7): INV1(2)=AL(8,7): INV1(3)=AL(9,7)
INV1(4)=AL(7,8): INV1(5)=AL(8,8): INV1(6)=AL(9,8)
INV1(7)=AL(7,9): INV1(8)=AL(8,9): INV1(9)=AL(9,9)
gosub *BLKOUTCOPY
return
'----------------------------------------------------------------------------
*BLKOUTCOPY
for BLKX=1 to 9
BLKOUT(BLKX)=INV1(BLKX)
next BLKX
return
'----------------------------------------------------------------------------
*DISP1
'?" INV1(1~)=";
for KKK=1 to 9
?INV1(KKK);
next kkk
return
'---------------------------------------
*DISP3
?" "
for YYY=1 to 9
for XXX=1 to 9
?AL(XXX,YYY);
if XXX=3 then ?" ";
if XXX=6 then ?" ";
next XXX
if YYY=3 then ?" "
if YYY=6 then ?" "
?" "
next YYY
return
'---------------------------------------
'問題のテーブルデータの設定
'ニコリ全問解説数独P6
*TBL_P6
data 6,0,2,0,0,1,0,0,5
data 0,0,1,0,0,0,6,0,0
data 0,8,0,0,5,0,0,2,3
data 3,0,0,9,0,2,0,0,0
data 0,0,4,0,0,0,8,0,0
data 0,0,0,1,0,3,0,0,7
data 5,1,0,0,6,0,0,8,0
data 0,0,3,0,0,0,2,0,0
data 2,0,0,7,0,0,5,0,1

for YY=1 to 9
for XX=1 to 9
read AL(XX,YY)
next XX
next YY
return





今我が家の庭に大きく咲きだした変わった形のアジサイ
ばあちゃんが大事にしていた形見です。

c0335218_20195548.jpg

とんがり帽子の形をしています。 まだこれから大きくなるところですね。

c0335218_20200528.jpg


何という花?



c0335218_20201743.jpg

葉っぱの中心に紫色のかわいい花が咲いています。
c0335218_20204033.jpg






by telmic-gunma | 2018-06-20 20:41 | HP電卓 | Trackback | Comments(6)

101歳で現役のお医者さん(女性)の記事を読んでいたら、ボケ防止で「数独」をやっていると書いてありました。
私にとっては、 「数独」って何 初めて見たけど  と言う感じでした。

「数独」を調べてみたらもう一つの呼び名が「ナンプレ」と言い、クロスワードパズルの数字版のようなもと分かりました。
たてよこ 9マス X 9マス に1~9の一桁の数字をダブらないように入れていきます。
最初に問題として数字がいくつか入れてあり、解く人は空いたマスに約束に則り埋めていきます。
入門用としてやさしい 4マス X 4マス のものや 6マス X 6マスの物などがあります。

早速 初級の問題やってみました。かなり頭を使いましたね。
このお医者さんの歳まであと30年くらい。
そんな先まで私の脳みそ大丈夫か?


これは標準の大きさ 9X9マスのものです。 ルールは
1、 ひとつの横の列には、1から9までの数字が1回ずつ入る。
2、 ひとつの立ての列には、1から9までの数字が1回ずつ入る。
3、 太い線で囲まれたブロックに、1から9までの数字が1回ずつ入る。


c0335218_20592059.jpg



これは一番簡単な 4X4マスのものです。
1、 ひとつの横の列には、1から4までの数字が1回ずつ入る。
2、 ひとつの立ての列には、1から4までの数字が1回ずつ入る。
3、 太い線で囲まれたブロックに、1から4までの数字が1回ずつ入る。


c0335218_20590340.jpg

答えを書いてみます。  これは初級の初級です。
空いたマスにその行にない1~4の数字を選ぶわけです。

c0335218_20592634.jpg


本もたくさん出版されています。
「数独」と「ナンプレ」 この名前の違いは出版社のちがいですか?


c0335218_20584712.jpg
ネットを見るとこの「数独」をパソコンで解くソフトを何人も発表しています。
この「数独」をHP電卓を使って解くことができれば最高に面白いのではないかとおもいつきました。

まずはメモリー容量や論理の動きなど皆目わからないので、BASICでやってみます。
最初はごく普通に、縦横のデータから可能性のある数値を導き出してやろうとしました。
しかしパズルを計算機で解くというのは、普通の計算ソフトや制御ソフトとは違うのですね。
人間の頭で考えるとすぐできることが、ソフトに置き換えるというのはすごく難しいようです。
行ったり戻ったり もうぐちゃぐちゃ。 二週間考えてもソフトできませんでした。(私だけかもしれませんが)
逆に考えると、人間の脳というのは、そんなプログラムが出来ていない問題でもちゃんと答えをだしてくれるというすごいものなのですね。
そんな時思いついたのは、データを入力した表が正しいかいなかは、パソコンで瞬時に解るのですからデータを乱数で作ってもいいのじゃないかということです。
正攻法はとりあえず諦めて 乱数を発生させて空欄にはめ込んで、正解になるまで何度も繰り返すという強引な方法でやってみました。

これは エプソンの PC386LSC です。
NECのPC9801のソフトがそのままうごきます。
30年近く前のものになるのでしょうか。
デスクトップパソコンとノートパソコンの丁度あいだと言ったところですね。
キーはデスクトップと同じで押しやすく 出張にも持って行きやすかったので気に入ってました。


c0335218_20585542.jpg
やってみた結果です。
4X4マスで合計16マスあるうち空欄の数で答えの出るまでの回数は大幅に違います。
空欄 2個  正解までの演算回数 10回
空欄 3個  正解までの演算回数 82回
空欄 4個  正解までの演算回数 450回
空欄 5個  正解までの演算回数 1384回
空欄 6個  正解までの演算回数 3737回
空欄 7個  正解までの演算回数 9038回  (これで 約 7分の時間がかかりました。)
空欄 8個  正解までの演算回数 200000回やっても答えは出ませんでした。(1時間以上)

やはり人間の頭で考えるような普通の手順で解くべきですね。
それと この問題はHP電卓で解けるかしら。 グダグダ考えているより作ってしまった方が早いですね。


N88BASICで 4X4を乱数で強引に解くプログラムです。 これは一日も掛からず出来ました。

1' SAVE "ADOK_M36",A
100'
103 RANDOMIZE
105 DIM X(20)
110 GOSUB 9800         ’問題のデータを読み込む
150 GOSUB 9000         ’問題を16マスに表示して確認する
170 '
180 GOSUB 9800         ’空欄のある問題のデータを読み込む
200 GOSUB 4000         ’すべての空欄(空いたマス)を乱数で埋める。
300 GOSUB 5000         ’縦横すべての条件を満たしているか確認する
310 CNT=CNT+1: PRINT CNT   ’乱数を入れて確認した回数を表示する
320 IF ER<>0 THEN GOTO 180  ’データが条件を満たさなければ180行がらやり直し
370 GOSUB 9000         ’条件を満たしたので完成した表16マスを表示する
380 '
990 PRINT" OK END "      ’完成したので"OK" を画面に表示する
995 STOP '停止して終了

4000'              16マスのうち空欄に乱数を入れる
4100 FOR I=1 TO 16
4110 A=( RND X 4 ) + 1    ’1~4の乱数を発生させる
4120 JF X(I)=0 THEN X(I)=A  ’空欄ならば乱数を入れる
4180 NEXT I
4250 RETURN

5000' 4文字単位で処理するためにデータ転送して同じ数字が無いか比較する
5510 S1=X(1):S2=X(2):S3=X(5):S4=X(6):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'AA
5520 S1=X(3):S2=X(4):S3=X(7):S4=X(8):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'BB
5530 S1=X(9):S2=X(10):S3=X(13):S4=X(14):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'CC
5540 S1=X(11):S2=X(12):S3=X(15):S4=X(16):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'DD

5545 '横の行 4文字のデータ比較
5550 S1=X(1):S2=X(2):S3=X(3):S4=X(4):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'A1
5560 S1=X(5):S2=X(6):S3=X(7):S4=X(8):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'A2
5570 S1=X(9):S2=X(10):S3=X(11):S4=X(12):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'A3
5580 S1=X(13):S2=X(14):S3=X(15):S4=X(16):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'A4

5585 '縦の列 4文字のデータ比較
5590 S1=X(1):S2=X(5):S3=X(9):S4=X(13):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'B1
5600 S1=X(2):S2=X(6):S3=X(10):S4=X(14):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'B2
5610 S1=X(3):S2=X(7):S3=X(11):S4=X(15):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'B3
5620 S1=X(4):S2=X(8):S3=X(12):S4=X(16):GOSUB 5700: IF ER<>0 THEN GOTO 5650 'B4
5630 PRINT "Double Check OK"
5650 RETURN

5700 ' 4文字についてのみ同じものが無いか比較する
5710 ER=0
5720 IF S1<>0 AND S1=S2 THEN ER=1: GOTO 5760
5725 IF S1<>0 AND S1=S3 THEN ER=1: GOTO 5760
5730 IF S1<>0 AND S1=S4 THEN ER=1: GOTO 5760
5735 IF S2<>0 AND S2=S3 THEN ER=1: GOTO 5760
5740 IF S2<>0 AND S2=S4 THEN ER=1: GOTO 5760
5745 IF S3<>0 AND S3=S4 THEN ER=1: GOTO 5760
5760 RETURN

9000 ' 全16文字データを画面表示する
9010 PRINT "X 1=" ; X(1); X(2); X(3); X(4)
9015 PRINT "X 5 =" ; X(5); X(6); X(7); X(8)
9020 PRINT "X 9 =" ; X(9); X(10); X(11); X(12)
9025 PRINT "X13=" ; X(13); X(14); X(15); X(16)
9030 RETURN

9800 ' 問題データ  (ゼロは空欄のことです)
9810 X(1)=0:X(2)=4:X(3)=1:X(4)=2
9810 X(5)=1:X(6)=2:X(7)=3:X(8)=4
9810 X(9)=2:X(10)=3:X(11)=4:X(12)=1
9810 X(13)=4:X(14)=1:X(15)=0:X(16)=3
9830 RETURN




我が家の庭に咲いている花


西洋シャクナゲ
c0335218_21445058.jpg





昔は 「テツセン」 と言ったそうです。

c0335218_21452092.jpg
c0335218_21470978.jpg


散歩している途中の道端にあるリンゴの木です。 
ちょうど花が咲いていました。

c0335218_21453574.jpg

c0335218_21454449.jpg

道ばたに咲いていたきれいな花、 名前は解りません。

c0335218_21445672.jpg

















by telmic-gunma | 2018-05-12 12:58 | HP電卓 | Trackback | Comments(10)