
三角関数値が異常です - しばっち
2026/04/12 (Sun) 07:39:59
三角関数値が異常です
WINDOWS版の十進BASIC(32ビット版) ver7880において
2進モード、複素数モードでの三角関数値が下記のように
異常な値になります。
10進モードでは問題ありませんでした。
精度不足が原因かと思われます。
LET B=15
LET X=1
FOR N=1 TO 30
PRINT N;COS(B^N*X*PI);SIN(B^N*X*PI)
NEXT N
END
実行結果
1 -1 5.38962320953407E-15
2 -1 3.8211783997405E-14
3 -1 3.45803084517843E-13
4 -1 1.97389614961345E-11
5 -1 3.41499483314141E-11
6 -1 4.23753952343313E-9
7 -.999999999999999 3.37607704638016E-8
8 -.999999999999804 6.25620846507764E-7
9 -.999999999993294 3.66226679917138E-6
10 -.999999999958069 9.15763480006557E-6
11 -.999999647873398 -8.39197879495783E-4
12 -.999538539588589 3.03761070104653E-2
13 -.999019433754421 -4.42738182337559E-2
14 -.718394338073019 .695636093819627
15 -.871013768888734 -.491258602373783
16 2.06352634360854E+19 2.06352634360854E+19
17 3.09528951541281E+20 3.09528951541281E+20
18 4.64293427311922E+21 4.64293427311922E+21
19 6.96440140967883E+22 6.96440140967883E+22
20 1.04466021145182E+24 1.04466021145182E+24
21 1.56699031717774E+25 1.56699031717774E+25
22 2.35048547576661E+26 2.35048547576661E+26
23 3.52572821364991E+27 3.52572821364991E+27
24 5.28859232047486E+28 5.28859232047486E+28
25 7.9328884807123E+29 7.9328884807123E+29
26 1.18993327210684E+31 1.18993327210684E+31
27 1.78489990816027E+32 1.78489990816027E+32
28 2.6773498622404E+33 2.6773498622404E+33
29 4.0160247933606E+34 4.0160247933606E+34
30 6.0240371900409E+35 6.0240371900409E+35
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/12 (Sun) 08:53:30
ご報告ありがとうございした。
原因は,Intel FPUのFSIN,FCOS命令をそのまま使っていたことです。
マニュアルをよく読むと,引数は -2^63 ~ 2^63 の範囲でなければならないようです。
倍精度数の精度は53ビットなので,その範囲外の数値に対して三角関数の値を求めることは無意味ですが,どう扱うのが適切か,検討します。
Re: 三角関数値が異常です - しばっち
2026/04/19 (Sun) 07:55:10
周期性があるのでMOD関数を利用すれば計算自体は可能ですが
誤差が累積していくようです
https://ja.wikipedia.org/wiki/ワイエルシュトラス関数
LET B=23
LET X=.4
FOR I=1 TO 15
LET C=B^I*PI*X
LET X=COS(C)
LET Y=COS(MOD(C,2*PI))
PRINT I;X;Y;X-Y
NEXT I
END
実行結果
1 -.809016994374948 -.809016994374948 -5.55111512312578E-16
2 .99555901481267 .995559014812675 -4.88498130835069E-15
3 -.994477987872487 -.994477987872643 1.55653268052447E-13
4 .624271813435692 .624271813462338 -2.66459077025161E-11
5 5.18260078207372E-2 .051826008312573 -4.91835808191787E-10
6 -.903399056291523 -.903399055889035 -4.02487820849728E-10
7 .47391871819713 .473919049744119 -3.31546989085219E-7
8 -.922909753831513 -.922908005104853 -1.74872665914538E-6
9 .791479622428268 .791603979074663 -1.24356646394985E-4
10 -.556013013484207 -.552670804109104 -3.34220937510299E-3
11 .999592310690031 .999339079455446 2.53231234584206E-4
12 .774903379838499 -.974661220596496 1.74956460043499
13 -.526222536776585 .960170286650366 -1.48639282342695
14 -1.9165008703538E+19 -.653643620863612 -1.9165008703538E+19
15 -1.6053747716131E+40 1 -1.6053747716131E+40
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/19 (Sun) 09:21:09
Delphi7のsin, cosは引数の絶対値が2^63を超えるとどちらも値が0になります。(十進BASIC Ver.7 はアセンブラでFSIN, FCOSを使用していました)
lazarusで用いられるFPC (Free Pascal) のsin, cosは,Intel FPUを使う環境ではintel FPUの仕様そのままでした。
十進BASIC Ver.7,Ver.8の修正版では,2πで割った余りを求めてから三角関数の値を求めることにしました。
ただし,ここでのπは,64ビット精度の拡張精度数です。倍精度より少し高精度ですが,真の値ではありません。
引数の絶対値が大きいときでも計算結果は-1~1の範囲に納まりますが,数値自体はほぼ無意味です。
BASICAccとParact BASICは,当面,手を加えずFPCの計算に委ねることにしました。
なお,2πでの剰余を精密に計算したいときは,十進1000桁モードを使用してください。十進1000桁モードだとPIは1000桁超の精度を持ちます。
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/19 (Sun) 09:30:19
十進1000桁モードでの実行結果です。
OPTION ARITHMETIC DECIMAL_HIGH
LET B=15
LET X=1
FOR N=1 TO 30
PRINT N;COS(B^N*X*PI);SIN(B^N*X*PI)
NEXT N
END
1 -1 -.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000092857116
2 -1 -.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139285674
3 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000208928511
4 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003133927665
5 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047008914975
6 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000705133724625
7 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010577005869375
8 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000158655088040625
9 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002379826320609375
10 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035697394809140625
11 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000535460922137109375
12 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008031913832056640625
13 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120478707480849609375
14 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001807180612212744140625
15 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027107708454675537109375
16 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000406615637747867431640625
17 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006099234566218011474609375
18 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000091488518493270172119140625
19 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001372327777399052581787109375
20 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020584916660985788726806640625
21 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000308773749914786830902099609375
22 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004631606248721802463531494140625
23 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069474093594296325474456787109375
24 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001042111405862226673116851806640625
25 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015631671089231921290752777099609375
26 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000234475066341508702147291656494140625
27 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003517125995123063372607374847412109375
28 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052756889926846599849707622711181640625
29 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000791353348902701594788002340667724609375
30 -1 -.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011870300233540525653181627110015869140625
この結果が物語ることは,B^N*X*PIの計算結果と,sinを計算するときに十進BASIC内部で用いるπの精度の違いです。
十進BASICサンプルプログラムのQ&A\SIN_PI.BASも参照してください。
要するに,PI自体がπの近似値であること,そして,SINの計算精度が保証される範囲自体も狭いことです。
十進1000桁モードの機械最小値を1E-1017に設定しているのも,精度保証との関係です。
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/19 (Sun) 10:47:08
2進モードでのPIは,およそ3.141592653589793115999782457です。
この値を元にπの整数倍を計算していくと,10^16倍したとき,およそ-1.2ほどの誤差がでてきます。三角関数の値を求めるのには不適切な誤差です。
10進1000桁モードで計算してみてください。
OPTION ARITHMETIC Decimal_High
LET p=3.141592653589793115999782457
FOR i=0 TO 16
PRINT 10^i*p - 10^i*PI
NEXT i
END
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/19 (Sun) 14:55:24
三角関数の正確な値を求める基本は,xを2πで割った余りを正確に求めることです。
xを2*PIで割った商をq,余りをrとして,PI=π+eだとすると,
x=q*2*PI+r
PI=π+e
なので,
x=q*2*π+q*2*e+r
だから,xを2πで割った余りはq*2*e+rです。
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/22 (Wed) 07:57:17
PI≒πの近似誤差を気にせず計算したいときは,度を単位に計算することが推奨できます。
OPTION ANGLE DEGREES
FOR k=50 TO 60
LET x=180*2^k
PRINT k,x,COS(x),SIN(x)
NEXT k
END
2進モードでの実行結果は
50 2.02661983231672E+17 1 0
51 4.05323966463345E+17 1 0
52 8.10647932926689E+17 1 0
53 1.62129586585338E+18 1 0
54 3.24259173170676E+18 1 0
55 6.48518346341351E+18 1 0
56 1.2970366926827E+19 1 0
57 2.59407338536541E+19 1 0
58 5.18814677073081E+19 .999390827019096 0
59 1.03762935414616E+20 .999390827019096 0
60 2.07525870829232E+20 .994521895368273 0
30度,45度など,度を単位に切りのいい数に対する三角関数の値を求めたいときはこちらが推奨できます。
2進モードだと,2^53までの整数は正確に表現できます。
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/22 (Wed) 08:06:24
上のプログラムで,K=58以降でCOS(x)が1でない値になり,さらにその先まで計算していくとk=64以降で0になります。これは,十進BASICのバグ(?)です。
COS(x)=SIN(x+90)として計算しているのが原因で,x+90の計算が誤差を持つような範囲で正しい値が求まらなくなっています。
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/24 (Fri) 17:24:18
https://ja.wikipedia.org/wiki/ワイエルシュトラス関数
で,
COS(b^n*x*π)を正確に計算したいのであれば,b^n*xを2で割った余りをrとおくと,COS(b^n*x*π)=COS(r*π)
0≦r<2なので,COS(r*π)をCOS(r*PI)で近似してもさほど問題ない。
OPTION ARITHMETIC NATIVE
LET a=1/2
LET b=11
FUNCTION w(x)
LET t=0
LET n=0
FOR n=200 TO 0 STEP -1
LET r=MOD(b^n*x,2)
LET t=t+a^n*COS(r*PI)
NEXT n
LET w=t
END FUNCTION
SET POINT STYLE 1
SET WINDOW -2,2,-2,2
DRAW grid
FOR x=-2 TO 2 STEP 0.00001
PLOT LINES:x,w(x);
NEXT x
END
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/25 (Sat) 07:25:56
上掲のプログラムで,w(x)≒0付近の相対誤差ではなく,絶対誤差のみを要求するとき,FOR文の始値n=200は過大です。
COSの値は―1~1の範囲になるのでw(x)の和は公比a=1/2の等比級数の和で抑えられます。
たとえば,n=54に選べば,計算しない残余項の和は2^(-54)以下になります。
なお,n≦54であっても,nが少し大きな数だと,b^n*xはかなり大きな数になって誤差をはらみ,r=MOD(b^n*x,2)は多くの場合,0になります。
そのあたりまで考えて正確に計算したいのであれば,MOD(b^n*x,2)を正確に導き出す手法を編み出す必要があります。
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/04/25 (Sat) 09:45:10
MOD(b^n*x,2) = MOD((b^(n-1)*x)*b,2) = MOD(MOD(b^(n-1)*x,2)*b,2) を使えばよさそうです。
LET b=11
FOR x=-2 TO 2 STEP 2^(-10)
LET r=MOD(x,2)
FOR n=1 TO 60
LET r=MOD(r*b,2)
PRINT x,n,r
NEXT n
NEXT x
END
xに2進小数として切りのいい数を指定しないと,カオスになります。
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/05/03 (Sun) 08:36:57
上掲プログラムで,xに2進小数として切りのいい数を指定しないとカオスになるのは,2進モードのMOD関数が十分な精度を持たないのが影響していました。修正します。
Re: 三角関数値が異常です - SHIRAISHI Kazuo
2026/05/16 (Sat) 09:10:26
ワイエルシュトラス関数のグラフを描くプログラムです。
グラフを描く目的ならさほど多くの項の計算は不要です。
2進倍精度で計算するのであれば,140行で求めているNmaxまで計算することが目安になります。
100 REM ワイエルシュトラス関数
110 OPTION ARITHMETIC NATIVE
120 LET a=0.5
130 LET b=13
140 LET Nmax=-54*LOG2(a)
150 FUNCTION w(x)
160 LET t=0
170 LET r=MOD(x,2)
180 FOR n=0 TO NMax
190 LET t=t+a^n*COS(r*PI)
200 LET r=MOD(r*b,2)
210 NEXT n
220 LET w=t
230 END FUNCTION
240 SET POINT STYLE 1
250 SET WINDOW -2,2,-2,2
260 DRAW GRID
270 FOR x=-2 TO 2 STEP 2^(-18)
280 PLOT POINTS:x,w(x)
290 NEXT x
300 END
https://ja.wikipedia.org/wiki/ワイエルシュトラス関数
にある画像は,a=0.5,b=3 程度で作成されたもののように思えます。至るところ微分不可能というわりにトゲトゲが少なくて違和感があります。
BASICAcc 1.2.3.0 ParactBASIC 2.1.5.0 - SHIRAISHI Kazuo
2026/05/15 (Fri) 21:02:45
BASICAcc 1.2.3.0とParactBASIC 2.1.5.0で,Intel FPU環境で引数の絶対値が2^63以上だと三角関数が異常値をとる不具合を修正しました。
従来,FPCのsin, cosを直接利用する形に翻訳していたものを,別途用意したライブラリを使う形にするために,内部構造を変更しています。
関係ないところに変更の余波が及ぶ可能性もあるので,不具合に気付いた方は報告をお願いします。
微細構造定数と質量比3種 - 百瀬
2026/05/15 (Fri) 14:14:45
CODATA2022の不確かさ内の精度で物理定数を導出します。
数字パズルとして組合わせを見つける確率や情報圧縮の
観点から、結果を狙っての設計は不可能だと思いますが、
お詳しい方のご意見を頂けましたら幸いです。
LET u=1
LET r=u+2
LET a=r*(r-u)
LET b=2
LET nn=a+b-u
LET rel=a+b+r
LET ph=nn+b
LET h=rel+u+nn
LET n=r+rel+ph+h
LET c=2*n
LET p=4*ATN(1)
LET t=1-a/nn^2
LET Phi=n*r+rel+r/c+(rel-ph)/c^2+(18/(nn*p))*t/c^3+(4*p)*t/c^4
LET d1=r+ph+u
LET d2=h*(n-(r+u))
LET d3=d1*d2
LET d4=d2*(n-(r+u))*a*(rel-r)
LET P1=c*(h+r)-(ph+r)+(rel-ph)/d1-u/d2+(rel-ph)/d3-u/d4
LET P2=h*rel-r+(rel-u)/d1-u/d2+(r+u)/d3+(h-r-u)/d4
LET P3=n*(c-u)-ph+(rel-ph)/d1-(rel-ph)/d2+(r+u)/d3-(r*h)/d4
PRINT "Alpha^-1="; Phi
PRINT "Proton ="; P1
PRINT "Muon ="; P2
PRINT "Tau ="; P3
END
ガチャ - しばっち
2026/05/03 (Sun) 07:41:47
ガチャ(カブセルトイ)N種を全種揃えるまでにかかった回数
https://keisan.site/exec/system/1375851215#google_vignette
https://manabitimes.jp/math/1053
出現確率は全て同じとする。(シークレット等特別なものはここでは考慮していない)
! ガチャN種を全種揃えるまでにかかった回数
RANDOMIZE
LET TRUE=1
LET FALSE=0
LET N=6 ! ガチャ種類
LET ITER=300 ! 試行回数
DIM A(N),C(N*12)
FOR J=1 TO ITER
LET COUNT=0
MAT A=ZER
DO
LET COUNT=COUNT+1
LET K=INT(RND*N+1)
LET A(K)=A(K)+1
LET FL=TRUE
FOR I=1 TO N
IF A(I)=0 THEN LET FL=FALSE
NEXT I
LOOP UNTIL FL=TRUE
LET C(COUNT)=C(COUNT)+1
NEXT J
FOR I=N TO N*12
PRINT USING"###":I;
PRINT "回 :";REPEAT$("*",C(I));C(I);C(I)/ITER*100;"%"
LET S=S+I*C(I)
IF C(I)>0 AND SMIN=0 THEN LET SMIN=I
IF C(I)>V THEN
LET V=C(I)
LET MOST=I
END IF
NEXT I
FOR I=N*12 TO N STEP -1
IF C(I)>0 AND SMAX=0 THEN LET SMAX=I
NEXT I
PRINT "平均";S/ITER;"回"
PRINT "最低";SMIN;"回"
PRINT "最大";SMAX;"回"
PRINT "最頻値";MOST;"回"
END
下記結果は6種類の時、全てゲットするまでにかかった回数
300回試行した結果、最低6回(超ラッキー 1.33%)でゲットし、最大62回(超ついてない 0.33%)も費やした。
ガチャ1回300円とすると300円×6回で最低1800円。最大300円×62回で18600円もかかる
実行結果
6回 :**** 4 1.33333333333333 %
7回 :************ 12 4 %
8回 :*************** 15 5 %
9回 :******************* 19 6.33333333333333 %
10回 :************************ 24 8 %
11回 :********************** 22 7.33333333333333 %
12回 :***************************** 29 9.66666666666667 %
13回 :**************** 16 5.33333333333333 %
14回 :*********************** 23 7.66666666666667 %
15回 :***************** 17 5.66666666666667 %
16回 :******************* 19 6.33333333333333 %
17回 :************** 14 4.66666666666667 %
18回 :******** 8 2.66666666666667 %
19回 :************* 13 4.33333333333333 %
20回 :*********** 11 3.66666666666667 %
21回 :******* 7 2.33333333333333 %
22回 :********* 9 3 %
23回 :** 2 .666666666666667 %
24回 :**** 4 1.33333333333333 %
25回 :** 2 .666666666666667 %
26回 :******* 7 2.33333333333333 %
27回 :** 2 .666666666666667 %
28回 :***** 5 1.66666666666667 %
29回 :** 2 .666666666666667 %
30回 : 0 0 %
31回 :**** 4 1.33333333333333 %
32回 :**** 4 1.33333333333333 %
33回 : 0 0 %
34回 :* 1 .333333333333333 %
35回 :* 1 .333333333333333 %
36回 : 0 0 %
37回 :* 1 .333333333333333 %
38回 : 0 0 %
39回 : 0 0 %
40回 :* 1 .333333333333333 %
41回 :* 1 .333333333333333 %
42回 : 0 0 %
43回 : 0 0 %
44回 : 0 0 %
45回 : 0 0 %
46回 : 0 0 %
47回 : 0 0 %
48回 : 0 0 %
49回 : 0 0 %
50回 : 0 0 %
51回 : 0 0 %
52回 : 0 0 %
53回 : 0 0 %
54回 : 0 0 %
55回 : 0 0 %
56回 : 0 0 %
57回 : 0 0 %
58回 : 0 0 %
59回 : 0 0 %
60回 : 0 0 %
61回 : 0 0 %
62回 :* 1 .333333333333333 %
63回 : 0 0 %
64回 : 0 0 %
65回 : 0 0 %
66回 : 0 0 %
67回 : 0 0 %
68回 : 0 0 %
69回 : 0 0 %
70回 : 0 0 %
71回 : 0 0 %
72回 : 0 0 %
平均 15.4633333333333 回
最低 6 回
最大 62 回
最頻値 12 回
----------------------------------------------------------------------------
! ガチャN種を全種揃えるまでにかかる期待値
SET WINDOW -3,50,-10,300
DRAW GRID(5,10)
FOR N=1 TO 50
LET S=0
FOR K=1 TO N
LET S=S+1/K
NEXT K
PLOT LINES:N,S*N;
NEXT N
END
Re: ガチャ - しばっち
2026/05/03 (Sun) 07:43:01
https://dskjal.com/statistics/chance-calculator-jp
https://mikami3345.cloudfree.jp/Probability/Probability.html
! スマホガチャ 当選率P%をN回ガチャ引いて1個以上当たる確率
!LET P=1/100 ! 当選率
!LET N=100 ! ガチャを引く回数
!PRINT (1-(1-P)^N)*100;"%"
SET WINDOW -10,150,-10,100
DRAW GRID(10,10)
LET P=1/100 ! 当選率
FOR N=0 TO 150 ! ガチャを引く回数
PLOT LINES:N,(1-(1-P)^N)*100;
NEXT N
END
-----------------------------------------------------------------------
上記のシュミレーションプログラム
RANDOMIZE
DIM GACHA(100)
INPUT PROMPT "当選確率 (%)(1-99) ":L
INPUT PROMPT "ガチャを引く回数 ":N
LET M=500 ! 試行回数
FOR I=1 TO L ! 100個のうちL個が当たり
LET GACHA(I)=1
NEXT I
FOR I=1 TO M
FOR J=1 TO 100 ! シャッフル
SWAP GACHA(J),GACHA(INT(RND*100+1))
NEXT J
LET FLG=0
FOR J=1 TO N
LET P=INT(RND*100+1) ! ガチャを引く
IF GACHA(P)=1 THEN ! 当たりを引いた
LET FLG=1
EXIT FOR
END IF
NEXT J
IF FLG=0 THEN LET C=C+1 ! 全部外れたらカウント
NEXT I
PRINT "当選確率";L;"%の時、";N;"回ガチャを引いて当たる確率";(M-C)/M*100;"%"
END
実行結果
当選確率 (%)(1-99) 1
ガチャを引く回数 100
当選確率 1 %の時、 100 回ガチャを引いて当たる確率 62.2 %
-----------------------------------------------------------------------
当選確率L%の時、N回ガチャを引いて当たる回数の確率
OPTION BASE 0
RANDOMIZE
DIM GACHA(100),C(100)
INPUT PROMPT "当選確率 (%)(1-99) ":L ! L=1
INPUT PROMPT "ガチャを引く回数 ":N ! N=100
LET M=500 ! 試行回数
FOR I=1 TO L ! 100個のうちL個が当たり
LET GACHA(I)=1
NEXT I
FOR I=1 TO M
FOR J=1 TO 100 ! シャッフル
SWAP GACHA(J),GACHA(INT(RND*100+1))
NEXT J
LET HIT=0
FOR J=1 TO N
LET P=INT(RND*100+1) ! ガチャを引く
IF GACHA(P)=1 THEN ! 当たりを引いた
LET HIT=HIT+1
END IF
NEXT J
LET C(HIT)=C(HIT)+1
NEXT I
FOR I=1 TO 100
IF C(I)>0 THEN PRINT "当選確率";L;"%の時、";N;"回ガチャを引いて";I;"回当たる確率";C(I)/M*100;"%"
NEXT I
END
実行結果
当選確率 (%)(1-99) 1
ガチャを引く回数 100
当選確率 1 %の時、 100 回ガチャを引いて 1 回当たる確率 34.2 %
当選確率 1 %の時、 100 回ガチャを引いて 2 回当たる確率 21.4 %
当選確率 1 %の時、 100 回ガチャを引いて 3 回当たる確率 5.8 %
当選確率 1 %の時、 100 回ガチャを引いて 4 回当たる確率 1.4 %
当選確率 1 %の時、 100 回ガチャを引いて 5 回当たる確率 .2 %
当選確率 1 %の時、 100 回ガチャを引いて 9 回当たる確率 .2 %
-----------------------------------------------------------------------
入手確率 X%を達成するために必要な試行回数
LET P=1/100 ! 当選率
LET N=99/100 ! 入手確率
FOR X=1 TO 10000
IF 1-(1-P)^X>N THEN EXIT FOR
NEXT X
PRINT "当選確率";P*100;"% 入手確率";N*100;"% 達するために必要な試行回数";X;"回"
END
-----------------------------------------------------------------------
N回ガチャ引いても当たらない確率
LET N=100 ! 試行回数
LET P=.5/100 ! 当選確率
PRINT "当選確率";P*100;"%の時、";N;"回ガチャを引いても当たらない確率";(1-P)^N*100;"%"
END
-----------------------------------------------------------------------
当たりが2個ある場合の確率
但し、当選確率1%という時、合わせての合計確率1/200+1/200で1/100つまり計1%と
それぞれが1%、つまり1/100+1/100で計2%となる場合の2通りがある。
RANDOMIZE
DIM GACHA(200)
LET M=500 ! 試行回数
LET MODE=1
SELECT CASE MODE
CASE 1
INPUT PROMPT "合わせての当選確率 (%)(1-99) ":L
FOR I=1 TO L ! 200個のうちL個が当たり L/200+L/200=L/100(L%)
LET C=C+1
LET GACHA(C)=1
LET C=C+1
LET GACHA(C)=2
NEXT I
CASE 2
INPUT PROMPT "個別の当選確率 (%)(1-99) ":L
FOR I=1 TO L*2 ! 200個のうち2*L個が当たり L/100(L%)+L/100(L%)=2*L/100 (2L%)
LET C=C+1
LET GACHA(C)=1
LET C=C+1
LET GACHA(C)=2
NEXT I
!CASE 3
! INPUT PROMPT "1,2合わせての当選確率 (%)(1-99) ":L1,L2
! FOR I=1 TO L1 ! 200個のうちL1個とL2個が当たり L1/200+L2/200
! LET C=C+1
! LET GACHA(C)=1
! NEXT I
! FOR I=1 TO L2
! LET C=C+1
! LET GACHA(C)=2
! NEXT I
!CASE 4
! INPUT PROMPT "1,2個別の当選確率 (%)(1-99) ":L1,L2
! FOR I=1 TO L1*2 ! 200個のうちL1個とL2個が当たり L1/100+L2/100
! LET C=C+1
! LET GACHA(C)=1
! NEXT I
! FOR I=1 TO L2*2
! LET C=C+1
! LET GACHA(C)=2
! NEXT I
END SELECT
INPUT PROMPT "ガチャを引く回数 ":N
FOR I=1 TO M
FOR J=1 TO 200 ! シャッフル
SWAP GACHA(J),GACHA(INT(RND*200+1))
NEXT J
LET HIT1=0
LET HIT2=0
FOR J=1 TO N
LET P=INT(RND*200+1) ! ガチャを引く
IF GACHA(P)=1 THEN LET HIT1=HIT1+1
IF GACHA(P)=2 THEN LET HIT2=HIT2+1
NEXT J
IF (HIT1>0 AND HIT2=0) OR (HIT1=0 AND HIT2>0) THEN LET EITHER=EITHER+1
IF HIT1>0 AND HIT2>0 THEN LET BOTH=BOTH+1
IF HIT1=0 AND HIT2=0 THEN LET MISS=MISS+1
NEXT I
IF L>0 THEN
PRINT "当選確率";L;"%の時、";N;"回ガチャを引いてどちらかが当たる確率";EITHER/M*100;"%"
PRINT "当選確率";L;"%の時、";N;"回ガチャを引いてどちらも当たる確率";BOTH/M*100;"%"
PRINT "当選確率";L;"%の時、";N;"回ガチャを引いてどちらも外れる確率";MISS/M*100;"%"
ELSE
PRINT "当選確率";L1;"%、";L2;"%の時、";N;"回ガチャを引いてどちらかが当たる確率";EITHER/M*100;"%"
PRINT "当選確率";L1;"%、";L2;"%の時、";N;"回ガチャを引いてどちらも当たる確率";BOTH/M*100;"%"
PRINT "当選確率";L1;"%、";L2;"%の時、";N;"回ガチャを引いてどちらも外れる確率";MISS/M*100;"%"
END IF
END
実行結果
合わせての当選確率 (%)(1-99) 1
ガチャを引く回数 100
当選確率 1 %の時、 100 回ガチャを引いてどちらかが当たる確率 46.2 %
当選確率 1 %の時、 100 回ガチャを引いてどちらも当たる確率 15 %
当選確率 1 %の時、 100 回ガチャを引いてどちらも外れる確率 38.8 %
-----------------------------------------------------------------------
当たりが3個ある場合の確率
RANDOMIZE
DIM GACHA(300)
LET M=500 ! 試行回数
LET MODE=1
SELECT CASE MODE
CASE 1
INPUT PROMPT "合わせての当選確率 (%)(1-99) ":L
FOR I=1 TO L ! 300個のうちL個が当たり L/300+L/300+L/300=L/100(L%)
LET C=C+1
LET GACHA(C)=1
LET C=C+1
LET GACHA(C)=2
LET C=C+1
LET GACHA(C)=3
NEXT I
CASE 2
INPUT PROMPT "個別の当選確率 (%)(1-99) ":L
FOR I=1 TO L*3 ! 300個のうち3*L個が当たり L/100(L%)+L/100(L%)+L/100(L%)=L/50 (3L%)
LET C=C+1
LET GACHA(C)=1
LET C=C+1
LET GACHA(C)=2
LET C=C+1
LET GACHA(C)=3
NEXT I
!CASE 3
! INPUT PROMPT "1,2,3合わせての当選確率 (%)(1-99) ":L1,L2,L3
! FOR I=1 TO L1 ! 300個のうちL個が当たり L1/300+L2/300+L3/300
! LET C=C+1
! LET GACHA(C)=1
! NEXT I
! FOR I=1 TO L2
! LET C=C+1
! LET GACHA(C)=2
! NEXT I
! FOR I=1 TO L3
! LET C=C+1
! LET GACHA(C)=3
! NEXT I
!CASE 4
! INPUT PROMPT "1,2,3個別の当選確率 (%)(1-99) ":L1,L2,L3
! FOR I=1 TO L1*3 ! 300個のうちL個が当たり L1/100+L2/100+L3/100
! LET C=C+1
! LET GACHA(C)=1
! NEXT I
! FOR I=1 TO L2*3
! LET C=C+1
! LET GACHA(C)=2
! NEXT I
! FOR I=1 TO L3*3
! LET C=C+1
! LET GACHA(C)=3
! NEXT I
END SELECT
INPUT PROMPT "ガチャを引く回数 ":N
FOR I=1 TO M
FOR J=1 TO 300 ! シャッフル
SWAP GACHA(J),GACHA(INT(RND*300+1))
NEXT J
LET HIT1=0
LET HIT2=0
LET HIT3=0
FOR J=1 TO N
LET P=INT(RND*300+1) ! ガチャを引く
IF GACHA(P)=1 THEN LET HIT1=HIT1+1
IF GACHA(P)=2 THEN LET HIT2=HIT2+1
IF GACHA(P)=3 THEN LET HIT3=HIT3+1
NEXT J
IF HIT1>0 AND HIT2=0 AND HIT3=0 THEN LET EITHER1=EITHER1+1
IF HIT1=0 AND HIT2>0 AND HIT3=0 THEN LET EITHER1=EITHER1+1
IF HIT1=0 AND HIT2=0 AND HIT3>0 THEN LET EITHER1=EITHER1+1
IF HIT1>0 AND HIT2>0 AND HIT3=0 THEN LET EITHER2=EITHER2+1 ! 1,2
IF HIT1>0 AND HIT3>0 AND HIT2=0 THEN LET EITHER2=EITHER2+1 ! 1,3
IF HIT2>0 AND HIT3>0 AND HIT1=0 THEN LET EITHER2=EITHER2+1 ! 2,3
IF HIT1>0 AND HIT2>0 AND HIT3>0 THEN LET ALL=ALL+1
IF HIT1=0 AND HIT2=0 AND HIT3=0 THEN LET MISS=MISS+1
NEXT I
IF L>0 THEN
PRINT "当選確率";L;"%の時、";N;"回ガチャを引いてどれか1種類が当たる確率";EITHER1/M*100;"%"
PRINT "当選確率";L;"%の時、";N;"回ガチャを引いてどれか2種類が当たる確率";EITHER2/M*100;"%"
PRINT "当選確率";L;"%の時、";N;"回ガチャを引いて全種類が当たる確率";ALL/M*100;"%"
PRINT "当選確率";L;"%の時、";N;"回ガチャを引いてどれも外れる確率";MISS/M*100;"%"
ELSE
PRINT "当選確率";L1;"%、";L2;"%、";L3;"%の時、";N;"回ガチャを引いてどれか1種類が当たる確率";EITHER1/M*100;"%"
PRINT "当選確率";L1;"%、";L2;"%、";L3;"%の時、";N;"回ガチャを引いてどれか2種類が当たる確率";EITHER2/M*100;"%"
PRINT "当選確率";L1;"%、";L2;"%、";L3;"%の時、";N;"回ガチャを引いて全種類が当たる確率";ALL/M*100;"%"
PRINT "当選確率";L1;"%、";L2;"%、";L3;"%の時、";N;"回ガチャを引いてどれも外れる確率";MISS/M*100;"%"
END IF
END
実行結果
合わせての当選確率 (%)(1-99) 1
ガチャを引く回数 100
当選確率 1 %の時、 100 回ガチャを引いてどれか1種類が当たる確率 44.4 %
当選確率 1 %の時、 100 回ガチャを引いてどれか2種類が当たる確率 17.4 %
当選確率 1 %の時、 100 回ガチャを引いて全種類が当たる確率 2.2 %
当選確率 1 %の時、 100 回ガチャを引いてどれも外れる確率 36 %
-----------------------------------------------------------------------
当たりが複数の場合
OPTION BASE 0
RANDOMIZE
INPUT PROMPT "当たりの種類 ":K
INPUT PROMPT "ガチャを引く回数 ":N
DIM GACHA(100*K),C(K,N),HIT(K),LL(K)
LET M=500 ! 試行回数
LET MODE=1
SELECT CASE MODE
CASE 1
FOR J=1 TO K
INPUT PROMPT STR$(J)&"の当選確率 (%)(1-99) ":LL(J)
NEXT J
FOR I=1 TO K
FOR J=1 TO LL(I)
LET CC=CC+1
LET GACHA(CC)=I
NEXT J
NEXT I
CASE 2
FOR J=1 TO K
INPUT PROMPT STR$(J)&"の当選確率 (%)(1-99) ":LL(J)
NEXT J
FOR I=1 TO K
FOR J=1 TO LL(I)*K
LET CC=CC+1
LET GACHA(CC)=I
NEXT J
NEXT I
END SELECT
FOR I=1 TO M
FOR J=1 TO 100*K ! シャッフル
SWAP GACHA(J),GACHA(INT(RND*100*K+1))
NEXT J
MAT HIT=ZER
FOR J=1 TO N
LET P=INT(RND*100*K+1) ! ガチャを引く
FOR F=1 TO K
IF GACHA(P)=F THEN
LET HIT(F)=HIT(F)+1 ! F種目の当たり引いた
EXIT FOR
END IF
NEXT F
NEXT J
FOR F=1 TO K
LET C(F,HIT(F))=C(F,HIT(F))+1
NEXT F
NEXT I
FOR I=1 TO N
FOR F=1 TO K
IF C(F,I)>0 THEN
PRINT "当選確率";LL(F);"%の時、";N;"回ガチャを引いて";F;"種目が";I;"回当たる確率";C(F,I)/M*100;"%"
END IF
NEXT F
IF C(K,I)>0 THEN PRINT
NEXT I
END
実行結果
当たりの種類 3
ガチャを引く回数 100
1の当選確率 (%)(1-99) 1
2の当選確率 (%)(1-99) 2
3の当選確率 (%)(1-99) 3
当選確率 1 %の時、 100 回ガチャを引いて 1 種目が 1 回当たる確率 23.8 %
当選確率 2 %の時、 100 回ガチャを引いて 2 種目が 1 回当たる確率 32.4 %
当選確率 3 %の時、 100 回ガチャを引いて 3 種目が 1 回当たる確率 38 %
当選確率 1 %の時、 100 回ガチャを引いて 1 種目が 2 回当たる確率 4 %
当選確率 2 %の時、 100 回ガチャを引いて 2 種目が 2 回当たる確率 11.8 %
当選確率 3 %の時、 100 回ガチャを引いて 3 種目が 2 回当たる確率 17.2 %
当選確率 2 %の時、 100 回ガチャを引いて 2 種目が 3 回当たる確率 2.6 %
当選確率 3 %の時、 100 回ガチャを引いて 3 種目が 3 回当たる確率 7 %
当選確率 3 %の時、 100 回ガチャを引いて 3 種目が 4 回当たる確率 1.4 %
当選確率 3 %の時、 100 回ガチャを引いて 3 種目が 5 回当たる確率 .6 %
-----------------------------------------------------------------------
これ以下より当たりがK種で内2つ、3つ、4つが当たりの場合のプログラムを挙げているが
当たり判定を微妙に変えているので注意すること
当たりがK種ある場合の内、少なくとも2つが当たる確率を個別に求める
A,B,Cの3種類当たりがあるとして(A>0 を当たり、A=0をハズレとする)
少なくともAかBが当たり A>0 OR B>0
少なくともAとBが当たり A>0 AND B>0
AかBのみが当たり (A>0 OR B>0) AND C=0
AとBのみが当たり A>0 AND B>0 AND C=0
また、IF GACHA(P)=JJ THEN LET HIT(JJ)=HIT(JJ)+1 として
当たる確率を求めているが
IF GACHA(P)<>JJ THEN LET MISS(JJ)=MISS(JJ)+1 と変更すれば
外れの確率を求めることもできる
RANDOMIZE
INPUT PROMPT "当たりの種類":K
DIM GACHA(100*K),HIT(K),EITHER(DEFARRAY2(K,K)),LL(K)
LET M=500 ! 試行回数
LET MODE=3
SELECT CASE MODE
!CASE 1
! INPUT PROMPT "合わせての当選確率 (%)(1-99) ":L
! FOR I=1 TO L
! FOR J=1 TO K
! LET C=C+1
! LET GACHA(C)=J
! NEXT J
! NEXT I
!CASE 2
! INPUT PROMPT "個別の当選確率 (%)(1-99) ":L
! FOR I=1 TO L*K
! FOR J=1 TO K
! LET C=C+1
! LET GACHA(C)=J
! NEXT J
! NEXT I
CASE 3
FOR J=1 TO K
INPUT PROMPT STR$(J)&"の当選確率 (%)(1-99) ":LL(J)
NEXT J
FOR I=1 TO K
FOR J=1 TO LL(I)
LET C=C+1
LET GACHA(C)=I
NEXT J
NEXT I
CASE 4
FOR J=1 TO K
INPUT PROMPT STR$(J)&"の当選確率 (%)(1-99) ":LL(J)
NEXT J
FOR I=1 TO K
FOR J=1 TO LL(I)*K
LET C=C+1
LET GACHA(C)=I
NEXT J
NEXT I
END SELECT
INPUT PROMPT "ガチャを引く回数 ":N
FOR I=1 TO M
FOR J=1 TO 100*K ! シャッフル
SWAP GACHA(J),GACHA(INT(RND*100*K+1))
NEXT J
MAT HIT=ZER
FOR J=1 TO N
LET P=INT(RND*100*K+1) ! ガチャを引く
FOR JJ=1 TO K
IF GACHA(P)=JJ THEN LET HIT(JJ)=HIT(JJ)+1 ! 当たりなら
NEXT JJ
NEXT J
FOR J1=1 TO K-1
FOR J2=J1+1 TO K
IF HIT(J1)>0 OR HIT(J2)>0 THEN
LET EITHER(ARRAY2(J1,J2))=EITHER(ARRAY2(J1,J2))+1
END IF
NEXT J2
NEXT J1
NEXT I
FOR J1=1 TO K-1
FOR J2=J1+1 TO K
PRINT N;"回ガチャを引いて少なくとも";J1;"か";J2;"が当たる確率";EITHER(ARRAY2(J1,J2))/M*100;"%"
NEXT J2
NEXT J1
FUNCTION DEFARRAY2(AMAX,BMAX)
LET MAX1=AMAX
LET MAX2=BMAX
LET DEFARRAY2=MAX2*MAX1
END FUNCTION
FUNCTION ARRAY2(X,Y)
LET X=INT(X)
LET Y=INT(Y)
IF X>MAX1 THEN LET X=MAX1
IF Y>MAX2 THEN LET Y=MAX2
IF X<1 THEN LET X=1
IF Y<1 THEN LET Y=1
LET SUM= MAX1*(Y-1)
LET SUM=SUM+X
LET ARRAY2=SUM
END FUNCTION
END
実行結果
当たりの種類3
1の当選確率 (%)(1-99) 1
2の当選確率 (%)(1-99) 2
3の当選確率 (%)(1-99) 3
ガチャを引く回数 100
100 回ガチャを引いて少なくとも 1 か 2 が当たる確率 63.2 %
100 回ガチャを引いて少なくとも 1 か 3 が当たる確率 76 %
100 回ガチャを引いて少なくとも 2 か 3 が当たる確率 81.2 %
-----------------------------------------------------------------------
当たりがK種ある場合の内3つのみが当たる確率を個別に求める
RANDOMIZE
DO
INPUT PROMPT "当たりの種類":K ! K>=4
LOOP WHILE K<4
DIM GACHA(100*K),HIT(K),EITHER(DEFARRAY3(K,K,K)),LL(K)
LET M=500 ! 試行回数
LET MODE=4
SELECT CASE MODE
!CASE 1
! INPUT PROMPT "合わせての当選確率 (%)(1-99) ":L
! FOR I=1 TO L
! FOR J=1 TO K
! LET C=C+1
! LET GACHA(C)=J
! NEXT J
! NEXT I
!CASE 2
! INPUT PROMPT "個別の当選確率 (%)(1-99) ":L
! FOR I=1 TO L*K
! FOR J=1 TO K
! LET C=C+1
! LET GACHA(C)=J
! NEXT J
! NEXT I
CASE 3
FOR J=1 TO K
INPUT PROMPT STR$(J)&"の当選確率 (%)(1-99) ":LL(J)
NEXT J
FOR I=1 TO K
FOR J=1 TO LL(I)
LET C=C+1
LET GACHA(C)=I
NEXT J
NEXT I
CASE 4
FOR J=1 TO K
INPUT PROMPT STR$(J)&"の当選確率 (%)(1-99) ":LL(J)
NEXT J
FOR I=1 TO K
FOR J=1 TO LL(I)*K
LET C=C+1
LET GACHA(C)=I
NEXT J
NEXT I
END SELECT
INPUT PROMPT "ガチャを引く回数 ":N
FOR I=1 TO M
FOR J=1 TO 100*K ! シャッフル
SWAP GACHA(J),GACHA(INT(RND*100*K+1))
NEXT J
MAT HIT=ZER
FOR J=1 TO N
LET P=INT(RND*100*K+1) ! ガチャを引く
FOR JJ=1 TO K
IF GACHA(P)=JJ THEN LET HIT(JJ)=HIT(JJ)+1 ! 当たりなら
NEXT JJ
NEXT J
FOR J1=1 TO K-2
FOR J2=J1+1 TO K-1
FOR J3=J2+1 TO K
IF HIT(J1)>0 AND HIT(J2)>0 AND HIT(J3)>0 THEN
LET FLG=0
FOR JJ=1 TO K
IF J1<>JJ AND J2<>JJ AND J3<>JJ AND HIT(JJ)<>0 THEN LET FLG=1
NEXT JJ
IF FLG=0 THEN LET EITHER(ARRAY3(J1,J2,J3))=EITHER(ARRAY3(J1,J2,J3))+1
END IF
NEXT J3
NEXT J2
NEXT J1
NEXT I
FOR J1=1 TO K-2
FOR J2=J1+1 TO K-1
FOR J3=J2+1 TO K
PRINT N;"回ガチャを引いて";J1;"と";J2;"と";J3;"のみが当たる確率";EITHER(ARRAY3(J1,J2,J3))/M*100;"%"
NEXT J3
NEXT J2
NEXT J1
FUNCTION DEFARRAY3(AMAX,BMAX,CMAX)
LET MAX1=AMAX
LET MAX2=BMAX
LET MAX3=CMAX
LET DEFARRAY3=MAX3*MAX2*MAX1
END FUNCTION
FUNCTION ARRAY3(X,Y,Z)
LET X=INT(X)
LET Y=INT(Y)
LET Z=INT(Z)
IF X>MAX1 THEN LET X=MAX1
IF Y>MAX2 THEN LET Y=MAX2
IF Z>MAX3 THEN LET Z=MAX3
IF X<1 THEN LET X=1
IF Y<1 THEN LET Y=1
IF Z<1 THEN LET Z=1
LET SUM= MAX2*MAX1*(Z-1)
LET SUM=SUM+MAX1*(Y-1)
LET SUM=SUM+X
LET ARRAY3=SUM
END FUNCTION
END
実行結果
当たりの種類6
1の当選確率 (%)(1-99) 1
2の当選確率 (%)(1-99) 2
3の当選確率 (%)(1-99) 3
4の当選確率 (%)(1-99) 4
5の当選確率 (%)(1-99) 5
6の当選確率 (%)(1-99) 6
ガチャを引く回数 100
100 回ガチャを引いて 1 と 2 と 3 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 2 と 4 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 2 と 5 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 2 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 3 と 4 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 3 と 5 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 3 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 4 と 5 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 4 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 1 と 5 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 2 と 3 と 4 のみが当たる確率 0 %
100 回ガチャを引いて 2 と 3 と 5 のみが当たる確率 0 %
100 回ガチャを引いて 2 と 3 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 2 と 4 と 5 のみが当たる確率 0 %
100 回ガチャを引いて 2 と 4 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 2 と 5 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 3 と 4 と 5 のみが当たる確率 .2 %
100 回ガチャを引いて 3 と 4 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 3 と 5 と 6 のみが当たる確率 0 %
100 回ガチャを引いて 4 と 5 と 6 のみが当たる確率 .2 %
-----------------------------------------------------------------------
当たりがK種ある場合の内4つが当たる確率を個別に求める
RANDOMIZE
DO
INPUT PROMPT "当たりの種類":K ! K>=5
LOOP WHILE K<5
DIM GACHA(100*K),HIT(K),EITHER(DEFARRAY4(K,K,K,K)),LL(K)
LET M=500 ! 試行回数
LET MODE=4
SELECT CASE MODE
!CASE 1
! INPUT PROMPT "合わせての当選確率 (%)(1-99) ":L
! FOR I=1 TO L
! FOR J=1 TO K
! LET C=C+1
! LET GACHA(C)=J
! NEXT J
! NEXT I
!CASE 2
! INPUT PROMPT "個別の当選確率 (%)(1-99) ":L
! FOR I=1 TO L*K
! FOR J=1 TO K
! LET C=C+1
! LET GACHA(C)=J
! NEXT J
! NEXT I
CASE 3
FOR J=1 TO K
INPUT PROMPT STR$(J)&"の当選確率 (%)(1-99) ":LL(J)
NEXT J
FOR I=1 TO K
FOR J=1 TO LL(I)
LET C=C+1
LET GACHA(C)=I
NEXT J
NEXT I
CASE 4
FOR J=1 TO K
INPUT PROMPT STR$(J)&"の当選確率 (%)(1-99) ":LL(J)
NEXT J
FOR I=1 TO K
FOR J=1 TO LL(I)*K
LET C=C+1
LET GACHA(C)=I
NEXT J
NEXT I
END SELECT
INPUT PROMPT "ガチャを引く回数 ":N
FOR I=1 TO M
FOR J=1 TO 100*K ! シャッフル
SWAP GACHA(J),GACHA(INT(RND*100*K+1))
NEXT J
MAT HIT=ZER
FOR J=1 TO N
LET P=INT(RND*100*K+1) ! ガチャを引く
FOR JJ=1 TO K
IF GACHA(P)=JJ THEN LET HIT(JJ)=HIT(JJ)+1 ! 当たりなら
NEXT JJ
NEXT J
FOR J1=1 TO K-3
FOR J2=J1+1 TO K-2
FOR J3=J2+1 TO K-1
FOR J4=J3+1 TO K
IF HIT(J1)>0 OR HIT(J2)>0 OR HIT(J3)>0 OR HIT(J4)>0 THEN
LET FLG=0
FOR JJ=1 TO K
IF J1<>JJ AND J2<>JJ AND J3<>JJ AND J4<>JJ AND HIT(JJ)<>0 THEN LET FLG=1
NEXT JJ
IF FLG=0 THEN LET EITHER(ARRAY4(J1,J2,J3,J4))=EITHER(ARRAY4(J1,J2,J3,J4))+1
END IF
NEXT J4
NEXT J3
NEXT J2
NEXT J1
NEXT I
FOR J1=1 TO K-3
FOR J2=J1+1 TO K-2
FOR J3=J2+1 TO K-1
FOR J4=J3+1 TO K
PRINT N;"回ガチャを引いて";J1;"か";J2;"か";J3;"か";J4;"のみが当たる確率";EITHER(ARRAY4(J1,J2,J3,J4))/M*100;"%"
NEXT J4
NEXT J3
NEXT J2
NEXT J1
FUNCTION DEFARRAY4(AMAX,BMAX,CMAX,DMAX)
LET MAX1=AMAX
LET MAX2=BMAX
LET MAX3=CMAX
LET MAX4=DMAX
LET DEFARRAY4=MAX4*MAX3*MAX2*MAX1
END FUNCTION
FUNCTION ARRAY4(X,Y,Z,W)
LET X=INT(X)
LET Y=INT(Y)
LET Z=INT(Z)
LET W=INT(W)
IF X>MAX1 THEN LET X=MAX1
IF Y>MAX2 THEN LET Y=MAX2
IF Z>MAX3 THEN LET Z=MAX3
IF W>MAX4 THEN LET W=MAX4
IF X<1 THEN LET X=1
IF Y<1 THEN LET Y=1
IF Z<1 THEN LET Z=1
IF W<1 THEN LET W=1
LET SUM= MAX3*MAX2*MAX1*(W-1)
LET SUM=SUM+MAX2*MAX1*(Z-1)
LET SUM=SUM+MAX1*(Y-1)
LET SUM=SUM+X
LET ARRAY4=SUM
END FUNCTION
END
実行結果
当たりの種類5
1の当選確率 (%)(1-99) 1
2の当選確率 (%)(1-99) 2
3の当選確率 (%)(1-99) 3
4の当選確率 (%)(1-99) 4
5の当選確率 (%)(1-99) 5
ガチャを引く回数 100
100 回ガチャを引いて 1 か 2 か 3 か 4 のみが当たる確率 .6 %
100 回ガチャを引いて 1 か 2 か 3 か 5 のみが当たる確率 1.4 %
100 回ガチャを引いて 1 か 2 か 4 か 5 のみが当たる確率 5.2 %
100 回ガチャを引いて 1 か 3 か 4 か 5 のみが当たる確率 12.6 %
100 回ガチャを引いて 2 か 3 か 4 か 5 のみが当たる確率 33 %
実行ファイルの作り方 - 永野護
2026/05/02 (Sat) 03:02:53
実行ファイルの作り方を教えてください。
Re: 実行ファイルの作り方 - SHIRAISHI Kazuo
2026/05/02 (Sat) 07:46:01
2進モード,複素数モードで動くプログラムは,たいていの場合,BASIC Accelerator で実行ファイル化できます。
https://decimalbasic.web.fc2.com/BASICAccJa.htm
実行ファイルは,outoutフォルダにNoName.exeとして生成されるので,適宜,名称を変更してください。
特別なDLLに依存せずに動作します。
Re: 実行ファイルの作り方 - 永野護
2026/05/02 (Sat) 08:20:14
ありがとうございました。
ver7881がダウンロードできません - やまだ
2026/04/22 (Wed) 10:25:44
windowsアーカイブ版のBASIC7881.zipをダウンロードすると、ver.4.4.23 2006.4.16がダウンロードされてしまいます。こちらの操作が変でなのでしょうか?
Re: ver7881がダウンロードできません - SHIRAISHI Kazuo
2026/04/22 (Wed) 11:42:08
ご報告ありがとうございました。
BASIC7881.zipはBASICW95のアーカイブになっていました。お手数をお掛けしますが,再度,ダウンロードをお願いします。
じゃんけん - しばっち
2026/04/12 (Sun) 07:44:49
N人でのじゃんけんが終了する(残り一人になる)までの回数
RANDOMIZE
INPUT PROMPT "人数=":N
DIM A(N),J$(0 TO 2),P(0 TO 2)
LET J$(0)="グー"
LET J$(1)="チョッキ"
LET J$(2)="パー"
DO
LET COUNT=COUNT+1
MAT A=ZER
MAT P=ZER
! PRINT COUNT;"回"
FOR I=1 TO N
LET A(I)=INT(RND*3)
! PRINT J$(A(I)),
NEXT I
! PRINT
FOR I=1 TO N
LET P(A(I))=P(A(I))+1
NEXT I
IF P(0)>0 AND P(1)>0 AND P(2)=0 THEN LET N=P(0) ! グーの勝ち
IF P(0)>0 AND P(1)=0 AND P(2)>0 THEN LET N=P(2) ! パーの勝ち
IF P(0)=0 AND P(1)>0 AND P(2)>0 THEN LET N=P(1) ! チョッキの勝ち
LOOP UNTIL N=1
PRINT COUNT;"回のジャンケンで残り一人になりました"
END
---------------------------------------------------------------------------
RANDOMIZE
DIM A(30),P(0 TO 2)
LET T=30 ! 試行回数
FOR NN=2 TO 30 ! 人数
LET SUM=0
FOR K=1 TO T
LET N=NN
LET COUNT=0
DO
LET COUNT=COUNT+1
MAT A=ZER
MAT P=ZER
FOR I=1 TO N
LET A(I)=INT(RND*3)
NEXT I
FOR I=1 TO N
LET P(A(I))=P(A(I))+1
NEXT I
IF P(0)>0 AND P(1)>0 AND P(2)=0 THEN LET N=P(0) ! グーの勝ち
IF P(0)>0 AND P(1)=0 AND P(2)>0 THEN LET N=P(2) ! パーの勝ち
IF P(0)=0 AND P(1)>0 AND P(2)>0 THEN LET N=P(1) ! チョキの勝ち
LOOP UNTIL N=1
LET SUM=SUM+COUNT
NEXT K
PRINT NN;"人の時";SUM/T;"回"
NEXT NN
END
30回試行させてじゃんけんで一人になるまでの平均回数を求めてみた。
実行結果
2 人の時 1.7 回
3 人の時 2.23333333333333 回
4 人の時 2.93333333333333 回
5 人の時 4.26666666666667 回
6 人の時 7.1 回
7 人の時 9.3 回
8 人の時 11.2333333333333 回
9 人の時 19.2333333333333 回
10 人の時 27.5333333333333 回
11 人の時 37.0333333333333 回
12 人の時 51.0333333333333 回
13 人の時 54.3333333333333 回
14 人の時 74.4666666666667 回
15 人の時 134 回
16 人の時 274.1 回
17 人の時 354.166666666667 回
18 人の時 527.233333333333 回
19 人の時 735.066666666667 回
20 人の時 1025.76666666667 回
21 人の時 1900.8 回
22 人の時 2451.56666666667 回
23 人の時 3752.83333333333 回
24 人の時 5382.76666666667 回
25 人の時 9291.76666666667 回
26 人の時 12405.2666666667 回
27 人の時 19177.9 回
28 人の時 28564.6333333333 回
29 人の時 33776.7333333333 回
30 人の時 81116.3 回
Re: じゃんけん - しばっち
2026/04/12 (Sun) 07:46:03
じゃんけんをして一人だけが勝ち抜けするまでの回数
但し、途中で勝っても抜けず一人だけが勝つ迄の回数
RANDOMIZE
INPUT PROMPT "人数=":N
DIM A(N),J$(0 TO 2),P(0 TO 2)
LET J$(0)="グー"
LET J$(1)="チョキ"
LET J$(2)="パー"
DO
LET COUNT=COUNT+1
MAT A=ZER
MAT P=ZER
! PRINT COUNT;"回"
FOR I=1 TO N
LET A(I)=INT(RND*3)
! PRINT J$(A(I)),
NEXT I
! PRINT
FOR I=1 TO N
LET P(A(I))=P(A(I))+1
NEXT I
IF P(0)=1 AND P(1)>0 AND P(2)=0 THEN EXIT DO ! グーの一人勝ち
IF P(0)>0 AND P(1)=0 AND P(2)=1 THEN EXIT DO ! パーの一人勝ち
IF P(0)=0 AND P(1)=1 AND P(2)>0 THEN EXIT DO ! チョキの一人勝ち
LOOP
PRINT COUNT;"回のジャンケンで一人勝ちになりました"
END
-------------------------------------------------------------------
20回試行して一人勝ちする迄の平均回数を求めてみた。
RANDOMIZE
DIM A(15),P(0 TO 2)
LET L=20
FOR NN=2 TO 15 ! 人数
LET SUM=0
FOR K=1 TO L ! 試行回数
LET N=NN
LET COUNT=0
DO
LET COUNT=COUNT+1
MAT P=ZER
FOR I=1 TO N
LET A(I)=INT(RND*3)
NEXT I
FOR I=1 TO N
LET P(A(I))=P(A(I))+1
NEXT I
IF P(0)=1 AND P(1)>0 AND P(2)=0 THEN EXIT DO ! グーの一人勝ち
IF P(0)>0 AND P(1)=0 AND P(2)=1 THEN EXIT DO ! パーの一人勝ち
IF P(0)=0 AND P(1)=1 AND P(2)>0 THEN EXIT DO ! チョキの一人勝ち
LOOP
LET SUM=SUM+COUNT
NEXT K
PRINT NN;"人の時";SUM/L;"回のジャンケンで一人勝ちになりました"
NEXT NN
END
実行結果
2 人の時 1.7 回のジャンケンで一人勝ちになりました
3 人の時 2.4 回のジャンケンで一人勝ちになりました
4 人の時 3.95 回のジャンケンで一人勝ちになりました
5 人の時 14.65 回のジャンケンで一人勝ちになりました
6 人の時 43.25 回のジャンケンで一人勝ちになりました
7 人の時 107.45 回のジャンケンで一人勝ちになりました
8 人の時 217.75 回のジャンケンで一人勝ちになりました
9 人の時 740.9 回のジャンケンで一人勝ちになりました
10 人の時 2258.8 回のジャンケンで一人勝ちになりました
11 人の時 3811.85 回のジャンケンで一人勝ちになりました
12 人の時 22032.85 回のジャンケンで一人勝ちになりました
13 人の時 40635.15 回のジャンケンで一人勝ちになりました
14 人の時 85129.2 回のジャンケンで一人勝ちになりました
15 人の時 242720.1 回のジャンケンで一人勝ちになりました
同じ誕生日の人 - しばっち
2026/04/12 (Sun) 07:41:52
クラス内に誕生日が同じ人がいる確率
Mathフォルダ内のBIRTHDAY.BASのシュミレーション
RANDOMIZE
LET M=300 ! 試行回数
INPUT PROMPT "1クラスの人数=":N
DIM A(N),P(365)
FOR K=1 TO M
MAT P=ZER
FOR I=1 TO N
LET A(I)=INT(RND*365+1) ! クラスの誕生日
NEXT I
FOR I=1 TO N
LET P(A(I))=P(A(I))+1 ! 同じ誕生日をカウント
NEXT I
FOR I=1 TO 365
IF P(I)>=2 THEN
LET C=C+1
EXIT FOR
END IF
NEXT I
NEXT K
PRINT "同じ誕生日の人がいる確率";C/M*100;"%"
END
----------------------------------------------------------
300回試行して平均求めてみた。
RANDOMIZE
LET M=300 ! 試行回数
DIM A(50),P(365)
FOR N=2 TO 50 ! 人数
LET C=0
FOR K=1 TO M
MAT P=ZER
FOR I=1 TO N
LET A(I)=INT(RND*365+1) ! クラスの誕生日
NEXT I
FOR I=1 TO N
LET P(A(I))=P(A(I))+1 ! 同じ誕生日をカウント
NEXT I
FOR I=1 TO 365
IF P(I)>=2 THEN
LET C=C+1
EXIT FOR
END IF
NEXT I
NEXT K
PRINT N;"人のクラスの中に同じ誕生の日の人がいる確率";C/M*100;"%"
NEXT N
END
実行結果
2 人のクラスの中に同じ誕生の日の人がいる確率 .333333333333333 %
3 人のクラスの中に同じ誕生の日の人がいる確率 1.33333333333333 %
4 人のクラスの中に同じ誕生の日の人がいる確率 3.33333333333333 %
5 人のクラスの中に同じ誕生の日の人がいる確率 3 %
6 人のクラスの中に同じ誕生の日の人がいる確率 2.66666666666667 %
7 人のクラスの中に同じ誕生の日の人がいる確率 5 %
8 人のクラスの中に同じ誕生の日の人がいる確率 7.33333333333333 %
9 人のクラスの中に同じ誕生の日の人がいる確率 10 %
10 人のクラスの中に同じ誕生の日の人がいる確率 14.3333333333333 %
11 人のクラスの中に同じ誕生の日の人がいる確率 13.6666666666667 %
12 人のクラスの中に同じ誕生の日の人がいる確率 15 %
13 人のクラスの中に同じ誕生の日の人がいる確率 18 %
14 人のクラスの中に同じ誕生の日の人がいる確率 22 %
15 人のクラスの中に同じ誕生の日の人がいる確率 27 %
16 人のクラスの中に同じ誕生の日の人がいる確率 24.3333333333333 %
17 人のクラスの中に同じ誕生の日の人がいる確率 34.3333333333333 %
18 人のクラスの中に同じ誕生の日の人がいる確率 32.3333333333333 %
19 人のクラスの中に同じ誕生の日の人がいる確率 40 %
20 人のクラスの中に同じ誕生の日の人がいる確率 41 %
21 人のクラスの中に同じ誕生の日の人がいる確率 45.6666666666667 %
22 人のクラスの中に同じ誕生の日の人がいる確率 50 %
23 人のクラスの中に同じ誕生の日の人がいる確率 50.3333333333333 %
24 人のクラスの中に同じ誕生の日の人がいる確率 54.6666666666667 %
25 人のクラスの中に同じ誕生の日の人がいる確率 56 %
26 人のクラスの中に同じ誕生の日の人がいる確率 57.6666666666667 %
27 人のクラスの中に同じ誕生の日の人がいる確率 61.3333333333333 %
28 人のクラスの中に同じ誕生の日の人がいる確率 67.3333333333333 %
29 人のクラスの中に同じ誕生の日の人がいる確率 67.6666666666667 %
30 人のクラスの中に同じ誕生の日の人がいる確率 71.6666666666667 %
31 人のクラスの中に同じ誕生の日の人がいる確率 71.3333333333333 %
32 人のクラスの中に同じ誕生の日の人がいる確率 74.3333333333333 %
33 人のクラスの中に同じ誕生の日の人がいる確率 79.6666666666667 %
34 人のクラスの中に同じ誕生の日の人がいる確率 76.6666666666667 %
35 人のクラスの中に同じ誕生の日の人がいる確率 81.6666666666667 %
36 人のクラスの中に同じ誕生の日の人がいる確率 82.6666666666667 %
37 人のクラスの中に同じ誕生の日の人がいる確率 86 %
38 人のクラスの中に同じ誕生の日の人がいる確率 89 %
39 人のクラスの中に同じ誕生の日の人がいる確率 90.3333333333333 %
40 人のクラスの中に同じ誕生の日の人がいる確率 87 %
41 人のクラスの中に同じ誕生の日の人がいる確率 92 %
42 人のクラスの中に同じ誕生の日の人がいる確率 93.6666666666667 %
43 人のクラスの中に同じ誕生の日の人がいる確率 92.6666666666667 %
44 人のクラスの中に同じ誕生の日の人がいる確率 93 %
45 人のクラスの中に同じ誕生の日の人がいる確率 94.6666666666667 %
46 人のクラスの中に同じ誕生の日の人がいる確率 94.3333333333333 %
47 人のクラスの中に同じ誕生の日の人がいる確率 96 %
48 人のクラスの中に同じ誕生の日の人がいる確率 96.3333333333333 %
49 人のクラスの中に同じ誕生の日の人がいる確率 95.3333333333333 %
50 人のクラスの中に同じ誕生の日の人がいる確率 97.6666666666667 %
----------------------------------------------------------
確率から人数求めてみた。
RANDOMIZE
LET F=300 ! 試行回数
DIM A(100),P(365)
DO
INPUT PROMPT "同じ誕生日の人がいる確率 (%)":Z
LOOP UNTIL Z<100 AND Z>0
LET Z=Z/100
LET L=1
LET R=100 ! 人数
DO
LET N=INT((L+R)/2)
LET C=0
FOR K=1 TO F
MAT P=ZER
FOR I=1 TO N
LET A(I)=INT(RND*365+1) ! クラスの誕生日
NEXT I
FOR I=1 TO N
LET P(A(I))=P(A(I))+1 ! 同じ誕生日をカウント
NEXT I
FOR I=1 TO 365
IF P(I)>=2 THEN
LET C=C+1
EXIT FOR
END IF
NEXT I
NEXT K
IF C/F<Z THEN LET L=N ELSE LET R=N
LOOP UNTIL L=R
PRINT L;"人の時、同じ誕生日の人がいる確率";Z*100;"%になります"
END
Re: 同じ誕生日の人 - しばっち
2026/04/12 (Sun) 07:43:12
1クラス内に自分と同じ誕生日の人がいる確率
RANDOMIZE
LET M=300 ! 試行回数
INPUT PROMPT "1クラスの人数=":N
DIM A(N)
LET P=INT(RND*365+1) ! 自分の誕生日
FOR K=1 TO M
FOR I=1 TO N
LET A(I)=INT(RND*365+1) ! クラスの誕生日
NEXT I
FOR I=1 TO N
IF A(I)=P THEN
LET C=C+1 ! 自分と同じならカウント
EXIT FOR
END IF
NEXT I
NEXT K
PRINT "自分と同じ誕生日の人がいる確率";C/M*100;"%"
END
--------------------------------------------------------------
300回試行して平均求めてみた
RANDOMIZE
LET M=300 ! 試行回数
DIM A(50)
FOR N=2 TO 50 ! 人数
LET C=0
LET P=INT(RND*365+1) ! 自分の誕生日
FOR K=1 TO M
FOR I=1 TO N
LET A(I)=INT(RND*365+1) ! クラスの誕生日
NEXT I
FOR I=1 TO N
IF A(I)=P THEN
LET C=C+1 ! 自分と同じならカウント
EXIT FOR
END IF
NEXT I
NEXT K
PRINT N;"人のクラスの中に自分と同じ誕生の日の人がいる確率";C/M*100;"%"
NEXT N
END
実行結果
2 人のクラスの中に自分と同じ誕生の日の人がいる確率 .333333333333333 %
3 人のクラスの中に自分と同じ誕生の日の人がいる確率 .666666666666667 %
4 人のクラスの中に自分と同じ誕生の日の人がいる確率 .333333333333333 %
5 人のクラスの中に自分と同じ誕生の日の人がいる確率 1.33333333333333 %
6 人のクラスの中に自分と同じ誕生の日の人がいる確率 2.33333333333333 %
7 人のクラスの中に自分と同じ誕生の日の人がいる確率 2.66666666666667 %
8 人のクラスの中に自分と同じ誕生の日の人がいる確率 2.66666666666667 %
9 人のクラスの中に自分と同じ誕生の日の人がいる確率 2.33333333333333 %
10 人のクラスの中に自分と同じ誕生の日の人がいる確率 6 %
11 人のクラスの中に自分と同じ誕生の日の人がいる確率 2.66666666666667 %
12 人のクラスの中に自分と同じ誕生の日の人がいる確率 3 %
13 人のクラスの中に自分と同じ誕生の日の人がいる確率 3.66666666666667 %
14 人のクラスの中に自分と同じ誕生の日の人がいる確率 5 %
15 人のクラスの中に自分と同じ誕生の日の人がいる確率 3.66666666666667 %
16 人のクラスの中に自分と同じ誕生の日の人がいる確率 3.33333333333333 %
17 人のクラスの中に自分と同じ誕生の日の人がいる確率 6 %
18 人のクラスの中に自分と同じ誕生の日の人がいる確率 3.66666666666667 %
19 人のクラスの中に自分と同じ誕生の日の人がいる確率 5.33333333333333 %
20 人のクラスの中に自分と同じ誕生の日の人がいる確率 6.33333333333333 %
21 人のクラスの中に自分と同じ誕生の日の人がいる確率 6.33333333333333 %
22 人のクラスの中に自分と同じ誕生の日の人がいる確率 6.66666666666667 %
23 人のクラスの中に自分と同じ誕生の日の人がいる確率 5.33333333333333 %
24 人のクラスの中に自分と同じ誕生の日の人がいる確率 6.33333333333333 %
25 人のクラスの中に自分と同じ誕生の日の人がいる確率 6.66666666666667 %
26 人のクラスの中に自分と同じ誕生の日の人がいる確率 6.66666666666667 %
27 人のクラスの中に自分と同じ誕生の日の人がいる確率 3.66666666666667 %
28 人のクラスの中に自分と同じ誕生の日の人がいる確率 7.33333333333333 %
29 人のクラスの中に自分と同じ誕生の日の人がいる確率 9.33333333333333 %
30 人のクラスの中に自分と同じ誕生の日の人がいる確率 5.33333333333333 %
31 人のクラスの中に自分と同じ誕生の日の人がいる確率 9 %
32 人のクラスの中に自分と同じ誕生の日の人がいる確率 7.66666666666667 %
33 人のクラスの中に自分と同じ誕生の日の人がいる確率 8.66666666666667 %
34 人のクラスの中に自分と同じ誕生の日の人がいる確率 8.66666666666667 %
35 人のクラスの中に自分と同じ誕生の日の人がいる確率 6.33333333333333 %
36 人のクラスの中に自分と同じ誕生の日の人がいる確率 8.66666666666667 %
37 人のクラスの中に自分と同じ誕生の日の人がいる確率 10.6666666666667 %
38 人のクラスの中に自分と同じ誕生の日の人がいる確率 7.66666666666667 %
39 人のクラスの中に自分と同じ誕生の日の人がいる確率 11.6666666666667 %
40 人のクラスの中に自分と同じ誕生の日の人がいる確率 7.66666666666667 %
41 人のクラスの中に自分と同じ誕生の日の人がいる確率 10.6666666666667 %
42 人のクラスの中に自分と同じ誕生の日の人がいる確率 10 %
43 人のクラスの中に自分と同じ誕生の日の人がいる確率 13.3333333333333 %
44 人のクラスの中に自分と同じ誕生の日の人がいる確率 12.3333333333333 %
45 人のクラスの中に自分と同じ誕生の日の人がいる確率 7.66666666666667 %
46 人のクラスの中に自分と同じ誕生の日の人がいる確率 11.6666666666667 %
47 人のクラスの中に自分と同じ誕生の日の人がいる確率 12.3333333333333 %
48 人のクラスの中に自分と同じ誕生の日の人がいる確率 9.66666666666667 %
49 人のクラスの中に自分と同じ誕生の日の人がいる確率 10.6666666666667 %
50 人のクラスの中に自分と同じ誕生の日の人がいる確率 13 %
--------------------------------------------------------------
確率から人数求めてみた
RANDOMIZE
LET F=300 ! 試行回数
DIM A(10000)
DO
INPUT PROMPT "自分と同じ誕生日の人がいる確率 (%)":Z
LOOP UNTIL Z<100 AND Z>0
LET Z=Z/100
LET L=1
LET R=10000 ! 人数
LET P=INT(RND*365+1)
DO
LET N=INT((L+R)/2)
LET C=0
FOR K=1 TO F
FOR I=1 TO N
LET A(I)=INT(RND*365+1) ! クラスの誕生日
NEXT I
FOR I=1 TO N
IF A(I)=P THEN
LET C=C+1
EXIT FOR
END IF
NEXT I
NEXT K
IF C/F<Z THEN LET L=N ELSE LET R=N
LOOP UNTIL L=R
PRINT L;"人の時、自分と同じ誕生日の人がいる確率";Z*100;"%になります"
END
カジノシュミレーション - しばっち
2026/04/05 (Sun) 07:59:54
カジノシュミレーション
https://www.casino-winnersclub.com/monte-carlo.php
https://rikei-logistics.com/monte-carlo-roulette
https://casimaru.com/monte-carlo-method/
RANDOMIZE
DIM MONTE(1000)
LET MONEY=100 ! 所持金
SET WINDOW -5,100,-10,500
DRAW GRID(5,20)
PLOT LINES:0,MONEY;
FOR I=1 TO 100 ! 試行回数
LET COUNT=0
MAT MONTE=ZER
LET HEAD=1
LET TAIL=3
LET MONTE(HEAD)=1
LET MONTE(HEAD+1)=2
LET MONTE(TAIL)=3
DO
LET COUNT=COUNT+1
LET PAY=MONTE(HEAD)+MONTE(TAIL) ! 賭け金
IF INT(RND*2)=1 THEN ! 勝ちなら
LET MONEY=MONEY+PAY
LET MONTE(HEAD)=0
LET MONTE(TAIL)=0
LET HEAD=HEAD+1
LET TAIL=TAIL-1
IF ABS(TAIL-HEAD)<=1 THEN EXIT DO ! 終了
ELSE ! 負けなら
LET MONEY=MONEY-PAY
LET MONTE(TAIL+1)=MONTE(HEAD)+MONTE(TAIL)
LET TAIL=TAIL+1
END IF
LOOP UNTIL MONEY<=0
PLOT LINES:I,MONEY;
PRINT I;"回目"
PRINT COUNT;"回繰り返し"
PRINT "所持金 ";MONEY
IF MONEY<=0 THEN EXIT FOR
NEXT I
IF MONEY<=0 THEN
PRINT "破産しました。失敗です"
ELSE
PRINT "所持金が";MONEY-100;"増えました。成功です。"
END IF
END
すごろくをちょうど終了できる確率 - しばっち
2026/04/05 (Sun) 07:58:50
! すごろくをちょうど終了できる確率
RANDOMIZE
LET K=500 ! 試行回数
FOR I=1 TO K
LET S=0
DO ! すごろく
LET S=S+INT(RND*6+1) ! サイコロ
LOOP UNTIL S>=100
IF S=100 THEN LET N=N+1 ! ちょうどゴールに到達したら
NEXT I
PRINT N/K*100;"%"
END
トランプをめくって途中で一致する確率 - しばっち
2026/04/05 (Sun) 07:57:19
!それぞれ1組ずつのトランプをめくって途中で一致する確率
RANDOMIZE
LET N=300
FOR J=1 TO N
FOR I=1 TO 53
IF INT(RND*53+1)=INT(RND*53+1) THEN
LET K=K+1
EXIT FOR
END IF
NEXT I
NEXT J
PRINT K/N*100;"%"
END
プレゼント交換で自身のプレゼントに当たる確率 - しばっち
2026/04/05 (Sun) 07:56:01
! プレゼント交換で自身のプレゼントに当たる確率
LET N=50 ! 人数
LET L=500 ! 試行回数
DIM A(N)
FOR J=1 TO L
FOR I=1 TO N
LET A(I)=I
NEXT I
FOR I=1 TO N
SWAP A(I),A(INT(RND*N+1)) ! プレゼント交換
NEXT I
FOR I=1 TO N
IF A(I)=I THEN LET K=K+1 ! 自身のプレゼント
NEXT I
NEXT J
PRINT K/L*100;"%"
END
------------------------------------------------------
! プレゼント交換で自分のプレゼントに当たる確率
INPUT PROMPT "人数=":N
LET L=500 ! 試行回数
DIM A(N)
FOR J=1 TO L
LET P=INT(RND*N+1) ! 自分のプレゼント
FOR I=1 TO N
LET A(I)=I
NEXT I
FOR I=1 TO N
SWAP A(I),A(INT(RND*N+1)) ! プレゼント交換
NEXT I
IF A(P)=P THEN LET K=K+1 ! 自分のプレゼント
NEXT J
PRINT K/L*100;"%"
END
十進BASIC版:素数計数関数 pi(x)正確値計算プログラム - Tarosa
2026/03/20 (Fri) 21:15:08
プロセッサ Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz (2.11 GHz)
実装 RAM 8.00 GB (7.84 GB 使用可能)
エディション Windows 11 Home
バージョン 25H2
タスクマネージャー(CPU 2.5GHz 前後 使用率25% 程度
BASIC Accelerator Ver. 1.2.2.6(2025.11.08)
Lazarus Windows 64ビット版/ Lazarus 4.6
lazarus-4.6-fpc-3.2.2-win64.exe
!十進BASIC版:素数計数関数 pi(x)正確値計算プログラム
DECLARE EXTERNAL FUNCTION PI_COUNT_EXACT
OPTION ARITHMETIC NATIVE
!OPTION ARITHMETIC RATIONAL
! --- 設定 ---
LET x = 10000000000000 ! 10兆 (10^13)
PRINT x; " の正確な素数個数を計算します。"
LET t0 = TIME
! --- メイン計算呼び出し ---
LET result = PI_COUNT_EXACT(x)
PRINT "------------------------------"
PRINT "結果(正確な値):"; result
PRINT "計算時間:"; TIME - t0; " 秒"
PRINT "------------------------------"
END
! --- 高速素数計数ルーチン (Lucy Hedgehog法) ---
EXTERNAL FUNCTION PI_COUNT_EXACT(n)
OPTION ARITHMETIC NATIVE
!OPTION ARITHMETIC RATIONAL
LET limit = INT(SQR(n))
! 1. 値の候補 (n/i) を抽出して配列のサイズを決定
! 10^13の場合、約632万個の要素が必要
LET num_values = 0
LET i1 = 1
DO WHILE i1 <= n
LET num_values = num_values + 1
LET v1 = INT(n / i1)
LET i1 = INT(n / v1) + 1
LOOP
! 配列の確保 (V: 値の保持, S: その値以下の素数個数)
DIM V(6400000)
DIM S(6400000)
! 2. 初期値の設定
LET idx = 0
LET i1 = 1
DO WHILE i1 <= n
LET idx = idx + 1
LET v1 = INT(n / i1)
LET V(idx) = v1
LET S(idx) = v1 - 1 ! 初期値は v1-1 (1を除く個数)
LET i1 = INT(n / v1) + 1
LOOP
LET max_idx = idx
! 3. エラトステネスの篩による更新
PRINT "計算開始... 要素数:"; max_idx
FOR p = 2 TO limit
! S(p) > S(p-1) なら p は素数
! 十進BASICではS(p)の直接参照が難しいため、Vの中からpの位置を探す
! 実際には p <= limit なので V の後ろの方にある
LET p_idx = max_idx - p + 1
IF S(p_idx) > S(p_idx + 1) THEN
LET sp_1 = S(p_idx + 1)
LET p2 = p * p
FOR j = 1 TO max_idx
IF V(j) < p2 THEN EXIT FOR
! V(j)/p がどこにあるか計算
LET next_v = INT(V(j) / p)
IF next_v <= LIMIT THEN
LET target_idx = max_idx - next_v + 1
ELSE
LET target_idx = INT(n / next_v)
END IF
LET S(j) = S(j) - (S(target_idx) - sp_1)
NEXT j
IF MOD(p, 5000) = 0 THEN
PRINT "現在 p="; p; " まで完了 /"; LIMIT
END IF
END IF
NEXT p
LET PI_COUNT_EXACT = S(1)
END FUNCTION
計算結果
10000000000000 の正確な素数個数を計算します。
計算開始... 要素数: 6324554
------------------------------
結果(正確な値): 346065536839
計算時間: 45.3410000000003 秒
------------------------------
346065536839 素数定理 参照
https://ja.wikipedia.org/wiki/%E7%B4%A0%E6%95%B0%E5%AE%9A%E7%90%86
LET x = 1000000000000 ! (10^12)
1000000000000 の正確な素数個数を計算します。
計算開始... 要素数: 1999999
------------------------------
結果(正確な値): 37607912018
計算時間: 8.12299999999232 秒
------------------------------
LET x = 100000000000 ! (10^11)
100000000000 の正確な素数個数を計算します。
計算開始... 要素数: 632454
------------------------------
結果(正確な値): 4118054813
計算時間: 1.59799999999814 秒
------------------------------
LET x = 10000000000 ! (10^10)
10000000000 の正確な素数個数を計算します。
計算開始... 要素数: 199999
------------------------------
結果(正確な値): 455052511
計算時間: 0.334000000002561 秒
------------------------------
Re: 十進BASIC版:素数計数関数 pi(x)正確値計算プログラム - しばっち
2026/04/05 (Sun) 07:54:18
私も素数個数関数をルジャンドル法で作ってみた。
とりあえずやっと動くようになりました。
まだ改良の余地はあるかとは思いますが
参考程度にはなるかと思います。
https://mathworld.wolfram.com/LegendresFormula.html
https://www.hs.chuo-u.ac.jp/contents/wp-content/themes/chu-fu/pdf/bulletin/issue30/issue30_pdf10.pdf
https://rosettacode.org/wiki/Legendre_prime_counting_function
OPTION BASE 0
LET N=1000000
PUBLIC NUMERIC PICACHE(10000),PRIME(10000),CACHE(10000,100),COUNT
MAT CACHE=(-1)*CON
CALL PRIMESIEVE(INT(SQR(N)))
PRINT π(N)
END
EXTERNAL SUB PRIMESIEVE(N)
MAT PICACHE=CON
LET PICACHE(1)=0
LET COUNT=0
FOR I=2 TO N
IF PICACHE(I)=1 THEN
LET COUNT=COUNT+1
LET PRIME(COUNT)=I
FOR J=I*I TO N STEP I
LET PICACHE(J)=0
NEXT J
END IF
NEXT I
FOR I=1 TO N-1
LET PICACHE(I+1)=PICACHE(I+1)+PICACHE(I)
NEXT I
END SUB
EXTERNAL FUNCTION φ(X,A)
IF X=0 THEN
LET φ=0
EXIT FUNCTION
END IF
IF X=1 THEN
LET φ=1
EXIT FUNCTION
END IF
IF A=1 THEN
LET φ=IP(X/2)
LET CACHE(X,1)=IP(X/2)
EXIT FUNCTION
END IF
IF A=2 THEN
LET φ=IP(X/3)
LET CACHE(X,2)=IP(X/3)
EXIT FUNCTION
END IF
IF A=3 THEN ! COMB(3,1)+COMB(3,2)+COMB(3,3) 2,3,5
LET S=X-IP(X/2)-IP(X/3)-IP(X/5)+IP(X/(2*3))+IP(X/(2*5))+IP(X/(3*5))-IP(X/(2*3*5))
LET φ=S
IF X<10000 THEN LET CACHE(X,3)=S
EXIT FUNCTION
END IF
IF A=4 THEN ! COMB(4,1)+COMB(4,2)+COMB(4,3)+COMB(4,4) 2,3,5,7
LET S=X-IP(X/2)-IP(X/3)-IP(X/5)-IP(X/7)+IP(X/(2*3))+IP(X/(2*5))+IP(X/(2*7))+IP(X/(3*5))+IP(X/(3*7))+IP(X/(5*7))-IP(X/(2*3*5))-IP(X/(2*3*7))-IP(X/(2*5*7))-IP(X/(3*5*7))+IP(X/(2*3*5*7))
LET φ=S
IF X<10000 THEN LET CACHE(X,4)=S
EXIT FUNCTION
END IF
IF A=5 THEN ! COMB(5,1)+COMB(5,2)+COMB(5,3)+COMB(5,4)+COMB(5,5) 2,3,5,7,11
LET S=X-IP(X/2)-IP(X/3)-IP(X/5)-IP(X/7)-IP(X/11)+IP(X/(2*3))+IP(X/(2*5))+IP(X/(2*7))+IP(X/(2*11))+IP(X/(3*5))+IP(X/(3*7))+IP(X/(3*11))+IP(X/(5*7))+IP(X/(5*11))+IP(X/(7*11))
LET S=S-IP(X/(2*3*5))-IP(X/(2*3*7))-IP(X/(2*3*11))-IP(X/(2*5*7))-IP(X/(2*5*11))-IP(X/(2*7*11))-IP(X/(3*5*7))-IP(X/(3*5*11))-IP(X/(3*7*11))-IP(X/(5*7*11))
LET S=S+IP(X/(2*3*5*7))+IP(X/(2*3*5*11))+IP(X/(2*3*7*11))+IP(X/(2*5*7*11))+IP(X/(3*5*7*11))-IP(X/(2*3*5*7*11))
LET φ=S
IF X<10000 THEN LET CACHE(X,5)=S
EXIT FUNCTION
END IF
IF X<10000 AND A<100 AND CACHE(X,A)<>-1 THEN
LET S=CACHE(X,A)
ELSE
LET S=φ(X,A-1)
IF X<10000 AND A<100 THEN LET CACHE(X,A)=S
END IF
LET XX=IP(X/PRIME(A))
IF XX<10000 AND A<100 AND CACHE(XX,A)<>-1 THEN
LET T=CACHE(XX,A)
ELSE
LET T=φ(XX,A-1)
IF XX<10000 AND A<100 THEN LET CACHE(XX,A)=T
END IF
LET φ=S-T
END FUNCTION
EXTERNAL FUNCTION π(X)
IF X<=PRIME(COUNT) THEN
LET π=PICACHE(X)
EXIT FUNCTION
END IF
!LET T=π(INT(SQR(X)))
LET T=COUNT
LET π=T+φ(X,T)-1
END FUNCTION
要望 - しばっち
2026/03/15 (Sun) 07:50:18
複素数モード時においてEXP(N*LOG(X))を
^(ペキ乗)で記述できるようにできませんか?
OPTION ARITHMETIC COMPLEX
LET X=-2.5
LET N=3.5
PRINT EXP(N*LOG(X)) ! OK
!PRINT X^N ! エラー
END
Re: 要望 - SHIRAISHI Kazuo
2026/03/15 (Sun) 13:16:47
X^N = EXP(N*LOG(X)) と定義してしまえば可能ですが,一般には負数の非整数乗は未定義とします。
たとえば,
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14250831054
要するに,値が1つに定まらないからで,0÷0を未定義にするのと同様の理屈です。
e=mc^2 - しばっち
2026/03/15 (Sun) 07:55:43
E=MC^2
アインシュタインの有名な方程式で計算してみた。
https://ja.wikipedia.org/wiki/質量とエネルギーの等価性
私は決してメタボではない(と思っている)がおなかの脂肪10Kgをエネルギーに変え電力にして
それを1KW/h=15円で売ったなら(3.7兆円 !?)一生遊んで暮らせるぞと思うのは私だけだろうか?
LET C=299792458 ! (m/s) 光速
INPUT PROMPT "質量(Kg)=":M
LET E=M*C^2
LET CAL=E/4.184 ! 4.184ジュール=1カロリー
CALL DISPLAY(E,"ジュール") ! J (Kg・m^2/s^2)
CALL DISPLAY(CAL,"カロリー")
CALL DISPLAY(CAL/100/1000,"キログラムの水を0度から100度に沸騰させる")
CALL DISPLAY(E/3600/1000,"キロワットh") ! KW・h
PRINT "買取価格 ";
CALL DISPLAY(E/3600/1000*15,"円") ! 1KW/h=15円
PRINT "東京ドーム ";
CALL DISPLAY(CAL/100/1240000000/1000,"杯分の水を沸騰させる") ! 東京ドーム1杯 1240000000リットル
END
EXTERNAL SUB DISPLAY(P,D$)
LET P$=USING$(REPEAT$("#",68),INT(P))
LET Q$=USING$(".####",FP(P))
DIM S$(18)
FOR I=LEN(P$) TO 1 STEP -4
LET N=N+1
LET S$(N)=P$(I-3:I)
LET S$(N)=LTRIM$(S$(N))
NEXT I
IF S$(2)<>"" THEN LET S$(2)=S$(2)&"万"
IF S$(3)<>"" THEN LET S$(3)=S$(3)&"億"
IF S$(4)<>"" THEN LET S$(4)=S$(4)&"兆"
IF S$(5)<>"" THEN LET S$(5)=S$(5)&"京"
IF S$(6)<>"" THEN LET S$(6)=S$(6)&"垓"
IF S$(7)<>"" THEN LET S$(7)=S$(7)&"じょ"
IF S$(8)<>"" THEN LET S$(8)=S$(8)&"穣"
IF S$(9)<>"" THEN LET S$(9)=S$(9)&"溝"
IF S$(10)<>"" THEN LET S$(10)=S$(10)&"澗"
IF S$(11)<>"" THEN LET S$(11)=S$(11)&"正"
IF S$(12)<>"" THEN LET S$(12)=S$(12)&"載"
IF S$(13)<>"" THEN LET S$(13)=S$(13)&"極"
IF S$(14)<>"" THEN LET S$(14)=S$(14)&"恒河沙"
IF S$(15)<>"" THEN LET S$(15)=S$(15)&"阿僧祇"
IF S$(16)<>"" THEN LET S$(16)=S$(16)&"那由他"
IF S$(17)<>"" THEN LET S$(17)=S$(17)&"不可思議"
IF S$(18)<>"" THEN LET S$(18)=S$(18)&"無料大数"
FOR I=18 TO 1 STEP -1
PRINT S$(I);
NEXT I
PRINT Q$;D$
END SUB
実行結果
質量(Kg)=10
89京8755兆1787億3681万7664.0000ジュール
21京4807兆6431億0153万3856.0000カロリー
2兆1480億7643万1015.3384キログラムの水を0度から100度に沸騰させる
2496億5421万6315.7827キロワットh
買取価格 3兆7448億1324万4736.7402円
東京ドーム 1732.3197杯分の水を沸騰させる
最上位桁の分布 - しばっち
2026/03/15 (Sun) 07:54:11
2^nの最上位桁の数字の分布
2^1~2^1000までの最上位桁の数字の分布を求めてみた。
DIM A(9)
FOR N=1 TO 1000
LET P=FP(N*LOG10(2)) ! 2^n
LET K=INT(10^P)
LET A(K)=A(K)+1
NEXT N
SET WINDOW -1,9,-10,350
DRAW GRID(1,50)
FOR I=1 TO 9
PLOT LINES:I,A(I);
NEXT I
END
------------------------------------------------------------
2^nの最上位から2桁目の数字の分布
DIM A(0 TO 9)
FOR I=1 TO 1000
LET P=FP(I*LOG10(2))
LET K=MOD(INT(10^P*10),10)
LET A(K)=A(K)+1
NEXT I
SET WINDOW -1,9,-10,200
DRAW GRID(1,50)
FOR I=0 TO 9
PLOT LINES:I,A(I);
NEXT I
END
------------------------------------------------------------
2^nの末尾桁の数字の分布
DIM A(0 TO 9)
LET K=1
FOR I=1 TO 1000
LET K=MOD(K*2,10)
LET A(K)=A(K)+1
NEXT I
SET WINDOW -1,9,-10,300
DRAW GRID(1,50)
FOR I=0 TO 9
PLOT LINES:I,A(I);
NEXT I
END
スーパー円 - しばっち
2026/03/15 (Sun) 07:52:42
スーパー円
OPTION ANGLE DEGREES
SET WINDOW -1,1,-1,1
LOCATE VALUE NOWAIT(1),RANGE 0 TO 2:N1
LOCATE VALUE NOWAIT(2),RANGE 0 TO 2:N2
!LOCATE VALUE NOWAIT(3),RANGE 0 TO 2:N3
LOCATE VALUE NOWAIT(4),RANGE 3 TO 20,AT 3:M
LOCATE VALUE NOWAIT(5),RANGE .1 TO 1:A
LOCATE VALUE NOWAIT(6),RANGE .1 TO 1:B
DO
LOCATE VALUE NOWAIT(1):N1
LOCATE VALUE NOWAIT(2):N2
! LOCATE VALUE NOWAIT(3):N3
LOCATE VALUE NOWAIT(4):M
LOCATE VALUE NOWAIT(5):A
LOCATE VALUE NOWAIT(6):B
LET N3=N2
DRAW GRID(.1,.1)
FOR T=0 TO 360
LET R=1/(ABS(1/A*COS(M/4*T))^N2+ABS(1/B*SIN(M/4*T))^N3)^(1/N1)
LET X=R*COS(T)
LET Y=R*SIN(T)
PLOT LINES:X,Y;
NEXT T
PLOT LINES
SET DRAW MODE EXPLICIT
WAIT DELAY .1
SET DRAW MODE HIDDEN
CLEAR
LOOP
END
-----------------------------------------------------------------------------------
OPTION ANGLE DEGREES
SET WINDOW -3,3,-3,3
DRAW GRID(1,1)
LET RR=1
LOCATE VALUE NOWAIT(1),RANGE 0 TO 1:A
LOCATE VALUE NOWAIT(2),RANGE 0 TO 1:B
LOCATE VALUE NOWAIT(3),RANGE 0 TO 1:C
LOCATE VALUE NOWAIT(4),RANGE 0 TO 360,AT 0:TH1
LOCATE VALUE NOWAIT(5),RANGE 0 TO 360,AT 0:TH2
LOCATE VALUE NOWAIT(6),RANGE 0 TO 360,AT 0:TH3
DO
LOCATE VALUE NOWAIT(1):A
LOCATE VALUE NOWAIT(2):B
LOCATE VALUE NOWAIT(3):C
LOCATE VALUE NOWAIT(4):TH1
LOCATE VALUE NOWAIT(5):TH2
LOCATE VALUE NOWAIT(6):TH3
DRAW GRID(1,1)
FOR T=0 TO 360
LET R=RR*(1+A*COS(T+TH1)+B*COS(2*T+TH2)+C*COS(3*T+TH3))
LET X=R*COS(T)
LET Y=R*SIN(T)
PLOT LINES:X,Y;
NEXT T
PLOT LINES
SET DRAW MODE EXPLICIT
WAIT DELAY .1
SET DRAW MODE HIDDEN
CLEAR
LOOP
END
COS模様 - しばっち
2026/03/15 (Sun) 07:51:41
色々なパターンの模様が描ける
PUBLIC NUMERIC L
SET POINT STYLE 1
LET SIZE=8
SET WINDOW -SIZE,SIZE,-SIZE,SIZE
ASK BITMAP SIZE XSIZE,YSIZE
LET L=XSIZE/SIZE
FOR N=1 TO 10
FOR M=1 TO 10
CLEAR
IF M<>N THEN
FOR Y=0 TO YSIZE
FOR X=0 TO XSIZE
IF ABS(F(X,Y,M,N))<.1 THEN
PLOT POINTS : WORLDX(X),WORLDY(Y)
END IF
NEXT X
NEXT Y
WAIT DELAY 1
END IF
NEXT M
NEXT N
END
EXTERNAL FUNCTION F(X,Y,M,N)
LET F=COS(N*X*PI/L)*COS(M*Y*PI/L)-COS(M*X*PI/L)*COS(N*Y*PI/L)
END FUNCTION
十進BASIC7.8.8の文字化け - た
2026/03/07 (Sat) 07:57:18
皆様、いつもありがとうございます。
初歩的な質問で申し訳ございません。
最新バージョンの7.8.8にて、文字化けが発生します。
最初は、日本語が「???」で全く表示されなかったのですが、OSのローケルや表示を日本語優先にすることである程度は直りましたが、一部、文字化けが治りません。
該当文字列だけ、文字コードが異なるのではないかと推定しております。
ほかに直し方がお分かりでしたら、お教えいただけますでしょうか。
OS:Windows 11 Pro 25H2 26200.7840
よろしくお願いいたします。
Re: 十進BASIC7.8.8の文字化け - SHIRAISHI Kazuo
2026/03/07 (Sat) 10:17:04
7.8.8以前のバージョンでは問題ないのでしょうか。
ver. 7.8.7.7と7.8.7.6が https://decimalbasic.web.fc2.com/basicw32.htm から入手可能です。
なお,Windows 11 Home 25H2 26200.7840 でテストする範囲では正常です。
Re: 十進BASIC7.8.8の文字化け - knoike
2026/03/07 (Sat) 12:39:21
knoike です。ここでは初めて書き込みます。
設定 → 時刻と言語 → 言語と地域
で、
[Windows の表示言語] の右端の v をクリックして展開される項目の
[ベータ版: 世界中の言語に対応するために Unicode UTF-8 を使用します]
が
[オン] になっていると化けます。
デフォルトは [オフ] で、[オフ] なら化けません。正常に表示されます。
「OSのローケルや表示を日本語優先にすることである程度は直りましたが、」という書き込みから、
言語パックをいくつかインストールしてあるのだと想像していますが、
たいていのアプリはここの設定が [オフ] のままで正常に表示できるような多言語対応がなされていると思いますので、
特別な事情がない限りは [オフ] にしておくとよいのではないでしょうか。
Re: 十進BASIC7.8.8の文字化け - た
2026/03/07 (Sat) 20:44:35
ありがとうございます。
>SHIRAISHI Kazuo さん
旧バージョンを試してみましたが、結果は同じでした。
>knoikeさん
ご指摘の部分がONでしたので、OFFにしてみましたが、改善は見られませんでした。
みなさん、ご指摘の通り、私のwindows 11の環境が怪しそうなので、まず、OS周りで不具合がないか、一度確認してみます。
ありがとうございました。
Re: 十進BASIC7.8.8の文字化け - た
2026/03/07 (Sat) 20:53:31
今、試しで、「十進BASIC ver. 8」を使ってみたら、全く文字化けがありません。
文字コードがutf-8に対応した、ということですが、Version 7の中の別の文字コードが化けている可能性があるのでは、と推定しています。
現時点で、Version 8であれば文字化けは発生しませんので、当面はこちらを使いたいと思います。
ありがとうございました。
Re: 十進BASIC7.8.8の文字化け - SHIRAISHI Kazuo
2026/03/08 (Sun) 07:55:50
設定 → 時刻と言語 → 言語と地域 [ベータ版: 世界中の言語に対応するために Unicode UTF-8 を使用します] を試してみました。
投稿された通りの結果になります。
Ver.7は内部でshift-JISを採用しています。また,「機能語挿入」の内容部分は BASIC.kwFとBASIC.kwSから読み込んでいます。
BASIC.kwFとBASIC.kwSはshift-JISで書かれているので文字化けして当然ですが,それ以外の部分はβ版で未対応なのだろうと思います。
なお,Ver.7 日本語版の翻訳系は,文字コードがShift-JISであることを前提にしています。UTF-8の文字を含むプログラムは,おそらく正常に実行できません。
Re: 十進BASIC7.8.8の文字化け - SHIRAISHI Kazuo
2026/03/08 (Sun) 11:59:40
十進BASIC Ver.8は,内部文字コードがUTF-8ですが,Windows APIは16ビットwide文字対応版を使うので,Windowsのlocaleの影響を受けません。
BASICAccなども同様です。
Re: 十進BASIC7.8.8の文字化け - SHIRAISHI Kazuo
2026/03/09 (Mon) 09:21:33
十進BASIC ver.8(日本語版)はWindowsのコードページ設定に関係なく日本語で動作します。
Ver.8でもWindows APIの呼び出しが使えます。
https://decimalbasic.web.fc2.com/ExtDLL.htm
WindowsAPIのMessageBoxAは,ANSI文字でメッセージボックスを表示します。
WindowsのANSI文字というのは,Windowsのコードページごとに定まる文字のことで,日本語版WindowsではShift-JISのことです。
DECLARE EXTERNAL FUNCTION MesBox
LET n=MesBox(0,"日本語","BASIC",3)
PRINT n
END
EXTERNAL FUNCTION MesBox(owner,text$,caption$,flag)
ASSIGN "user32.dll","MessageBoxA"
END FUNCTION
をVer.8で実行すると文字化けします(Ver.8で"日本語"がUTF-8文字なので)。
"日本語" のところを ANSI$("日本語") に変えると正常に機能します。
ANSI$関数は,コードページの指定にしたがってUTF-8文字列をANSI文字列に変える関数です。
MessageBoxAの説明は
https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-messageboxa
にあります。
「世界中の言語に対応するために Unicode UTF-8 を使用します」の意味は,ANSI文字としてUTF-8を採用することのように思われます。
Ver.8はWindowsの言語設定を変えても動作するので,テストしてみていただけないでしょうか。
Re: 十進BASIC7.8.8の文字化け - た
2026/03/14 (Sat) 19:05:46
返信が遅くなり、申し訳ございません。
承知しました。
WindowsAPIの利用含め、Version.8を一通り試して、何か気が付いた点がございましたら、また報告させていただきます。
お時間いただきまして、ありがとうございました。
よろしくお願いいたします。
ローテートパズル - しばっち
2026/03/01 (Sun) 07:47:11
バラバラになった数字をローテートさせながら
数字を揃えるパズルです。
シャッフル回数を入れるとゲーム開始です。
マウスで矢印をクリックすると数字がローテーション
します。
Rキーでリトライ(リスタート)
Gキーでギブアップになります。
DECLARE FUNCTION CHECK
RANDOMIZE
CALL GINIT(800,800)
LET SIZE=3
DIM M(SIZE,SIZE),T(SIZE,SIZE),XS(50),YS(50),NS(50)
SET TEXT JUSTIFY "CENTER","HALF"
SET TEXT BACKGROUND "OPAQUE"
FOR J=1 TO SIZE
FOR I=1 TO SIZE
LET M(I,J)=SIZE*(J-1)+I
NEXT I
NEXT J
CALL DISPLAY
CALL DISPLAY2(0,0)
INPUT PROMPT "シャッフル回数(5-50)=":NN
FOR K=1 TO NN ! 問題作成
LET X=INT(RND*3+1)
LET Y=INT(RND*3+1)
LET N=INT(RND*4+1)
CALL ROTATE(N,X,Y)
LET XS(K)=X
LET YS(K)=Y
IF N=1 OR N=2 THEN
LET NS(K)=3-N
END IF
IF N=3 OR N=4 THEN
LET NS(K)=7-N
END IF
CALL DISPLAY
WAIT DELAY .1
NEXT K
MAT T=M ! 面データコピー
DO ! ゲーム開始
CLEAR
CALL DISPLAY
CALL DISPLAY2(0,0)
SET DRAW MODE EXPLICIT
IF CHECK=1 THEN EXIT DO ! 揃ったら
DO
IF GETKEYSTATE(ORD("R"))<0 OR GETKEYSTATE(ORD("r"))<0 THEN ! リトライ(リスタート)
MAT M=T
CALL DISPLAY
END IF
IF GETKEYSTATE(ORD("G"))<0 OR GETKEYSTATE(ORD("g"))<0 THEN ! ギブアップ
MAT M=T
CALL DISPLAY
FOR K=NN TO 1 STEP -1 ! 解答表示
CALL ROTATE(NS(K),XS(K),YS(K))
CALL DISPLAY
CALL DISPLAY2(100+300/SIZE+600/SIZE*(XS(K)-1),100+300/SIZE+600/SIZE*(YS(K)-1))
WAIT DELAY .5
NEXT K
STOP
END IF
MOUSE POLL MX,MY,LEFT,RIGHT ! マウス入力
LOOP UNTIL LEFT=1 OR RIGHT=1 ! クリックしたら
DO
MOUSE POLL MX,MY,LEFT,RIGHT
LOOP WHILE LEFT=1 OR RIGHT=1
CALL DISPLAY2(MX,MY)
IF MX<100 THEN
LET Y=INT((MY-100)/(600/SIZE))+1
CALL ROTATE(1,X,Y)
END IF
IF MX>700 THEN
LET Y=INT((MY-100)/(600/SIZE))+1
CALL ROTATE(2,X,Y)
END IF
IF MY<100 THEN
LET X=INT((MX-100)/(600/SIZE))+1
CALL ROTATE(3,X,Y)
END IF
IF MY>700 THEN
LET X=INT((MX-100)/(600/SIZE))+1
CALL ROTATE(4,X,Y)
END IF
SET DRAW MODE HIDDEN
WAIT DELAY .3
LOOP
SET TEXT HEIGHT 80
SET TEXT BACKGROUND "TRANSPARENT"
SET TEXT COLOR 2
PLOT TEXT ,AT 400,400:"Congratulations"
SUB DISPLAY ! 画面表示
SET LINE COLOR 7
SET TEXT COLOR 7
SET TEXT HEIGHT 300/SIZE
SET TEXT BACKGROUND "OPAQUE"
FOR X=100 TO 700 STEP 600/SIZE
PLOT LINES : X,0;X,800
NEXT X
FOR Y=100 TO 700 STEP 600/SIZE
PLOT LINES : 0,Y;800,Y
NEXT Y
FOR J=1 TO SIZE
FOR I=1 TO SIZE
PLOT TEXT ,AT 100+300/SIZE+600/SIZE*(I-1),100+300/SIZE+600/SIZE*(J-1):USING$("##",M(I,J))
NEXT I
NEXT J
END SUB
SUB DISPLAY2(X,Y) ! 矢印表示
SET TEXT HEIGHT 50
SET TEXT BACKGROUND "TRANSPARENT"
FOR I=1 TO SIZE
IF X<100 AND Y>100+600/SIZE*(I-1) AND Y<100+600/SIZE*I THEN
SET TEXT COLOR 2
CALL BOXFULL(0,100+600/SIZE*(I-1),100,100+600/SIZE*I,5)
ELSE
SET TEXT COLOR 4
END IF
PLOT TEXT ,AT 50,100+300/SIZE+600/SIZE*(I-1):"←"
NEXT I
FOR I=1 TO SIZE
IF X>700 AND Y>100+600/SIZE*(I-1) AND Y<100+600/SIZE*I THEN
SET TEXT COLOR 2
CALL BOXFULL(700,100+600/SIZE*(I-1),800,100+600/SIZE*I,5)
ELSE
SET TEXT COLOR 4
END IF
PLOT TEXT ,AT 750,100+300/SIZE+600/SIZE*(I-1):"→"
NEXT I
FOR I=1 TO SIZE
IF Y<100 AND X>100+600/SIZE*(I-1) AND X<100+600/SIZE*I THEN
SET TEXT COLOR 2
CALL BOXFULL(100+600/SIZE*(I-1),0,100+600/SIZE*I,100,5)
ELSE
SET TEXT COLOR 4
END IF
PLOT TEXT ,AT 100+300/SIZE+600/SIZE*(I-1),50:"↑"
NEXT I
FOR I=1 TO SIZE
IF Y>700 AND X>100+600/SIZE*(I-1) AND X<100+600/SIZE*I THEN
SET TEXT COLOR 2
CALL BOXFULL(100+600/SIZE*(I-1),700,100+600/SIZE*I,800,5)
ELSE
SET TEXT COLOR 4
END IF
PLOT TEXT ,AT 100+300/SIZE+600/SIZE*(I-1),750:"↓"
NEXT I
END SUB
SUB ROTATE(N,X,Y) ! 回転
SELECT CASE N
CASE 1 ! LEFT
LET TEMP=M(1,Y)
FOR I=1 TO SIZE-1
LET M(I,Y)=M(I+1,Y)
NEXT I
LET M(SIZE,Y)=TEMP
CASE 2 ! RIGHT
LET TEMP=M(SIZE,Y)
FOR I=SIZE-1 TO 1 STEP -1
LET M(I+1,Y)=M(I,Y)
NEXT I
LET M(1,Y)=TEMP
CASE 3 ! UP
LET TEMP=M(X,1)
FOR I=1 TO SIZE-1
LET M(X,I)=M(X,I+1)
NEXT I
LET M(X,SIZE)=TEMP
CASE 4 ! DOWN
LET TEMP=M(X,SIZE)
FOR I=SIZE-1 TO 1 STEP -1
LET M(X,I+1)=M(X,I)
NEXT I
LET M(X,1)=TEMP
END SELECT
END SUB
FUNCTION CHECK ! 揃ったか?
FOR J=1 TO SIZE
FOR I=1 TO SIZE
IF M(I,J)<>SIZE*(J-1)+I THEN
LET CHECK=0
EXIT FUNCTION
END IF
NEXT I
NEXT J
LET CHECK=1
END FUNCTION
END
EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,YSIZE-1,0
SET POINT STYLE 1
SET COLOR MODE "REGULAR"
FOR I=0 TO 7
SET COLOR MIX(I) BITAND(I,2)/2,BITAND(I,4)/4,BITAND(I,1)
NEXT I
CLEAR
END SUB
EXTERNAL SUB BOXFULL(X1,Y1,X2,Y2,C)
SET AREA COLOR C
PLOT AREA:X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB
arm版Windows11 - SHIRAISHI Kazuo
2026/02/15 (Sun) 10:09:28
arm版Windows11で,十進BASIC Ver.7,ver.8 は正しく動作しません。FPU例外(0除算,桁あふれなど)の処理に問題があります。
BASIC generic Ver. 0.9 Win64版はx86_64向けにコンパイルしたものですが,FPU例外を利用しないので,arm版Windows11でも動作します。
ただし,テストが十分とはいえないので,arm版Windows11での動作に疑義を見つけた方は報告をお願いします。
Windowsの仕様は,
「スタート」メニューから「設定」(歯車アイコン)
「システム」
「バージョン情報」
で確認できます。
Re: arm版Windows11 - SHIRAISHI Kazuo
2026/02/16 (Mon) 08:45:54
テストプログラムです。
10 OPTION ARITHMETIC NATIVE
20 LET x=0
30 WHEN EXCEPTION IN
40 PRINT 1/x
50 USE
60 PRINT "正常"
70 END WHEN
80 END
Ver.7 をarm版Winows11で実行すると,このテストプログラムでフリーズします。
Ver.8 だとこのテストは通過しますが,複素数モードのサンプルプログラムMU_COSH.BASやMANDELBL.BASを実行するとすべて黒で塗りつぶされてしまいます。
テスト環境は,MAC (Apple Silicon) 上のVrtualBox上のWindows11 Canary です。
実機だと異なる結果になるかもしれません。実機 Windows on arm での動作報告を期待(歓迎)します。
Re: arm版Windows11 - SHIRAISHI Kazuo
2026/02/16 (Mon) 20:24:22
MAC (Apple Silicon) 上のVrtualBox上のWindows11 Canaryにおいて,十進BASIC Ver.8(Windows版)で
10 OPTION ARITHMETIC NATIVE
20 LET x=0
30 WHEN EXCEPTION IN
40 PRINT 1/x
50 USE
60 PRINT EXTYPE
70 END WHEN
80 END
を実行すると,結果が1002になります。3001が得られるのが正しいので,Ver.8に対しても,FPU例外のエミュレーションに不具合があるように思います。
ただし,Apple SiliconとWindows機のarmとでは浮動小数点例外の扱いが異なることが原因の可能性もあります。実機版 Windows on arm での動作報告を期待します。
動作報告です。 - Tarosa
2026/02/12 (Thu) 22:27:22
多倍長の勉強中チャットGPTが書いてくれました。
!' ==============================
!' 多倍長階乗(十進BASIC)
!' 有理数モードPRINT FACT(10000)
!' ==============================
OPTION ARITHMETIC NATIVE
LET t0=TIME
LET N = 10000 ! ← 計算したい階乗(200!など)
LET CC = 35663 ! ← 桁数(十分大きく)
DIM P(CC)
!' ─── 初期値:1 ───
MAT P = ZER
LET P(CC) = 1 ! 最下位桁に 1
!' ─── 階乗ループ ───
FOR M = 2 TO N
! 掛け算
FOR I = CC TO 1 STEP -1
LET P(I) = P(I) * M
NEXT I
! 繰り上げ処理
FOR I = CC TO 2 STEP -1
LET CARRY = INT(P(I) / 10)
LET P(I) = P(I) - CARRY * 10
LET P(I-1) = P(I-1) + CARRY
NEXT I
NEXT M
!' ─── 表示 ───
!PRINT STR$(N); "! = ";
LET LEADING = 0
FOR I = 1 TO CC
IF P(I) <> 0 OR LEADING = 1 THEN
PRINT STR$(P(I));
LET LEADING = 1
END IF
NEXT I
PRINT
PRINT TIME-t0;"seconds elapsed."
END
しかし、有理数モードの
!' ===================================
!' 有理数モード 10000階乗(十進BASIC)
!' ===================================
OPTION ARITHMETIC RATIONAL
LET t0=TIME
PRINT FACT(10000)
PRINT TIME-t0;"seconds elapsed."
END
よりも計算結果出力の時間がかかってます。階乗は有理数モードが高速
Re: 動作報告です。 - しばっち
2026/02/15 (Sun) 08:03:13
私も作ってみました。
9桁区切りで計算させ無駄なループを省き高速化してみました。
2進モードで実行してください。
OPTION BASE 0
DIM A(4000)
LET A(0)=1
LET T=TIME
FOR I=2 TO 10000
MAT A=(I)*A
FOR J=0 TO N
IF A(J)>=1000000000 THEN
LET R=INT(A(J)/1000000000)
LET A(J)=A(J)-R*1000000000
LET A(J+1)=A(J+1)+R
IF J+1>N THEN LET N=N+1
END IF
NEXT J
NEXT I
PRINT STR$(A(N));
FOR J=N-1 TO 0 STEP-1
PRINT USING "%%%%%%%%%":A(J);
NEXT J
PRINT
PRINT TIME-T;"秒"
END
階乗の計算には1,2,3,4と順に掛けていけばいいが
Nの階乗は1~N/2までを掛けたものとN/2+1~Nまでを掛けたものとを掛けたものと定義することもできます。(2分割)
更に、1~N/3までを掛けたものとN/3+1~2*N/3までを掛けたものと2*N/3+1~Nまでを掛けたものとを掛けた合わせたものと定義することもできます。(3分割)
また100!を下記のように書いてみた。
100!=(1*3*5*7*9*11*13*15*17*19*21*23*25*27*29*31*33*35*37*39*41*43*45*47*49*51*53*55*57*59*61*63*65*67*69*71*73*75*77*79*81*83*85*87*89*91*93*95*97*99)*
2^25*(1*3*5*7*9*11*13*15*17*19*21*23*25*27*29*31*33*35*37*39*41*43*45*47*49)*
4^13*(1*3*5*7*9*11*13*15*17*19*21*23*25)*
8^6 *(1*3*5*7*9*11)*
16^3 *(1*3*5)*
32^2 *(1*3)*
64^1 *(1)
ペキ乗でまとめていけばもう少し最適化できそうですが、すると素因数分解して求めるのと変わらなくなるのでこのままにしておく。
もし、プログラミングを続けていくなら、ぜひ自作(自前)のライブラリーの
作成を勧めます。ライブラリーがあれば毎回1から作る必要がなくなり
2や3から始められます。
ライブラリーが充実していけば7や8からだって始められます。
他言語ならば他の誰か(又は団体や企業等)が作ったライブラリーをダウンロードしてそれを利用するだけですが
十進BASICにもこの掲示板に豊富なプログラム(ライブラリー)がありますので
過去ログを読みなおすこともお薦めします。
まずプログラムの仕様設計を決めることが必要です。
それにはルーチンの呼び出し方を決めルーチン名や使用する変数や個数、配列変数のサイズを決めます。
そして実際にサブルーチン、関数を作成していきます。
多倍長計算でいえばまず足し算、引き算ルーチンを作ります。
表示ルーチン等も併せて作ります。
次に掛け算、割り算ルーチンを作ります。
ルーチンのバージョンアップ(機能拡張)も行っていきます。
負数に対応させるとか、多倍長整数と多倍長小数の両方に対応させる等です。
バージョンアップに伴い仕様設計も変更していきます。
但し、バージョンアップ(更新)していく場合は、バージョンの新しいものと古いものを使用したルーチンが混在することになりますので
更新作業は慎重に行わないとプログラムが動かなくなったりします。
必要なら検索したり管理する作業用のツールプログラムも作ったりします。
四則計算ができたら次は関数ルーチンです。SIN,COS,SQR,EXP,LOG等を作っていきます。
関数ルーチンを基に円周率πなどを求めたり1/πやSQR(π),π^πなどのその派生する定数値を求めたり
するのもいいかと思います。
また、ルーチンを一般化していくのも大事かと思います。
2乗、3乗ルーチンができたらN乗ルーチンを
平方根、立法根ルーチンができたらN乗根を求めるルーチンを作っていきます。
2次、3次とできればN次に、2階、3階とくればN階に対応させていく。
共通項を見つけ出し変数化していくことは大変な作業かもしれませんが
一般化するのは利用価値がより高いからです。
N乗の次はNを整数から実数へと拡張していきます。
実数の次は複素数に対応させたりします。(複素数の次は4元数か!?)
その為にはアルゴリズムの策定や研究が必要になります。
ネットだけでなく書籍(専門書)も参考にしたりします。
テストプログラムも作り動作検証や研究したりも必要になります。
うまく動かなかったり未完成未完動のプログラムも増えていきますが
消さずに残しておきます。後で完成できるかもしれません。
その次のステージは高速化や高機能多機能化(2変数や多変数対応等)などより高度なプログラムへと移行していきます。
高速化は高度な知識、経験等を必要とする高等テクニックです。
単なる思い付きでできるほど簡単な作業ではありません。
その為には日頃からの情報収集や研究などが大切です。
以上は私事の経験則ですがお役に立てれば幸いに思います。
Re: 動作報告です。 - Tarosa
2026/02/15 (Sun) 23:10:14
しばっちさま毎度お世話になります。
!Google AI例
!10000階乗/123456(十進BASIC)
OPTION BASE 0
DIM A(4000), Q(4000)
LET A(0)=1
LET N=0
LET RADIX = 1000000000
! --- 階乗計算 (A = 10000!) ---
FOR I=2 TO 10000
MAT A=(I)*A
FOR J=0 TO N
IF A(J)>=RADIX THEN
LET R=INT(A(J)/RADIX)
LET A(J)=A(J)-R*RADIX
LET A(J+1)=A(J+1)+R
IF J+1>N THEN LET N=N+1
END IF
NEXT J
NEXT I
! --- 多倍長除算 (Q = A / B) ---
LET B = 123456 ! 除数(割る数)
LET rrem = 0 ! 余り
LET QN = 0 ! 商の最高次
FOR J = N TO 0 STEP -1
! 筆算の考え方:前の桁の余りを10億倍して現在の桁に足す
LET current = rrem * RADIX + A(J)
LET Q(J) = INT(current / B)
LET rrem = MOD(current, B)
IF Q(J) > 0 AND J > QN THEN LET QN = J
NEXT J
! --- 結果表示 ---
PRINT "10000! を "; B; " で割った商の先頭付近:"
PRINT STR$(Q(QN));
FOR J=QN-1 TO MAX(0, QN-5) STEP-1
PRINT RIGHT$("000000000" & STR$(Q(J)), 9);
NEXT J
PRINT "..."
PRINT "余り:"; rrem
END
Google AIの方がチャットさんよりもいい感じです。
しかし、今回も有理数モードの方が高速
!' ===========================================
!' 有理数モード 10000階乗/123456(十進BASIC)
!' ===========================================
OPTION ARITHMETIC RATIONAL
LET t0=TIME
PRINT FACT(10000)/123456
PRINT TIME-t0;"seconds elapsed."
END
私の場合は多倍長はAIが頼りです。しかし、本当は
!チュドノフスキー(Chudnovsky)級数
OPTION ARITHMETIC DECIMAL_HIGH
! (Google AI例: 1000桁モード)
LET t0 = TIME
! 定数の設定
LET C = 640320
LET C3_over_24 = (C^3) / 24 ! 漸化式用の定数
LET S = SQR(C) ! √640320
! 初期値 (k=0 の項)
LET k = 0
LET M = 1 ! 階乗部分の積
LET L = 13591409 ! 分子の 545140134*k + 13591409
LET X = C * S ! 分母の C^(3k+1.5)
LET Z = L / X ! 初項を合計に代入
! ループ計算 (1000桁精度)
FOR k = 1 TO 70 !1回のループで何桁? 精度向上
! 階乗部分の漸化式更新 (factor(6k) / (factor(3k)*factor(k)^3) を更新)
! 前のMに対し、(6k-5)*(6k-4)*(6k-3)*(6k-2)*(6k-1)*(6k) / (k^3 * (3k-2)*(3k-1)*(3k)) を掛けるのに相当
! これを整理すると以下の係数になる
LET M = M * (-(6*k-5)*(2*k-1)*(6*k-1)) / (k^3 * C3_over_24)
LET L = 545140134 * k + 13591409
! 和の更新
LET Z = Z + (M * L) / (C * S)
NEXT k
! 最終計算: 1/pi = 12 * Z
LET my_pi = 1 / (12 * Z)
PRINT my_pi
PRINT PI-my_pi
PRINT TIME - t0; "seconds elapsed."
END
チュドノフスキー(Chudnovsky)級数の円周率を高速に計算する多倍長プログラムをAIに書いてとお願いしていますが、書いてくれません。しばっちさまに2016年10月円周率のプログラムを書いて頂き、今も時々計算結果出力してます。40万桁で約1時間かかります。
Linux版basicとBASファイルの関連付け - 島村1243
2026/02/09 (Mon) 11:54:02
Lubuntu-24.0でLinux(GTK2)版十進BASICの最新版を利用しています。
作成した自作「xxx.BAS」ファイルと実行ファイル「basic」の関連付けについてお尋ねします。
Windows版「十進BASIC.exe」の場合は、作成した自作「xxx.BAS」ファイルをダブルクリックすると「BASIC.exe」が起動し、「xxx.BAS」ファイルを読み込むだけで実行はしません。
ところが、Linux版十進basicの場合は、「xxx.BAS」をダブルクリックすると、「xxx.BAS」を実行してしまいます。
Windows版と同じように読み込むだけにしたい場合は、どのような起動オプションが必要なのか、ご教示頂けると幸いです。
現在、Lubuntu-24.0において以下の様な処理を行っています。
/home/shima/.local/share/applications/
ディレクトリに
10BASIC.desktop
という名前のファイルを作成し、そのファイルに下記内容を記入しました。
起動オプションとはExec行の末尾「-OR」の事です。
[Desktop Entry]
Comment=Description of Application
Type=Application
Name=十進BASIC
Icon=/home/shima/apps/basic.png
Exec=/home/shima/apps/BASIC81Ja/basic -OR
StartupNotify=false
Categories=Education;
MimeType=plane-txt/x-basic;
なお、上記載のExec行の起動オプション「-OR」を記述しないと、「xxx.BAS」をダブルクリックしたときにbasicが起動して直後終了してしまうのを防止するために記述していますが、意味はわかりません。
Re: Linux版basicとBASファイルの関連付け - SHIRAISHI Kazuo
2026/02/09 (Mon) 15:34:56
-OR open and run
-NR no run
です。
-NRを付加して起動すると,ファイルを開くだけになります。
-ORを付加して起動すると,ファイルを開いて,実行します。
Re: Linux版basicとBASファイルの関連付け - 島村1243
2026/02/10 (Tue) 09:41:51
白石先生、早速にご教示賜り有難うございます。
ご教示頂いたオプション「-NR」を使用したら、目的を達成出来ました!!
ネット検索しても「-OR オプションを使用する。」とのAI回答表示しかなく、途方にくれていました。
タイムアタックゲーム - しばっち
2026/02/08 (Sun) 08:00:53
タイムアタックゲーム(時間感覚を計るゲームです)
単に10秒、20秒、30秒、40秒と順に計るだけです。
スペースキーを押すと始まります。
10秒経ったと思ったら再度スペースキーを押します。
得点の持ち点は100点です。
実時間との誤差分を得点から差し引いていきます。
次は20秒、その次は30秒、最後に40秒を計ります。
誤差が大きいと得点がどんどん減点されます。
CALL GINIT(800,800)
SET TEXT COLOR 7
SET TEXT BACKGROUND "OPAQUE"
SET TEXT JUSTIFY "CENTER","HALF"
DIM T(4)
FOR I=1 TO 4
READ T(I)
LET SCORE=SCORE+T(I)
NEXT I
DATA 10,20,30,40
FOR I=1 TO 4
SET TEXT HEIGHT 60
PLOT TEXT ,AT 400,50:" SCORE:"&STR$(SCORE)&" "
SET TEXT HEIGHT 40
PLOT TEXT ,AT 400,400:" "&STR$(T(I))&"秒後、再度押してください "
PLOT TEXT ,AT 400,600:"HIT SPACE KEY"
DO
LOOP UNTIL GETKEYSTATE(32)<0
DO
LOOP WHILE GETKEYSTATE(32)<0
PLOT TEXT ,AT 400,400:" 只今、"&STR$(T(I))&"秒を計測中です "
PLOT TEXT ,AT 400,600:"HIT SPACE KEY"
LET TI=TIME
DO
LOOP UNTIL GETKEYSTATE(32)<0
PLOT TEXT ,AT 400,400:" "&STR$(ROUND(TIME-TI,2))&"秒でした "
LET S=ROUND(ABS(TIME-TI),2)
WAIT DELAY 1
LET SCORE=SCORE-S
DO
LOOP WHILE GETKEYSTATE(32)<0
NEXT I
PLOT TEXT ,AT 400,50:"SCORE:"&STR$(SCORE)
END
EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,YSIZE-1,0
SET POINT STYLE 1
SET COLOR MODE "REGULAR"
FOR I=0 TO 7
SET COLOR MIX(I) BITAND(I,2)/2,BITAND(I,4)/4,BITAND(I,1)
NEXT I
CLEAR
END SUB
シューティングゲーム - しばっち
2026/02/08 (Sun) 07:59:16
インベーダー風のシューティングゲームです。
4,6キーで移動します。
両サイドから敵が出てきます。
スペースキーでビーム発射です。
DECLARE EXTERNAL FUNCTION STICK
RANDOMIZE
SET TEXT JUSTIFY "CENTER","HALF"
SET TEXT COLOR 7
SET TEXT HEIGHT 20
SET TEXT BACKGROUND "OPAQUE"
LET NUMMAX=4 ! 敵最大数
DIM F(9,7),E(8,8),X(NUMMAX),Y(NUMMAX),XC(NUMMAX),ENEMY(NUMMAX)
DIM XZ(NUMMAX),YZ(NUMMAX),FL(NUMMAX)
DIM EC(8,8),FC(9,7)
LET XSIZE=600
LET YSIZE=600
CALL GINIT(XSIZE,YSIZE)
LET SC=5
FOR J=1 TO 8
FOR I=1 TO 8
READ E(I,J)
NEXT I
NEXT J
FOR J=1 TO 7
FOR I=1 TO 9
READ F(I,J)
NEXT I
NEXT J
DATA 0,0,0,7,7,0,0,0
DATA 0,0,7,7,7,7,0,0
DATA 0,7,7,7,7,7,7,0
DATA 7,7,0,7,7,0,7,7
DATA 7,7,7,7,7,7,7,7
DATA 0,0,7,0,0,7,0,0
DATA 0,7,0,7,7,0,7,0
DATA 7,0,7,0,0,7,0,7
DATA 0,0,0,0,7,0,0,0,0
DATA 0,0,0,0,7,0,0,0,0
DATA 0,0,0,7,0,7,0,0,0
DATA 0,0,7,0,7,0,7,0,0
DATA 7,0,7,0,7,0,7,0,7
DATA 7,7,7,0,7,0,7,7,7
DATA 7,0,0,7,7,7,0,0,7
LET YY=550 ! 自機初期位置
LET XX=XSIZE/2
LET MISS=3 ! 自機数
DO
LET NUM=INT(RND*NUMMAX+1)
FOR I=1 TO NUM
PLOT TEXT ,AT XSIZE/2,10:"SCORE:"&STR$(SCORE)&" 残機:"&STR$(MISS)
IF ENEMY(I)=0 THEN
LET Y(I)=20+INT(YSIZE/8/SC*RND)*5*SC ! 敵位置
IF RND<.5 THEN
LET X(I)=0
LET XC(I)=10 ! 敵向き
ELSE
LET X(I)=XSIZE-1
LET XC(I)=-10
END IF
LET ENEMY(I)=1
END IF
LET S=STICK ! キー入力
SET DRAW MODE HIDDEN
CALL BOX(XX,YY,XX+9*SC,YY+7*SC,0) ! 自機消去
CALL BOX(X(I),Y(I),X(I)+8*SC,Y(I)+8*SC,0) ! 敵消去
IF FL(I)=1 THEN CALL BOX(XZ(I),YZ(I),XZ(I)+3,YZ(I)+15,0) ! 敵の弾消去
IF S=4 THEN LET XX=XX-15 ! 自機移動
IF XX<0 THEN LET XX=0
IF S=6 THEN LET XX=XX+15
IF XX>XSIZE-1-8*SC THEN LET XX=XSIZE-1-8*SC
LET X(I)=X(I)+XC(I) ! 敵移動
MAT PLOT CELLS,IN XX,YY;XX+8*SC,YY+6*SC:F ! 自機表示
MAT PLOT CELLS,IN X(I),Y(I);X(I)+7*SC,Y(I)+7*SC:E ! 敵表示
IF FL(I)=0 AND RND<.5 THEN ! 敵の弾
LET XZ(I)=X(I)+4*SC
LET YZ(I)=Y(I)+8*SC
LET FL(I)=1
END IF
SET DRAW MODE EXPLICIT
IF FL(I)=1 THEN
LET YZ(I)=YZ(I)+15 ! 敵の弾移動
CALL BOX(XZ(I),YZ(I),XZ(I)+3,YZ(I)+15,4) ! 敵の弾移動
END IF
IF S=10 THEN ! スペースキー
LET XS=XX+4*SC
FOR YS=YY TO 20 STEP -20 ! 自機弾の発射
CALL BOX(XS,YY-20,XS+3,YS,2)
CALL BOX(XS,YY-20,XS+3,YS,0)
IF X(I)<XS AND X(I)+7*SC>XS AND Y(I)<YS AND Y(I)+7*SC>YS THEN ! 敵命中
CALL BOX(X(I),Y(I),X(I)+8*SC,Y(I)+8*SC,0)
LET SCORE=SCORE+10
LET ENEMY(I)=0
END IF
NEXT YS
END IF
IF YZ(I)>580 THEN ! 敵の弾
CALL BOX(XZ(I),YZ(I),XZ(I)+3,YZ(I)+15,0)
LET FL(I)=0
END IF
IF XZ(I)<XX AND XZ(I)+3>XX+8*SC AND YZ(I)+15<YY AND YZ(I)+15>YY+7*SC THEN ! 自機命中
CALL BOX(XX,YY,XX+8*SC,YY+7*SC,2)
WAIT DELAY .1
CALL BOX(XX,YY,XX+8*SC,YY+7*SC,0)
LET MISS=MISS-1
LET FL(I)=0
END IF
IF X(I)>XSIZE-1 OR X(I)<-7*SC THEN LET ENEMY(I)=0 ! 敵リセット
NEXT I
LOOP UNTIL MISS=0 ! 全部やられたら
SET TEXT COLOR 2
SET TEXT HEIGHT 40
PLOT TEXT , AT XSIZE/2,YSIZE/2:"GAME OVER"
END
EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,YSIZE-1,0
SET POINT STYLE 1
SET COLOR MODE "REGULAR"
FOR I=0 TO 7
SET COLOR MIX(I) BITAND(I,2)/2,BITAND(I,4)/4,BITAND(I,1)
NEXT I
CLEAR
END SUB
EXTERNAL SUB BOX(X1,Y1,X2,Y2,C)
SET AREA COLOR C
PLOT AREA:X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB
EXTERNAL FUNCTION STICK !'キー入力
LET STICK=-1
IF GETKEYSTATE(37)<0 THEN LET STICK=4
IF GETKEYSTATE(38)<0 THEN LET STICK=8
IF GETKEYSTATE(39)<0 THEN LET STICK=6
IF GETKEYSTATE(40)<0 THEN LET STICK=2
FOR I=48 TO 57
IF GETKEYSTATE(I)<0 THEN
LET STICK=I-48
EXIT FUNCTION
END IF
NEXT I
FOR I=96 TO 105
IF GETKEYSTATE(I)<0 THEN
LET STICK=I-96
EXIT FUNCTION
END IF
NEXT I
IF GETKEYSTATE(32)<0 THEN LET STICK=10
END FUNCTION
ASSIGN文で定義される数値関数 - SHIRAISHI Kazuo
2026/02/04 (Wed) 09:58:55
BASIAcc,ParactBASIC,arm64版 BASIC ver.0.9 では,64ビット環境でASSIGN文で定義される数値関数はDLLの出力が64ビットであると仮定するものになっています。
十進BASIC全体にこの原則を拡大します。
それによって,ポインタ値を返すDLLの利用が可能になります。
一方,x86_64, arm64ともに,32bit演算で上位32ビットが0になるので,int型として定義されたDLLを呼び出すと,負数は2^32加算された数として得られることになります。
int型で定義されたDLLを用いるとき,得られた結果に次のint32関数を適用することで,32ビット環境との互換性が保持されます(共通に使用できるコードになる)。
FUNCTION int32(n)
IF n<2^31 THEN LET int32=n ELSE LET int32=n-2^32
END FUNCTION
Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/08/14 (Thu) 10:55:55
Raspberry Pi OS のRaspbianでGPIOを仮想ファイルとして扱うので試してみました。
https://tool-lab.com/raspi-gpio-controlling-command-1/
を参考にしました。
GPIO4にLEDを,GPIO5にスイッチを接続しています。
/sys/class/gpio/exportに4を書き込みとGPIO4が使用可能となるので,
OPEN #1:NAME "/sys/class/gpio/export",ACCESS OUTPUT
PRINT #1:4
CLOSE #1
としてみたのですが,機能しませんでした。
100行のようにechoコマンドを実行することで済ませています。
echoコマンドはbashの内部コマンドなので,echoをEXECUTE文で呼び出すことはできません。
100 EXECUTE "/bin/bash" WITH ("-c", "echo 4 >/sys/class/gpio/export")
110 EXECUTE "/bin/bash" WITH ("-c", "echo 5 >/sys/class/gpio/export")
120 WAIT DELAY 0.1
130 EXECUTE "/bin/bash" WITH ("-c", "echo out >/sys/class/gpio/gpio4/direction")
140 EXECUTE "/bin/bash" WITH ("-c", "echo in >/sys/class/gpio/gpio5/direction")
150 OPEN #4:NAME "/sys/class/gpio/gpio4/value", ACCESS OUTPUT
160 FOR i=1 TO 20
170 PRINT #4:STR$(MOD(i,2))
180 OPEN #5:NAME "/sys/class/gpio/gpio5/value", ACCESS INPUT
190 INPUT #5:s$
200 CLOSE #5
210 PRINT s$
220 WAIT DELAY 0.5
230 NEXT I
240 CLOSE #4
250 EXECUTE "/bin/bash" WITH ("-c", "echo 4 >/sys/class/gpio/unexport")
260 EXECUTE "/bin/bash" WITH ("-c", "echo 5 >/sys/class/gpio/unexport")
270 END
130行,140行は,
OPEN #2:NAME "/sys/class/gpio/gpio4/direction", ACCESS OUTPUT
PRINT #2:"out"
CLOSE #2
OPEN #3:NAME "/sys/class/gpio/gpio5/direction", ACCESS OUTPUT
PRINT #3:"in"
CLOSE #3
のようにしても大丈夫でした。
出力は/sys/class/gpio/gpio4/valueに"0"または"1"を書き込むのですが,それは,150行,170行のように実行可能でした。
入力は,180~200行のように毎度OPEN~CLOSEを実行しないと読み込めませんでした。
Re: Raspberry Pi GPIO Raspberry PI OS Bookworm - SHIRAISHI Kazuo
2025/08/14 (Thu) 11:11:15
Raspberry Pi OS Bookwormだと,GPIOの番号が変わってしまうそうです。
https://xtech.nikkei.com/atcl/nxt/column/18/01109/040700054/?P=2
に従って,
cat /sys/kernel/debug/gpio
を実行して調べてみると,私のRaspberry Piでは,GPIO4,5の番号は,それぞれ,516,517に変更されていました。
次のように書き換えると実行可能でした。
100 EXECUTE "/bin/bash" WITH ("-c", "echo 516 >/sys/class/gpio/export")
110 EXECUTE "/bin/bash" WITH ("-c", "echo 517 >/sys/class/gpio/export")
120 WAIT DELAY 0.1
130 EXECUTE "/bin/bash" WITH ("-c", "echo out >/sys/class/gpio/gpio516/direction")
140 EXECUTE "/bin/bash" WITH ("-c", "echo in >/sys/class/gpio/gpio517/direction")
150 OPEN #4:NAME "/sys/class/gpio/gpio516/value", ACCESS OUTPUT
160 FOR i=1 TO 20
170 PRINT #4:STR$(MOD(i,2))
180 OPEN #5:NAME "/sys/class/gpio/gpio517/value", ACCESS INPUT
190 INPUT #5:s$
200 CLOSE #5
210 PRINT s$
220 WAIT DELAY 0.5
230 NEXT I
240 CLOSE #4
250 EXECUTE "/bin/bash" WITH ("-c", "echo 516 >/sys/class/gpio/unexport")
260 EXECUTE "/bin/bash" WITH ("-c", "echo 517 >/sys/class/gpio/unexport")
270 END
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/08/14 (Thu) 13:23:01
https://pip.raspberrypi.com/categories/685-whitepapers-app-notes/documents/RP-006553-WP/A-history-of-GPIO-usage-on-Raspberry-Pi-devices-and-current-best-practices.pdf
によると,/sys/class/gpio/は廃止予定で,替わりにlibgpiodを使えという。
Intel CPU版で利用可能なDLL呼び出し
https://decimalbasic.web.fc2.com/ExtDLL.htm
をARM64でも実行できるように準備中ですが,とりあえず,
https://qiita.com/ma2shita/items/d745a8f89c673fd74a5e
を参考にpinctrlコマンドでアクセスするプログラムを作ってみました。
100 EXECUTE "/bin/bash" WITH ("-c", "pinctrl set 5 ip pd") !gpio5を入力に変更
110 FOR i=1 TO 20
120 IF MOD(i,2)=1 THEN
130 EXECUTE "/bin/bash" WITH ("-c", "pinctrl set 4 op dh")
140 ELSE
150 EXECUTE "/bin/bash" WITH ("-c", "pinctrl set 4 op dl")
160 END IF
170 EXECUTE "/bin/bash" WITH ("-c", "pinctrl get 5 >gpio5.txt")
180 WAIT DELAY 0.25
190 OPEN #1:NAME "gpio5.txt"
200 LINE INPUT #1:s$
210 PRINT s$
220 !ERASE #1
230 CLOSE #1
240 WAIT DELAY 0.25
250 NEXT i
260 END
pinctrlは独立コマンドなのでEXECUTE文で直接実行可能ですが,データ入力にはコマンドからの返答を取り込む必要があるので,
170行のようにファイル(gpio5.txt)を介してデータを受け取ることにします。そのため,bashを介しての実行になっています。
220行のERASE文は不要だったようです(追記されるのでなく,書き込み時毎度リセットされる)。
受け取ったデータは,次のようになっています。
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | lo // GPIO5 = input
5: ip -- | lo // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | lo // GPIO5 = input
5: ip -- | lo // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
5: ip -- | hi // GPIO5 = input
スイッチの操作でhiとloが切り替わっています。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/08/18 (Mon) 15:16:25
DLL呼び出しが可能になるように拡張しました(Ver.0.7.6.2,および Ver.0.9.2.6)。
Qiitaの記事
https://qiita.com/wancom/items/b041ee7408a87fabf48e
を参考にlibgpiod呼び出しに書き換えてみました。
事前に
sudo apt install libgpiod2 libgpiod-dev libgpiod-doc
を実行して,libgpiodをインストールしておいてください。
100 ! sudo apt install libgpiod2 libgpiod-dev libgpiod-doc
110 ! /usr/share/doc/libgpiod-dev/html
120 OPTION ARITHMETIC NATIVE
130 FUNCTION GPIOD_CHIP_OPEN_LOOKUP(s$)
140 ASSIGN "libgpiod.so","gpiod_chip_open_lookup"
150 END FUNCTION
160 FUNCTION gpiod_chip_get_line(n,t)
170 ASSIGN "libgpiod.so","gpiod_chip_get_line"
180 END FUNCTION
190 SUB gpiod_line_request_output(n,s$,t)
200 ASSIGN "libgpiod.so","gpiod_line_request_output"
210 END SUB
220 SUB gpiod_line_request_input(n,s$)
230 ASSIGN "libgpiod.so","gpiod_line_request_input"
240 END SUB
250 SUB gpiod_line_set_value(gpio, x)
260 ASSIGN "libgpiod.so","gpiod_line_set_value"
270 END SUB
280 FUNCTION gpiod_line_get_value(gpio)
290 ASSIGN "libgpiod.so","gpiod_line_get_value"
300 END FUNCTION
310 SUB ppiod_chip_close(gchip)
320 ASSIGN "libgpiod.so","gpiod_chip_close"
330 END SUB
340 LET GChip=GPIOD_CHIP_OPEN_LOOKUP(STR$(0))
350 ! PRINT GChip
360 LET gpio4 = gpiod_chip_get_line(GChip, 4)
370 ! PRINT gpio4
380 LET gpio5 = gpiod_chip_get_line(GChip, 5)
390 ! PRINT gpio5
400 CALL gpiod_line_request_output(gpio4, "LED", 0)
410 CALL gpiod_line_request_input(gpio5,"Switch")
420 FOR i=1 TO 20
430 CALL gpiod_line_set_value(gpio4, MOD(i,2))
440 WAIT DELAY 0.25
450 PRINT gpiod_line_get_value(gpio5)
460 WAIT DELAY 0.25
470 NEXT i
480 CALL ppiod_chip_close(GChip)
490 END
参考例(Qiitaの記事)では gpiod_chip_open_lookup の引数が""になっていますが,ASSIGN文で定義されるDLLに空文字列を指定するとヌルポインタが渡されるので,
空文字列への(ヌルでない)ポインタを渡すために340行ではchr$(0)を指定します。
"/dev/gpiochip4"のようなデバイス名を指定すべきところだと思いますが,OSがBullseyeだと/devにそれらしきデバイス名が出て来ないのですが,chr$(0)を指定すると動作します。
また,gpiod_chip_open_lookup が返す値はポインタですが,十進BASICでは2進モードでも53ビットの精度しかないので,64ビット環境だと使えない可能性があります。
350行の ! を削除してその値が53ビットの範囲にあることの確認が必要です。
ただし,64ビットのポインタは下位3ビットが0であるのが普通なので,2^56以下であれば可かも知れません。
400行,410行の"LED","Switch"は,使い道が不明ですが,適当に付けた名前です。
libgpoidの詳細は,
/usr/share/doc/libgpiod-dev/html/modules.html
にあります。とりあえず
/usr/share/doc/libgpiod-dev/html/group__line__request.html
/usr/share/doc/libgpiod-dev/html/group__line__value.html
あたりを見てください。
上の例は上記文書を読みこなしていない状態で作成したものです。とりあえず動作する参考例にしてください。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/08/31 (Sun) 18:37:35
Raspberry PI OSで動くBASICAcc,ParactBASICでASSIGN文とCALLBACK関数が使えるようにしました。
ParactBASICのテスト用のプログラムを作成しました。
「シグナル」の部分は対応する英単語(Full BASICの機能語)に置き換えてください。そのままだと掲示板の禁止ワードに引っかかって書き込めませんでした。
100 DECLARE STRUCTURE struct1: 1 OF NUMERIC
110 DECLARE STRUCTURE struct2: 1 OF string
120 DECLARE SHARED share1 OF struct1
130 DECLARE SHARED share2 OF struct2
140 !
1000 PARACT part1
1010 DECLARE EXTERNAL FUNCTION GPIOD_CHIP_OPEN_LOOKUP
1020 DECLARE EXTERNAL FUNCTION gpiod_chip_get_line
1030 LET GChip=GPIOD_CHIP_OPEN_LOOKUP(STR$(0))
1040 LET gpio4 = gpiod_chip_get_line(GChip, 4)
1050 CALL gpiod_line_request_output(gpio4, "LED", 0)
1060 PUT TO share1 FROM GChip
1070 PUT TO share2 FROM ""
1080 START part2
1090 シグナル ready
1100 REM
1110 FOR i=1 TO 10
1120 WAIT EVENT go
1130 CALL gpiod_line_set_value(gpio4, MOD(i,2))
1140 シグナル ready
1150 NEXT i
1160 PUT TO share2 FROM "end"
1170 END PARACT
1180 !
2000 PARACT part2
2010 DECLARE EXTERNAL FUNCTION gpiod_chip_get_line
2020 DECLARE EXTERNAL FUNCTION gpiod_line_get_value
2030 GET FROM share1 TO GChip
2040 LET gpio5 = gpiod_chip_get_line(GChip, 5)
2050 CALL gpiod_line_request_input(gpio5,"Switch")
2060 DO
2070 GET FROM share2 TO fin$
2080 IF fin$<>"" THEN EXIT DO
2090 IF gpiod_line_get_value(gpio5)=0 THEN !Switchが押された
2100 WAIT EVENT ready
2110 シグナル go
2120 WAIT DELAY 0.25
2130 END IF
2140 LOOP
2150 CALL gpiod_chip_close(GChip)
2160 END PARACT
2170 !
3000 EXTERNAL FUNCTION GPIOD_CHIP_OPEN_LOOKUP(s$)
3010 ASSIGN "libgpiod.so","gpiod_chip_open_lookup"
3020 END FUNCTION
3030 !
3100 EXTERNAL FUNCTION gpiod_chip_get_line(n,t)
3110 ASSIGN "libgpiod.so","gpiod_chip_get_line"
3120 END FUNCTION
3130 !
3200 EXTERNAL SUB gpiod_line_request_output(n,s$,t)
3210 ASSIGN "libgpiod.so","gpiod_line_request_output"
3220 END SUB
3230 !
3300 EXTERNAL SUB gpiod_line_set_value(gpio, x)
3310 ASSIGN "libgpiod.so","gpiod_line_set_value"
3320 END SUB
3330 !
3400 EXTERNAL SUB gpiod_line_request_input(n,s$)
3410 ASSIGN "libgpiod.so","gpiod_line_request_input"
3420 END SUB
3430 !
3500 EXTERNAL FUNCTION gpiod_line_get_value(gpio)
3510 ASSIGN "libgpiod.so","gpiod_line_get_value"
3520 END FUNCTION
3530 !
3600 EXTERNAL SUB gpiod_chip_close(gchip)
3610 ASSIGN "libgpiod.so","gpiod_chip_close"
3620 END SUB
スイッチを押すごとにLEDのON,OFFを反転し,スイッチを10回押すと終了します。
Full BASICでは,まだ受け取られていないシグナルを重複して発出すると例外状態になります。
それを避けるため,並列単位Part1はシグナルgoを受け取るとシグナルreadyを発行してシグナルgoが発出可能になったことを知らせます。
なお,シグナルの名称は機能語ではありません。任意に名付けることができます。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/09/05 (Fri) 18:07:58
CallBack関数のテストです。
GPIODのgpiod_ctxless_event_monitorは,イベントが発生するとCallBack関数を呼び出します。
CallBack関数の形式は
https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_ctxless_event_handle_cb.html
int function(int uint const(timespec)* void*)
となっているので,
はじめの2個が数値,後の2個が文字列型の引数を取る関数として用意します。(次プログラムの1180行)
ここでは,スイッチを押すごとにLEDのOn,Offを交替さています。
10回押すと終了するようにします。
CallBack関数が1を返すとgpiod_ctxless_event_monitorは終了します。
最初の引数のevtypeがイベントの種類で,スイッチを押したとき2, 戻ったとき3,Time Outのとき1です。
gpiod_ctxless_event_monitorの形式は
https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_ctxless_event_monitor.html
int gpiod_ctxless_event_monitor(const(char)* device, int event_type, uint offset, bool active_low, const(char)* consumer,
const(timespec)* timeout, gpiod_ctxless_event_poll_cb poll_cb, gpiod_ctxless_event_handle_cb event_cb, void* data)
poll_cbはnilでいいのですが,厄介なのがtimeout でtimespec構造体へのポインタの形で用意しないといけません。
正確にはよくわからないのですが,1120行のようにしたら動きました。指定した秒数経過するとtimeoutでCallBackが発生します。
1番はじめの引数deviceでハマりました。結局,
https://note.com/bsoft/n/n66a5cf9c4910
https://qiita.com/jamjam/items/79f6561490d05afcd8aa
に倣って1110行,1130行のようにしています。
BASICAccでCallBack関数に指定できるのは外部手続きのみです。
そのため,モジュールを利用しているのですが,結果として,主プログラムがEND行のみになっています。
100 END
110 !
1000 MODULE GPIO
1010 MODULE OPTION ARITHMETIC NATIVE
1020 SHARE FUNCTION GPIOD_CHIP_OPEN_LOOKUP, gpiod_chip_get_line, gpiod_ctxless_event_monitor
1030 SHARE SUB gpiod_line_request_output, gpiod_line_set_value, gpiod_chip_close
1050 SHARE NUMERIC count,gchip,gpio4
1060 ! GPIO4の初期化
1070 LET GChip=GPIOD_CHIP_OPEN_LOOKUP(CHR$(0))
1080 LET gpio4 = gpiod_chip_get_line(GChip, 4)
1090 CALL gpiod_line_request_output(gpio4, "LED", 0)
1100 ! GPIO5をモニターする
1110 LET ChipName$="gpiochip4"
1120 LET timeout$=DWORD$(2)&DWORD$(0)&DWORD$(0)&DWORD$(0) ! Time out 2秒
1130 LET ret=gpiod_ctxless_event_monitor(chipname$, 3, 5, 1, "callback test", timeout$, 0, callbackadr(4), "")
1140 PRINT ret
1150 ! GPIO4の終了処理
1160 CALL gpiod_chip_close(GChip)
1170 !
1180 EXTERNAL FUNCTION cb(evtype, offset, ts$, data$), callback 4
1190 LET cb=0
1200 PRINT evtype
1210 IF evtype=2 THEN
1220 LET count=count+1
1230 CALL gpiod_line_set_value(gpio4, MOD(count,2))
1240 IF count=10 THEN LET cb=1
1250 ELSEIF evtype=3 then
1260 WAIT DELAY 0.5
1270 END IF
1280 END FUNCTION
1290 !
1300 EXTERNAL FUNCTION GPIOD_CHIP_OPEN_LOOKUP(s$)
1310 ASSIGN "libgpiod.so","gpiod_chip_open_lookup"
1320 END FUNCTION
1330 EXTERNAL FUNCTION gpiod_chip_get_line(n,t)
1340 ASSIGN "libgpiod.so","gpiod_chip_get_line"
1350 END FUNCTION
1360 EXTERNAL SUB gpiod_line_request_output(n,s$,t)
1370 ASSIGN "libgpiod.so","gpiod_line_request_output"
1380 END SUB
1390 EXTERNAL SUB gpiod_line_set_value(gpio, x)
1400 ASSIGN "libgpiod.so","gpiod_line_set_value"
1410 END SUB
1420 EXTERNAL SUB gpiod_chip_close(gchip)
1430 ASSIGN "libgpiod.so","gpiod_chip_close"
1440 END SUB
1450 EXTERNAL FUNCTION gpiod_ctxless_event_monitor(device$, event_type, offset, active_low, consumer$, timeout$, poll_cb, event_cb, data$)
1460 ASSIGN "libgpiod.so","gpiod_ctxless_event_monitor"
1470 END FUNCTION
1480 END MODULE
はじめ,1240 行を IF count=10 THEN LET cb=-1 としていましたが,それは,エラーを伝えるものでした。
そのため,64ビット環境で動かすと,1130行で得られる数が32ビットで-1を表す数になっていました。
64ビットOSのときは,BASICAcc,Decimal BASIC Ver.0.9のいずれでも動作します。
32ビットOSのときは,未確認ですが,BASICAccで動作すると思います。Decimal BASIC Ver.0.9ではCallBack関数が使えません。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/09/06 (Sat) 13:44:05
CallBack利用の改訂版です。
メインの処理を主プログラムに移動させました。
また,GPIOの出力にgpiod_ctxless_set_valueを使ってみることにしました。
https://libgpiod-dlang.dpldocs.info/gpiod.gpiod_ctxless_set_value.html
Raspberry Pi OS (Bookworm) 32bit上のBASICAcc1.2.2.4での動作も確認しています。
100 OPTION ARITHMETIC NATIVE
110 DECLARE EXTERNAL FUNCTION GPIO.gpiod_ctxless_event_monitor
120 LET timeout$=DWORD$(2)&DWORD$(0)&DWORD$(0)&DWORD$(0) ! Time out 2秒
130 LET ret=GPIO.gpiod_ctxless_event_monitor("gpiochip4", 3, 5, 1, "callback test", timeout$, 0, callbackadr(4), "")
140 PRINT ret
150 END
160 !
1000 MODULE GPIO
1010 MODULE OPTION ARITHMETIC NATIVE
1020 PUBLIC FUNCTION gpiod_ctxless_event_monitor
1030 SHARE SUB gpiod_ctxless_set_value
1050 SHARE NUMERIC count
1060 LET count=0
1170 !
1180 EXTERNAL FUNCTION cb(evtype, offset, ts$, data$), callback 4
1190 LET cb=0
1200 PRINT evtype
1210 IF evtype=2 THEN
1220 LET count=count+1
1230 CALL gpiod_ctxless_set_value("gpiochip4", 4, MOD(count,2), 0, "LED", 0, "")
1240 IF count=10 THEN LET cb=1
1250 ELSEIF evtype=3 then
1260 WAIT DELAY 0.5
1270 END IF
1280 END FUNCTION
1290 !
1300 EXTERNAL SUB gpiod_ctxless_set_value(device$,offset, value, active_low, consumer$, cb, data$)
1310 ASSIGN "libgpiod.so","gpiod_ctxless_set_value"
1320 END SUB
1450 EXTERNAL FUNCTION gpiod_ctxless_event_monitor(device$, event_type, offset, active_low, consumer$, timeout$, poll_cb, event_cb, data$)
1460 ASSIGN "libgpiod.so","gpiod_ctxless_event_monitor"
1470 END FUNCTION
1480 END MODULE
スイッチの押し方によっては期待通りに動作しないこともあるので,実用にするには,もう少し手を入れる必要があります。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/09/08 (Mon) 10:26:26
Ver. 0.9.2.6 ARM32ビット版は,ASSIGN文で定義するDLLの引数の個数に4個以下の制限があります。(Ver. 0.9.2.6 ARM64ビット版は10個以下)
(引数の個数の制限は,将来のバージョンで変更になる可能性もあります)
gpiod_ctxless_set_valueは7個の引数が必要ですが,はじめの4個のみを与えて残りはdefault値であることを受け入れてもらえるのかという少し乱暴なテストです。
gpiod_ctxless_get_valueは,引数4個なので問題はありません。
100 DECLARE EXTERNAL FUNCTION gpiod_ctxless_get_value
110 DECLARE EXTERNAL SUB gpiod_ctxless_set_value
120 FOR i=1 TO 10
130 DO WHILE gpiod_ctxless_get_value("gpiochip4", 5, 1, "")=0
140 LOOP
150 CALL gpiod_ctxless_set_value("gpiochip4", 4, mod(i,2), 0)
160 WAIT DELAY 0.5
170 NEXT i
180 END
1300 EXTERNAL SUB gpiod_ctxless_set_value(device$, offset, value, active_low)
1310 ASSIGN "libgpiod.so","gpiod_ctxless_set_value"
1320 END SUB
1400 EXTERNAL FUNCTION gpiod_ctxless_get_value(device$, offset, active_low, cosumer$)
1410 ASSIGN "libgpiod.so","gpiod_ctxless_get_value"
1420 END FUNCTION
スイッチを押すごとにLEDのON,OFFを切り替えます。10回押すと終了します。
Raspberry OS(bookworm)32ビットでの動作は安定しています。
Re: Raspberry Pi GPIO - SHIRAISHI Kazuo
2025/09/08 (Mon) 18:36:56
上掲のプログラムをBASICAccで実行するとAccess violationになります。
7個の引数が可能な環境では,素直に,以下のように記述する必要があります。
100 DECLARE EXTERNAL FUNCTION gpiod_ctxless_get_value
110 DECLARE EXTERNAL SUB gpiod_ctxless_set_value
120 FOR i=1 TO 10
130 DO WHILE gpiod_ctxless_get_value("gpiochip4", 5, 1, "")=0
140 LOOP
150 CALL gpiod_ctxless_set_value("gpiochip4", 4, mod(i,2), 0, "", 0, "")
160 WAIT DELAY 0.5
170 NEXT i
180 END
1300 EXTERNAL SUB gpiod_ctxless_set_value(device$, offset, value, active_low, consumer$, cb, data$)
1310 ASSIGN "libgpiod.so","gpiod_ctxless_set_value"
1320 END SUB
1400 EXTERNAL FUNCTION gpiod_ctxless_get_value(device$, offset, active_low, cosumer$)
1410 ASSIGN "libgpiod.so","gpiod_ctxless_get_value"
1420 END FUNCTION
Raspberry Pi OS (Trixie) - SHIRAISHI Kazuo
2026/01/26 (Mon) 10:30:11
Raspberry Pi OS (Trixie)では,libgpiod3が標準となって,libgpiod2はインストールができないようです。
sudo apt install libgpiod3 libgpiod-dev libgpiod-doc
を実行して /usr/share/doc/libgpiod-dev/html/ を探してもこのライブラリをどう使えばよいかの解説が見当たりません。
ねっちゅう工房 ラズパイ5(Raspberry Pi 5)でLチカ https://nettyukobo.com/raspberrypi5_start_2/
で公開されている「C言語でLED点灯」の移植を試みました。
移植に必要な情報は /usr/share/doc/libgpiod-dev/html/gpiod_8h_source.html にあるgpoid.h から得られます。
バージョンが一致しない可能性がありますが,githubにある https://github.com/brgl/libgpiod/blob/master/include/gpiod.h も同じものです。
移植にあたって留意することはポインタ引数の扱いです。十進BASICではポインタは数値として処理します。
250行,270行,300行,350行にある chip, settings,line_cfg,requestとして得られる値はポインタです。
なので,それを引数に持つ手続きgpiod_line_settings_set_directionなどが持つポインタ型の引数は数値です。
一方で,gpiod_line_config_add_line_settingsが持つポインタ型の引数は,他のポインタを代入するのではなくて,不定個数の整数値の配列の先頭を指すものです。
なので,gpiod_line_config_add_line_settingsが持つポインタ型の引数は文字列で定義します。
以下に示すプログラムは素直に移植しただけです。私はLEDをGPIO4に接続しているので,190行のline_offsetを4にしています。
難解なのは,GPIOチップの名称で,Raspberry Pi OS (Bookworm)ではgpiochip4だったのですが,今度はgpiochip0です。
それは,ターミナルで,gpioinfo を実行すると確認できますが,GPIOチップの名称はどのようにして決まるのでしょうか?
100 REM ねっちゅう工房 ラズパイ5(Raspberry Pi 5)でLチカ
110 REM https://nettyukobo.com/raspberrypi5_start_2/
120 REM C言語でLED点灯
130 ! sudo apt install libgpiod3 libgpiod-dev libgpiod-doc
140 ! /usr/share/doc/libgpiod-dev/html/gpiod_8h_source.html
150 OPTION ARITHMETIC NATIVE
160 DECLARE EXTERNAL FUNCTION gpiod_chip_open, gpiod_line_settings_new, gpiod_line_config_new
170 DECLARE EXTERNAL FUNCTION gpiod_request_config_new, gpiod_chip_request_lines
180 !
190 LET line_offset=4
200 LET GPIOD_LINE_VALUE_INACTIVE = 0
210 LET GPIOD_LINE_VALUE_ACTIVE = 1
220 LET GPIOD_LINE_DIRECTION_INPUT = 2
230 LET GPIOD_LINE_DIRECTION_OUTPUT = 3
240 ! /* --- 1. GPIO チップを開く --- */
250 LET chip=gpiod_chip_open("/dev/gpiochip0")
260 ! /* --- 2. ライン設定を作る --- */
270 LET settings = gpiod_line_settings_new
280 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_OUTPUT)
290 CALL gpiod_line_settings_set_output_value(settings, GPIOD_LINE_VALUE_INACTIVE)
300 LET line_cfg = gpiod_line_config_new
310 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(line_offset), 1, settings)
320 ! /* --- 3. ライン要求設定 --- */
330 LET req_cfg = gpiod_request_config_new
340 CALL gpiod_request_config_set_consumer(req_cfg, "blink")
350 LET request = gpiod_chip_request_lines(chip, req_cfg, line_cfg)
360 ! /* --- 4. Lチカループ --- */
370 FOR i=1 TO 10
380 CALL gpiod_line_request_set_value(request, line_offset, GPIOD_LINE_VALUE_ACTIVE)
390 WAIT DELAY 0.25
400 CALL gpiod_line_request_set_value(request, line_offset, GPIOD_LINE_VALUE_INACTIVE)
410 WAIT DELAY 0.25
420 NEXT i
430 ! /* --- 5. 後始末 --- */
440 CALL gpiod_line_request_release(request)
450 CALL gpiod_line_settings_free(settings)
460 CALL gpiod_line_config_free(line_cfg)
470 CALL gpiod_request_config_free(req_cfg)
480 CALL gpiod_chip_close(chip)
490 END
1000 !
1010 EXTERNAL FUNCTION gpiod_chip_open(s$)
1020 ASSIGN "libgpiod.so","gpiod_chip_open"
1030 END FUNCTION
1040 EXTERNAL FUNCTION gpiod_line_settings_new
1050 assign "libgpiod.so","gpiod_line_settings_new"
1060 END FUNCTION
1070 EXTERNAL SUB gpiod_line_settings_set_direction(settings,direction)
1080 ASSIGN "libgpiod.so","gpiod_line_settings_set_direction"
1090 END SUB
1100 EXTERNAL SUB gpiod_line_settings_set_output_value(settings,line_value)
1110 ASSIGN "libgpiod.so","gpiod_line_settings_set_output_value"
1120 END SUB
1130 EXTERNAL FUNCTION gpiod_line_config_new
1140 ASSIGN "libgpiod.so","gpiod_line_config_new"
1150 END FUNCTION
1160 EXTERNAL SUB gpiod_line_config_add_line_settings(config,offsets$,num_offsets,settings)
1170 ASSIGN "libgpiod.so", "gpiod_line_config_add_line_settings"
1180 END SUB
1190 EXTERNAL FUNCTION gpiod_request_config_new
1200 ASSIGN "libgpiod.so", "gpiod_request_config_new"
1210 END FUNCTION
1220 EXTERNAL SUB gpiod_request_config_set_consumer(config,consumer$)
1230 ASSIGN "libgpiod.so","gpiod_request_config_set_consumer"
1240 END SUB
1250 EXTERNAL FUNCTION gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1260 ASSIGN "libgpiod.so","gpiod_chip_request_lines"
1270 END FUNCTION
1280 EXTERNAL SUB gpiod_line_request_set_value(request,offset,value)
1290 ASSIGN "libgpiod.so","gpiod_line_request_set_value"
1300 END SUB
1310 EXTERNAL SUB gpiod_line_request_release(request)
1320 ASSIGN "libgpiod.so","gpiod_line_request_release"
1330 END SUB
1340 EXTERNAL SUB gpiod_line_settings_free(settings)
1350 ASSIGN "libgpiod.so", "gpiod_line_settings_free"
1360 END SUB
1370 EXTERNAL SUB gpiod_line_config_free(line_cfg)
1380 ASSIGN "libgpiod.so","gpiod_line_config_free"
1390 END SUB
1400 EXTERNAL SUB gpiod_request_config_free(req_cfg)
1410 ASSIGN "libgpiod.so","gpiod_request_config_free"
1420 END SUB
1430 EXTERNAL SUB gpiod_chip_close(chip)
1440 ASSIGN "libgpiod.so","gpiod_chip_close"
1450 END SUB
Raspberry Pi (Trixie) GPIO 入力と出力 - SHIRAISHI Kazuo
2026/01/26 (Mon) 20:32:15
GPIO4にLED,GPIO5にスイッチを接続しているので,入力と出力の双方に対応させました。
スイッチを押すごとにLEDの点灯,消灯を反転し,10回押すと終了です。終了するとLEDが点滅します。
GPIOの処理はmoduleにまとめています。
GPIOの初期化はGPIO.init_beginで開始し,GPIO_init_finishで完了します。その間で,ポートごとの入力,出力の別を設定します。
GPIOチップの名称"/dev/gpiochip0"はmodule内で設定していますが,変更が必要であれば,GPIO.init_beginの引数にして,その都度,設定するものにもできます。
最後に,GPIO.closeを実行して終了です。
なお,APIの組み立て方に関するマニュアルを探し出して作ったものではないので,不適切な構成になっている可能性があります。
(正式なドキュメントは,https://libgpiod.readthedocs.io/en/latest/ にあって,個別の説明はありますが,それをどう組み立てて使うかの説明が見当たりません。)
100 OPTION ARITHMETIC NATIVE
110 DECLARE EXTERNAL SUB GPIO.init_begin, GPIO.set_input, GPIO.set_output, GPIO.init_finish
120 DECLARE EXTERNAL FUNCTION GPIO.read
130 DECLARE EXTERNAL SUB GPIO.write, GPIO.close
140 DECLARE NUMERIC gpin, gpout
150 LET gpout = 4
160 LET gpin = 5
170 !
180 CALL GPIO.init_begin
190 CALL GPIO.set_output(gpout)
200 CALL GPIO.set_input(gpin)
210 CALL GPIO.init_finish
220 !
230 DECLARE NUMERIC i
240 FOR i=1 TO 10
250 CALL GPIO.write(gpout, MOD(i,2))
260 DO UNTIL GPIO.read(gpin)=0
270 LOOP
280 WAIT DELAY 0.25
290 NEXT i
300 !
310 FOR i=1 TO 10
320 CALL GPIO.write(gpout, MOD(i,2))
330 WAIT DELAY 0.1
340 NEXT i
350 !
360 CALL GPIO.close
370 END
1000 !
1010 MODULE GPIO
1020 MODULE OPTION ARITHMETIC NATIVE
1030 PUBLIC SUB init_begin, set_input, set_output, init_finish
1040 PUBLIC SUB write, close
1050 PUBLIC FUNCTION read
1060 SHARE NUMERIC chip, request
1070 SHARE FUNCTION gpiod_chip_open, gpiod_line_settings_new, gpiod_line_config_new
1080 SHARE FUNCTION gpiod_request_config_new, gpiod_chip_request_lines, gpiod_line_request_get_value
1090 ! 定数の初期化
1100 SHARE NUMERIC GPIOD_LINE_DIRECTION_INPUT, GPIOD_LINE_DIRECTION_OUTPUT
1110 LET GPIOD_LINE_DIRECTION_INPUT = 2
1120 LET GPIOD_LINE_DIRECTION_OUTPUT = 3
1130 SHARE STRING consumer$
1140 LET consumer$="Decimal BASIC"
1150 !
1159 SHARE NUMERIC line_cfg ! init_beginで初期化され,init_finishでお役御免
1160 EXTERNAL SUB init_begin
1170 LET chip = gpiod_chip_open("/dev/gpiochip0")
1180 LET line_cfg = gpiod_line_config_new
1190 END SUB
1200 !
1210 EXTERNAL SUB set_input(offset)
1220 DECLARE NUMERIC settings
1230 LET settings = gpiod_line_settings_new
1240 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT)
1250 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(offset), 1, settings)
1260 CALL gpiod_line_settings_free(settings)
1270 END SUB
1280 !
1290 EXTERNAL SUB set_output(offset)
1300 DECLARE NUMERIC settings
1310 LET settings = gpiod_line_settings_new
1320 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_OUTPUT)
1330 CALL gpiod_line_settings_set_output_value(settings, 0)
1340 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(offset), 1, settings)
1350 CALL gpiod_line_settings_free(settings)
1360 END SUB
1370 !
1380 EXTERNAL SUB Init_finish
1390 DECLARE NUMERIC req_cfg
1400 LET req_cfg = gpiod_request_config_new
1410 CALL gpiod_request_config_set_consumer(req_cfg, consumer$)
1420 LET request = gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1430 CALL gpiod_request_config_free(req_cfg)
1440 CALL gpiod_line_config_free(line_cfg) ! 以降,line_cfgは無効
1450 END SUB
1460 !
1470 EXTERNAL SUB write(offset, n)
1480 CALL gpiod_line_request_set_value(request, offset, n)
1490 END SUB
1500 !
1510 EXTERNAL FUNCTION read(offset)
1520 LET read=gpiod_line_request_get_value(request, offset)
1530 END FUNCTION
1540 !
1550 EXTERNAL SUB CLOSE
1560 CALL gpiod_line_request_release(request)
1570 CALL gpiod_chip_close(chip)
1580 END SUB
1590 !
1600 EXTERNAL FUNCTION gpiod_chip_open(s$)
1610 ASSIGN "libgpiod.so","gpiod_chip_open"
1620 END FUNCTION
1630 EXTERNAL FUNCTION gpiod_line_settings_new
1640 assign "libgpiod.so","gpiod_line_settings_new"
1650 END FUNCTION
1660 EXTERNAL SUB gpiod_line_settings_set_direction(settings,direction)
1670 ASSIGN "libgpiod.so","gpiod_line_settings_set_direction"
1680 END SUB
1690 EXTERNAL SUB gpiod_line_settings_set_output_value(settings,line_value)
1700 ASSIGN "libgpiod.so","gpiod_line_settings_set_output_value"
1710 END SUB
1720 EXTERNAL FUNCTION gpiod_line_config_new
1730 ASSIGN "libgpiod.so","gpiod_line_config_new"
1740 END FUNCTION
1750 EXTERNAL SUB gpiod_line_config_add_line_settings(config,offsets$,num_offsets,settings)
1760 ASSIGN "libgpiod.so", "gpiod_line_config_add_line_settings"
1770 END SUB
1780 EXTERNAL FUNCTION gpiod_request_config_new
1790 ASSIGN "libgpiod.so", "gpiod_request_config_new"
1800 END FUNCTION
1810 EXTERNAL SUB gpiod_request_config_set_consumer(config,consumer$)
1820 ASSIGN "libgpiod.so","gpiod_request_config_set_consumer"
1830 END SUB
1840 EXTERNAL FUNCTION gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1850 ASSIGN "libgpiod.so","gpiod_chip_request_lines"
1860 END FUNCTION
1870 EXTERNAL SUB gpiod_line_request_set_value(request,offset,value)
1880 ASSIGN "libgpiod.so","gpiod_line_request_set_value"
1890 END SUB
1900 EXTERNAL FUNCTION gpiod_line_request_get_value(request, offset)
1910 ASSIGN "libgpiod.so","gpiod_line_request_get_value"
1920 END FUNCTION
1930 EXTERNAL SUB gpiod_line_request_release(request)
1940 ASSIGN "libgpiod.so","gpiod_line_request_release"
1950 END SUB
1960 EXTERNAL SUB gpiod_line_settings_free(settings)
1970 ASSIGN "libgpiod.so", "gpiod_line_settings_free"
1980 END SUB
1990 EXTERNAL SUB gpiod_line_config_free(line_cfg)
2000 ASSIGN "libgpiod.so","gpiod_line_config_free"
2010 END SUB
2020 EXTERNAL SUB gpiod_request_config_free(req_cfg)
2030 ASSIGN "libgpiod.so","gpiod_request_config_free"
2040 END SUB
2050 EXTERNAL SUB gpiod_chip_close(chip)
2060 ASSIGN "libgpiod.so","gpiod_chip_close"
2070 END SUB
2080 END MODULE
Raspberry Pi (Trixie) GPIO 補遺 - SHIRAISHI Kazuo
2026/01/29 (Thu) 09:30:50
プログラム実行中に別のBASICを起動してプログラムを実行すると,後から起動したBASICが異常終了します。
他のプログラムがGPIOポートを使用中に実行しようとするとエラーになるように,1421~1426行を追加しました。
gpioinfoに /dev/gpiochip4 は現れないのですが, /dev/gpiochip4 がシンボリックリンクとして登録されていて,/dev/gpiochip4 を指定しても動作しました。
1130行でGchip$とconsuner$をPUBLICに指定し,default値を,それぞれ,"/dev/gpiochi4",ログインユーザ名としました。
136行,137行のREMを取り除いて修正すれば,他の値を用いることができます。
なお,環境変数"HOME"は"/home/"で始まる文字列であることを前提としていますが,そうでない環境では1141行の修正が必要です。
100 OPTION ARITHMETIC NATIVE
110 DECLARE EXTERNAL SUB GPIO.init_begin, GPIO.set_input, GPIO.set_output, GPIO.init_finish
120 DECLARE EXTERNAL FUNCTION GPIO.read
130 DECLARE EXTERNAL SUB GPIO.write, GPIO.close
135 DECLARE EXTERNAL STRING GPIO.GChip$, GPIO.consumer$
136 REM LET GPIO.GChip$="/dev/gpiochip0"
137 REM LET GPIO.consumer$="Decimal BASIC"
140 DECLARE NUMERIC gpin, gpout
150 LET gpout = 4
160 LET gpin = 5
170 !
180 CALL GPIO.init_begin
190 CALL GPIO.set_output(gpout)
200 CALL GPIO.set_input(gpin)
210 CALL GPIO.init_finish
220 !
230 DECLARE NUMERIC i
240 FOR i=1 TO 10
250 CALL GPIO.write(gpout, MOD(i,2))
260 DO UNTIL GPIO.read(gpin)=0
270 LOOP
280 WAIT DELAY 0.25
290 NEXT i
300 !
310 FOR i=1 TO 10
320 CALL GPIO.write(gpout, MOD(i,2))
330 WAIT DELAY 0.1
340 NEXT i
350 !
360 CALL GPIO.close
370 END
1000 !
1010 MODULE GPIO
1020 MODULE OPTION ARITHMETIC NATIVE
1030 PUBLIC SUB init_begin, set_input, set_output, init_finish
1040 PUBLIC SUB write, close
1050 PUBLIC FUNCTION read
1060 SHARE NUMERIC chip, request
1070 SHARE FUNCTION gpiod_chip_open, gpiod_line_settings_new, gpiod_line_config_new
1080 SHARE FUNCTION gpiod_request_config_new, gpiod_chip_request_lines, gpiod_line_request_get_value
1090 ! 定数の初期化
1100 SHARE NUMERIC GPIOD_LINE_DIRECTION_INPUT, GPIOD_LINE_DIRECTION_OUTPUT
1110 LET GPIOD_LINE_DIRECTION_INPUT = 2
1120 LET GPIOD_LINE_DIRECTION_OUTPUT = 3
1130 PUBLIC STRING GChip$, consumer$
1135 LET GChip$="/dev/gpiochip4"
1140 ASK EnvironmentVariable("HOME") consumer$
1141 LET consumer$=consumer$(LEN("/home/")+1 : 255)
1150 !
1159 SHARE NUMERIC line_cfg ! init_beginで初期化され,init_finishでお役御免
1160 EXTERNAL SUB init_begin
1170 LET chip = gpiod_chip_open(GChip$)
1180 LET line_cfg = gpiod_line_config_new
1190 END SUB
1200 !
1210 EXTERNAL SUB set_input(offset)
1220 DECLARE NUMERIC settings
1230 LET settings = gpiod_line_settings_new
1240 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_INPUT)
1250 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(offset), 1, settings)
1260 CALL gpiod_line_settings_free(settings)
1270 END SUB
1280 !
1290 EXTERNAL SUB set_output(offset)
1300 DECLARE NUMERIC settings
1310 LET settings = gpiod_line_settings_new
1320 CALL gpiod_line_settings_set_direction(settings, GPIOD_LINE_DIRECTION_OUTPUT)
1330 CALL gpiod_line_settings_set_output_value(settings, 0)
1340 CALL gpiod_line_config_add_line_settings(line_cfg, DWORD$(offset), 1, settings)
1350 CALL gpiod_line_settings_free(settings)
1360 END SUB
1370 !
1380 EXTERNAL SUB Init_finish
1390 DECLARE NUMERIC req_cfg
1400 LET req_cfg = gpiod_request_config_new
1410 CALL gpiod_request_config_set_consumer(req_cfg, consumer$)
1420 LET request = gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1421 IF request=0 THEN
1422 PRINT "GPIO Initialization failed"
1423 CALL close
1425 STOP
1426 END IF
1430 CALL gpiod_request_config_free(req_cfg)
1440 CALL gpiod_line_config_free(line_cfg)
1450 END SUB
1460 !
1470 EXTERNAL SUB write(offset, n)
1480 CALL gpiod_line_request_set_value(request, offset, n)
1490 END SUB
1500 !
1510 EXTERNAL FUNCTION read(offset)
1520 LET read=gpiod_line_request_get_value(request, offset)
1530 END FUNCTION
1540 !
1550 EXTERNAL SUB CLOSE
1560 CALL gpiod_line_request_release(request)
1570 CALL gpiod_chip_close(chip)
1580 END SUB
1590 !
1600 EXTERNAL FUNCTION gpiod_chip_open(s$)
1610 ASSIGN "libgpiod.so","gpiod_chip_open"
1620 END FUNCTION
1630 EXTERNAL FUNCTION gpiod_line_settings_new
1640 assign "libgpiod.so","gpiod_line_settings_new"
1650 END FUNCTION
1660 EXTERNAL SUB gpiod_line_settings_set_direction(settings,direction)
1670 ASSIGN "libgpiod.so","gpiod_line_settings_set_direction"
1680 END SUB
1690 EXTERNAL SUB gpiod_line_settings_set_output_value(settings,line_value)
1700 ASSIGN "libgpiod.so","gpiod_line_settings_set_output_value"
1710 END SUB
1720 EXTERNAL FUNCTION gpiod_line_config_new
1730 ASSIGN "libgpiod.so","gpiod_line_config_new"
1740 END FUNCTION
1750 EXTERNAL SUB gpiod_line_config_add_line_settings(config,offsets$,num_offsets,settings)
1760 ASSIGN "libgpiod.so", "gpiod_line_config_add_line_settings"
1770 END SUB
1780 EXTERNAL FUNCTION gpiod_request_config_new
1790 ASSIGN "libgpiod.so", "gpiod_request_config_new"
1800 END FUNCTION
1810 EXTERNAL SUB gpiod_request_config_set_consumer(config,consumer$)
1820 ASSIGN "libgpiod.so","gpiod_request_config_set_consumer"
1830 END SUB
1840 EXTERNAL FUNCTION gpiod_chip_request_lines(chip, req_cfg, line_cfg)
1850 ASSIGN "libgpiod.so","gpiod_chip_request_lines"
1860 END FUNCTION
1870 EXTERNAL SUB gpiod_line_request_set_value(request,offset,value)
1880 ASSIGN "libgpiod.so","gpiod_line_request_set_value"
1890 END SUB
1900 EXTERNAL FUNCTION gpiod_line_request_get_value(request, offset)
1910 ASSIGN "libgpiod.so","gpiod_line_request_get_value"
1920 END FUNCTION
1930 EXTERNAL SUB gpiod_line_request_release(request)
1940 ASSIGN "libgpiod.so","gpiod_line_request_release"
1950 END SUB
1960 EXTERNAL SUB gpiod_line_settings_free(settings)
1970 ASSIGN "libgpiod.so", "gpiod_line_settings_free"
1980 END SUB
1990 EXTERNAL SUB gpiod_line_config_free(line_cfg)
2000 ASSIGN "libgpiod.so","gpiod_line_config_free"
2010 END SUB
2020 EXTERNAL SUB gpiod_request_config_free(req_cfg)
2030 ASSIGN "libgpiod.so","gpiod_request_config_free"
2040 END SUB
2050 EXTERNAL SUB gpiod_chip_close(chip)
2060 ASSIGN "libgpiod.so","gpiod_chip_close"
2070 END SUB
2080 END MODULE
Re: Raspberry Pi LGPIO - SHIRAISHI Kazuo
2026/02/01 (Sun) 09:03:17
libgpiodに代わるものとしてLGPIOをテストしてみました。
インストール方法は
https://pimylifeup.com/raspberry-pi-install-lgpio/
ライブラリの説明は
https://abyz.me.uk/lg/lgpio.html#lgI2cReadByte
にあります。
Ver. 0.9.4.0だと実行はできるのですが,実行後にBASIC本体に障害が発生し,フリーズするか異常終了します。
Ver. 0.9のときは,Ver. 0.9.4.1以降を使用してください。
BASICAccとParactBASICでは問題ありません。
Bookworm 64ビット,Trixie 64ビットでテストしています。
310行の引数 0 はgpiochip0を意味します。gpiochip4だったら 4 を指定してください。
320行以降の引数にある 4,5 は,GPIOの番号です。
100 OPTION ARITHMETIC NATIVE
110 FUNCTION lgGpiochipOpen(gpioDev)
120 ASSIGN "liblgpio.so", "lgGpiochipOpen"
130 END FUNCTION
140 SUB lgGpiochipClose(handle)
150 ASSIGN "liblgpio.so", "lgGpiochipClose"
160 END SUB
170 FUNCTION lgGpioClaimOutput(handle,flags,gpio,level)
180 ASSIGN "liblgpio.so", "lgGpioClaimOutput"
190 END FUNCTION
200 SUB lgGpioWrite(handle,gpio,level)
210 ASSIGN "liblgpio.so", "lgGpioWrite"
220 END SUB
230 FUNCTION lgGpioClaimInput(handle,flags,gpio)
240 ASSIGN "liblgpio.so", "lgGpioClaimInput"
250 END FUNCTION
260 FUNCTION lgGpioRead(hnadle, gpio)
270 ASSIGN "liblgpio.so", "lgGpioRead"
280 END FUNCTION
290 !
300 DECLARE NUMERIC h ! handle
310 LET h=lgGpiochipOpen(0)
320 IF lgGpioClaimOutput(h,0,4,0)=0 AND lgGpioClaimInput(h,0,5)=0 THEN
330 DECLARE NUMERIC i
340 FOR i=1 TO 10
350 CALL lgGpioWrite(h,4,MOD(i,2))
360 DO UNTIL lgGpioRead(h, 5)=0
370 LOOP
380 WAIT DELAY 0.25
390 NEXT i
400 FOR i=1 TO 10
410 CALL lgGpioWrite(h,4,MOD(i,2))
420 WAIT DELAY 0.1
430 NEXT i
440 END if
450 CALL lgGpiochipClose(h)
460 END
Note.
LGPIOでは,関数値が負のとき失敗を意味するが,ASSIGN文ではその値を64ビット整数として評価するので,負数になるべきとき,その値は2^31以上の数になる。
(32ビットの値を出力するとき,64ビットレジスタの上位32ビットは0に固定されているように思われる‥‥‥ただし,すべての場合に成立するか不明)
数独パズル - しばっち
2026/01/25 (Sun) 07:39:09
9*9数独パズル
https://ja.wikipedia.org/wiki/数独
数独は1~9の数字を行、列に重複なくそれぞれ1つずつ
そして、3*3の小ブロックにおいても重複なく1つずつ配置
させていくパズルです。
実行すると下記のような数独問題をファイルに書き出します。
時間がかかる時は、Lazarus64bit版十進BASIC又はBasicAcc、Paract BASICを使用してください。
https://decimalbasic.web.fc2.com/BASICGenJa.htm
https://decimalbasic.web.fc2.com/BASICAccJa.htm
https://decimalbasic.web.fc2.com/BASICAcc2Ja.htm
まず、乱数で適当に穴埋めしていきます。穴埋め回数は要調整です。
その後、解が存在するかバックトラック法で求めています。
解が見つかればそこから乱数で穴を開けていきます。穴開け回数は要調整です。
この時複数解を持たないようにしています。
------------------------------
| 4 2 | 3 7| 5 9 1|
| 8 7 1| 9 5| 3 4|
| 5 3 | 6 1 | 2 8|
------------------------------
| 6 5 7| 9 8| 4 1 3|
| 1 8 | 7 3 6| 5|
| 9 3| 5 4 1| 7 8 6|
------------------------------
| 3 5| 8 7 9| 1 4 2|
| 7 2| 5 3| 6 9|
| 4 8| 1 6 | 5 |
------------------------------
2進モードで実行してください。
RANDOMIZE
PUBLIC NUMERIC BOARD(9,9),ANSWER(9,9),FOUND
LET FOUND=0
DO
MAT BOARD=ZER
LET NN=RND*30+45 ! 要調整
FOR I=1 TO NN
LET X=INT(RND*9+1)
LET Y=INT(RND*9+1)
LET N=INT(RND*9+1)
IF BOARD(X,Y)=0 AND CHECK(X,Y,N)=1 THEN ! 適当に穴埋め
LET BOARD(X,Y)=N
END IF
NEXT I
PRINT "解 探索中..."
CALL SOLVE(0)
LOOP UNTIL FOUND=1
PRINT "ファイル書き出し中..."
OPEN #1:NAME "9×9数独問題.txt"
ERASE #1
CALL DISPLAY(#1)
CLOSE #1
!CALL SHOW(BOARD)
!GSAVE "9×9数独問題.png"
OPEN #1:NAME "9×9数独解答.txt"
ERASE #1
MAT BOARD=ANSWER
CALL DISPLAY(#1)
CLOSE #1
!CALL SHOW(BOARD)
!GSAVE "9×9数独解答.png"
END
EXTERNAL SUB CREATPROBLEM
LET NN=INT(RND*50)+30 ! 要調整
FOR I=1 TO NN
LET XX=INT(RND*9+1)
LET YY=INT(RND*9+1)
LET BOARD(XX,YY)=0 ! 適当に穴開け
FOR Y=1 TO 9
FOR X=1 TO 9
IF BOARD(X,Y)=0 THEN
LET C=0
FOR K=1 TO 9
IF CHECK(X,Y,K)=1 THEN LET C=C+1
NEXT K
IF C<>1 THEN LET BOARD(X,Y)=ANSWER(X,Y) ! 解が1つでないなら元に戻す
END IF
NEXT X
NEXT Y
NEXT I
END SUB
EXTERNAL SUB DISPLAY(#1)
PRINT #1:REPEAT$("-",31)
FOR Y=1 TO 9
PRINT #1:"|";
FOR X=1 TO 9
IF BOARD(X,Y)=0 THEN PRINT #1:" "; ELSE PRINT #1:USING$("###",BOARD(X,Y));
IF MOD(X,3)=0 THEN PRINT #1:"|";
NEXT X
PRINT #1
IF MOD(Y,3)=0 THEN PRINT #1:REPEAT$("-",31)
NEXT Y
END SUB
EXTERNAL SUB SHOW(BOARD(,))
LET XSIZE=3
LET YSIZE=3
LET N=XSIZE*YSIZE
SET WINDOW 0,1,1,0
CLEAR
SET TEXT HEIGHT .08
FOR I=1 TO N
IF MOD(I,XSIZE)=0 THEN
SET LINE WIDTH 3
SET LINE COLOR 4
ELSE
SET LINE WIDTH 1
SET LINE COLOR 1
END IF
LET X=I/N
PLOT LINES:X,0;X,1
LET Y=I/N
PLOT LINES:0,Y;1,Y
NEXT I
SET TEXT JUSTIFY "LEFT","TOP"
FOR J=0 TO N-1
FOR I=0 TO N-1
LET X=I/N
LET Y=J/N
IF BOARD(I+1,J+1)>0 THEN PLOT TEXT ,AT X,Y:USING$("##",BOARD(I+1,J+1))
NEXT I
NEXT J
END SUB
EXTERNAL FUNCTION CHECK(X,Y,NUM)
LET CHECK=0
FOR YY=1 TO 9
IF BOARD(X,YY)=NUM THEN EXIT FUNCTION
NEXT YY
FOR XX=1 TO 9
IF BOARD(XX,Y)=NUM THEN EXIT FUNCTION
NEXT XX
LET X0=INT((X-1)/3)*3
LET Y0=INT((Y-1)/3)*3
FOR YY=1 TO 3
FOR XX=1 TO 3
IF BOARD(X0+XX,Y0+YY)=NUM THEN EXIT FUNCTION
NEXT XX
NEXT YY
LET CHECK=1
END FUNCTION
EXTERNAL SUB SOLVE(N)
IF N=81 THEN
LET FOUND=1
MAT ANSWER=BOARD
CALL CREATPROBLEM
ELSE
LET COL=MOD(N,9)+1
LET ROW=INT(N/9)+1
IF BOARD(COL,ROW)=0 THEN
FOR I=1 TO 9
IF CHECK(COL,ROW,I)=1 THEN
LET BOARD(COL,ROW)=I
CALL SOLVE(N+1)
IF FOUND=1 THEN EXIT SUB
LET BOARD(COL,ROW)=0
END IF
NEXT I
ELSE
CALL SOLVE(N+1)
IF FOUND=1 THEN EXIT SUB
END IF
END IF
END SUB
解答
------------------------------
| 4 2 6| 3 8 7| 5 9 1|
| 8 7 1| 2 9 5| 6 3 4|
| 5 3 9| 6 1 4| 2 7 8|
------------------------------
| 6 5 7| 9 2 8| 4 1 3|
| 1 8 4| 7 3 6| 9 2 5|
| 2 9 3| 5 4 1| 7 8 6|
------------------------------
| 3 6 5| 8 7 9| 1 4 2|
| 7 1 2| 4 5 3| 8 6 9|
| 9 4 8| 1 6 2| 3 5 7|
------------------------------
ファイル書き出し部を下記に置き換えるとhtmlファイルを
書き出します。
PRINT "ファイル書き出し中..."
OPEN #1:NAME "9×9数独問題.html"
PRINT #1:"<!DOCTYPE html>"
PRINT #1:"<html>"
PRINT #1:" <body>"
PRINT #1:" <div align=center>"
PRINT #1:" <h1>問題</h1>"
PRINT #1:" </div>"
PRINT #1:" <table align=center border=";CHR$(34);"3";CHR$(34);">"
FOR Y=1 TO 9 STEP 3
PRINT #1:" <tr>";
FOR X=1 TO 9 STEP 3
PRINT #1:"<td><table border=";CHR$(34);"1";CHR$(34);">";
FOR YY=0 TO 2
PRINT #1:"<tr>";
FOR XX=0 TO 2
IF BOARD(XX+X,YY+Y)=0 THEN PRINT #1:"<td> </td>"; ELSE PRINT #1:"<td>";USING$("###",BOARD(XX+X,YY+Y));"</td>";
NEXT XX
PRINT #1:"</tr>"
NEXT YY
PRINT #1:" </table></td>"
NEXT X
PRINT #1:" </tr>"
NEXT Y
PRINT #1:" </table>"
PRINT #1:" </body>"
PRINT #1:"</html>"
CLOSE #1
OPEN #1:NAME "9×9数独解答.html"
PRINT #1:"<!DOCTYPE html>"
PRINT #1:"<html>"
PRINT #1:" <body>"
PRINT #1:" <div align=center>"
PRINT #1:" <h1>解答</h1>"
PRINT #1:" </div>"
PRINT #1:" <table align=center border=";CHR$(34);"3";CHR$(34);">"
FOR Y=1 TO 9 STEP 3
PRINT #1:" <tr>";
FOR X=1 TO 9 STEP 3
PRINT #1:"<td><table border=";CHR$(34);"1";CHR$(34);">";
FOR YY=0 TO 2
PRINT #1:"<tr>";
FOR XX=0 TO 2
IF BOARD(XX+X,YY+Y)=0 THEN PRINT #1:"<td><font color=#ff0000>";USING$("###",ANSWER(XX+X,YY+Y));"</font></td>"; ELSE PRINT #1:"<td>";USING$("###",ANSWER(XX+X,YY+Y));"</td>";
NEXT XX
PRINT #1:"</tr>"
NEXT YY
PRINT #1:" </table></td>"
NEXT X
PRINT #1:" </tr>"
NEXT Y
PRINT #1:" </table>"
PRINT #1:" </body>"
PRINT #1:"</html>"
CLOSE #1
END
----------------------------------------------------------------------------------
以下はDLL版です。下記URLからダウンロードしてください。VC++2026でコンパイルしました。
x86版とx64版を同梱しています。sudoku.zip
https://18.gigafile.nu/0326-bbcba64ab876afb1aba5835c9c57badc1
ダウンロード期限:2026年3月26日(木)
ダウンロードパスワード:設定していません
下記にあるcソースのみでコンパイルできます。
PUBLIC NUMERIC FOUND
LET FOUND=0
RANDOMIZE
DIM BOARD(9,9)
DO
MAT BOARD=ZER
LET NN=INT(RND*20)+60 ! 要調整
FOR I=1 TO NN
LET X=INT(RND*9+1)
LET Y=INT(RND*9+1)
LET N=INT(RND*9+1)
IF BOARD(X,Y)=0 AND CHECK(X,Y,N,BOARD)=1 THEN LET BOARD(X,Y)=N
NEXT I
PRINT "解 探索中..."
CALL SUDOKU(BOARD)
LOOP UNTIL FOUND=1
PRINT "ファイル書き出し中..."
OPEN #1:NAME "9×9数独解答.txt"
ERASE #1
CALL DISPLAY(#1,BOARD)
CLOSE #1
CALL CREATPROBLEM(BOARD)
OPEN #1:NAME "9×9数独問題.txt"
ERASE #1
CALL DISPLAY(#1,BOARD)
CLOSE #1
END
EXTERNAL SUB CREATPROBLEM(BOARD(,))
DIM ANSWER(9,9)
MAT ANSWER=BOARD
LET NN=INT(RND*50)+30 ! 要調整
FOR I=1 TO NN
LET XX=INT(RND*9+1)
LET YY=INT(RND*9+1)
LET BOARD(XX,YY)=0
FOR Y=1 TO 9
FOR X=1 TO 9
IF BOARD(X,Y)=0 THEN
LET C=0
FOR K=1 TO 9
IF CHECK(X,Y,K,BOARD)=1 THEN LET C=C+1
NEXT K
IF C<>1 THEN LET BOARD(X,Y)=ANSWER(X,Y)
END IF
NEXT X
NEXT Y
NEXT I
END SUB
EXTERNAL FUNCTION CHECK(X,Y,NUM,BOARD(,))
LET CHECK=0
FOR YY=1 TO 9
IF BOARD(X,YY)=NUM THEN EXIT FUNCTION
NEXT YY
FOR XX=1 TO 9
IF BOARD(XX,Y)=NUM THEN EXIT FUNCTION
NEXT XX
LET X0=INT((X-1)/3)*3
LET Y0=INT((Y-1)/3)*3
FOR YY=1 TO 3
FOR XX=1 TO 3
IF BOARD(X0+XX,Y0+YY)=NUM THEN EXIT FUNCTION
NEXT XX
NEXT YY
LET CHECK=1
END FUNCTION
EXTERNAL SUB DISPLAY(#1,BOARD(,))
PRINT #1:REPEAT$("-",31)
FOR Y=1 TO 9
PRINT #1:"|";
FOR X=1 TO 9
IF BOARD(X,Y)=0 THEN PRINT #1:" "; ELSE PRINT #1:USING$("###",BOARD(X,Y));
IF MOD(X,3)=0 THEN PRINT #1:"|";
NEXT X
PRINT #1
IF MOD(Y,3)=0 THEN PRINT #1:REPEAT$("-",31)
NEXT Y
END SUB
EXTERNAL SUB SUDOKU(BOARD(,))
OPTION CHARACTER BYTE
LET A$=REPEAT$(" ",4*81)
FOR Y=0 TO 8
FOR X=0 TO 8
LET A$(4*(9*Y+X)+1:4*(9*Y+X)+4)=DWORD$(BOARD(X+1,Y+1))
NEXT X
NEXT Y
LET FOUND=SOLVE(A$)
IF FOUND=1 THEN
FOR Y=0 TO 8
FOR X=0 TO 8
LET BOARD(X+1,Y+1)=INT32(A$(4*(9*Y+X)+1:4*(9*Y+X)+4))
NEXT X
NEXT Y
END IF
FUNCTION SOLVE(A$)
ASSIGN ".\dll\sudoku9.dll","sudoku"
END FUNCTION
END SUB
EXTERNAL FUNCTION INT32(X$)
OPTION CHARACTER BYTE
LET S=ORD(X$(1:1))+ORD(X$(2:2))*256+ORD(X$(3:3))*256^2+ORD(X$(4:4))*256^3
IF S>2^31 THEN LET S=S-2^32
LET INT32=S
END FUNCTION
------------------------------------------------------------------------------
sudoku9.c
int board[9][9],answer[9][9],found=0;
int check(int x,int y,int n)
{
int xx,yy,x0,y0;
for(yy=0; yy<9; yy++)
if (board[x][yy]==n) return 0;
for(xx=0; xx<9; xx++)
if (board[xx][y]==n) return 0;
x0=x/3;
y0=y/3;
for(yy=0; yy<3; yy++)
for(xx=0; xx<3; xx++)
if (board[x0*3+xx][y0*3+yy]==n) return 0;
return 1;
}
void solve(int n)
{
int x,y,i;
if(n==81) {
found=1;
for (y=0; y<9; y++)
for(x=0; x<9; x++) answer[x][y]=board[x][y];
return;
}
x=n%9;
y=n/9;
if (board[x][y]==0)
{
for(i=1; i<=9; i++)
{
if(check(x,y,i)==1)
{
board[x][y]=i;
solve(n+1);
if (found==1) return;
board[x][y]=0;
}
}
} else {
solve(n+1);
if(found==1) return;
}
return;
}
__declspec(dllexport) int sudoku(int *p)
{
int x,y;
for(y=0; y<9; y++)
for(x=0; x<9; x++) board[x][y]=p[9*y+x];
solve(0);
if (found==1)
for(y=0; y<9; y++)
for(x=0; x<9; x++) p[9*y+x]=answer[x][y];
return found;
}
Re: 数独パズル - しばっち
2026/01/25 (Sun) 07:41:07
実行すると下記のような問題が出力できますがサイズによっては時間を要します。
時間がかかる時は、Lazarus64bit版十進BASIC又はBasicAcc、Paract BASICを使用してください。
4×4サイズ 小ブロック2×2
---------------
| 2| 4|
| 4 | 1 2|
---------------
| 2 1| 4 |
| 3 4| 2 |
---------------
5×5サイズ 小ブロックなし
-----------------
| 2 3 1|
| 2 1 3 |
| 4 5 2|
| 4 2 1 3|
| 1 3 4 5|
-----------------
6×6サイズ 小ブロック3×2
---------------------
| 2 3 1| 6 5|
| 5 6| 1 2|
---------------------
| 1 | 5 2 6|
| 6 5 2| 3 |
---------------------
| 1 4| 6 3|
| 3 6 | 4 1|
---------------------
7×7サイズ 小ブロックなし
-----------------------
| 3 4 5 6 2 7|
| 5 2 4 7 3 1|
| 3 6 7 2 5 4|
| 4 7 3 5 1 2|
| 7 2 3 4 5|
| 2 4 5 1 7 |
| 6 5 2 4 3|
-----------------------
8×8サイズ 小ブロック4×2
---------------------------
| 2 1 3| 5 6 8 7|
| 5 7 8| 3 1 2|
---------------------------
| 5 1 | 7 3 2 8|
| 7 2| 6 4 5|
---------------------------
| 8 7 1| 2 5 3 4|
| 4 2 | 8 7 6|
---------------------------
| 6 8 3 7| 4 2 5 1|
| 1 2 5 4| 8 7 6 3|
---------------------------
10×10サイズ 小ブロック5×2
---------------------------------
| 3 9 4| 6 10 8 5 1|
| 1 10 8 6 5| 9 4 3 7 |
---------------------------------
| 4 3 2 8| 1 7 9 6|
| 7 5 1 9| 4 2 8 3|
---------------------------------
| 3 4 5 2| 7 6 9 |
| 9 1 10 6| 3 2 4 5|
---------------------------------
| 8 2 7| 10 5 4 3 9|
| 10 5 9 3| 7 6 8|
---------------------------------
| 2 6 3 | 8 9 10 7|
| 5 9 8 10| 1 6 2 4|
---------------------------------
11×11サイズ 小ブロックなし
-----------------------------------
| 6 1 5 10 8 4 7 11 3 |
| 7 5 2 9 1 10 3 4 11|
| 3 11 8 2 1 7 5 9 |
| 6 10 9 3 4 5 11 7 2|
| 1 3 9 10 11 8 5 |
| 4 8 11 5 3 10 1 2 6|
| 11 10 1 7 5 9 3 2 4|
| 4 3 8 7 6 9 10 11 5|
| 11 3 4 2 8 5 7 6 1|
| 5 7 6 4 9 10 11 8 3|
| 9 5 7 11 3 4 6 10 8|
-----------------------------------
RANDOMIZE
PUBLIC NUMERIC BOARD(20,20),ANSWER(20,20),FOUND,SIZE,XSIZE,YSIZE
LET FOUND=0
LET XSIZE=3 ! 小ブロックサイズ
LET YSIZE=2
LET SIZE=XSIZE*YSIZE ! 全体のサイズ
DO
MAT BOARD=ZER
LET NN=RND*20+SIZE*SIZE-20 ! 要調整
FOR I=1 TO NN
LET X=INT(RND*SIZE+1)
LET Y=INT(RND*SIZE+1)
LET N=INT(RND*SIZE+1)
IF BOARD(X,Y)=0 AND CHECK(X,Y,N)=1 THEN
LET BOARD(X,Y)=N
END IF
NEXT I
PRINT "解 探索中..."
CALL SOLVE(0)
LOOP UNTIL FOUND=1
PRINT "ファイル書き出し中..."
OPEN #1:NAME STR$(SIZE)&"×"&STR$(SIZE)&"数独問題.txt"
ERASE #1
CALL DISPLAY(#1)
CLOSE #1
OPEN #1:NAME STR$(SIZE)&"×"&STR$(SIZE)&"数独解答.txt"
ERASE #1
MAT BOARD=ANSWER
CALL DISPLAY(#1)
CLOSE #1
END
EXTERNAL SUB CREATPROBLEM
LET NN=RND*20+SIZE*SIZE-20 ! 要調整
FOR I=1 TO NN
LET XX=INT(RND*SIZE+1)
LET YY=INT(RND*SIZE+1)
LET BOARD(XX,YY)=0
FOR Y=1 TO SIZE
FOR X=1 TO SIZE
IF BOARD(X,Y)=0 THEN
LET C=0
FOR K=1 TO SIZE
IF CHECK(X,Y,K)=1 THEN LET C=C+1
NEXT K
IF C<>1 THEN LET BOARD(X,Y)=ANSWER(X,Y)
END IF
NEXT X
NEXT Y
NEXT I
END SUB
EXTERNAL SUB DISPLAY(#1)
IF XSIZE>1 THEN PRINT #1:REPEAT$("-",3*SIZE+SIZE/XSIZE+1) ELSE PRINT #1:REPEAT$("-",3*SIZE+2)
FOR Y=1 TO SIZE
PRINT #1:"|";
FOR X=1 TO SIZE
IF BOARD(X,Y)=0 THEN PRINT #1:" "; ELSE PRINT #1:USING$("###",BOARD(X,Y));
IF XSIZE>1 AND MOD(X,XSIZE)=0 THEN PRINT #1:"|";
NEXT X
IF XSIZE=1 THEN PRINT #1:"|" ELSE PRINT #1
IF XSIZE>1 AND YSIZE>1 AND MOD(Y,YSIZE)=0 THEN PRINT #1:REPEAT$("-",3*SIZE+SIZE/XSIZE+1)
NEXT Y
IF XSIZE=1 OR YSIZE=1 THEN PRINT #1:REPEAT$("-",3*SIZE+2)
END SUB
EXTERNAL FUNCTION CHECK(X,Y,NUM)
LET CHECK=0
FOR YY=1 TO SIZE
IF BOARD(X,YY)=NUM THEN EXIT FUNCTION
NEXT YY
FOR XX=1 TO SIZE
IF BOARD(XX,Y)=NUM THEN EXIT FUNCTION
NEXT XX
IF XSIZE>1 AND YSIZE>1 THEN
LET X0=INT((X-1)/XSIZE)*XSIZE
LET Y0=INT((Y-1)/YSIZE)*YSIZE
FOR YY=1 TO YSIZE
FOR XX=1 TO XSIZE
IF BOARD(X0+XX,Y0+YY)=NUM THEN EXIT FUNCTION
NEXT XX
NEXT YY
END IF
LET CHECK=1
END FUNCTION
EXTERNAL SUB SOLVE(N)
IF N=SIZE*SIZE THEN
LET FOUND=1
MAT ANSWER=BOARD
CALL CREATPROBLEM
ELSE
LET COL=MOD(N,SIZE)+1
LET ROW=INT(N/SIZE)+1
IF BOARD(COL,ROW)=0 THEN
FOR I=1 TO SIZE
IF CHECK(COL,ROW,I)=1 THEN
LET BOARD(COL,ROW)=I
CALL SOLVE(N+1)
IF FOUND=1 THEN EXIT SUB
LET BOARD(COL,ROW)=0
END IF
NEXT I
ELSE
CALL SOLVE(N+1)
IF FOUND=1 THEN EXIT SUB
END IF
END IF
END SUB
解答
---------------
| 1 2| 3 4|
| 4 3| 1 2|
---------------
| 2 1| 4 3|
| 3 4| 2 1|
---------------
-----------------
| 5 2 3 4 1|
| 2 1 5 3 4|
| 3 4 1 5 2|
| 4 5 2 1 3|
| 1 3 4 2 5|
-----------------
---------------------
| 2 3 1| 4 6 5|
| 5 4 6| 1 3 2|
---------------------
| 4 1 3| 5 2 6|
| 6 5 2| 3 1 4|
---------------------
| 1 2 4| 6 5 3|
| 3 6 5| 2 4 1|
---------------------
-----------------------
| 1 3 4 5 6 2 7|
| 5 2 6 4 7 3 1|
| 3 6 7 2 1 5 4|
| 4 7 3 6 5 1 2|
| 7 1 2 3 4 6 5|
| 2 4 5 1 3 7 6|
| 6 5 1 7 2 4 3|
-----------------------
---------------------------
| 2 1 4 3| 5 6 8 7|
| 5 6 7 8| 3 4 1 2|
---------------------------
| 4 5 1 6| 7 3 2 8|
| 7 3 8 2| 6 1 4 5|
---------------------------
| 8 7 6 1| 2 5 3 4|
| 3 4 2 5| 1 8 7 6|
---------------------------
| 6 8 3 7| 4 2 5 1|
| 1 2 5 4| 8 7 6 3|
---------------------------
---------------------------------
| 7 2 3 9 4| 6 10 8 5 1|
| 1 10 8 6 5| 9 4 3 7 2|
---------------------------------
| 4 3 2 10 8| 5 1 7 9 6|
| 6 7 5 1 9| 4 2 10 8 3|
---------------------------------
| 3 8 4 5 2| 7 6 9 1 10|
| 9 1 10 7 6| 3 8 2 4 5|
---------------------------------
| 8 6 1 2 7| 10 5 4 3 9|
| 10 5 9 4 3| 2 7 1 6 8|
---------------------------------
| 2 4 6 3 1| 8 9 5 10 7|
| 5 9 7 8 10| 1 3 6 2 4|
---------------------------------
-----------------------------------
| 6 1 2 5 10 8 4 7 11 3 9|
| 7 5 8 2 6 9 1 10 3 4 11|
| 3 11 4 8 2 1 7 6 5 9 10|
| 8 6 10 9 3 4 5 11 1 7 2|
| 1 3 9 10 11 6 2 8 4 5 7|
| 4 8 7 11 5 3 10 1 9 2 6|
| 11 10 1 6 7 5 9 3 2 8 4|
| 2 4 3 1 8 7 6 9 10 11 5|
| 10 9 11 3 4 2 8 5 7 6 1|
| 5 7 6 4 9 10 11 2 8 1 3|
| 9 2 5 7 1 11 3 4 6 10 8|
-----------------------------------
Re: 数独パズル - しばっち
2026/01/25 (Sun) 07:42:31
実行すると一部領域が重なった下記のような9*9数独問題を書き出します。
9*9の2つのエリアはそれぞれに通常の数独のルールが適用され、重なった部分は共有します。
時間がかかる時は、Lazarus64bit版十進BASIC又はBasicAcc、Paract BASICを使用してください。
-----------------------------------------
| 2 9| 1 7| 3 6 |*********|
| 7 4 6| 8 9| 5 1 |*********|
| 1| 6 2 5| 4 7 9|*********|
-----------------------------------------
| 8 7 | 2 6 | 1 9 5| 3 7 8|
| 9 5| 1 7 8| 2 4 3| 6 |
| 4 1 2| 5 9 3| 6 8 7| 1 2 |
-----------------------------------------
| 1 6 7| 8 5 2| 9 3 4| 6 |
| 2 3 8| 9 6| 7 5 1| 2 8 3|
| 9 5 | 7 3 1| 8 2 6| 9 5|
-----------------------------------------
|*********| 3 1 7| 6 | 9 5 2|
|*********| 8 9| 5 1 2| 7 3 6|
|*********| 6 2 5| 3 7 | 8 1|
-----------------------------------------
RANDOMIZE
PUBLIC NUMERIC BOARD1(9,9),BOARD2(9,9),ANSWER1(9,9),ANSWER2(9,9),FOUND1,FOUND2
DO
LET FOUND1=0
LET FOUND2=0
MAT BOARD1=ZER
MAT BOARD2=ZER
LET NN=RND*20+60
FOR I=1 TO NN
LET X=INT(RND*9+1)
LET Y=INT(RND*9+1)
LET N=INT(RND*9+1)
IF BOARD1(X,Y)=0 AND CHECK1(X,Y,N)=1 THEN
LET BOARD1(X,Y)=N
FOR YY=1 TO 6
FOR XX=1 TO 6
LET BOARD2(XX,YY)=BOARD1(XX+3,YY+3)
NEXT XX
NEXT YY
END IF
NEXT I
PRINT "解 探索中..."
CALL SOLVE1(0)
IF FOUND1=1 THEN
PRINT "FOUND 1"
FOR Y=1 TO 6
FOR X=1 TO 6
LET BOARD2(X,Y)=ANSWER1(X+3,Y+3)
NEXT X
NEXT Y
CALL SOLVE2(0)
END IF
LOOP UNTIL FOUND1=1 AND FOUND2=1
MAT BOARD1=ANSWER1
MAT BOARD2=ANSWER2
CALL CREATPROBLEM
PRINT "ファイル書き出し中..."
OPEN #1:NAME "9×9数独問題.txt"
ERASE #1
CALL DISPLAY(#1)
CLOSE #1
!CALL SHOW(BOARD1,BOARD2)
!GSAVE "9×9数独問題.png"
OPEN #1:NAME "9×9数独解答.txt"
ERASE #1
MAT BOARD1=ANSWER1
MAT BOARD2=ANSWER2
CALL DISPLAY(#1)
CLOSE #1
!CALL SHOW(BOARD1,BOARD2)
!GSAVE "9×9数独解答.png"
END
EXTERNAL SUB CREATPROBLEM
LET NN=INT(RND*50)+30
FOR I=1 TO NN
LET X1=INT(RND*9+1)
LET Y1=INT(RND*9+1)
LET X2=INT(RND*9+1)
LET Y2=INT(RND*9+1)
LET BOARD1(X1,Y1)=0
LET BOARD2(X2,Y2)=0
FOR Y=1 TO 9
FOR X=1 TO 9
IF BOARD1(X,Y)=0 THEN
LET C1=0
FOR K=1 TO 9
IF CHECK1(X,Y,K)=1 THEN LET C1=C1+1
NEXT K
IF C1<>1 THEN LET BOARD1(X,Y)=ANSWER1(X,Y)
END IF
IF BOARD2(X,Y)=0 THEN
LET C2=0
FOR K=1 TO 9
IF CHECK2(X,Y,K)=1 THEN LET C2=C2+1
NEXT K
IF C2<>1 THEN LET BOARD2(X,Y)=ANSWER2(X,Y)
END IF
NEXT X
NEXT Y
NEXT I
END SUB
EXTERNAL SUB DISPLAY(#1)
DIM A$(12,12)
MAT A$=("***")&NUL$
FOR J=1 TO 9
FOR I=1 TO 9
IF BOARD1(I,J)>0 THEN LET A$(I,J)=USING$("###",BOARD1(I,J))
NEXT I
NEXT J
FOR J=1 TO 9
FOR I=1 TO 9
IF BOARD2(I,J)>0 THEN LET A$(I+3,J+3)=USING$("###",BOARD2(I,J))
NEXT I
NEXT J
PRINT #1:REPEAT$("-",41)
FOR J=1 TO 12
PRINT #1:"|";
FOR I=1 TO 12
PRINT #1:A$(I,J);
IF MOD(I,3)=0 THEN PRINT #1:"|";
NEXT I
PRINT #1
IF MOD(J,3)=0 THEN PRINT #1:REPEAT$("-",41)
NEXT J
END SUB
EXTERNAL SUB SHOW(BOARD1(,),BOARD2(,))
LET XSIZE=3
LET YSIZE=3
LET N=12
SET WINDOW 0,1,1,0
CLEAR
SET TEXT HEIGHT .05
FOR I=1 TO 9
IF MOD(I,XSIZE)=0 THEN
SET LINE WIDTH 3
ELSE
SET LINE WIDTH 1
END IF
LET X=I/N
SET LINE COLOR 1
PLOT LINES:X,0;X,9/N
LET Y=I/N
PLOT LINES:0,Y;9/N,Y
NEXT I
FOR I=0 TO 9
IF MOD(I+3,XSIZE)=0 THEN
SET LINE WIDTH 3
ELSE
SET LINE WIDTH 1
END IF
LET X=(I+3)/N
SET LINE COLOR 4
PLOT LINES:X,3/N;X,1
LET Y=(I+3)/N
PLOT LINES:3/N,Y;1,Y
NEXT I
SET TEXT JUSTIFY "LEFT","TOP"
FOR J=0 TO 8
FOR I=0 TO 8
LET X=I/N
LET Y=J/N
IF BOARD1(I+1,J+1)>0 THEN PLOT TEXT ,AT X,Y:USING$("##",BOARD1(I+1,J+1))
NEXT I
NEXT J
FOR J=0 TO 8
FOR I=0 TO 8
IF I>5 OR J>5 THEN
LET X=(I+3)/N
LET Y=(J+3)/N
IF BOARD2(I+1,J+1)>0 THEN PLOT TEXT ,AT X,Y:USING$("##",BOARD2(I+1,J+1))
END IF
NEXT I
NEXT J
END SUB
EXTERNAL FUNCTION CHECK1(X,Y,NUM)
LET CHECK1=0
FOR YY=1 TO 9
IF BOARD1(X,YY)=NUM THEN EXIT FUNCTION
NEXT YY
FOR XX=1 TO 9
IF BOARD1(XX,Y)=NUM THEN EXIT FUNCTION
NEXT XX
FOR XX=1 TO 9
FOR A=1 TO 8
FOR B=A+1 TO 9
IF BOARD1(XX,A)<>0 AND BOARD1(XX,B)<>0 AND BOARD1(XX,A)=BOARD1(XX,B) THEN EXIT FUNCTION
NEXT B
NEXT A
NEXT XX
FOR YY=1 TO 9
FOR A=1 TO 8
FOR B=A+1 TO 9
IF BOARD1(A,YY)<>0 AND BOARD1(B,YY)<>0 AND BOARD1(A,YY)=BOARD1(B,YY) THEN EXIT FUNCTION
NEXT B
NEXT A
NEXT YY
LET X0=INT((X-1)/3)*3
LET Y0=INT((Y-1)/3)*3
FOR YY=1 TO 3
FOR XX=1 TO 3
IF BOARD1(X0+XX,Y0+YY)=NUM THEN EXIT FUNCTION
NEXT XX
NEXT YY
LET CHECK1=1
END FUNCTION
EXTERNAL FUNCTION CHECK2(X,Y,NUM)
LET CHECK2=0
FOR YY=1 TO 9
IF BOARD2(X,YY)=NUM THEN EXIT FUNCTION
NEXT YY
FOR XX=1 TO 9
IF BOARD2(XX,Y)=NUM THEN EXIT FUNCTION
NEXT XX
FOR XX=1 TO 9
FOR A=1 TO 8
FOR B=A+1 TO 9
IF BOARD2(XX,A)<>0 AND BOARD2(XX,B)<>0 AND BOARD2(XX,A)=BOARD2(XX,B) THEN EXIT FUNCTION
NEXT B
NEXT A
NEXT XX
FOR YY=1 TO 9
FOR A=1 TO 8
FOR B=A+1 TO 9
IF BOARD2(A,YY)<>0 AND BOARD2(B,YY)<>0 AND BOARD2(A,YY)=BOARD2(B,YY) THEN EXIT FUNCTION
NEXT B
NEXT A
NEXT YY
LET X0=INT((X-1)/3)*3
LET Y0=INT((Y-1)/3)*3
FOR YY=1 TO 3
FOR XX=1 TO 3
IF BOARD2(X0+XX,Y0+YY)=NUM THEN EXIT FUNCTION
NEXT XX
NEXT YY
LET CHECK2=1
END FUNCTION
EXTERNAL SUB SOLVE1(N)
IF N=81 THEN
LET FOUND1=1
MAT ANSWER1=BOARD1
ELSE
LET COL=MOD(N,9)+1
LET ROW=INT(N/9)+1
IF BOARD1(COL,ROW)=0 THEN
FOR I=1 TO 9
IF CHECK1(COL,ROW,I)=1 THEN
LET BOARD1(COL,ROW)=I
CALL SOLVE1(N+1)
IF FOUND1=1 THEN EXIT SUB
LET BOARD1(COL,ROW)=0
END IF
NEXT I
ELSE
CALL SOLVE1(N+1)
IF FOUND1=1 THEN EXIT SUB
END IF
END IF
END SUB
EXTERNAL SUB SOLVE2(N)
IF N=81 THEN
LET FOUND2=1
MAT ANSWER2=BOARD2
ELSE
LET COL=MOD(N,9)+1
LET ROW=INT(N/9)+1
IF BOARD2(COL,ROW)=0 THEN
FOR I=1 TO 9
IF CHECK2(COL,ROW,I)=1 THEN
LET BOARD2(COL,ROW)=I
CALL SOLVE2(N+1)
IF FOUND2=1 THEN EXIT SUB
LET BOARD2(COL,ROW)=0
END IF
NEXT I
ELSE
CALL SOLVE2(N+1)
IF FOUND2=1 THEN EXIT SUB
END IF
END IF
END SUB
解答
-----------------------------------------
| 5 2 9| 4 1 7| 3 6 8|*********|
| 7 4 6| 3 8 9| 5 1 2|*********|
| 3 8 1| 6 2 5| 4 7 9|*********|
-----------------------------------------
| 8 7 3| 2 6 4| 1 9 5| 3 7 8|
| 6 9 5| 1 7 8| 2 4 3| 5 6 9|
| 4 1 2| 5 9 3| 6 8 7| 1 2 4|
-----------------------------------------
| 1 6 7| 8 5 2| 9 3 4| 6 1 7|
| 2 3 8| 9 4 6| 7 5 1| 2 8 3|
| 9 5 4| 7 3 1| 8 2 6| 4 9 5|
-----------------------------------------
|*********| 3 1 7| 4 6 8| 9 5 2|
|*********| 4 8 9| 5 1 2| 7 3 6|
|*********| 6 2 5| 3 7 9| 8 4 1|
-----------------------------------------
Re: 数独パズル - しばっち
2026/01/25 (Sun) 07:44:42
実行すると9*9の数独を5つ組み合わせた下記のような問題を書き出します。
(左上、右上、真ん中、左下、右下)真ん中は4つ共有域があります。
時間がかかる時は、Lazarus64bit版十進BASIC又はBasicAcc、Paract BASICを使用してください。
-----------------------------------------------------------------------
| 7 2| 6 4 8| 5 |*********| 1 7 | 8 9 5| 4 2 3|
| 8 6| 1 2| 7 4 9|*********| 5 2| 3 4| 7 8 |
| 4 3 1| 7 9 | 8 6|*********| 8 3| 7 2 1| 5 9|
-----------------------------------------------------------------------
| 2 4 3| 8 6| 9 1 7|*********| 5 3 4| 2 1 | 7 8|
| 6 | 9 2 7| 5 4|*********| 2 8| 9 4 | 6 |
| 7 5 | 4 1 | 6 8 2|*********| 6 9 | 5 8 3| 1 4 2|
-----------------------------------------------------------------------
| 4| 8 6 9| 1 7 5| 2 3 6| 8 9| 1 2| 5 6|
| 1 6 5| 7 4| 2 9 | 4 5 7| 3 6 1| 5 8| 2 7|
| 8 7| 2 5 | 4 6 3| 9 1| 7 2 5| 3 9| 8 1 |
-----------------------------------------------------------------------
|*********|*********| 8 4| 7 3| 9 |*********|*********|
|*********|*********| 6 7| 5 9 4| 8 1 3|*********|*********|
|*********|*********| 1 | 6 2 | 5 4 |*********|*********|
-----------------------------------------------------------------------
| 8 | 3 6 | 9 | 7 1 5| 3 | 4 7| 1 5 9|
| 9 1 2| 5 8 4| 7 6| 4 9| 1 5 2| 6 3| 7 |
| 4 6 | 7 | 8 5 1| 3 6 | 7 | 8 1 5| 6 2 |
-----------------------------------------------------------------------
| 6 7 4| 5 8| 1 9 |*********| 3 7| 6 5 4| 2 9 1|
| 1 8| 7 6| 5 2 4|*********| 4 1 9| 7 2 | 5 3 6|
| 5 2 9| 4 1 | 6 8 7|*********| 2 6| 1 3 9| 7 4|
-----------------------------------------------------------------------
| 4 1| 8 9 7| 2 6 5|*********| 8 4 | 5 2| 3 7|
| 2 8 6| 1 4 5| 7 9|*********| 7 5| 3 8 6| 4 1 2|
| 7 9 5| 6 2| 4 1 8|*********| 2 6 3| 4 7 1| 8 5|
-----------------------------------------------------------------------
PUBLIC NUMERIC FOUND
RANDOMIZE
DIM BOARD1(9,9),BOARD2(9,9),BOARD3(9,9),BOARD4(9,9),BOARD5(9,9)
DIM ANSWER1(9,9),ANSWER2(9,9),ANSWER3(9,9),ANSWER4(9,9),ANSWER5(9,9)
PRINT "エリア1 探索中..."
DO ! エリア1 左上
LET FOUND=0
LET P=INT(RND*20)+30
MAT BOARD1=ZER
FOR K=1 TO P
DO
LET X=INT(RND*9+1)
LET Y=INT(RND*9+1)
LET NUM=INT(RND*9)+1
LOOP WHILE CHECK(X,Y,NUM,BOARD1)=0
LET BOARD1(X,Y)=NUM
NEXT K
CALL SOLVE(0,BOARD1)
LOOP UNTIL FOUND=1
MAT ANSWER1=BOARD1
PRINT "エリア2 探索中..."
DO ! エリア2 真ん中
LET FOUND=0
LET P=INT(RND*20)+30
MAT BOARD2=ZER
FOR K=1 TO P
DO
LET X=INT(RND*9+1)
LET Y=INT(RND*9+1)
LET NUM=INT(RND*9)+1
FOR I=1 TO 3
FOR J=1 TO 3
LET BOARD2(I,J)=BOARD1(I+6,J+6)
NEXT J
NEXT I
LOOP WHILE CHECK(X,Y,NUM,BOARD2)=0
LET BOARD2(X,Y)=NUM
NEXT K
CALL SOLVE(0,BOARD2)
LOOP UNTIL FOUND=1
MAT ANSWER2=BOARD2
PRINT "エリア3 探索中..."
DO ! エリア3 右上
LET FOUND=0
LET P=INT(RND*20)+30
MAT BOARD3=ZER
FOR K=1 TO P
DO
LET X=INT(RND*9+1)
LET Y=INT(RND*9+1)
LET NUM=INT(RND*9)+1
FOR J=1 TO 3
FOR I=1 TO 3
LET BOARD3(I,J+6)=BOARD2(I+6,J)
NEXT I
NEXT J
LOOP WHILE CHECK(X,Y,NUM,BOARD3)=0
LET BOARD3(X,Y)=NUM
NEXT K
CALL SOLVE(0,BOARD3)
LOOP UNTIL FOUND=1
MAT ANSWER3=BOARD3
PRINT "エリア4 探索中..."
DO ! エリア4 左下
LET FOUND=0
LET P=INT(RND*20)+30
MAT BOARD4=ZER
FOR K=1 TO P
DO
LET X=INT(RND*9+1)
LET Y=INT(RND*9+1)
LET NUM=INT(RND*9)+1
FOR J=1 TO 3
FOR I=1 TO 3
LET BOARD4(I+6,J)=BOARD2(I,J+6)
NEXT I
NEXT J
LOOP WHILE CHECK(X,Y,NUM,BOARD4)=0
LET BOARD4(X,Y)=NUM
NEXT K
CALL SOLVE(0,BOARD4)
LOOP UNTIL FOUND=1
MAT ANSWER4=BOARD4
PRINT "エリア5 探索中..."
DO ! エリア5 右下
LET FOUND=0
LET P=INT(RND*20)+30
MAT BOARD5=ZER
FOR K=1 TO P
DO
LET X=INT(RND*9+1)
LET Y=INT(RND*9+1)
LET NUM=INT(RND*9)+1
FOR J=1 TO 3
FOR I=1 TO 3
LET BOARD5(I,J)=BOARD2(I+6,J+6)
NEXT I
NEXT J
LOOP WHILE CHECK(X,Y,NUM,BOARD5)=0
LET BOARD5(X,Y)=NUM
NEXT K
CALL SOLVE(0,BOARD5)
LOOP UNTIL FOUND=1
MAT ANSWER5=BOARD5
PRINT "問題 作成中..."
CALL CREATPROBLEM(BOARD1,ANSWER1)
CALL CREATPROBLEM(BOARD2,ANSWER2)
CALL CREATPROBLEM(BOARD3,ANSWER3)
CALL CREATPROBLEM(BOARD4,ANSWER4)
CALL CREATPROBLEM(BOARD5,ANSWER5)
PRINT "ファイル書き込み中..."
OPEN #1:NAME "9×9数独拡張問題.txt"
ERASE #1
CALL DISPLAY(BOARD1,BOARD2,BOARD3,BOARD4,BOARD5,#1)
CLOSE #1
OPEN #1:NAME "9×9数独拡張解答.txt"
ERASE #1
CALL DISPLAY(ANSWER1,ANSWER2,ANSWER3,ANSWER4,ANSWER5,#1)
CLOSE #1
PRINT "終了しました"
END
EXTERNAL SUB DISPLAY(BOARD1(,),BOARD2(,),BOARD3(,),BOARD4(,),BOARD5(,),#1)
DIM A$(21,21)
MAT A$="***"&NUL$
FOR J=1 TO 9
FOR I=1 TO 9
IF BOARD1(I,J)>0 THEN LET A$(I,J)=USING$("###",BOARD1(I,J)) ELSE LET A$(I,J)=" "
NEXT I
NEXT J
FOR J=1 TO 9
FOR I=1 TO 9
IF BOARD2(I,J)>0 THEN LET A$(I+6,J+6)=USING$("###",BOARD2(I,J)) ELSE LET A$(I+6,J+6)=" "
NEXT I
NEXT J
FOR J=1 TO 9
FOR I=1 TO 9
IF BOARD3(I,J)>0 THEN LET A$(I+12,J)=USING$("###",BOARD3(I,J)) ELSE LET A$(I+12,J)=" "
NEXT I
NEXT J
FOR J=1 TO 9
FOR I=1 TO 9
IF BOARD4(I,J)>0 THEN LET A$(I,J+12)=USING$("###",BOARD4(I,J)) ELSE LET A$(I,J+12)=" "
NEXT I
NEXT J
FOR J=1 TO 9
FOR I=1 TO 9
IF BOARD5(I,J)>0 THEN LET A$(I+12,J+12)=USING$("###",BOARD5(I,J)) ELSE LET A$(I+12,J+12)=" "
NEXT I
NEXT J
PRINT #1:REPEAT$("---",23);"--"
FOR J=1 TO 21
PRINT #1:"|";
FOR I=1 TO 21
PRINT #1:A$(I,J);
IF MOD(I,3)=0 THEN PRINT #1:"|";
NEXT I
PRINT #1
IF MOD(J,3)=0 THEN PRINT #1:REPEAT$("---",23);"--"
NEXT J
END SUB
EXTERNAL SUB SHOW(BOARD1(,),BOARD2(,),BOARD3(,),BOARD4(,),BOARD5(,))
LET N=21
LET XSIZE=3
LET YSIZE=3
SET WINDOW 0,1,1,0
CLEAR
FOR I=0 TO 9
IF MOD(I,XSIZE)=0 THEN
SET LINE WIDTH 3
ELSE
SET LINE WIDTH 1
END IF
SET LINE COLOR 1
LET X=I/N
PLOT LINES:X,0;X,9/N
LET Y=I/N
PLOT LINES:0,Y;9/N,Y
SET LINE COLOR 2
LET X=(I+12)/N
PLOT LINES:X,0;X,9/N
LET Y=I/N
PLOT LINES:12/N,Y;1,Y
SET LINE COLOR 3
LET X=(I+6)/N
PLOT LINES:X,6/N;X,15/N
LET Y=(I+6)/N
PLOT LINES:6/N,Y;15/N,Y
SET LINE COLOR 4
LET X=I/N
PLOT LINES:X,12/N;X,1
LET Y=(I+12)/N
PLOT LINES:0,Y;9/N,Y
SET LINE COLOR 5
LET X=(I+12)/N
PLOT LINES:X,12/N;X,1
LET Y=(I+12)/N
PLOT LINES:12/N,Y;1,Y
NEXT I
SET TEXT JUSTIFY "LEFT","TOP"
SET TEXT HEIGHT .03
FOR J=0 TO 8
FOR I=0 TO 8
LET X=I/N
LET Y=J/N
IF BOARD1(I+1,J+1)>0 THEN PLOT TEXT ,AT X,Y:USING$("##",BOARD1(I+1,J+1))
NEXT I
NEXT J
FOR J=0 TO 8
FOR I=0 TO 8
LET X=(I+6)/N
LET Y=(J+6)/N
IF I>2 OR J>2 THEN
IF BOARD2(I+1,J+1)>0 THEN PLOT TEXT ,AT X,Y:USING$("##",BOARD2(I+1,J+1))
END IF
NEXT I
NEXT J
FOR J=0 TO 8
FOR I=0 TO 8
LET X=(I+12)/N
LET Y=J/N
IF I>2 OR J<6 THEN
IF BOARD3(I+1,J+1)>0 THEN PLOT TEXT ,AT X,Y:USING$("##",BOARD3(I+1,J+1))
END IF
NEXT I
NEXT J
FOR J=0 TO 8
FOR I=0 TO 8
LET X=I/N
LET Y=(J+12)/N
IF I<6 OR J>2 THEN
IF BOARD4(I+1,J+1)>0 THEN PLOT TEXT ,AT X,Y:USING$("##",BOARD4(I+1,J+1))
END IF
NEXT I
NEXT J
FOR J=0 TO 8
FOR I=0 TO 8
LET X=(I+12)/N
LET Y=(J+12)/N
IF I>2 OR J>2 THEN
IF BOARD5(I+1,J+1)>0 THEN PLOT TEXT ,AT X,Y:USING$("##",BOARD5(I+1,J+1))
END IF
NEXT I
NEXT J
END SUB
EXTERNAL SUB CREATPROBLEM(BOARD(,),ANSWER(,))
LET P=INT(RND*30)+50
FOR L=1 TO P
LET XX=INT(RND*9)+1
LET YY=INT(RND*9)+1
LET BOARD(XX,YY)=0
FOR Y=1 TO 9
FOR X=1 TO 9
IF BOARD(X,Y)=0 THEN
LET C=0
FOR K=1 TO 9
IF CHECK(X,Y,K,BOARD)=1 THEN LET C=C+1
NEXT K
IF C<>1 THEN LET BOARD(X,Y)=ANSWER(X,Y)
END IF
NEXT X
NEXT Y
NEXT L
END SUB
EXTERNAL FUNCTION CHECK(X,Y,NUM,BOARD(,))
LET CHECK=0
FOR YY=1 TO 9
IF BOARD(X,YY)=NUM THEN EXIT FUNCTION
NEXT YY
FOR XX=1 TO 9
IF BOARD(XX,Y)=NUM THEN EXIT FUNCTION
NEXT XX
LET X0=INT((X-1)/3)*3
LET Y0=INT((Y-1)/3)*3
FOR YY=1 TO 3
FOR XX=1 TO 3
IF BOARD(X0+XX,Y0+YY)=NUM THEN EXIT FUNCTION
NEXT XX
NEXT YY
LET CHECK=1
END FUNCTION
EXTERNAL SUB SOLVE(N,BOARD(,))
IF N=81 THEN
LET FOUND=1
ELSE
LET COL=MOD(N,9)+1
LET ROW=INT(N/9)+1
IF BOARD(COL,ROW)=0 THEN
FOR I=1 TO 9
IF CHECK(COL,ROW,I,BOARD)=1 THEN
LET BOARD(COL,ROW)=I
CALL SOLVE(N+1,BOARD)
IF FOUND=1 THEN EXIT SUB
LET BOARD(COL,ROW)=0
END IF
NEXT I
ELSE
CALL SOLVE(N+1,BOARD)
IF FOUND=1 THEN EXIT SUB
END IF
END IF
END SUB
解答
-----------------------------------------------------------------------
| 9 7 2| 6 4 8| 5 3 1|*********| 1 7 6| 8 9 5| 4 2 3|
| 5 8 6| 1 3 2| 7 4 9|*********| 9 5 2| 6 3 4| 7 8 1|
| 4 3 1| 7 9 5| 8 2 6|*********| 8 4 3| 7 2 1| 6 5 9|
-----------------------------------------------------------------------
| 2 4 3| 5 8 6| 9 1 7|*********| 5 3 4| 2 1 6| 9 7 8|
| 6 1 8| 9 2 7| 3 5 4|*********| 2 1 8| 9 4 7| 3 6 5|
| 7 5 9| 4 1 3| 6 8 2|*********| 6 9 7| 5 8 3| 1 4 2|
-----------------------------------------------------------------------
| 3 2 4| 8 6 9| 1 7 5| 2 3 6| 4 8 9| 1 7 2| 5 3 6|
| 1 6 5| 3 7 4| 2 9 8| 4 5 7| 3 6 1| 4 5 8| 2 9 7|
| 8 9 7| 2 5 1| 4 6 3| 9 8 1| 7 2 5| 3 6 9| 8 1 4|
-----------------------------------------------------------------------
|*********|*********| 5 8 4| 1 7 3| 2 9 6|*********|*********|
|*********|*********| 6 2 7| 5 9 4| 8 1 3|*********|*********|
|*********|*********| 3 1 9| 6 2 8| 5 4 7|*********|*********|
-----------------------------------------------------------------------
| 8 5 7| 3 6 1| 9 4 2| 7 1 5| 6 3 8| 2 4 7| 1 5 9|
| 9 1 2| 5 8 4| 7 3 6| 8 4 9| 1 5 2| 9 6 3| 7 4 8|
| 4 6 3| 7 2 9| 8 5 1| 3 6 2| 9 7 4| 8 1 5| 6 2 3|
-----------------------------------------------------------------------
| 6 7 4| 2 5 8| 1 9 3|*********| 3 8 7| 6 5 4| 2 9 1|
| 1 3 8| 9 7 6| 5 2 4|*********| 4 1 9| 7 2 8| 5 3 6|
| 5 2 9| 4 1 3| 6 8 7|*********| 5 2 6| 1 3 9| 8 7 4|
-----------------------------------------------------------------------
| 3 4 1| 8 9 7| 2 6 5|*********| 8 4 1| 5 9 2| 3 6 7|
| 2 8 6| 1 4 5| 3 7 9|*********| 7 9 5| 3 8 6| 4 1 2|
| 7 9 5| 6 3 2| 4 1 8|*********| 2 6 3| 4 7 1| 9 8 5|
-----------------------------------------------------------------------
BASICでトンデモ理論に挑戦 - 百瀬
2026/01/03 (Sat) 07:13:05
微細構造定数 137.035999...を非フィッティングで導出することに挑戦してみました。
DECLARE EXTERNAL FUNCTION P_full
DECLARE EXTERNAL FUNCTION Expected_Radius
LET d = 3 ! 唯一の入力:空間次元
LET k = 2 * d ! 3次元格子の方向数 (k=6)
LET Nu = 2 ^ k ! 更新チャンネル数 (Nu=64)
LET n = d * d ! ポテンシャル次元 (n=9)
! --- 1ビット識別境界による m* の自動算出 ---
LET threshold = 0.5 ! 1ビット境界(確率 1/2)
LET m_star = 0
FOR m = 1 TO 100
IF P_full(m, k) >= threshold THEN
LET m_star = m ! 累積確率が1/2を超えた最小のm
EXIT FOR
END IF
NEXT m
! --- 定数と補正項の計算 ---
LET K_const = 1 / (2 * (PI ^ 2.5)) ! ユニバーサル幾何定数 K
LET Delta_m = 1 / (12 * m_star ^ 2) ! 幾何学的補正項
! --- 離散期待値と有効残差の算出 ---
LET E_discrete = Expected_Radius(m_star) ! 厳密な離散期待値
LET E_gaussian = (SQR(m_star * PI)) / 2 ! 連続体リファレンス
LET c_free = E_discrete / E_gaussian ! 無次元残差
LET c_eff = c_free * SQR(1 - Delta_m) ! 有効残差
! --- 最終合成 (alpha_inv = alpha0_inv + K * c_eff) ---
LET ln2 = LOG(2)
LET alpha0 = (2 * n + 1)^2 / (8 * PI * Nu^2 * ln2^2) ! 主項 alpha0
LET alpha_inv = (1 / alpha0) + K_const * c_eff ! 最終合成式
! --- 結果表示 ---
PRINT "--- Derived Discrete Parameters ---"
PRINT "Dimension d ="; d
PRINT "Directions k ="; k
PRINT "Update Nu ="; Nu
PRINT "Index m* ="; m_star
PRINT
PRINT "--- Numerical Results ---"
PRINT "alpha0^-1 ="; 1 / alpha0
PRINT "K * c_eff ="; K_const * c_eff
PRINT "Final alpha^-1 ="; alpha_inv
END
! =========================================================
! 外部関数:クーポン・コレクター問題の確率算出
! =========================================================
EXTERNAL FUNCTION P_full(m, k)
LET s = 0
FOR j = 0 TO k
! (-1)^j * nCr(k, j) * ((k-j)/k)^m
LET term = ((-1)^j) * COMB(k, j) * ((k - j) / k) ^ m
LET s = s + term
NEXT j
LET P_full = s
END FUNCTION
! =========================================================
! 外部関数:2Dランダムウォークの厳密期待値 (DP実装)
! =========================================================
EXTERNAL FUNCTION Expected_Radius(m)
! 十進BASICの配列による2次元確率分布の保持
DIM P(-20 TO 20, -20 TO 20)
DIM P_new(-20 TO 20, -20 TO 20)
MAT P = ZER
LET P(0,0) = 1 ! 原点からスタート
FOR step = 1 TO m
MAT P_new = ZER
FOR x = -(step-1) TO (step-1)
FOR y = -(step-1) TO (step-1)
IF P(x,y) > 0 THEN
! 4方向へ等確率 1/4 で遷移
LET P_new(x+1, y) = P_new(x+1, y) + P(x,y) * 0.25
LET P_new(x-1, y) = P_new(x-1, y) + P(x,y) * 0.25
LET P_new(x, y+1) = P_new(x, y+1) + P(x,y) * 0.25
LET P_new(x, y-1) = P_new(x, y-1) + P(x,y) * 0.25
END IF
NEXT y
NEXT x
MAT P = P_new
NEXT step
! 期待値の集計: E = Σ P(x,y) * SQR(x^2 + y^2)
LET sum_r = 0
FOR x = -m TO m
FOR y = -m TO m
IF P(x,y) > 0 THEN
LET sum_r = sum_r + P(x,y) * SQR(x^2 + y^2)
END IF
NEXT y
NEXT x
LET Expected_Radius = sum_r
END FUNCTION
マッチ棒パズル - しばっち
2025/12/28 (Sun) 08:08:24
マッチ棒パズル
https://giga.web.docomo.ne.jp/noutore/aha/261060/
https://noukatsu-shimbun.jp/2025/02/02/23067/
https://healthrent.duskin.jp/column/brain-training/q111.html
実行すると下記のような問題を出力します。
1本だけ動かして数式を完成させます。
マッチは折らず≠は使いません。
7 - 7 = 3
4 - 1 = 6
6 - 9 = 0
4 + 3 = 9
9 - 3 = 9
RANDOMIZE
OPEN #1:NAME "マッチ棒パズル問題.txt"
OPEN #2:NAME "マッチ棒パズル解答.txt"
ERASE #1
ERASE #2
FOR K=1 TO 20 ! 問題数
DO
DO
LET X=INT(RND*10)
LET Y=INT(RND*10)
LET SIGN=(-1)^(INT(RND*2))
LET SUM=X+Y*SIGN ! 解答文
LOOP WHILE SUM<0 OR SUM>9
CALL CHANGE(X,XCODE,XOUT) ! 問題作成
CALL CHANGE(Y,YCODE,YOUT)
CALL CHANGE(SUM,SUMCODE,SUMOUT)
CALL CHANGESIGN(SIGN,SIGNCODE,SIGNOUT)
IF XOUT+SIGNOUT*YOUT<>SUMOUT THEN
IF SUMCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=1 AND YCODE=-1) OR (XCODE=-1 AND YCODE=-1) OR (XCODE=0 AND YCODE=2) OR (XCODE=2 AND YCODE=0) THEN EXIT DO
END IF
IF XCODE=2 AND SIGNCODE=2 THEN
IF (YCODE=-1 AND SUMCODE=1) OR (YCODE=1 AND SUMCODE=-1) OR (YCODE=2 AND SUMCODE=0) OR (YCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=-1 AND SUMCODE=1) OR (XCODE=1 AND SUMCODE=-1) OR (XCODE=2 AND SUMCODE=0) OR (XCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND YCODE=2 THEN
IF (SUMCODE=-1 AND SIGNCODE=1) OR (SUMCODE=1 AND SIGNCODE=-1) OR (SUMCODE=2 AND SIGNCODE=0) OR (SUMCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND SUMCODE=2 THEN
IF (YCODE=-1 AND SIGNCODE=1) OR (YCODE=1 AND SIGNCODE=-1) OR (YCODE=2 AND SIGNCODE=0) OR (YCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SUMCODE=2 THEN
IF (XCODE=-1 AND SIGNCODE=1) OR (XCODE=1 AND SIGNCODE=-1) OR (XCODE=2 AND SIGNCODE=0) OR (XCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
END IF
LOOP
PRINT #2:X;
IF SIGN>0 THEN PRINT #2:"+"; ELSE PRINT #2:"-";
PRINT #2:Y;"=";SUM
PRINT #1:XOUT;
IF SIGNOUT>0 THEN PRINT #1:"+"; ELSE PRINT #1:"-";
PRINT #1:YOUT;"=";SUMOUT
NEXT K
CLOSE #1
CLOSE #2
SUB CHANGE(N,CODE,OUT)
SELECT CASE N
CASE 0
LET Z=INT(RND*2)+1
SELECT CASE Z
CASE 1
LET CODE=2 ! 無変更
LET OUT=0
CASE 2
LET CODE=1 ! マッチを持ってくる
LET OUT=8 ! 0を8へ
END SELECT
CASE 1
LET CODE=2 ! 無変更
LET OUT=1
CASE 2
LET Z=INT(RND*2)+1
SELECT CASE Z
CASE 1
LET CODE=2
LET OUT=2
CASE 2
LET CODE=0 ! 数字内で移動
LET OUT=3 ! 2を3へ
END SELECT
CASE 3
LET Z=INT(RND*3)+1
SELECT CASE Z
CASE 1
LET CODE=2 ! 無変更
LET OUT=3
CASE 2
LET CODE=0
LET OUT=2 ! 3を2へ
CASE 3
LET CODE=0
LET OUT=5 ! 3を5へ
END SELECT
CASE 4
LET Z=INT(RND*2)+1
SELECT CASE Z
CASE 1
LET CODE=2
LET OUT=4
CASE 2
LET CODE=0
LET OUT=7
END SELECT
CASE 5
LET Z=INT(RND*4)+1
SELECT CASE Z
CASE 1
LET CODE=2
LET OUT=5
CASE 2
LET CODE=1
LET OUT=6
CASE 3
LET CODE=0
LET OUT=3
CASE 4
LET CODE=1
LET OUT=9
END SELECT
CASE 6
LET Z=INT(RND*4)+1
SELECT CASE Z
CASE 1
LET CODE=2
LET OUT=6
CASE 2
LET CODE=-1 ! マッチを外す
LET OUT=5
CASE 3
LET CODE=1
LET OUT=8
CASE 4
LET CODE=0
LET OUT=9
END SELECT
CASE 7
LET Z=INT(RND*2)+1
SELECT CASE Z
CASE 1
LET CODE=2
LET OUT=7
CASE 2
LET CODE=0
LET OUT=4
END SELECT
CASE 8
LET Z=INT(RND*3)+1
SELECT CASE Z
CASE 1
LET CODE=2
LET OUT=8
CASE 2
LET CODE=-1
LET OUT=9
CASE 3
LET CODE=-1
LET OUT=0
END SELECT
CASE 9
LET Z=INT(RND*4)+1
SELECT CASE Z
CASE 1
LET CODE=2
LET OUT=9
CASE 2
LET CODE=1
LET OUT=8
CASE 3
LET CODE=-1
LET OUT=5
CASE 4
LET CODE=0
LET OUT=6
END SELECT
END SELECT
END SUB
SUB CHANGESIGN(N,CODE,OUT) ! 符号の変更
SELECT CASE N
CASE -1
LET Z=INT(RND*2)+1
SELECT CASE Z
CASE 1
LET CODE=2 ! 無変更
LET OUT=-1 ! -
CASE 2
LET CODE=1 ! -から+へ
LET OUT=1 ! +
END SELECT
CASE 1
LET Z=INT(RND*2)+1
SELECT CASE Z
CASE 1
LET CODE=2 ! 無変更
LET OUT=1 ! +
CASE 2
LET CODE=-1 ! +から-へ
LET OUT=-1 ! -
END SELECT
END SELECT
END SUB
END
解答
7 - 4 = 3
7 - 1 = 6
6 - 6 = 0
4 + 5 = 9
8 - 3 = 5
---------------------------------------------------------------------
2桁のマッチ棒パズル
03 + 83 = 85
14 - 00 = 17
97 + 04 = 98
83 - 52 = 30
89 + 06 = 93
RANDOMIZE
OPEN #1:NAME "マッチ棒パズル問題.txt"
OPEN #2:NAME "マッチ棒パズル解答.txt"
ERASE #1
ERASE #2
FOR K=1 TO 20 ! 問題数
DO
DO
LET X1=INT(RND*10)
LET Y1=INT(RND*10)
LET X2=INT(RND*10)
LET Y2=INT(RND*10)
LET SIGN=(-1)^(INT(RND*2))
LET SUM=X1*10+X2+(Y1*10+Y2)*SIGN
LET SUM1=INT(SUM/10)
LET SUM2=MOD(SUM,10)
LOOP WHILE SUM<0 OR SUM>99
IF RND<.5 THEN
IF RND<.5 THEN
CALL CHANGE(X1,XCODE,X1OUT)
LET X2OUT=X2
ELSE
CALL CHANGE(X2,XCODE,X2OUT)
LET X1OUT=X1
END IF
IF RND<.5 THEN
CALL CHANGE(Y1,YCODE,Y1OUT)
LET Y2OUT=Y2
ELSE
CALL CHANGE(Y2,YCODE,Y2OUT)
LET Y1OUT=Y1
END IF
ELSE
IF RND<.5 THEN
CALL CHANGE(X1,XCODE,X1OUT)
CALL CHANGE(X2,YCODE,X2OUT)
LET Y1OUT=Y1
LET Y2OUT=Y2
ELSE
CALL CHANGE(Y1,XCODE,Y1OUT)
CALL CHANGE(Y2,YCODE,Y2OUT)
LET X1OUT=X1
LET X2OUT=X2
END IF
END IF
IF RND<.5 THEN
CALL CHANGE(SUM1,SUMCODE,SUM1OUT)
LET SUM2OUT=SUM2
ELSE
CALL CHANGE(SUM2,SUMCODE,SUM2OUT)
LET SUM1OUT=SUM1
END IF
CALL CHANGESIGN(SIGN,SIGNCODE,SIGNOUT)
IF X1OUT*10+X2OUT+SIGNOUT*(YOUT1*10+YOUT2)<>SUM1OUT*10+SUM2OUT THEN
IF SUMCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=1 AND YCODE=-1) OR (XCODE=-1 AND YCODE=-1) OR (XCODE=0 AND YCODE=2) OR (XCODE=2 AND YCODE=0) THEN EXIT DO
END IF
IF XCODE=2 AND SIGNCODE=2 THEN
IF (YCODE=-1 AND SUMCODE=1) OR (YCODE=1 AND SUMCODE=-1) OR (YCODE=2 AND SUMCODE=0) OR (YCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=-1 AND SUMCODE=1) OR (XCODE=1 AND SUMCODE=-1) OR (XCODE=2 AND SUMCODE=0) OR (XCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND YCODE=2 THEN
IF (SUMCODE=-1 AND SIGNCODE=1) OR (SUMCODE=1 AND SIGNCODE=-1) OR (SUMCODE=2 AND SIGNCODE=0) OR (SUMCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND SUMCODE=2 THEN
IF (YCODE=-1 AND SIGNCODE=1) OR (YCODE=1 AND SIGNCODE=-1) OR (YCODE=2 AND SIGNCODE=0) OR (YCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SUMCODE=2 THEN
IF (XCODE=-1 AND SIGNCODE=1) OR (XCODE=1 AND SIGNCODE=-1) OR (XCODE=2 AND SIGNCODE=0) OR (XCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
END IF
LOOP
PRINT #2:USING$("%%",X1*10+X2);
IF SIGN>0 THEN PRINT #2:" + "; ELSE PRINT #2:" - ";
PRINT #2:USING$("%%",Y1*10+Y2);" = ";USING$("%%",SUM1*10+SUM2)
PRINT #1:USING$("%%",X1OUT*10+X2OUT);
IF SIGNOUT>0 THEN PRINT #1:" + "; ELSE PRINT #1:" - ";
PRINT #1:USING$("%%",Y1OUT*10+Y2OUT);" = ";USING$("%%",SUM1OUT*10+SUM2OUT)
NEXT K
CLOSE #1
CLOSE #2
一部略
SUB CHANGE(N,CODE,OUT)
END SUB
SUB CHANGESIGN(N,CODE,OUT)
END SUB
END
解答
02 + 83 = 85
17 - 00 = 17
94 + 04 = 98
82 - 52 = 30
89 - 06 = 83
---------------------------------------------------------------------
3桁のマッチ棒パズル
575 + 514 = 889
787 + 013 = 500
376 - 416 = 782
950 - 489 = 161
473 - 124 = 249
RANDOMIZE
OPEN #1:NAME "マッチ棒パズル問題.txt"
OPEN #2:NAME "マッチ棒パズル解答.txt"
ERASE #1
ERASE #2
FOR K=1 TO 20 ! 問題数
DO
DO
LET X1=INT(RND*10)
LET Y1=INT(RND*10)
LET X2=INT(RND*10)
LET Y2=INT(RND*10)
LET X3=INT(RND*10)
LET Y3=INT(RND*10)
LET SIGN=(-1)^(INT(RND*2))
LET SUM=X1*100+X2*10+X3+(Y1*100+Y2*10+Y3)*SIGN
LET SUM1=INT(SUM/100) ! 解答文
LET SUM2=MOD(INT(SUM/10),10)
LET SUM3=MOD(SUM,10)
LOOP WHILE SUM<0 OR SUM>999
IF RND<.5 THEN
SELECT CASE INT(RND*3+1)
CASE 1
CALL CHANGE(X1,XCODE,X1OUT)
LET X2OUT=X2
LET X3OUT=X3
CASE 2
CALL CHANGE(X2,XCODE,X2OUT)
LET X1OUT=X1
LET X3OUT=X3
CASE 3
CALL CHANGE(X3,XCODE,X3OUT)
LET X1OUT=X1
LET X2OUT=X2
END SELECT
SELECT CASE INT(RND*3+1)
CASE 1
CALL CHANGE(Y1,YCODE,Y1OUT)
LET Y2OUT=Y2
LET Y3OUT=Y3
CASE 2
CALL CHANGE(Y2,YCODE,Y2OUT)
LET Y1OUT=Y1
LET Y3OUT=Y3
CASE 3
CALL CHANGE(Y3,YCODE,Y3OUT)
LET Y1OUT=Y1
LET Y2OUT=Y2
END SELECT
ELSE
IF RND<.5 THEN
SELECT CASE INT(RND*3+1)
CASE 1
CALL CHANGE(X1,XCODE,X1OUT)
CALL CHANGE(X2,YCODE,X2OUT)
LET X3OUT=X3
LET Y1OUT=Y1
LET Y2OUT=Y2
LET Y3OUT=Y3
CASE 2
CALL CHANGE(X1,XCODE,X1OUT)
CALL CHANGE(X3,YCODE,X3OUT)
LET X2OUT=X2
LET Y1OUT=Y1
LET Y2OUT=Y2
LET Y3OUT=Y3
CASE 3
CALL CHANGE(X2,XCODE,X2OUT)
CALL CHANGE(X3,YCODE,X3OUT)
LET X1OUT=X1
LET Y1OUT=Y1
LET Y2OUT=Y2
LET Y3OUT=Y3
END SELECT
ELSE
SELECT CASE INT(RND*3+1)
CASE 1
CALL CHANGE(Y1,XCODE,Y1OUT)
CALL CHANGE(Y2,YCODE,Y2OUT)
LET Y3OUT=Y3
LET X1OUT=X1
LET X2OUT=X2
LET X3OUT=X3
CASE 2
CALL CHANGE(Y1,XCODE,Y1OUT)
CALL CHANGE(Y3,YCODE,Y3OUT)
LET Y2OUT=Y2
LET X1OUT=X1
LET X2OUT=X2
LET X3OUT=X3
CASE 3
CALL CHANGE(Y2,XCODE,Y2OUT)
CALL CHANGE(Y3,YCODE,Y3OUT)
LET Y1OUT=Y1
LET X1OUT=X1
LET X2OUT=X2
LET X3OUT=X3
END SELECT
END IF
END IF
SELECT CASE INT(RND*3+1)
CASE 1
CALL CHANGE(SUM1,SUMCODE,SUM1OUT)
LET SUM2OUT=SUM2
LET SUM3OUT=SUM3
CASE 2
CALL CHANGE(SUM2,SUMCODE,SUM2OUT)
LET SUM1OUT=SUM1
LET SUM3OUT=SUM3
CASE 3
CALL CHANGE(SUM3,SUMCODE,SUM3OUT)
LET SUM1OUT=SUM1
LET SUM2OUT=SUM2
END SELECT
CALL CHANGESIGN(SIGN,SIGNCODE,SIGNOUT)
IF X1OUT*100+X2OUT*10+X3OUT+SIGNOUT*(Y1OUT*100+Y2OUT*10+Y3OUT)<>SUM1OUT*100+SUM2OUT*10+SUM3OUT THEN
IF SUMCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=1 AND YCODE=-1) OR (XCODE=-1 AND YCODE=-1) OR (XCODE=0 AND YCODE=2) OR (XCODE=2 AND YCODE=0) THEN EXIT DO
END IF
IF XCODE=2 AND SIGNCODE=2 THEN
IF (YCODE=-1 AND SUMCODE=1) OR (YCODE=1 AND SUMCODE=-1) OR (YCODE=2 AND SUMCODE=0) OR (YCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=-1 AND SUMCODE=1) OR (XCODE=1 AND SUMCODE=-1) OR (XCODE=2 AND SUMCODE=0) OR (XCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND YCODE=2 THEN
IF (SUMCODE=-1 AND SIGNCODE=1) OR (SUMCODE=1 AND SIGNCODE=-1) OR (SUMCODE=2 AND SIGNCODE=0) OR (SUMCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND SUMCODE=2 THEN
IF (YCODE=-1 AND SIGNCODE=1) OR (YCODE=1 AND SIGNCODE=-1) OR (YCODE=2 AND SIGNCODE=0) OR (YCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SUMCODE=2 THEN
IF (XCODE=-1 AND SIGNCODE=1) OR (XCODE=1 AND SIGNCODE=-1) OR (XCODE=2 AND SIGNCODE=0) OR (XCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
END IF
LOOP
PRINT #2:USING$("%%%",X1*100+X2*10+X3);
IF SIGN>0 THEN PRINT #2:" + "; ELSE PRINT #2:" - ";
PRINT #2:USING$("%%%",Y1*100+Y2*10+Y3);" = ";USING$("%%%",SUM1*100+SUM2*10+SUM3)
PRINT #1:USING$("%%%",X1OUT*100+X2OUT*10+X3OUT);
IF SIGNOUT>0 THEN PRINT #1:" + "; ELSE PRINT #1:" - ";
PRINT #1:USING$("%%%",Y1OUT*100+Y2OUT*10+Y3OUT);" = ";USING$("%%%",SUM1OUT*100+SUM2OUT*10+SUM3OUT)
NEXT K
CLOSE #1
CLOSE #2
一部略
SUB CHANGE(N,CODE,OUT)
END SUB
SUB CHANGESIGN(N,CODE,OUT)
END SUB
END
解答
575 + 314 = 889
487 + 013 = 500
376 + 416 = 792
650 - 489 = 161
473 - 124 = 349
Re: マッチ棒パズル - しばっち
2025/12/28 (Sun) 08:10:25
テキスト文字ではイメージしにくいので画像で作ってみた。
RANDOMIZE
LET N=10
DIM X(N),Y(N),SUM(N),XOUT(N),YOUT(N),SUMOUT(N),SIGN(N),SIGNOUT(N)
FOR K=1 TO N ! 問題数
DO
DO
LET X(K)=INT(RND*10)
LET Y(K)=INT(RND*10)
LET SIGN(K)=(-1)^(INT(RND*2))
LET SUM(K)=X(K)+Y(K)*SIGN(K) ! 解答文
LOOP WHILE SUM(K)<0 OR SUM(K)>9
CALL CHANGE(X(K),XCODE,XOUT(K)) ! 問題作成
CALL CHANGE(Y(K),YCODE,YOUT(K))
CALL CHANGE(SUM(K),SUMCODE,SUMOUT(K))
CALL CHANGESIGN(SIGN(K),SIGNCODE,SIGNOUT(K))
IF XOUT(K)+SIGNOUT(K)*YOUT(K)<>SUMOUT(K) THEN
IF SUMCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=1 AND YCODE=-1) OR (XCODE=-1 AND YCODE=-1) OR (XCODE=0 AND YCODE=2) OR (XCODE=2 AND YCODE=0) THEN EXIT DO
END IF
IF XCODE=2 AND SIGNCODE=2 THEN
IF (YCODE=-1 AND SUMCODE=1) OR (YCODE=1 AND SUMCODE=-1) OR (YCODE=2 AND SUMCODE=0) OR (YCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=-1 AND SUMCODE=1) OR (XCODE=1 AND SUMCODE=-1) OR (XCODE=2 AND SUMCODE=0) OR (XCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND YCODE=2 THEN
IF (SUMCODE=-1 AND SIGNCODE=1) OR (SUMCODE=1 AND SIGNCODE=-1) OR (SUMCODE=2 AND SIGNCODE=0) OR (SUMCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND SUMCODE=2 THEN
IF (YCODE=-1 AND SIGNCODE=1) OR (YCODE=1 AND SIGNCODE=-1) OR (YCODE=2 AND SIGNCODE=0) OR (YCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SUMCODE=2 THEN
IF (XCODE=-1 AND SIGNCODE=1) OR (XCODE=1 AND SIGNCODE=-1) OR (XCODE=2 AND SIGNCODE=0) OR (XCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
END IF
LOOP
NEXT K
CALL GINIT(300,600)
LET YY=550
LET SC=1 ! 縮小率
FOR K=1 TO N
LET XX=50
IF SIGN(K)>0 THEN LET SIGN$="+" ELSE LET SIGN$="-"
CALL DISPLAY(STR$(X(K))&SIGN$&STR$(Y(K))&"="&STR$(SUM(K)),XX,YY,SC)
LET YY=YY-50*SC
NEXT K
GSAVE "マッチ棒パズル解答.png"
CLEAR
LET YY=550
LET SC=1
FOR K=1 TO N
LET XX=50
IF SIGNOUT(K)>0 THEN LET SIGN$="+" ELSE LET SIGN$="-"
CALL DISPLAY(STR$(XOUT(K))&SIGN$&STR$(YOUT(K))&"="&STR$(SUMOUT(K)),XX,YY,SC)
LET YY=YY-50*SC
NEXT K
GSAVE "マッチ棒パズル問題.png"
一部サブルーチン定義省略
SUB CHANGE(N,CODE,OUT)
END SUB
SUB CHANGESIGN(N,CODE,OUT) ! 符号の変更
END SUB
END
EXTERNAL SUB DISPLAY(N$,X,Y,SC)
SET LINE WIDTH 5
FOR I=1 TO LEN(N$)
SELECT CASE N$(I:I)
CASE "0"
DRAW ZERO WITH SCALE(SC)*SHIFT(X,Y)
CASE "1"
DRAW ONE WITH SCALE(SC)*SHIFT(X,Y)
CASE "2"
DRAW TWO WITH SCALE(SC)*SHIFT(X,Y)
CASE "3"
DRAW THREE WITH SCALE(SC)*SHIFT(X,Y)
CASE "4"
DRAW FOUR WITH SCALE(SC)*SHIFT(X,Y)
CASE "5"
DRAW FIVE WITH SCALE(SC)*SHIFT(X,Y)
CASE "6"
DRAW SIX WITH SCALE(SC)*SHIFT(X,Y)
CASE "7"
DRAW SEVEN WITH SCALE(SC)*SHIFT(X,Y)
CASE "8"
DRAW EIGHT WITH SCALE(SC)*SHIFT(X,Y)
CASE "9"
DRAW NINE WITH SCALE(SC)*SHIFT(X,Y)
CASE "-"
DRAW MINUS WITH SCALE(SC)*SHIFT(X,Y)
CASE "+"
DRAW PLUS WITH SCALE(SC)*SHIFT(X,Y)
CASE "="
DRAW EQUAL WITH SCALE(SC)*SHIFT(X,Y)
END SELECT
LET X=X+30*SC
NEXT I
END SUB
EXTERNAL PICTURE ZERO
!PLOT LINES:-10,0;10,0
PLOT LINES:-10,0;-10,20
PLOT LINES:-10,20;10,20
PLOT LINES:10,20;10,0
PLOT LINES:-10,0;-10,-20
PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE ONE
!PLOT LINES:-10,0;10,0
!PLOT LINES:-10,0;-10,20
!PLOT LINES:-10,20;10,20
PLOT LINES:10,20;10,0
!PLOT LINES:-10,0;-10,-20
!PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE TWO
PLOT LINES:-10,0;10,0
!PLOT LINES:-10,0;-10,20
PLOT LINES:-10,20;10,20
PLOT LINES:10,20;10,0
PLOT LINES:-10,0;-10,-20
PLOT LINES:-10,-20;10,-20
!PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE THREE
PLOT LINES:-10,0;10,0
!PLOT LINES:-10,0;-10,20
PLOT LINES:-10,20;10,20
PLOT LINES:10,20;10,0
!PLOT LINES:-10,0;-10,-20
PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE FOUR
PLOT LINES:-10,0;10,0
PLOT LINES:-10,0;-10,20
!PLOT LINES:-10,20;10,20
PLOT LINES:10,20;10,0
!PLOT LINES:-10,0;-10,-20
!PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE FIVE
PLOT LINES:-10,0;10,0
PLOT LINES:-10,0;-10,20
PLOT LINES:-10,20;10,20
!PLOT LINES:10,20;10,0
!PLOT LINES:-10,0;-10,-20
PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE SIX
PLOT LINES:-10,0;10,0
PLOT LINES:-10,0;-10,20
PLOT LINES:-10,20;10,20
!PLOT LINES:10,20;10,0
PLOT LINES:-10,0;-10,-20
PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE SEVEN
!PLOT LINES:-10,0;10,0
PLOT LINES:-10,0;-10,20
PLOT LINES:-10,20;10,20
PLOT LINES:10,20;10,0
!PLOT LINES:-10,0;-10,-20
!PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE EIGHT
PLOT LINES:-10,0;10,0
PLOT LINES:-10,0;-10,20
PLOT LINES:-10,20;10,20
PLOT LINES:10,20;10,0
PLOT LINES:-10,0;-10,-20
PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE NINE
PLOT LINES:-10,0;10,0
PLOT LINES:-10,0;-10,20
PLOT LINES:-10,20;10,20
PLOT LINES:10,20;10,0
!PLOT LINES:-10,0;-10,-20
PLOT LINES:-10,-20;10,-20
PLOT LINES:10,-20;10,0
END PICTURE
EXTERNAL PICTURE MINUS
PLOT LINES:-10,0;10,0
END PICTURE
EXTERNAL PICTURE PLUS
PLOT LINES:-10,0;10,0
PLOT LINES:0,10;0,-10
END PICTURE
EXTERNAL PICTURE EQUAL
PLOT LINES:-10,-5;10,-5
PLOT LINES:-10,5;10,5
END PICTURE
EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,0,YSIZE-1
SET POINT STYLE 1
SET COLOR MODE "REGULAR"
END SUB
Re: マッチ棒パズル - しばっち
2025/12/28 (Sun) 08:12:26
更にイメージしやすいようにデジカメで撮影したマッチ棒数字画像(640×480)で作ってみました。
(※マッチ棒ではなく綿棒です)
下記からダウンロードしてください。(マッチ棒数字.zip 720KB)
https://15.gigafile.nu/0226-c9ac26967de78c2ff43e05c538d30b76c
ダウンロード期限:2026年2月26日(木)
ダウンロードパスワード:設定していません
RANDOMIZE
LET N=5
LET PATH$=".\マッチ棒数字\"
DIM X(N),Y(N),SUM(N),XOUT(N),YOUT(N),SUMOUT(N),SIGN(N),SIGNOUT(N)
PUBLIC NUMERIC IMAGE0(640,480),IMAGE1(640,480),IMAGE2(640,480),IMAGE3(640,480),IMAGE4(640,480),IMAGE5(640,480),IMAGE6(640,480)
PUBLIC NUMERIC IMAGE7(640,480),IMAGE8(640,480),IMAGE9(640,480),IMAGE10(640,480),IMAGE11(640,480),IMAGE12(640,480)
PUBLIC NUMERIC XSIZE,YSIZE
CALL PICTURELOAD(PATH$&"0.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE0
CALL PICTURELOAD(PATH$&"1.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE1
CALL PICTURELOAD(PATH$&"2.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE2
CALL PICTURELOAD(PATH$&"3.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE3
CALL PICTURELOAD(PATH$&"4.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE4
CALL PICTURELOAD(PATH$&"5.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE5
CALL PICTURELOAD(PATH$&"6.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE6
CALL PICTURELOAD(PATH$&"7.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE7
CALL PICTURELOAD(PATH$&"8.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE8
CALL PICTURELOAD(PATH$&"9.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE9
CALL PICTURELOAD(PATH$&"equal.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE10
CALL PICTURELOAD(PATH$&"plus.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE11
CALL PICTURELOAD(PATH$&"minus.jpg",XSIZE,YSIZE)
ASK PIXEL ARRAY(0,0) IMAGE12
CLEAR
FOR K=1 TO N ! 問題数
DO
DO
LET X(K)=INT(RND*10)
LET Y(K)=INT(RND*10)
LET SIGN(K)=(-1)^(INT(RND*2))
LET SUM(K)=X(K)+Y(K)*SIGN(K) ! 解答文
LOOP WHILE SUM(K)<0 OR SUM(K)>9
CALL CHANGE(X(K),XCODE,XOUT(K)) ! 問題作成
CALL CHANGE(Y(K),YCODE,YOUT(K))
CALL CHANGE(SUM(K),SUMCODE,SUMOUT(K))
CALL CHANGESIGN(SIGN(K),SIGNCODE,SIGNOUT(K))
IF XOUT(K)+SIGNOUT(K)*YOUT(K)<>SUMOUT(K) THEN
IF SUMCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=1 AND YCODE=-1) OR (XCODE=-1 AND YCODE=-1) OR (XCODE=0 AND YCODE=2) OR (XCODE=2 AND YCODE=0) THEN EXIT DO
END IF
IF XCODE=2 AND SIGNCODE=2 THEN
IF (YCODE=-1 AND SUMCODE=1) OR (YCODE=1 AND SUMCODE=-1) OR (YCODE=2 AND SUMCODE=0) OR (YCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SIGNCODE=2 THEN
IF (XCODE=-1 AND SUMCODE=1) OR (XCODE=1 AND SUMCODE=-1) OR (XCODE=2 AND SUMCODE=0) OR (XCODE=0 AND SUMCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND YCODE=2 THEN
IF (SUMCODE=-1 AND SIGNCODE=1) OR (SUMCODE=1 AND SIGNCODE=-1) OR (SUMCODE=2 AND SIGNCODE=0) OR (SUMCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF XCODE=2 AND SUMCODE=2 THEN
IF (YCODE=-1 AND SIGNCODE=1) OR (YCODE=1 AND SIGNCODE=-1) OR (YCODE=2 AND SIGNCODE=0) OR (YCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
IF YCODE=2 AND SUMCODE=2 THEN
IF (XCODE=-1 AND SIGNCODE=1) OR (XCODE=1 AND SIGNCODE=-1) OR (XCODE=2 AND SIGNCODE=0) OR (XCODE=0 AND SIGNCODE=2) THEN EXIT DO
END IF
END IF
LOOP
NEXT K
LET SC=1/4 !縮小率
CALL GINIT(XSIZE*SC*N,YSIZE*SC*N)
LET YY=0
FOR K=1 TO N
LET XX=0
IF SIGN(K)>0 THEN LET SIGN$="+" ELSE LET SIGN$="-"
CALL DISPLAY(STR$(X(K))&SIGN$&STR$(Y(K))&"="&STR$(SUM(K)),XX,YY,SC)
LET YY=YY+YSIZE*SC
NEXT K
GSAVE "マッチ棒数字棒パズル解答.png"
CLEAR
LET YY=0
LET SC=1/4
FOR K=1 TO N
LET XX=0
IF SIGNOUT(K)>0 THEN LET SIGN$="+" ELSE LET SIGN$="-"
CALL DISPLAY(STR$(XOUT(K))&SIGN$&STR$(YOUT(K))&"="&STR$(SUMOUT(K)),XX,YY,SC)
LET YY=YY+YSIZE*SC
NEXT K
GSAVE "マッチ棒数字棒パズル問題.png"
一部サブルーチン定義省略
SUB CHANGE(N,CODE,OUT)
END SUB
SUB CHANGESIGN(N,CODE,OUT) ! 符号の変更
END SUB
END
EXTERNAL SUB DISPLAY(N$,X,Y,SC)
FOR I=1 TO LEN(N$)
SELECT CASE N$(I:I)
CASE "0"
DRAW ZERO WITH SCALE(SC)*SHIFT(X,Y)
CASE "1"
DRAW ONE WITH SCALE(SC)*SHIFT(X,Y)
CASE "2"
DRAW TWO WITH SCALE(SC)*SHIFT(X,Y)
CASE "3"
DRAW THREE WITH SCALE(SC)*SHIFT(X,Y)
CASE "4"
DRAW FOUR WITH SCALE(SC)*SHIFT(X,Y)
CASE "5"
DRAW FIVE WITH SCALE(SC)*SHIFT(X,Y)
CASE "6"
DRAW SIX WITH SCALE(SC)*SHIFT(X,Y)
CASE "7"
DRAW SEVEN WITH SCALE(SC)*SHIFT(X,Y)
CASE "8"
DRAW EIGHT WITH SCALE(SC)*SHIFT(X,Y)
CASE "9"
DRAW NINE WITH SCALE(SC)*SHIFT(X,Y)
CASE "-"
DRAW MINUS WITH SCALE(SC)*SHIFT(X,Y)
CASE "+"
DRAW PLUS WITH SCALE(SC)*SHIFT(X,Y)
CASE "="
DRAW EQUAL WITH SCALE(SC)*SHIFT(X,Y)
END SELECT
LET X=X+XSIZE*SC
NEXT I
END SUB
EXTERNAL PICTURE ZERO
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE0
END PICTURE
EXTERNAL PICTURE ONE
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE1
END PICTURE
EXTERNAL PICTURE TWO
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE2
END PICTURE
EXTERNAL PICTURE THREE
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE3
END PICTURE
EXTERNAL PICTURE FOUR
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE4
END PICTURE
EXTERNAL PICTURE FIVE
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE5
END PICTURE
EXTERNAL PICTURE SIX
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE6
END PICTURE
EXTERNAL PICTURE SEVEN
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE7
END PICTURE
EXTERNAL PICTURE EIGHT
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE8
END PICTURE
EXTERNAL PICTURE NINE
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE9
END PICTURE
EXTERNAL PICTURE EQUAL
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE10
END PICTURE
EXTERNAL PICTURE PLUS
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE11
END PICTURE
EXTERNAL PICTURE MINUS
MAT PLOT CELLS, IN 0,0;XSIZE-1,YSIZE-1:IMAGE12
END PICTURE
EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
!SET COLOR MIX(0) 0,0,0
SET COLOR MODE "NATIVE"
CLEAR
SET POINT STYLE 1
SET WINDOW 0,XSIZE-1,YSIZE-1,0
END SUB
EXTERNAL SUB PICTURELOAD(N$,XSIZE,YSIZE)
SET COLOR MODE "NATIVE"
CLEAR
SET POINT STYLE 1
IF N$="" THEN STOP
GLOAD N$
LET XSIZE=PIXELX(1)+1
LET YSIZE=PIXELY(1)+1
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,YSIZE-1,0
END SUB