十進BASIC 第2掲示板過去ログ2014


Re: 質問

 投稿者:白石和夫  投稿日:2014年 1月 8日(水)18時02分6秒
  > No.3293[元記事へ]

喜多さんへのお返事です。

最新版で,通常のプログラムの実行はできますか?
たとえば,ver. 0.5.5.5で読み込んだサンプルプログラムを最新版にコピー&ペーストして実行するようなことは可能ですか?
特に,浮動小数点例外を利用するプログラム,COMPLEX\MANDELBL.BASなどは実行可能でしょうか?



> 白石和夫さんへのお返事です。
>
> > invalid floating point operationになるということなので,FPU例外の割り込みを禁止した状態でファイルダイアログを動かさないといけないように変更されたのかもしれません。
> >
> > Ver.0.5.5.5,Ver.0.4.9.4ではどうでしょうか。
> > もし,こちらの版でファイルダイアログが正しく動作するようなら,プログラム実行時以外FPU例外を抑止した版を作ります。
> >
>
>  Ver.0.5.5.5でファイル開いたり保存することができました。
>
>
 

Re: 質問

 投稿者:喜多  投稿日:2014年 1月 8日(水)19時31分15秒
  > No.3294[元記事へ]

白石和夫さんへのお返事です。

> 最新版で,通常のプログラムの実行はできますか?
> たとえば,ver. 0.5.5.5で読み込んだサンプルプログラムを最新版にコピー&ペーストして実行するようなことは可能ですか?
> 特に,浮動小数点例外を利用するプログラム,COMPLEX\MANDELBL.BASなどは実行可能でしょうか?

はい、実行できました!
 

Re: 質問

 投稿者:白石和夫  投稿日:2014年 1月 9日(木)08時24分18秒
  > No.3295[元記事へ]

実行は可能であれば,実行時のみFPU割り込みフラッグを有効にすることで対処可能と思います。
完成したときには,また,協力をお願いします。
 

Re: 質問

 投稿者:喜多  投稿日:2014年 1月 9日(木)13時37分14秒
  > No.3296[元記事へ]

白石和夫さんへのお返事です。

> 実行は可能であれば,実行時のみFPU割り込みフラッグを有効にすることで対処可能と思います。
> 完成したときには,また,協力をお願いします。
>

ご丁寧な対応ありがとうございます。完成したときにまた協力させていただきます。
 

Re: 質問

 投稿者:白石和夫  投稿日:2014年 1月10日(金)15時34分51秒
  > No.3296[元記事へ]

Ver. 0.6.3.4で実行時にのみ浮動小数点例外割り込みを許可するように変更しました。
これだとどうでしょうか。
プログラム実行中にOSの機能を利用する部分もあるので,それらの動作について不安があります。
不具合があれば,お知らせください。
(この版はMac版のみです)
 

Re: 中学生プログラミングコンテスト

 投稿者:山中和義  投稿日:2014年 1月12日(日)13時36分51秒
  > No.3279[元記事へ]

つづき

>  福島工業高等専門学校 情報処理教育センター
>  http://www.fukushima-nct.ac.jp/information/htdocs/index.php?page_id=25

> 予想問題


問題
1673×4649を計算せよ。

答え

ロシア農夫式乗算法、エジプト人のかけ算(2進法の筆算)

             11010001001      1673
       ×  1001000101001      4649
      -------------------
             11010001001      1673=1673×2^0
          11010001001        13384=1673×2^3
        11010001001          53536=1673×2^5
    11010001001             856576=1673×2^9
 11010001001               6852608=1673×2^12
 -----------------------
 11101101010110111110001   7777777


LET A=1673
LET B=4649
LET S=0
DO WHILE B>0
   IF MOD(B,2)=1 THEN LET S=S+A
   LET A=A*2
   LET B=INT(B/2)
LOOP
PRINT S
END



-------------------------------------------

問題
1次式の積 (Ax+B)(Cx+D)=ACx^2+(AD+BC)x+BD において、
各係数を求めるのに、AC,AD,BC,BDと乗算を4回行っている。
これを、(A+B)(C+D)=AC+AD+BC+BD を用いて、
AD+BC=(A+B)(C+D)-AC-BD と求めると、3回の乗算で済む。

これを利用して、1673×4649 の値は、

 x=100として、Ax+B=1673、Cx+D=4649 なので、
 A=16,B=73
 C=46,D=49

 A+B=16+73=89
 C+D=46+49=95
 AC=16*46=736
 BD=73*49=3577
 AD+BC=89*95-736-3577=4142

  7360000
   414200
 +    3577
 -----------
  7777777

と計算できる。(karatsuba法)

プログラムで確認してください。

答え

LET X=100 !100進法

LET P=1673 !2桁
LET Q=4649

LET A=INT(P/X)
LET B=MOD(P,X)
LET C=INT(Q/X)
LET D=MOD(Q,X)
PRINT A;B;C;D

LET AC=A*C
LET BD=B*D
PRINT (AC*X+((A+B)*(C+D)-AC-BD))*X+BD

PRINT X*Y !検算

END



-------------------------------------------

問題
13日の金曜日はいくつありますか。

答え

グレゴリオ暦では、400年で暦がひと回りする。
400年×365日+97日(閏日)は、7で割り切れる。 146097=7×20871

DIM W(0 TO 7-1)
MAT W=ZER
LET Y0=1900
FOR Y=Y0 TO Y0+400-1
   FOR M=1 TO 12
      LET T=DayOfWeek(Y,M,13)
      LET W(T)=W(T)+1
   NEXT M
NEXT Y
MAT PRINT W;
PRINT DayOfWeek(1900,1,1)
END

EXTERNAL FUNCTION DayOfWeek(y,m,d) !西暦y年m月d日の曜日 ※0なら日曜日、1なら月曜日、2なら火曜日、……、6なら土曜日
IF m<3 THEN
   LET y=y-1 !y年1,2月をy-1年13,14月へ
   LET m=m+12
END IF
LET  DayOfWeek=MOD(y+INT(y/4)-INT(y/100)+INT(y/400)+INT((13*m+8)/5)+d,7) !ツェラー(Zeller)の公式 1582年10月15日(金)以降
END FUNCTION

 

Re: 質問

 投稿者:喜多  投稿日:2014年 1月12日(日)17時36分6秒
  > No.3298[元記事へ]

白石和夫さんへのお返事です。

> Ver. 0.6.3.4で実行時にのみ浮動小数点例外割り込みを許可するように変更しました。
> これだとどうでしょうか。
> プログラム実行中にOSの機能を利用する部分もあるので,それらの動作について不安があります。
> 不具合があれば,お知らせください。
> (この版はMac版のみです)
>

Ver. 0.6.3.4ダウンロードしてみました。
プログラムの実行はできるのですが, ファイルの保存ができないみたいです。
 

Re: 質問

 投稿者:白石和夫  投稿日:2014年 1月12日(日)17時43分15秒
  > No.3300[元記事へ]

保存するとき,どの時点で
invalid floating point operation
がでますか?(メニューをクリックしてすぐ,ファイル名を入力するとき,ファイル名を指定した後など)
保存できないときでも読み込みはできるのですか?
保存できないとき,他に問題個所はありませんか?
実行しなくても保存できないのですか?
 

Re: 質問

 投稿者:喜多  投稿日:2014年 1月13日(月)23時03分36秒
  > No.3301[元記事へ]

白石和夫さんへのお返事です。

> 保存するとき,どの時点で
> invalid floating point operation
> がでますか?(メニューをクリックしてすぐ,ファイル名を入力するとき,ファイル名を指定した後など)
> 保存できないときでも読み込みはできるのですか?
> 保存できないとき,他に問題個所はありませんか?
> 実行しなくても保存できないのですか?

ファイルの保存や読み込みは「save」「open」を押すとすぐにinvalid floating point operationがでます。
 

Re: 質問

 投稿者:白石和夫  投稿日:2014年 1月14日(火)07時58分20秒
  > No.3302[元記事へ]

> ファイルの保存や読み込みは「save」「open」を押すとすぐにinvalid floating point operationがでます。

プログラム実行後に

「開く」
「末尾に追加読込」
「名前を付けて保存」
でinvalid floating point operationが出て,

「新規」
「保存」(開くメニューで名前のあるプログラムを読み込んで実行後)
オプション-文法
オプション-数値
オプション-フォント
表示-テキスト
表示-グラフィックス
などでは問題はない

と想定したのですが,どうでしょうか?
 

Re: 質問

 投稿者:喜多  投稿日:2014年 1月14日(火)14時40分28秒
  > No.3303[元記事へ]

白石和夫さんへのお返事です。

プログラム実行後だと
「開く」
「保存」
「名前を付けて保存」
は正常に動作しましたが
「末尾に追加読込」
でaccess violationと表示されます。


「新規」
「保存」(開くメニューで名前のあるプログラムを読み込んで実行後)
オプション-文法
オプション-数値
オプション-フォント
表示-テキスト
表示-グラフィックス
は問題ないみたいです。
 

Re: 質問

 投稿者:白石和夫  投稿日:2014年 1月14日(火)20時58分3秒
  > No.3304[元記事へ]

> プログラム実行後だと
> 「開く」
> 「保存」
>  「名前を付けて保存」
> は正常に動作しましたが
> 「末尾に追加読込」
> でaccess violationと表示されます。
>
>
> 「新規」
> 「保存」(開くメニューで名前のあるプログラムを読み込んで実行後)
>  オプション-文法
>  オプション-数値
>  オプション-フォント
>  表示-テキスト
>  表示-グラフィックス
>  は問題ないみたいです。

レポートありがとうございました。
「末尾に追加読込」でaccess violationになるのは,
OS10.9の非互換ではなくて,ソースファイルの更新忘れが原因でした。
もう一件,OS Xの開発ツールのバグ回避ミスが見つかりました。
早々に修正版を作成します。
 

Re: 質問

 投稿者:白石 和夫  投稿日:2014年 1月15日(水)08時59分40秒
  > No.3304[元記事へ]

ツールバーのアイコンでOpen,Saveを選ぶとエラーになるけれど,
ファイルメニューから「開く」,「保存」を選ぶと正常に動作するのでしょうか。
その場合,ツールバーの他のアイコンは正常に機能するのでしょうか?
 

数値組込み関数の桁あふれ

 投稿者:idx  投稿日:2014年 1月16日(木)14時35分14秒
  REM 部分荷重下の単純支持板の中央のたわみ
REM 「板とシェルの理論」130頁143式 参照
REM  a:板のx方向の幅
REM  b:板のy方向の長さ
REM  u:荷重のx方向の幅
REM  v:荷重のy方向の長さ
REM  q:単位面積当たりの荷重(kN/cm^2)
REM  t:板厚
REM  mu:ポアソン比(0.3)
REM  E:縦弾性係数 20500(kN/cm^2)

INPUT PROMPT "a(cm) =":a
INPUT PROMPT "b(cm) =":b
INPUT PROMPT "u(cm) =":u
INPUT PROMPT "v(cm) =":v
INPUT PROMPT "t(cm) =":t
INPUT PROMPT "q(kN/cm^2) =":q

LET mu=0.3
LET E=20500
LET D=E*t^3/12/(1-mu^3)
LET GS=0
FOR M=1 TO 1000 '100回程度ならOK
   IF MOD(M ,2) = 0 THEN GOTO 10

   LET AM=M*PI*b/2/a
   LET GM=M*PI*v/4/a
   LET s=1/M^5*SIN(M*PI*u/2/a)*(1-1/COSH(AM)*(COSH(AM-2*GM)+GM*SINH(AM-2*GM)+AM*SINH(2*GM)/2/COSH(AM)))
   LET GS=GS+S
10 NEXT M
   LET W=GS*4*q*a^4/d/PI^5
   PRINT "Sigma=";GS
   PRINT "w(cm)=";W



END
 

Re: 質問

 投稿者:喜多  投稿日:2014年 1月20日(月)17時53分31秒
  > No.3306[元記事へ]

白石 和夫さんへのお返事です。

> ツールバーのアイコンでOpen,Saveを選ぶとエラーになるけれど,
> ファイルメニューから「開く」,「保存」を選ぶと正常に動作するのでしょうか。
> その場合,ツールバーの他のアイコンは正常に機能するのでしょうか?
>

返信が遅くなってしまい大変申し訳ございません。
プログラムを実行せずにファイルメニューの『開く』『保存』やツールバーのopen, saveを選ぶとエラーになるけれど, プログラム実行後だとどちらも正常に動作するという意味でした。その他のアイコンも正常に機能しました。

ver0.6.3.5だとプログラム実行後でなくともファイルメニューの『開く』『保存』やツールバーのopen, saveが正常に機能しました。
お手数かけてしまい申し訳ないです。BASICが使えるようになって大変助かりました。ありがとうございます。
 

Re: 質問

 投稿者:白石和夫  投稿日:2014年 1月20日(月)20時59分17秒
  > No.3308[元記事へ]

ご報告ありがとうございました。安心しました。
また,何か気づいたことがありましたら,お知らせください。
 

奇妙な数

 投稿者:山中和義  投稿日:2014年 1月22日(水)11時41分38秒
  たとえば、
 1^2      + 5^2      + 6^2      = 2^2      + 3^2      + 7^2
 12^2     + 56^2     + 64^2     = 24^2     + 32^2     + 76^2
 123^2    + 561^2    + 642^2    = 242^2    + 323^2    + 761^2
 1237^2   + 5619^2   + 6428^2   = 2428^2   + 3237^2   + 7619^2
 12378^2  + 56194^2  + 64286^2  = 24286^2  + 32378^2  + 76194^2
 123789^2 + 561945^2 + 642864^2 = 242868^2 + 323787^2 + 761943^2
  23789^2 +  61945^2 +  42864^2 =  42868^2 +  23787^2 +  61943^2
   3789^2 +   1945^2 +   2864^2 =   2868^2 +   3787^2 +   1943^2
    789^2 +    945^2 +    864^2 =    868^2 +    787^2 +    943^2
     89^2 +     45^2 +     64^2 =     68^2 +     87^2 +     43^2
      9^2 +      5^2 +      4^2 =      8^2 +      7^2 +      3^2

   19^2   +   55^2   +   64^2   =   28^2   +   37^2   +   73^2
  1289^2  +  5645^2  +  6464^2  =  2468^2  +  3287^2  +  7643^2
 123789^2 + 561945^2 + 642864^2 = 242868^2 + 323787^2 + 761943^2
  2378^2  +  6194^2  +  4286^2  =  4286^2  +  2378^2  +  6194^2
   37^2   +   19^2   +   28^2   =   28^2   +   37^2   +   19^2
となる数が存在する。(ちなみに、1乗でも成り立つ)

一般に、
 (X-(A+B))^2+(X+A)^2+(X+B)^2=(X-B)^2+(X-A)^2+(X+(A+B))^2
とすればよい。


まず、a^2+b^2+c^2=d^2+e^2+f^2を満たす1桁の場合は、
  a  b  c   d  e  f
 -------------------
  1  4  9   3  5  8  *1乗のときは成り立たない
  1  5  6   2  3  7
  1  6  8   2  4  9
  2  3  8   4  5  6  *
  2  6  7   3  4  8
  3  7  8   4  5  9
である。

その中から、
  1  5  6   2  3  7
  3  7  8   4  5  9
を選び、6桁の数に着目して、1≦A<Bのすると、

  X-(A+B)  X+A      X+B      X-B      X-A      X+(A+B) ※2乗の記号は省く
 ------------------------------------------------------
  1      + 5      + 6      = 2      + 3      + 7
  1?     + 5?     + 6?     = 2?     + 3?     + 7?
  1??    + 5??    + 6??    = 2??    + 3??    + 7??
  1???   + 5???   + 6???   = 2???   + 3???   + 7???
  1????  + 5????  + 6????  = 2????  + 3????  + 7????
  1????9 + 5????5 + 6????4 = 2????8 + 3????7 + 7????3
   ????9 +  ????5 +  ????4 =  ????8 +  ????7 +  ????3
    ???9 +   ???5 +   ???4 =   ???8 +   ???7 +   ???3
     ??9 +    ??5 +    ??4 =    ??8 +    ??7 +    ??3
      ?9 +     ?5 +     ?4 =     ?8 +     ?7 +     ?3
       9 +      5 +      4 =      8 +      7 +      3
を考える。

ここで、検索時間が短縮になるように、
左辺の一番小さい数 X-(A+B) (6つの数の中で一番小さい)を、123789とする。
左辺の一番大きい数 X+B を、642864とする。

したがって、
 1      + 5      + 6      = 2      + 3      + 7
 12     + 5?     + 64     = 2?     + 3?     + 7?
 123    + 5??    + 642    = 2??    + 3??    + 7??
 1237   + 5???   + 6428   = 2???   + 3???   + 7???
 12378  + 5????  + 64286  = 2????  + 3????  + 7????
 123789 + 5????5 + 642864 = 2????8 + 3????7 + 7????3
  23789 +  ????5 +  42864 =  ????8 +  ????7 +  ????3
   3789 +   ???5 +   2864 =   ???8 +   ???7 +   ???3
    789 +    ??5 +    864 =    ??8 +    ??7 +    ??3
     89 +     ?5 +     64 =     ?8 +     ?7 +     ?3
      9 +      5 +      4 =      8 +      7 +      3
となる。

左辺の 5????5 の????を、1111から9999まで変化させて、Xを求める。
このとき、次のことに注意する。
・桁をひとつずつ消して、桁がひとつずつ減るので、0を含まない。
・左辺の和が3の倍数になる。

このXから、右辺の数が確定するので、その6つの数で。
桁をひとつずつ消して、条件を満たすものを洗い出せばよい。



PUBLIC NUMERIC K !桁数
LET K=6

LET P=123789 !X-(A+B)
LET R=642864 !X+B

LET S=0

FOR QQ=(10^(K-2)-1)/9 TO 10^(K-2)-1 !X+A
   IF POS(STR$(QQ),"0")>0 THEN !0を除く
   ELSE
      LET Q=(5*10^(K-2)+QQ)*10+5

      LET X=(P+Q+R)/3
      IF X=INT(X) THEN !和が3の倍数

         LET D=2*X-R !右辺 X-B
         IF POS(STR$(D),"0")>0 THEN
         ELSE
            IF INT(D/10^(K-1))=2 AND MOD(D,10)=8 THEN

               LET E=2*X-Q !右辺 X-A
               IF POS(STR$(E),"0")>0 THEN
               ELSE
                  IF INT(E/10^(K-1))=3 AND MOD(E,10)=7 THEN

                     LET F=2*X-P !右辺 X+(A+B)
                     IF POS(STR$(F),"0")>0 THEN
                     ELSE
                        IF INT(F/10^(K-1))=7 AND MOD(F,10)=3 THEN
                        !!!PRINT P;Q;R; D;E;F !debug

                           CALL chk(P,Q,R,D,E,F, rc)
                           IF rc<>0 THEN !条件を満たす
                              LET S=S+1
                              PRINT P;Q;R; D;E;F
                           END IF

                        END IF !f
                     END IF

                  END IF !e
               END IF

            END IF !d
         END IF

      END IF !3の倍数

   END IF !q
NEXT QQ

PRINT S;"通り"

END


EXTERNAL SUB chk(P,Q,R,D,E,F, rc) !条件を満たすかどうか確認する
LET rc=0
FOR i=1 TO K !最上位の桁を消す
   LET T=10^i
   IF MOD(P,T)^2+MOD(Q,T)^2+MOD(R,T)^2<>MOD(D,T)^2+MOD(E,T)^2+MOD(F,T)^2 THEN EXIT FOR
NEXT i
IF i>K THEN

   FOR i=1 TO K-1 !一の位の桁を消す
      LET T=10^i
      IF INT(P/T)^2+INT(Q/T)^2+INT(R/T)^2<>INT(D/T)^2+INT(E/T)^2+INT(F/T)^2 THEN EXIT FOR
   NEXT i
   IF i>K-1 THEN

      LET W=INT((K-1)/2)
      FOR i=1 TO W !最上位と一の位の桁を消す
         LET T=10^i
         LET TT=10^(K-i)
         IF INT(MOD(P,TT)/T)^2+INT(MOD(Q,TT)/T)^2+INT(MOD(R,TT)/T)^2 <> &
&           INT(MOD(D,TT)/T)^2+INT(MOD(E,TT)/T)^2+INT(MOD(F,TT)/T)^2 THEN EXIT FOR
      NEXT i
      IF i>W THEN

         LET W=INT((K-1)/2)
         FOR i=1 TO W !最上位と一の位の桁を残す
            LET T=10^(INT(K/2)-i)
            LET TT=10^(INT(K/2)+i)
            IF (INT(P/TT)*T+MOD(P,T))^2+(INT(Q/TT)*T+MOD(Q,T))^2+(INT(R/TT)*T+MOD(R,T))^2 <> &
&              (INT(D/TT)*T+MOD(D,T))^2+(INT(E/TT)*T+MOD(E,T))^2+(INT(F/TT)*T+MOD(F,T))^2 THEN EXIT FOR
         NEXT i
         IF i>W THEN
            LET rc=1 !OK
         END IF

      END IF

   END IF

END IF
END SUB


実行結果

123789  531315  642864  222448  333997  741523
123789  531345  642864  222468  333987  741543
123789  531375  642864  222488  333977  741563
123789  531615  642864  222648  333897  741723
123789  531645  642864  222668  333887  741743
123789  531675  642864  222688  333877  741763
123789  531915  642864  222848  333797  741923
123789  531945  642864  222868  333787  741943
123789  531975  642864  222888  333777  741963
123789  534315  642864  224448  332997  743523
123789  534345  642864  224468  332987  743543
123789  534375  642864  224488  332977  743563
123789  534615  642864  224648  332897  743723
123789  534645  642864  224668  332887  743743
123789  534675  642864  224688  332877  743763
123789  534915  642864  224848  332797  743923
123789  534945  642864  224868  332787  743943
123789  534975  642864  224888  332777  743963
123789  537315  642864  226448  331997  745523
123789  537345  642864  226468  331987  745543
123789  537375  642864  226488  331977  745563
123789  537615  642864  226648  331897  745723
123789  537645  642864  226668  331887  745743
123789  537675  642864  226688  331877  745763
123789  537915  642864  226848  331797  745923
123789  537945  642864  226868  331787  745943
123789  537975  642864  226888  331777  745963
123789  561315  642864  242448  323997  761523
123789  561345  642864  242468  323987  761543
123789  561375  642864  242488  323977  761563
123789  561615  642864  242648  323897  761723
123789  561645  642864  242668  323887  761743
123789  561675  642864  242688  323877  761763
123789  561915  642864  242848  323797  761923
123789  561945  642864  242868  323787  761943    ←←←
123789  561975  642864  242888  323777  761963
123789  564315  642864  244448  322997  763523
123789  564345  642864  244468  322987  763543
123789  564375  642864  244488  322977  763563
123789  564615  642864  244648  322897  763723
123789  564645  642864  244668  322887  763743
123789  564675  642864  244688  322877  763763
123789  564915  642864  244848  322797  763923
123789  564945  642864  244868  322787  763943
123789  564975  642864  244888  322777  763963
123789  567315  642864  246448  321997  765523
123789  567345  642864  246468  321987  765543    ←←← 並びがきれい
123789  567375  642864  246488  321977  765563
123789  567615  642864  246648  321897  765723
123789  567645  642864  246668  321887  765743
123789  567675  642864  246688  321877  765763
123789  567915  642864  246848  321797  765923
123789  567945  642864  246868  321787  765943
123789  567975  642864  246888  321777  765963
123789  591315  642864  262448  313997  781523
123789  591345  642864  262468  313987  781543
123789  591375  642864  262488  313977  781563
123789  591615  642864  262648  313897  781723
123789  591645  642864  262668  313887  781743
123789  591675  642864  262688  313877  781763
123789  591915  642864  262848  313797  781923
123789  591945  642864  262868  313787  781943
123789  591975  642864  262888  313777  781963
123789  594315  642864  264448  312997  783523
123789  594345  642864  264468  312987  783543
123789  594375  642864  264488  312977  783563
123789  594615  642864  264648  312897  783723
123789  594645  642864  264668  312887  783743
123789  594675  642864  264688  312877  783763
123789  594915  642864  264848  312797  783923
123789  594945  642864  264868  312787  783943
123789  594975  642864  264888  312777  783963
123789  597315  642864  266448  311997  785523
123789  597345  642864  266468  311987  785543
123789  597375  642864  266488  311977  785563
123789  597615  642864  266648  311897  785723
123789  597645  642864  266668  311887  785743
123789  597675  642864  266688  311877  785763
123789  597915  642864  266848  311797  785923
123789  597945  642864  266868  311787  785943
123789  597975  642864  266888  311777  785963
81 通り


 

不思議な数

 投稿者:山中和義  投稿日:2014年 1月26日(日)10時03分0秒
  12345679は不思議な数である。

まず、
12345679 ×  0 = 000000000

k=0,1,2,3,4,5,6,7,8とする。
m=9k+9のとき、
 12345679 ×  9 = 111111111
 12345679 × 18 = 222222222
 12345679 × 27 = 333333333
 12345679 × 36 = 444444444
 12345679 × 45 = 555555555
 12345679 × 54 = 666666666
 12345679 × 63 = 777777777
 12345679 × 72 = 888888888
 12345679 × 81 = 999999999

考察
12345679 × 9 = 12345679 × (10-1) = 123456790 - 12345679 = 111111111 が成り立つので、
12345679 × 18 = (12345679×9) × 2 = 111111111 × 2 = 222222222
12345679 × 27 = (12345679×9) × 3 = 111111111 × 3 = 333333333
12345679 × 36 = (12345679×9) × 4 = 111111111 × 4 = 444444444
 :
 :(同様に)
(終り)


次に、

> 12345679を14倍すると、172839506で、4以外の0~9の数字がすべて出現している。
> これは、3の倍数を除いた80までの自然数倍で見られる現象である。

実際に計算してみよう。

m=9k+1のとき、
 12345679 ×  1 =  12345679  8がない
 12345679 × 10 = 123456790
 12345679 × 19 = 234567901
 12345679 × 28 = 345679012
 12345679 × 37 = 456790123
 12345679 × 46 = 567901234
 12345679 × 55 = 679012345
 12345679 × 64 = 790123456
 12345679 × 73 = 901234567

m=9k+2のとき、
 12345679 ×  2 =  24691358  7がない
 12345679 × 11 = 135802469
 12345679 × 20 = 246913580
 12345679 × 29 = 358024691
 12345679 × 38 = 469135802
 12345679 × 47 = 580246913
 12345679 × 56 = 691358024
 12345679 × 65 = 802469135
 12345679 × 74 = 913580246

m=9k+4のとき、
 12345679 ×  4 =  49382716  5がない
 12345679 × 13 = 160493827
 12345679 × 22 = 271604938
 12345679 × 31 = 382716049
 12345679 × 40 = 493827160
 12345679 × 49 = 604938271
 12345679 × 58 = 716049382
 12345679 × 67 = 827160493
 12345679 × 76 = 938271604

m=9k+5のとき、
 12345679 ×  5 =  61728395  4がない
 12345679 × 14 = 172839506
 12345679 × 23 = 283950617
 12345679 × 32 = 395061728
 12345679 × 41 = 506172839
 12345679 × 50 = 617283950
 12345679 × 59 = 728395061
 12345679 × 68 = 839506172
 12345679 × 77 = 950617283

m=9k+7のとき、
 12345679 ×  7 =  86419753  2がない
 12345679 × 16 = 197530864
 12345679 × 25 = 308641975
 12345679 × 34 = 419753086
 12345679 × 43 = 530864197
 12345679 × 52 = 641975308
 12345679 × 61 = 753086419
 12345679 × 70 = 864197530
 12345679 × 79 = 975308641

m=9k+8のとき、
 12345679 ×  8 =  98765432  1がない
 12345679 × 17 = 209876543
 12345679 × 26 = 320987654
 12345679 × 35 = 432098765
 12345679 × 44 = 543209876
 12345679 × 53 = 654320987
 12345679 × 62 = 765432098
 12345679 × 71 = 876543209
 12345679 × 80 = 987654320


考察
たとえば、m=9k+2のとき、
『12345679 ×11 = 135802469 7がない』について
12345679×11 = 12345679×9 + 12345679×2 = 111111111 + 024691358 より、
各桁に、1を加えるので、
0→1、1→2、2→3、3→4、4→5、5→6、6→7、7→8、8→9、9→10(9→0)と巡回する。
9の前(ひとつ上の位)が6から、9→10の繰り上がりを考慮すると、6→8となり、7がなくなる。
024691358に7がないので、8はひとつとなる。

『12345679 × 20 = 246913580 7がない』について
12345679×20 = 12345679×9 + 12345679×11 = 111111111 + 135802469 として、
上記と同様な議論を行う。

『12345679 × 29 = 358024691 7がない』について
12345679×29 = 12345679×9 + 12345679×20 = 111111111 + 246913580 として、
上記と同様な議論を行う。

 :
 :(同様に)


以上から、
 12345679 × 9 = 111111111
と
 12345679 × 1 = 12345679  8がない
 12345679 × 2 = 24691358  7がない
 12345679 × 4 = 49382716  5がない
 12345679 × 5 = 61728395  4がない
 12345679 × 7 = 86419753  2がない
 12345679 × 8 = 98765432  1がない
から議論できる。


また、9の前(ひとつ上の位)の数をaとすると、『(a+1)がない』となる。
(終り)


LET n=12345679
FOR a=1 TO 9
   PRINT "m=9k+";STR$(a)
   FOR k=0 TO 8
      LET m=9*k+a
      PRINT USING "######## × ## = #########": n,m,n*m
   NEXT k
   PRINT
NEXT a
END

 

Re: 不思議な数

 投稿者:山中和義  投稿日:2014年 1月27日(月)11時30分58秒
  > No.3311[元記事へ]

123456789は不思議な数である。


まず、

k=0,1,2,3,4,5,6,7,8,9とする。
m=9k+9のとき、
 123456789 ×  9 =  1111111101
 123456789 × 18 =  2222222202
 123456789 × 27 =  3333333303
 123456789 × 36 =  4444444404
 123456789 × 45 =  5555555505
 123456789 × 54 =  6666666606
 123456789 × 63 =  7777777707
 123456789 × 72 =  8888888808
 123456789 × 81 =  9999999909
 123456789 × 90 = 11111111010

考察
123456789 × 9 = 123456789 × (10-1) = 1234567890 - 123456789 = 1111111101 が成り立つことより
(終り)


次に、

> 123456789 に3の倍数でない2桁の数(ただし、10の位の数と1の位の数の和が8以下)をかけると、
> 0123456789を並べ変えた数になる。このことを証明(説明)せよ。

実際に計算してみよう。

m=9k+1のとき、
123456789 ×  1 =   123456789
123456789 × 10 =  1234567890

m=9k+2のとき、
123456789 ×  2 =   246913578
123456789 × 11 =  1358024679
123456789 × 20 =  2469135780

m=9k+4のとき、
123456789 ×  4 =   493827156
123456789 × 13 =  1604938257
123456789 × 22 =  2716049358
123456789 × 31 =  3827160459
123456789 × 40 =  4938271560

m=9k+5のとき、
123456789 ×  5 =   617283945
123456789 × 14 =  1728395046
123456789 × 23 =  2839506147
123456789 × 32 =  3950617248
123456789 × 41 =  5061728349
123456789 × 50 =  6172839450

m=9k+7のとき、
123456789 ×  7 =   864197523
123456789 × 16 =  1975308624
123456789 × 25 =  3086419725
123456789 × 34 =  4197530826
123456789 × 43 =  5308641927
123456789 × 52 =  6419753028
123456789 × 61 =  7530864129
123456789 × 70 =  8641975230

m=9k+8のとき、
123456789 ×  8 =   987654312
123456789 × 17 =  2098765413
123456789 × 26 =  3209876514
123456789 × 35 =  4320987615
123456789 × 44 =  5432098716
123456789 × 53 =  6543209817
123456789 × 62 =  7654320918
123456789 × 71 =  8765432019
123456789 × 80 =  9876543120


考察
たとえば、m=9k+7のとき、
『123456789 × 16 =  1975308624』について
123456789×11 = 123456789×9 + 123456789×2 = 1111111101 + 864197523 より、
各桁に、1を加えるので、
0→1、1→2、2→3、3→4、4→5、5→6、6→7、7→8、8→9、9→10(9→0)と巡回する。
9の前(ひとつ上の位)が1から、9→10の繰り上がりを考慮すると、1→3となり、2がなくなる。
十の位の2は、0を加えるので2のままである。
よって、0→1、1→3、2→2、3→4、4→5、5→6、6→7、7→8、8→9、9→10(9→0)と巡回する。

『123456789 × 25 =  3086419725』について
123456789×25 = 123456789×9 + 123456789×16 = 1111111101 + 1975308624 として、
上記と同様な議論を行う。

また、k=7すなわちm=70の場合は、一巡したことになる。
(終り)


LET n=123456789
FOR a=1 TO 9
   IF a=3 OR a=6 THEN
   ELSE
      PRINT "m=9k+";STR$(a)
      FOR k=0 TO a
         LET m=9*k+a
         PRINT USING "######### × ## = ###########": n,m,n*m
      NEXT k
      PRINT
   END IF
NEXT a
END

 

階段の上り方

 投稿者:山中和義  投稿日:2014年 1月31日(金)09時41分9秒
  参考サイト http://www.nichinoken.co.jp/column/essay/sansu/2007_m07.html

問題
7段の階段を登るとき、「1段ずつ登る」、「1段とばしで登る」の2つの登り方があります。
1番下から1番上まで登るとき、「1段ずつ登る」「1段とばしで登る」を混ぜて登ってもよいとします。
このとき、次の問いに答えなさい。
(1) 登り方は何通りありますか。
(2) 5段目に必ず止まる登り方は何通りありますか。
(2001年 日大豊山中)

その1 漸化式

LET N=7 !段数 ※N≧1
LET A0=1
LET A1=1
FOR i=2 TO N
   LET A2=A1+A0
   LET A0=A1 !次へ
   LET A1=A2
NEXT i
PRINT A1;"通り"
END


その2 並べる

DEF ReptCOMB(N,R)=COMB(N+R-1,R) !重複組合せ
LET N=7 !段数
LET C=0 !場合の数
LET C1=0
LET C2=0
FOR Y=0 TO INT(N/2) !不定方程式を解く
   LET X=N-2*Y
   LET C=C+ReptCOMB(X+1,Y)
   LET C1=C1+FACT(X+Y)/(FACT(X)*FACT(Y)) !別解
   LET C2=C2+COMB(X+Y,Y) !別解
NEXT Y
PRINT C;"通り"
PRINT C1;"通り"
PRINT C2;"通り"
END



問題
1歩で1段または2段のいずれかで階段を昇るとき、
1歩で2段昇ることは連続しないものとすると、15段の階段を昇る昇り方は何通りあるか。
(2007年 京都大学前期数学[理系1問2])

その1 漸化式

LET N=15 !段数 ※N≧2
LET A0=1
LET A1=1
LET A2=2
FOR i=3 TO N
   LET A3=A2+A0
   LET A0=A1 !次へ
   LET A1=A2
   LET A2=A3
NEXT i
PRINT A2;"通り"
END


その2 並べる

LET N=15 !段数
LET C=0 !場合の数
FOR Y=0 TO INT(N/2) !不定方程式を解く
   LET X=N-2*Y
   LET C=C+COMB(X+1,Y)
NEXT Y
PRINT C;"通り"
END


その3 樹形図で考える

LET N=15 !段数
DIM A(0 TO N) !上り方
LET A(0)=0 !※番兵
PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(1,0, N,A)
END

EXTERNAL SUB try(P,S, N,A()) !バックトラック法で検索する
FOR i=1 TO 2
   IF i=2 AND i=A(P-1) THEN !1段とばしは連続しない
   ELSE
      LET A(P)=i !p歩目
      LET T=S+i
      IF T=N THEN !目的の段数へ到達したなら
         LET C=C+1
         PRINT "No."; C
         FOR K=1 TO P !結果を表示する
            PRINT A(K);
         NEXT K
         PRINT
      ELSEIF T<N THEN !次へ
         CALL try(P+1,T, N,A)
      END IF
   END IF
NEXT i
END SUB


 

input promptの実行時の、、、

 投稿者:小杉 崇夫  投稿日:2014年 2月 5日(水)18時52分8秒
  input promptの実行時の、ウィンドウの表示が、prompt文が、長いときに、ウィンドウが表示するときにはじめから、ウィンドウの表示を横に長くしている状態の設定できますか?
ウィンドウ表示後の、カーソルで、横に伸ばす事は出来るのですが、ウィンドウ表示前に、横幅を最初から、長く設定しておきたいのです。
takaoko2@gmail.comまで、回答ください。
 

Re: input promptの実行時の、、、

 投稿者:白石和夫  投稿日:2014年 2月 5日(水)20時02分59秒
  > No.3314[元記事へ]

JIS規格の範囲内には対応する命令は存在しません。
Windows版であれば,独自拡張関数のWinhandleの引数に"INPUT"を指定すれば
Win32 APIに渡すためのINPUTダイアログのハンドルが取得できるので,
Win32 APIを用いることで実現できるかもしれません(未確認)。

なお,メール等を利用した個別返答を求めるのはご遠慮ください。

 

Re: input promptの実行時の、、、

 投稿者:SECOND  投稿日:2014年 2月 7日(金)20時21分1秒
  > No.3314[元記事へ]

!インプット・ウィンドウの、左上位置(x0,y0)と、幅(xw,yw) ・・・縦幅は、規定寸? yw は無効。
!                                          x0, y0, xw, yw,
CALL SetWindowPos( WinHandle("INPUT" ),0, 100,300,700, 50, 0)

SUB SetWindowPos( handle,C2, x0,y0,xw,yw, nFLG)      !nFLG: 0=x0y0xwyw 1=x0y0 2=xwyw
   ASSIGN "user32.dll","SetWindowPos"
END SUB

SET ECHO "OFF"
INPUT PROMPT "メダルを何枚購入しますか?半角で入力(長文テスト)メダルを何枚購入しますか?半角で入力" :w$
PRINT w$

END
 

Re: 中学生プログラミングコンテスト

 投稿者:山中和義  投稿日:2014年 2月11日(火)10時48分38秒
  > No.3299[元記事へ]

つづき

>  福島工業高等専門学校 情報処理教育センター
>  http://www.fukushima-nct.ac.jp/information/htdocs/index.php?page_id=25
>
> 予想問題


問題
次の式を表示するプログラムをつくりなさい。
12345679 +         9 = 111111111
12345679 +        99 = 1222222221
12345679 +       999 = 12333333321
12345679 +      9999 = 123444444321
12345679 +     99999 = 1234555554321
12345679 +    999999 = 12345666654321
12345679 +   9999999 = 123456777654321
12345679 +  99999999 = 1234567887654321
12345679 + 999999999 = 12345678987654321

答え
OPTION ARITHMETIC RATIONAL !多桁の整数
LET A=12345679
FOR K=1 TO 9
   LET B=10^K-1 !数 999…
   PRINT USING "######## + ######### =": A,B;
   PRINT A*B
NEXT K
END


類題
次の式を表示するプログラムをつくりなさい。
         0 × 9 +  1 = 1
         1 × 9 +  2 = 11
        12 × 9 +  3 = 111
       123 × 9 +  4 = 1111
      1234 × 9 +  5 = 11111
     12345 × 9 +  6 = 111111
    123456 × 9 +  7 = 1111111
   1234567 × 9 +  8 = 11111111
  12345678 × 9 +  9 = 111111111
 123456789 × 9 + 10 = 1111111111

答え
たとえば、
     1234 × 9 +  5 =  11111
 +  11111 × 9 +  1 = 100000
 -----------------------------
    12345 × 9 +  6 = 111111
より、成り立つ。

たとえば、
   __123245678__
 9 ) ①11111111
      _9__
      ②1
     __18__
       ③1
      __27__
        ④1
       __36__
         ⑤1
        __45__
          ⑥1
         __54__
           ⑦1
          __63__
            ⑧1
           __72__
             ⑨
より、成り立つ。

LET K=9
FOR B=0 TO 9
   LET A=0
   FOR i=1 TO B !数 123…
      LET A=A*10+i
   NEXT i
   PRINT USING "######### × # + ## =": A,K,B+1;
   PRINT A*K+B+1
NEXT B
END


類題
次の式を表示するプログラムをつくりなさい。
        0 × 9 + 8 = 8
        9 × 9 + 7 = 88
       98 × 9 + 6 = 888
      987 × 9 + 5 = 8888
     9876 × 9 + 4 = 88888
    98765 × 9 + 3 = 888888
   987654 × 9 + 2 = 8888888
  9876543 × 9 + 1 = 88888888
 98765432 × 9 + 0 = 888888888

答え
たとえば、
 右辺の差に着目して、80000=81000-999-1=9000×9-111×9-1 なので、
      987 × 9 + 5 =  8888
     -111 × 9 - 1 = 80000
 +   9000 × 9
 ----------------------------
     9876 × 9 + 4 = 88888
より、成り立つ。

LET K=9
FOR B=0 TO 8
   LET A=0
   FOR i=1 TO B !数 987…
      LET A=A*10+(10-i)
   NEXT i
   PRINT USING "######### × # + # =": A,K,8-B;
   PRINT A*K+(8-B)
NEXT B
END


類題
次の式を表示するプログラムをつくりなさい。
         1 × 8 + 1 = 9
        12 × 8 + 2 = 98
       123 × 8 + 3 = 987
      1234 × 8 + 4 = 9876
     12345 × 8 + 5 = 98765
    123456 × 8 + 6 = 987654
   1234567 × 8 + 7 = 9876543
  12345678 × 8 + 8 = 98765432
 123456789 × 8 + 9 = 987654321

答え
たとえば、
 右辺の差に着目して、88889を変形すると、
     1234 × 8 + 4 =  9876
 +  11111 × 8 + 1 = 90000
                      -1111
 ---------------------------
    12345 × 8 + 5 = 98765
より、成り立つ。

LET K=8
FOR B=1 TO 9
   LET A=0
   FOR i=1 TO B !数 123…
      LET A=A*10+i
   NEXT i
   PRINT USING "######### × # + # =": A,K,B;
   PRINT A*K+B
NEXT B
END



-------------------------------------------
問題
次の足し算の結果はどちらが大きいか。
  123456789                 1
  123456780                21
  123456700               321
  123456000              4321
  123450000             54321
  123400000            654321
  123000000           7654321
  120000000          87654321
 + 100000000       + 987654321
 -------------     -------------

答え
各位で、
 9×1=1×9
 8×2=2×8
 7×3=3×7
 6×4=4×6
 5×5=5×5
より、同じになる。

LET A=123456789
LET S=0
FOR K=1 TO 9
   LET W=10^(K-1)
   LET S=S+INT(A/W)*W
   !!LET S=S+(A-MOD(A,W))
NEXT K
PRINT S

LET B=987654321
LET T=0
FOR K=1 TO 9
   LET T=T+MOD(B,10^K)
NEXT K
PRINT T

END

 

数値フーリェ逆変換

 投稿者:島村1243  投稿日:2014年 2月13日(木)18時56分46秒
  解析的にフーリェ変換した複素関数F(ω)を離散値の時間関数f(t)に戻すプログラム(IFFT)をお教えください。
例:F(ω)=1.021*(1/(0.01875+j*ω)-1/(5.01+j*ω))
表示時間の全幅:t=0~50[sec]
なお、上記F(ω)の元関数f(t)はf(t)=1.021*(exp(-0.01875*t)-exp(-5.01*t))です。
 

Re: 数値フーリェ逆変換

 投稿者:山中和義  投稿日:2014年 2月14日(金)14時38分34秒
  > No.3318[元記事へ]

島村1243さんへのお返事です。

> 解析的にフーリェ変換した複素関数F(ω)を離散値の時間関数f(t)に戻すプログラム(IFFT)をお教えください。
> 例:F(ω)=1.021*(1/(0.01875+j*ω)-1/(5.01+j*ω))
> 表示時間の全幅:t=0~50[sec]
> なお、上記F(ω)の元関数f(t)はf(t)=1.021*(exp(-0.01875*t)-exp(-5.01*t))です。



OPTION ARITHMETIC COMPLEX !複素数モード

SET bitmap SIZE 960,160 !表示領域
SET WINDOW -2,52,-1,2
DRAW grid(2,0.5)

LET T=50 !時間区間 [0,T]

DEF G(jw)=1.021*(1/(0.01875+jw)-1/(5.01+jw))
LET N=1024*8 !データ総数 ※大きいほど精度がよい
DIM d(0 TO N-1) !入出力用配列
LET Gamma=5 !※|γ|=3~7
!γを大きくすれば精度は上がりそうだが、
!あとでExp(γt)をかけるので、tが大きいところで発散する。
LET r=Gamma/T !γを決める
FOR k=0 TO N/2 !変換データの作成
   LET Fs=G( COMPLEX(r, 2*PI*k/T) ) !sk=γ+i*2π*k/T、k=0~n-1
   LET Hw=(COS(2*PI*k/N)+1)/2 !データは離散なため、ハニング関数をかけて平滑化する ※精度の向上
   LET d(k)=N/T*Fs*Hw !n/T*Y(k) * Hw 0~N/2

   IF NOT(k=0 OR k=N/2) THEN LET d(N-k)=COMPLEX(Re(d(k)),-Im(d(k))) !N-1~N/2+1は、共役複素数
NEXT k

CALL IFFT(d) !高速逆フーリエ変換

LET dt=T/N !時間刻み幅 ⊿t
FOR k=0 TO N-1 STEP 8 !結果の表示 [0,T]
   LET tt=k*dt !経過時間
   PLOT LINES: tt, Re(d(k))*EXP(r*tt); !Exp(γt)をかける ※Exp(γ*k*T/n)、k=0~n-1
NEXT k
PLOT LINES


!検算

DEF f(t)=1.021*(EXP(-0.01875*t)-EXP(-5.01*t))
SET LINE COLOR 4
FOR k=0 TO T STEP 1/2^8
   PLOT LINES: k,f(k);
NEXT k
PLOT LINES

END

EXTERNAL SUB IFFT(x()) !高速逆フーリエ変換 x() : 入力/出力データ
OPTION ARITHMETIC COMPLEX !複素数モード
DECLARE EXTERNAL SUB FFTMAIN
LET nx=SIZE(x)
LET theta=2*PI/nx
CALL FFTMAIN(x, theta)
MAT x=(1/nx)*x
END SUB

EXTERNAL SUB FFTMAIN(x(), theta)
OPTION ARITHMETIC COMPLEX !複素数モード
LET nx=SIZE(x)
IF MOD(nx, 2)<>0 THEN !DFTの計算
   DIM w(0 TO nx-1), xtmp(0 TO nx-1)
   MAT xtmp=x
   FOR k=0 TO nx-1
      LET tmp=theta*k
      FOR n=0 TO nx-1
         LET w(n)=EXP( COMPLEX(0, -tmp*n) )
      NEXT n
      LET x(k)=DOT(w, xtmp)
   NEXT k
ELSE !2分して再帰呼出し
   LET hnx=nx/2
   DIM x0(0 TO hnx-1), x1(0 TO hnx-1)
   FOR k=0 TO hnx-1
      LET x0(k)=x(k)+x(k+hnx)
      LET wk=EXP( COMPLEX(0, theta*k) )
      LET x1(k)=wk*(x(k)-x(k+hnx))
   NEXT k
   CALL FFTMAIN(x0, 2*theta)
   CALL FFTMAIN(x1, 2*theta)
   FOR k=0 TO hnx-1
      LET x(2*k)=x0(k)
      LET x(2*k+1)=x1(k)
   NEXT k
END IF
END SUB


 

Re: 数値フーリェ逆変換

 投稿者:島村1243  投稿日:2014年 2月14日(金)17時17分30秒
  > No.3319[元記事へ]

山中さん、早速のご教示有り難うございます。
ご教示頂いたプログラムはキチンと動作することを確認しました
いつも理路整然としたプログラム構成に素晴らしさを感じております。

さて、私の書き込みに表現不足が有り、意図が伝わらなかった点をまずお詫び致します。
今回、時間領域に戻したい関数Fは、F(jω)ではなく、実数ωのみを引数とする複素関数F(ω)です。

この目的は、ωの関数である相互インダクタンスM(ω)が存在し、時間領域の雷電流f(t)が電線に流れた時の通信線に生じる時間領域の誘導電圧v(t)を算出したいものです。

そのためにはf(t)を一度ω領域に変換してF(ω)とし、
V(ω)=ω×M(ω)×F(ω)
で求め、最後にω領域の複素関数V(ω)を逆変換してv(t)を得る、と考えています。
したがって周波数関数の因数にjωを使用すると、上記M(ω)が正しく表現できなくなってしまいます。

今の時点ではM(ω)の具体的関数形(カーソンポラチェックの式を使う)を得ていないので、一般的な意図で複素関数F(ω)の逆フーリェ変換方法をお尋ねした次第です。宜しくお願い致します。
 

Re: 数値フーリェ逆変換

 投稿者:山中和義  投稿日:2014年 2月15日(土)09時42分21秒
  > No.3320[元記事へ]

島村1243さんへのお返事です。

> 複素関数F(ω)の逆フーリェ変換方法をお尋ねした次第です。宜しくお願い致します。



DEF G(jw)=1.021*(1/(0.01875+jw)-1/(5.01+jw))
 :
FOR k=0 TO N/2 !変換データの作成
   LET Fs=G( COMPLEX(r, 2*PI*k/T) ) !sk=γ+i*2π*k/T、k=0~n-1
を

DEF G(w)=1.021*(1/(0.01875+j*w)-1/(5.01+j*w))
LET j=COMPLEX(0,1) !虚数単位

 :
FOR k=0 TO N/2 !変換データの作成
   LET Fs=G( COMPLEX(r, 2*PI*k/T)/j ) !sk=γ+i*2π*k/T、k=0~n-1

とすれば対応ができると思います。


また、
IF NOT(k=0 OR k=N/2) THEN LET d(N-k)=COMPLEX(Re(d(k)),-Im(d(k))) !N-1~N/2+1は、共役複素数
は
IF NOT(k=0 OR k=N/2) THEN LET d(N-k)=Conj(d(k)) !N-1~N/2+1は、共役複素数
とした方がわかりやすいですね。

 

Re: 数値フーリェ逆変換

 投稿者:島村1243  投稿日:2014年 2月15日(土)17時16分35秒
  山中和義さんへのお返事です。

>
> DEF G(w)=1.021*(1/(0.01875+j*w)-1/(5.01+j*w))
> LET j=COMPLEX(0,1) !虚数単位

>  :
> FOR k=0 TO N/2 !変換データの作成
>    LET Fs=G( COMPLEX(r, 2*PI*k/T)/j ) !sk=γ+i*2π*k/T、k=0~n-1
>

> とすれば対応ができると思います。
>
> また、
> IF NOT(k=0 OR k=N/2) THEN LET d(N-k)=COMPLEX(Re(d(k)),-Im(d(k))) !N-1~N/2+1は、共役複素数
> は
> IF NOT(k=0 OR k=N/2) THEN LET d(N-k)=Conj(d(k)) !N-1~N/2+1は、共役複素数
> とした方がわかりやすいですね。
>
>

ご教示頂いたとおりにコードを変更して、目的が達成出来ることを確認しました。
重ねてのご教示有難う御座いました。
(フーリエ変換なのに、なぜ「G( COMPLEX(r, 2*PI*k/T)/j )」のγを0としないのかが理解できませんでした。)
 

x^n-1の因数分解

 投稿者:山中和義  投稿日:2014年 2月22日(土)10時09分22秒
  x-1
x^2-1=(x-1)(x+1)
x^3-1=(x-1)(x^2+x+1)
x^4-1=(x-1)(x+1)(x^2+1)
x^5-1=(x-1)(x^4+x^3+x^2+x+1)
 :
 :


以下は、複素数が計算できる高校生のプログラミングによる数学である。


問題 円分多項式

α=(1+√3i)/2 (iは虚数単位)とします。

[1] αをガウス平面上に図示してください。

[2] α^2、α^3、α^4、α^5、をそれぞれ計算し、[1]と同じガウス平面上に全て図示してください。
  α^0=1もそこに書き加えてください。
  6つの点の位置関係を説明してください。

[3] これら6つの数と6次方程式x^6-1=0との間にある関係を説明してください。

[4] x^6-1=0 の左辺は円分多項式を用いて F1(x)×F2(x)×F3(x)×F6(x)=0と因数分解できます。
  F1(x)=0、F2(x)=0、F3(x)=0、F6(x)=0、それぞれを解いてガウス平面上に図示してください。
  Fn(x)のnの値とそれぞれの解の累乗との関係を説明してください。


ド・モアブルの定理について調べるのもいいかもしれません。



[5] F9(x)=x^6+x^3+1=0の6つの解をガウス平面上に図示してください。
  F1(x)=x-1とF3(x)=x^2+x+1をうまく使い、[3][4]をヒントにしてください。

[6] F9(x)=0の6つの解、それぞれ3乗するとどうなるでしょうか。

[7] F9(x)=F3(x^3)という関係式が成り立つのは式の上では明らかですが、これは一体何を意味する式なのか考えてみてください。

[8] F27(x)とF3(x)との関係はどうなると予想されるでしょうか。

[9] F1(x)=x-1とF3(x)=x^2+x+1を使ってx^81-1を因数分解してください。


考察

> [1],[2]

α^0=1
α^1=(1/2)+{(√3)/2}i =cosθ+i*sinθ、θ=2π/6=π/3
α^2=(-1/2)+{(√3)/2}i =cos2θ+i*sin2θ
α^3=-1 =cos3θ+i*sin3θ
α^4=(-1/2)+{-(√3)/2}i =cos4θ+i*sin4θ
α^5=(1/2)+{-(√3)/2}i =cos5θ+i*sin5θ

ガウス平面(z=x+iy、iは虚数単位)

         Y
        │
    α^2 ● ── ● α^1
     /  │  \
─ α^3 ● ── ・ ── ○ α^0 ─→X
     \  │  /
    α^4 ● ── ● α^5
        │

単位円に内接する正6角形の頂点である。


> [3]

f(x)=x^6-1 とすると、先の値を代入して、
f(α^0)=1^6-1=0
f(α^1)=( (1/2)+{(√3)/2}i )^6-1=0
f(α^2)=0
f(α^3)=0
f(α^4)=0
f(α^5)=0
なので、α^0,α^1,α^2,α^3,α^4,α^5は、x^6-1=0の相異なる6つの解である。

(別解)f(α)=0 の場合
α=(1/2)+{(√3)/2}iより、2α-1=(√3)i ∴4α^2-4α+4=0 ∴α^2-α+1=0
f(α)=α^6-1 なので、(α^6-1)÷(α^2-α+1)を考える。

             α^4+α^3-α-1
         ----------------------------------
α^2-α+1 )  α^6                      -1
             α^6-α^5+α^4
           ---------------------
                  α^5-α^4
                  α^5-α^4+α^3
                -----------------------
                           -α^3
                           -α^3+α^2-α
                         -------------------
                                -α^2+α-1
                                -α^2+α-1
                              --------------
                                         0

よって、f(α)=α^6-1=(α^2-α+1)(α^4+α^3-α-1)=0
(終り)

したがって、
x^6-1
=(x-α^0)(x-α^1)(x-α^2)(x-α^3)(x-α^4)(x-α^5)
=(x-α^0)(x-α^3){(x-α^2)(x-α^4)}{(x-α^1)(x-α^5)}
=(x-1)(x+1)(x^2+x+1)(x^2-x+1)

6=1*2*3*6 と素因数分解される


> [4]

1=(α^1)^6=(α^5)^6 なので、1の原始6乗根 x^2-x+1=0の解 1,2,3,4,5,6の中で、6と互いに素 1,5
1=(α^2)^3=(α^4)^3 なので、1の原始3乗根 x^2+x+1=0の解 ω
1=(α^3)^2 なので、1の原始2乗根 x+1=0の解
1=(α^0)^1 なので、1の原始1乗根 x-1=0の解

この場合、「べき乗する」ことは、「回転させる」ことである。



OPTION ARITHMETIC COMPLEX !ガウス平面(複素平面)
LET i=COMPLEX(0,1) !虚数単位

SET WINDOW -1.5,1.5, -1.5,1.5 !表示領域
DRAW grid(0.5,0.5)
DRAW circle !単位円

!x^6-1=0の6つの解
LET x1=EXP(2*PI*i*1/6) !α LET th=2*PI/6、LET x1=COS(1*th)+i*SIN(1*th)
LET x2=EXP(2*PI*i*2/6)
LET x3=EXP(2*PI*i*3/6)
LET x4=EXP(2*PI*i*4/6)
LET x5=EXP(2*PI*i*5/6)
LET x6=EXP(2*PI*i*6/6)

PRINT "x1="; x1
PRINT "x2="; x2
PRINT "x3="; x3
PRINT "x4="; x4
PRINT "x5="; x5
PRINT "x6="; x6

DRAW circle WITH SCALE(0.05)*SHIFT(x6)
DRAW disk WITH SCALE(0.05)*SHIFT(x3)
SET AREA COLOR 4 !赤色
DRAW disk WITH SCALE(0.05)*SHIFT(x1)
DRAW disk WITH SCALE(0.05)*SHIFT(x5)
SET AREA COLOR 2 !青色
DRAW disk WITH SCALE(0.05)*SHIFT(x2)
DRAW disk WITH SCALE(0.05)*SHIFT(x4)

PRINT x3^2
PRINT x2^3; x4^3
PRINT x1^6; x5^6
PRINT

!(x-α^2)(x-α^4)=x^2+x+1
PRINT -(x2+x4) !解と係数の関係、展開して係数比較
PRINT x2*x4

!(x-α^1)(x-α^5)=x^2-x+1
PRINT -(x1+x5)
PRINT x1*x5

END



-----------------------------------

> [5]

○①②●④⑤●⑦⑧

1,2,3,4,5,6,7,8,9の中で、9と互いに素 1,2,4,5,7,8


> [6]

(X^1)^3 → X^3
(X^2)^3 → X^6
(X^4)^3 → X^12 ≡ X^3
(X^5)^3 → X^15 ≡ X^6
(X^7)^3 → X^21 ≡ X^3
(X^8)^3 → X^24 ≡ X^6


> [7]

0=x^6+x^3+1=(x^3)^2+(x^3)+1=X^2+X+1より、X=x^3は、1の原始3乗根
よって、xは、1の原始9乗根

y^9-1
=(y-x^0){(y-x^3)(y-x^6)}{(y-x^1)(y-x^2)(y-x^4)(y-x^5)(y-x^7)(y-x^8)}
=(y-1)(y^2+y+1){(y^3)^2+(y^3)+1}
=(y-1)(y^2+y+1)(y^6+y^3+1)
=F1*F3*F9

9=1*3^2 と素因数分解される


> [8]

27=1*3^3 と素因数分解される
x^9-1=F1*F3*F9*F27=(x-1)(x^2+x+1)(x^6+x^3+1)(x^18+x^9+1)


> [9]

81=1*3^4 と素因数分解される
x^81-1=F1*F3*F9*F27*F81=(x-1)(x^2+x+1)(x^6+x^3+1)(x^18+x^9+1)(x^54+x^27+1)



OPTION ARITHMETIC COMPLEX !ガウス平面(複素平面)
LET i=COMPLEX(0,1) !虚数単位

SET WINDOW -1.5,1.5, -1.5,1.5 !表示領域
DRAW grid(0.5,0.5)
DRAW circle !単位円

LET N=9 !150程度

!Fn(x)=0のm個の解
DIM X(N)
LET M=0
FOR K=1 TO N
   IF gcd(K,N)=1 THEN !互いに素
      LET M=M+1
      LET X(M)=EXP(2*PI*K*i/N)
      DRAW disk WITH SCALE(0.05)*SHIFT(X(M))
      PRINT STR$(M);": "; X(M), K
   END IF
NEXT K

PRINT


!Fn(x)=(x-X[1])(x-X[2])…(x-X[m])=A[m]x^m+A[m-1]x^(m-1)+ … +A[2]x^2+A[1]x+A[0]
DIM A(0 TO N)
CALL PolynomialExpandD1(M,X, aa,A)
FOR K=0 TO aa
   LET T=INT(Re(A(K))+0.005) !精度 小数点以下3桁程度
   IF T<>0 THEN PRINT T; "x^";STR$(K)
   !!PRINT A(K),"x^";STR$(K)
NEXT K

END


EXTERNAL FUNCTION gcd(a,b) !最大公約数を求める
OPTION ARITHMETIC COMPLEX !ガウス平面(複素平面)
DO UNTIL b=0
   LET r=MOD(a,b)
   LET a=b
   LET b=r
LOOP
LET gcd=a
END FUNCTION


!POLY.LIB 抜粋

EXTERNAL SUB PolynomialExpandD1(N,X(), aa,A()) !(x-x[1])(x-x[2]) … (x-x[n])を展開する
OPTION ARITHMETIC COMPLEX !ガウス平面(複素平面)
MAT A=ZER
LET A(1)=1 !X-x[1] !n個の解について
LET A(0)=-X(1)
FOR K=2 TO N !ホーナー法による
   FOR i=K-1 TO 0 STEP -1 !展開する w=w*(X-x[k])
      LET A(i+1)=A(i+1)+A(i)
      LET A(i)=-A(i)*X(K)
   NEXT i
NEXT K
LET aa=N !次数
END SUB

 

WAIT DELAY の不具合

 投稿者:nagram  投稿日:2014年 2月23日(日)01時06分20秒
  WAIT DELAY で休止時間に変数や配列を単独で指定すると「実行時内部エラー」となります。定数や数値式の場合は問題ありません。十進BASICのバージョンは7.7.4。OSはWindows8。

LET s=3
PRINT "a"
WAIT DELAY 2
PRINT "b"
WAIT DELAY s-1 ! 1*sやs+0もOK。(s)はエラー。
PRINT "c"
WAIT DELAY s !「実行時内部エラー」となる
PRINT "d"
END

配列を指定した例
DIM t(2)
LET t(1)=2
LET t(2)=3
PRINT "e"
WAIT DELAY 2*t(1)-1
PRINT "f"
WAIT DELAY t(2) !「実行時内部エラー」となる
PRINT "g"
END
 

Re: WAIT DELAY の不具合

 投稿者:白石和夫  投稿日:2014年 2月23日(日)12時54分39秒
  > No.3326[元記事へ]

ご報告ありがとうございました。
修正版を作成します。

 

トーナメント表をつくる

 投稿者:山中和義  投稿日:2014年 2月24日(月)10時03分56秒
  (n+1)チームがトーナメント形式で対戦するとき、試合数は、n試合ある。
トーナメント表の形は、Cn(カタラン数)通りある。

参考サイト
 私的数学塾 http://www004.upp.so-net.ne.jp/s_honma/index.htm 内
  私の備忘録
   数学・・・代数学分野
    カタラン数 http://www004.upp.so-net.ne.jp/s_honma/number/catalan.htm


aとbの対戦を、(ab)と表す。

格子状経路の最短経路の場合の数と等しい。

n=2のとき
  B
  │*
A─・
  b

 a b *     (ab)

 ┌┴┐
 a   b


n=3のとき
     B
     │*
   ・─・
   │ │*
 A─・─・
   b   c

 a b * c *     ((ab)c)
 a b c * *     (a(bc))


   ┌┴─┐
 ┌┴┐  │
 a   b   c


 ┌┴─┐
 │  ┌┴┐
 a   b   c


n=4のとき
       B
       │*
     ・─・
     │ │*
   ・─・─・
   │ │ │*
 A─・─・─・
   b   c   d

 a b * c * d *     (((ab)c)d)
 a b * c d * *     ((ab)(cd))
 a b c * * d *     ((a(bc))d)
 a b c * d * *     (a((bc)d))
 a b c d * * *     (a(b(cd)))



!トーナメント表をつくる
LET N=4 !チーム数
LET W$=REPEAT$(" ",N+(N-1))
LET W$(1:1)="A"
CALL try(2,N,0,0,W$)
LET M=N-1
PRINT COMB(2*M,M+1)/M; "通り"
END

EXTERNAL SUB try(P,N,X,Y,W$) !バックトラック法で検索する
IF X=N-1 AND Y=N-1 THEN !終点なら
!!!PRINT W$ !debug
   CALL PrintOut(N,W$)
   !CALL PrintOut2(N,W$)
ELSE
   IF Y+1<=X THEN !縦方向
      LET W$(P:P)="*"
      CALL try(P+1,N,X,Y+1,W$)
   END IF
   IF X+1<N THEN !横方向
      LET W$(P:P)=CHR$((X+1)+ORD("A")) !B,C,D,…
      CALL try(P+1,N,X+1,Y,W$)
   END IF
END IF
END SUB

EXTERNAL SUB PrintOut(N,S$) !トーナメント表の形状を表示する(逆ポーランド記法)
DIM STK$(N) !stack
LET Q=0
FOR i=1 TO LEN(S$) !スクリプト文を解釈実行する
   LET T$=S$(i:i)
   SELECT CASE T$
   CASE "*" !pop
      LET X$=STK$(Q-1) !(x,y)
      LET Y$=STK$(Q)
      LET Q=Q-1 !(-2)+(1)=(-1)より
      LET STK$(Q)="("&X$&Y$&")"
   CASE IS>="A",IS<="Z" !push
      LET Q=Q+1
      LET STK$(Q)=T$
   CASE ELSE
      PRINT "論理エラーです。"; T$; i
      STOP
   END SELECT
NEXT i
PRINT STK$(1)
END SUB

EXTERNAL SUB PrintOut2(N,S$) !トーナメント表の形状を表示する
OPTION CHARACTER BYTE !バイト単位
DEF SPC(X)=(X-1)*4+1 !表示位置
DIM STK(N) !stack
LET W$=REPEAT$(" ",SPC(N)+1) !1行分の文字列(バッファ)
FOR i=1 TO LEN(S$) !スクリプト文を解釈実行する
   LET T$=S$(i:i)
   SELECT CASE T$
   CASE "*" !pop
      LET X=STK(P-1) !z=(xy)
      IF X<0 THEN
         LET X=-X
         LET K=SPC(X)+1
         LET W$(K:K)=CHR$(X+ORD("A")-1) !1,2,3,…をA,B,C,…へ
      END IF
      LET Y=STK(P)
      IF Y<0 THEN
         LET Y=-Y
         LET K=SPC(Y)+1
         LET W$(K:K)=CHR$(Y+ORD("A")-1)
      END IF
      LET Z=(X+Y)/2
      LET P=P-1 !(-2)+(+1)より
      LET STK(P)=Z

      PRINT W$
      LET W$=REPEAT$(" ",SPC(N)+1)

      LET W$(SPC(X):SPC(X)+1)="└" !対戦
      LET W$(SPC(Z):SPC(Z)+1)="┬"
      LET W$(SPC(Y):SPC(Y)+1)="┘"

      FOR J=1 TO P-1 !ブロック
         LET K=STK(J)
         IF K>0 THEN LET W$(SPC(K):SPC(K)+1)="│"
      NEXT J
   CASE IS>="A",IS<="Z" !push
      LET P=P+1
      LET STK(P)=-(ORD(T$)-ORD("A")+1) !A,B,C,…を-1,-2,-3,…へ
   CASE ELSE
      PRINT "論理エラーです。"; T$; i
      STOP
   END SELECT
NEXT i
PRINT W$ !決勝戦
PRINT
END SUB

 

Re: トーナメント表をつくる

 投稿者:GAI  投稿日:2014年 2月26日(水)19時26分43秒
  > No.3328[元記事へ]

山中和義さんへのお返事です。

> !トーナメント表をつくる

表がいろいろパターンが生まれるのが面白く、6人でのパターンを出力して(42通り)
ノートに整理して思ったのが、このトーナメント表をプログラムで組むことが如何に凄いことかということです。(特にPrintOut2)
縦との線が繋がっているし、横幅がそれぞれで異なるし、勝ち上がるラインの線の長さも異なっているしで、全体としてトーナメントの形状がとれていなくてはいけないしと・・・
これをアルゴリズムで組み上げることは私には神業に感じられます。
プログラムの主要な部分を読んでも、いろいろな技が組み合わされている感じで、ちょうどアナログテレビの裏側をのぞいた気分です。
これを効率よく組み上げられる技に感動します。
 

Re: トーナメント表をつくる

 投稿者:山中和義  投稿日:2014年 2月27日(木)10時26分18秒
  > No.3328[元記事へ]

問題
4つの自然数1,2,5,8をすべて使って、四則演算(加減乗除)と括弧による
1桁どうしの計算式の結果が、0から51までの数を表すようにしてください。
例
0=1+2+5-8、1=8-1*2-5、2=1+5-8/2、3=(1-2)×5+8 など

類題
4つの自然数1,2,4,10をすべて使って、0から50までの数を表す。

参考サイト
 私的数学塾 http://www004.upp.so-net.ne.jp/s_honma/index.htm 内
  私の備忘録
   数学・・・代数学分野
    カタラン数 http://www004.upp.so-net.ne.jp/s_honma/number/catalan.htm
  クイズ&パズル
   数の創出
   数の創出2 http://www004.upp.so-net.ne.jp/s_honma/relax/number3.htm
   最長不倒の4数を探せ! http://www004.upp.so-net.ne.jp/s_honma/relax/number23.html

考察
        B
        │+,-,*,/
      ・─・
      │ │+,-,*,/
    ・─・─・
    │ │ │+,-,*,/
  A─・─・─・
 a   b   c   d
 a   b   d   c
 a   c   b   d
    :
 d   c   b   a
として、逆ポーランド表記(後置表記)の式を生成する。
これは、中置表記での四則演算(加減乗除)と括弧による式を表すことができる。

式の形状は、
 a b + c + d +     (((a+b)+c)+d)
 a b + c d + +     ((a+b)+(c+d))
 a b c + + d +     ((a+(b+c))+d)
 a b c + d + +     (a+((b+c)+d))
 a b c d + + +     (a+(b+(c+d)))
となる。

よって、4!×5×4^3 通りを検証する。
(終り)



OPTION ARITHMETIC RATIONAL !分数の計算

PUBLIC NUMERIC D(4)
DATA 1,2,5,8
!DATA 1,2,4,10
MAT READ D

PUBLIC NUMERIC F(0 TO 7000) !0~n
MAT F=ZER

LET N=4 !チーム数
DIM A(N+(N-1))
LET A(1)=1 !A
CALL try(2,0,0, N,A)
END

EXTERNAL SUB try(P,X,Y, N,A()) !バックトラック法で検索する
OPTION ARITHMETIC RATIONAL !分数の計算
IF X=N-1 AND Y=N-1 THEN !終点なら
!!!MAT PRINT A; !debug
   CALL check(N,A)
ELSE
   IF Y+1<=X THEN !縦方向
      LET A(P)=-(Y+1) !*
      CALL try(P+1,X,Y+1, N,A)
   END IF
   IF X+1<N THEN !横方向
      LET A(P)=(X+1)+1 !B,C,D,…
      CALL try(P+1,X+1,Y, N,A)
   END IF
END IF
END SUB

EXTERNAL SUB check(N,P()) !数、演算子の並びを考える
OPTION ARITHMETIC RATIONAL !分数の計算
DIM A(N),B(N-1)
FOR h=0 TO FACT(N)-1 !a,b,c,…,d の順列
   CALL Num2PermFactorial(h, A,N)

   FOR J=0 TO 4^(N-1)-1 !+,-,*,/ の重複順列
      LET T=J !4進法
      FOR i=1 TO N-1 !+,-,*,/ を -1,-2,-3,-4 へ
         LET B(i)=-(MOD(T,4)+1)
         LET T=INT(T/4)
      NEXT i

      CALL Calc(N,P,A,B) !計算する
   NEXT J

NEXT h
END SUB

EXTERNAL SUB Calc(N,P(),A(),B()) !逆ポーランド記法の式を計算する
OPTION ARITHMETIC RATIONAL !分数の計算
DIM STK(N),EXP$(N) !stack
LET Q=0
FOR i=1 TO N+(N-1) !スクリプト文を解釈実行する
   SELECT CASE P(i)
   CASE IS<0 !* pop
      LET X=STK(Q-1) !(xy)
      LET Y=STK(Q)
      LET X$=EXP$(Q-1) !x○y
      LET Y$=EXP$(Q)

      LET Q=Q-1 !(-2)+(1)=(-1)より
      LET T=-P(i)
      IF B(T)=-1 THEN !加算
         LET STK(Q)=X+Y
         LET EXP$(Q)="(" & X$ & "+" & Y$ & ")"
      ELSEIF B(T)=-2 THEN !減算
         LET STK(Q)=X-Y
         LET EXP$(Q)="(" & X$ & "-" & Y$ & ")"
      ELSEIF B(T)=-3 THEN !乗算
         LET STK(Q)=X*Y
         LET EXP$(Q)=X$ & "×" & Y$
      ELSEIF B(T)=-4 THEN !除算
         IF Y=0 THEN EXIT SUB !0で割る
         LET STK(Q)=X/Y
         LET EXP$(Q)=X$ & "÷" & Y$
      ELSE
         PRINT "論理エラーです。"; T$; i
         STOP
      END IF
   CASE IS>0 !A,B,…,Z push
      LET T=D(A(P(i)))
      LET Q=Q+1
      LET STK(Q)=T
      IF T<0 THEN !負の値
         LET EXP$(Q)="(" & STR$(T) & ")"
      ELSE !非負の値
         LET EXP$(Q)=STR$(T)
      END IF
   CASE ELSE
      PRINT "論理エラーです。"; T$; i
      STOP
   END SELECT
NEXT i
!!!PRINT STK(1) !debug

LET T=STK(1) !結果を表示する
IF T>=0 AND T=INT(T) AND F(T)=0 THEN !非負整数、1番目
   LET F(T)=1
   PRINT T; "= "; EXP$(1)
END IF
END SUB



!COMB.LIB 抜粋

EXTERNAL SUB Num2PermFactorial(h, A(),N) !番号から順列パターンを生成する ※辞書式順序
OPTION ARITHMETIC RATIONAL !分数の計算
LET v=h !非負の10進数整数を階乗進数へ
FOR j=N TO 1 STEP -1 !下の桁から順に
   LET w=N-j+1
   LET t=INT(v/w)
   LET A(j)=v-t*w +1 !階乗進数の各桁の値+1 A[1..N]=(N-1)! … 3! 2! 1! 0!
   LET v=t
NEXT j
FOR j=N-1 TO 1 STEP -1 !順列パターンへ
   FOR k=j+1 TO N
      IF A(k)>=A(j) THEN LET A(k)=A(k)+1
   NEXT k
NEXT j
END SUB

 

max

 投稿者:永野護  投稿日:2014年 3月 1日(土)10時04分34秒
  質問です。a,bを任意の実数としたとき、
max(a,b)=(a+b+|a-b|)/2
min(a,b)=(a+b-|a-b|)/2
が成り立つ。
このことはmax(a,b,c)やmax(a,b,c,d)でもなりたつのでしょうか。
成り立つとすればどのような式になるのでしょうか。
 

Re: max

 投稿者:山中和義  投稿日:2014年 3月 1日(土)12時22分11秒
  > No.3331[元記事へ]

永野護さんへのお返事です。

> このことはmax(a,b,c)やmax(a,b,c,d)でもなりたつのでしょうか。
> 成り立つとすればどのような式になるのでしょうか。

max(a,b)は、トーナメント表で考えると、

 ┌┴┐
 a  b

の1通りと同値です。

max(a,b,c)は、

  ┌┴┐
 ┌┴┐ c
 a  b

  ┌┴┐
 ┌┴┐ b
 a  c

  ┌┴┐
 ┌┴┐ a
 b  c

の3通りと同値です。

max(a,b,c,d)は、15通りと同値です。

参考サイト
 私的数学塾 http://www004.upp.so-net.ne.jp/s_honma/index.htm 内
  クイズ&パズル
   トーナメントの組合せ http://www004.upp.so-net.ne.jp/s_honma/relax/game.html


また、2つの数では、
 max(a,b)-min(a,b)=|a-b|
 max(a,b)+min(a,b)=a+b
のように式が確定して、連立方程式が組めればよいのですが、
3つの数では、
差 2(max(a,b,c)-min(a,b,c))=|a-b|+|b-c|+|c-a|
となりますが、
和 max(a,b,c)+min(a,b,c)=a+b, b+c, c+a
は、異なる3つの数のとき、3通りになってしまいます。

したがって、次のような記述になります。


DEF MAX(a,b)=(a+b+ABS(a-b))/2
DEF MIN(a,b)=(a+b-ABS(a-b))/2

LET a=-1
LET b=-3
LET c=2

PRINT MAX(MAX(a,b),c)
PRINT MAX(MAX(a,c),b)
PRINT MAX(MAX(b,c),a)


PRINT ABS(a-b)+ABS(b-c)+ABS(c-a)
PRINT ( MAX(MAX(a,b),c)-MIN(MIN(a,b),c) )*2

END
 

max

 投稿者:永野護  投稿日:2014年 3月 1日(土)14時39分26秒
  山中様の丁寧な回答に感謝します。ありがとうございました。
敬具
 

Re: max

 投稿者:山中和義  投稿日:2014年 3月 2日(日)13時17分5秒
  > No.3331[元記事へ]

永野護さんへのお返事です。

> 質問です。a,bを任意の実数としたとき、
> max(a,b)=(a+b+|a-b|)/2
> min(a,b)=(a+b-|a-b|)/2
> が成り立つ。

maxをminで表すことが可能なんですね。

max(a,b)=a+b -min(a,b)
min(a,b)=a+b -max(a,b)
など



DEF MAX(a,b)=(a+b+ABS(a-b))/2
DEF MIN(a,b)=(a+b-ABS(a-b))/2

LET a=-1
LET b=-3

PRINT a+b -MIN(a,b) !max(a,b)
PRINT a+b -MAX(a,b) !min(a,b)
PRINT


LET c=2

DEF MAX3(a,b,c)=MAX(MAX(a,b),c)
DEF MIN3(a,b,c)=MIN(MIN(a,b),c)
PRINT a+b+c -(MIN(a,b)+MIN(b,c)+MIN(c,a)) +MIN3(a,b,c) !max(a,b,c)
PRINT a+b+c -(MAX(a,b)+MAX(b,c)+MAX(c,a)) +MAX3(a,b,c) !min(a,b,c)
PRINT


LET d=4

DEF MAX4(a,b,c,d)=MAX(MAX(a,b),MAX(c,d))
DEF MIN4(a,b,c,d)=MIN(MIN(a,b),MIN(c,d))
PRINT a+b+c+d -(MIN(a,b)+MIN(a,c)+MIN(a,d)+MIN(b,c)+MIN(b,d)+MIN(c,d)) +(MIN3(a,b,c)+MIN3(a,b,d)+MIN3(a,c,d)+MIN3(b,c,d)) -MIN4(a,b,c,d) !max(a,b,c,d)
PRINT a+b+c+d -(MAX(a,b)+MAX(a,c)+MAX(a,d)+MAX(b,c)+MAX(b,d)+MAX(c,d)) +(MAX3(a,b,c)+MAX3(a,b,d)+MAX3(a,c,d)+MAX3(b,c,d)) -MAX4(a,b,c,d) !min(a,b,c,d)

END

 

Re: max

 投稿者:山中和義  投稿日:2014年 3月 2日(日)13時57分27秒
  > No.3331[元記事へ]

永野護さんへのお返事です。

> 質問です。a,bを任意の実数としたとき、
> max(a,b)=(a+b+|a-b|)/2
> min(a,b)=(a+b-|a-b|)/2
> が成り立つ。
> このことはmax(a,b,c)やmax(a,b,c,d)でもなりたつのでしょうか。
> 成り立つとすればどのような式になるのでしょうか。

次のようになるようです。


LET a=-1
LET b=-3
LET c=2
LET d=4

PRINT ( (a+b+ABS(a-b))/2 + c +ABS((a+b+ABS(a-b))/2 - c) )/2 !max(a,b,c)
PRINT ( (a+b-ABS(a-b))/2 + c -ABS((a+b-ABS(a-b))/2 - c) )/2 !min(a,b,c)

PRINT ( a+b+c+d +ABS(a-b)+ABS(c-d) +ABS(a+b-c-d +ABS(a-b)-ABS(c-d)) )/4 !max(a,b,c,d)
PRINT ( a+b+c+d -ABS(a-b)-ABS(c-d) -ABS(a+b-c-d -ABS(a-b)+ABS(c-d)) )/4 !min(a,b,c,d)

END
 

max

 投稿者:永野護  投稿日:2014年 3月 6日(木)12時17分35秒
  詳しい解説ありがとうございました。
大変助かりました。
 

リーグ戦の勝敗

 投稿者:山中和義  投稿日:2014年 3月 9日(日)12時50分38秒
  リーグ戦(ラウンドロビン方式、総当たり)の勝敗結果(勝敗表)は何通りありますか。
ただし、
引き分けはないとします。
チームによって区別することはしません。

例
N=2のとき
   A  B
 A - ○ 1-0
 B × - 0-1

   A  B
 A - × 0-1
 B ○ - 1-0
なので、
 1チームが1勝0敗、1チームが0勝1敗。
の1通り。


N=3のとき
   A  B  C
 A - × × 0-2
 B ○ - × 1-1
 C ○ ○ - 2-0

   A  B  C
 A - ○ × 1-1
 B × - × 0-2
 C ○ ○ - 2-0

   A  B  C
 A - × ○ 1-1
 B ○ - × 1-1
 C × ○ - 1-1

   A  B  C
 A - ○ ○ 2-0
 B × - × 0-2
 C × ○ - 1-1

   A  B  C
 A - × × 0-2
 B ○ - ○ 2-0
 C ○ × - 1-1

   A  B  C
 A - ○ × 1-1
 B × - ○ 1-1
 C ○ × - 1-1

   A  B  C
 A - × ○ 1-1
 B ○ - ○ 2-0
 C × × - 0-2

   A  B  C
 A - ○ ○ 2-0
 B × - ○ 1-1
 C × × - 0-2
なので、
 1チームが2勝0敗、1チームが1勝1敗、1チームが0勝2敗。
 3チームが1勝1敗。
の2通り。


参考サイト http://oeis.org/A000571


LET N=6 !チーム数 ※2以上 N=11は困難

PUBLIC NUMERIC D(1500, 0 TO 9) !勝敗のパターン(履歴)

PUBLIC NUMERIC C
LET C=0
DIM M(N,N)!リーグ戦の勝敗結果
CALL try(1,N,M)
PRINT C; "通り"

END


!勝敗表(右上半分)
! 1 2 3 … k …  n
! _________
! -    \    1番目のチーム
!  - 左詰1 \ 0  2番目のチーム
!   -    \  3番目のチーム
!    \    \  :
!     - ___\ k番目のチーム
!      -     :
!       \ 0,1
!         -  n番目のチーム
!
!計算量 O( k^k * 2^COMB(k,2) )、k=[n/2]

EXTERNAL SUB try(P,N,M(,)) !バックトラック法で検索する
LET K=INT(N/2) !1の並びを左詰めにする(チームを区別しないので)
IF P<=K THEN !1~(半分) 番目のチームなら
   FOR W=0 TO K !0勝,1勝,2勝,…
      FOR J=1 TO W !1行目を埋める
         LET M(P,P+J)=1 !右上半分
         LET M(P+J,P)=0 !左下半分
      NEXT J
      FOR J=W+1 TO N-P !n敗,(n-1)敗,(n-2)敗,…
         LET M(P,P+J)=0
         LET M(P+J,P)=1
      NEXT J

      IF P=N-1 THEN !すべての行が埋まったなら
         CALL check(N,M)
      ELSE
         CALL try(P+1,N,M) !次の行へ
      END IF
   NEXT W

ELSE
   FOR W=0 TO 2^(N-P)-1 !p行目を埋める
      LET T=W
      FOR J=1 TO N-P
         LET B=MOD(T,2)
         LET M(P,P+J)=B !右上半分
         LET M(P+J,P)=1-B !左下半分
         LET T=INT(T/2)
      NEXT J

      IF P=N-1 THEN !すべての行が埋まったなら
         CALL check(N,M)
      ELSE
         CALL try(P+1,N,M) !次の行へ
      END IF

   NEXT W

END IF
END SUB

EXTERNAL SUB check(N,M(,)) !既出のパターンと同じかどうか確認する
DIM F(0 TO N-1) !勝敗のパターン
MAT F=ZER
FOR i=1 TO N !i番目のチームの勝ち数
   LET S=0
   FOR J=1 TO N
      LET S=S+M(i,J)
   NEXT J
   LET F(S)=F(S)+1
NEXT i
!!!MAT PRINT F; !0勝,1勝,2勝,…,(n-1)勝のチーム数

FOR i=1 TO C !既出のパターンと同じかどうか確認する
   FOR J=0 TO N-1
      IF D(i,J)<>F(J) THEN EXIT FOR
   NEXT J
   IF J>N-1 THEN EXIT FOR !同じパターンなら
NEXT i
IF i>C THEN !新規の場合、登録する
   LET C=C+1
   FOR J=0 TO N-1 !copy it
      LET D(C,J)=F(J)
   NEXT J

   PRINT "No."; STR$(C) !結果を表示する
   MAT PRINT F;
   MAT PRINT M;
END IF
END SUB

 

整式の余り

 投稿者:山中和義  投稿日:2014年 3月11日(火)19時57分30秒
  p(x)÷(x^d-1)、p(x)÷(x^(d-1)+x^(d-2)+ … +x^2+x+1) の場合

考察
(x-1){x^(d-1)+x^(d-2)+ … +x^2+x+1}=x^d-1 であるので、
次のように次数を下げることで余りを求めることができる。
x^n
=(x^d-1)x^(n-d) +x^(n-d)
=(x^d-1)x^(n-d) +(x^d-1)x^(n-2d) +x^(n-2d)
=(x^d-1)x^(n-d) +(x^d-1)x^(n-2d) +(x^d-1)x^(n-3d) +x^(n-3d)
=  :
=(x^d-1){x^(n-d) +x^(n-2d) +x^(n-3d) +x^(n-4d) + … } +x^r  ただし、n=qd+r
≡x^r  mod (x^d-1)
(終り)

例
x^8+x^7+1
=(x^3-1)(x5+x^2)+x^2  +(x^3-1)(x^4+x)+x  +1
≡x^2+x+1  mod (x^3-1)
≡0  mod (x^2+x+1)


DATA 8 !1+x^7+x^8
DATA 1,0,0,0,0,0,0,1,1
READ aa
DIM A(0 TO aa)
MAT READ A
LET d=3 !x^3-1
DIM B(0 TO d-1)
MAT B=ZER
FOR i=0 TO aa
   IF A(i)<>0 THEN
      LET q=INT(i/d) !i=q*d+r
      LET r=MOD(i,d)
      PRINT A(i); "x^"; STR$(r)
      LET B(r)=B(r)+A(i)
   END IF
NEXT i
MAT PRINT B; !余り B(0)+B(1)x+B(2)x^2+ …
END



同様に、
p(x)÷(x^d+1)、p(x)÷(x^(d-1)-x^(d-2)+ … +x^2-x+1) の場合

x^n
=(x^d+1)x^(n-d) -x^(n-d)
=(x^d+1)x^(n-d) -(x^d+1)x^(n-2d) +x^(n-2d)
=(x^d+1)x^(n-d) -(x^d+1)x^(n-2d) +(x^d+1)x^(n-3d) -x^(n-3d)
=(x^d+1)x^(n-d) -(x^d+1)x^(n-2d) +(x^d+1)x^(n-3d) -(x^d+1)x^(n-4d) +x^(n-4d)
=  :
=(x^d+1){x^(n-d) -x^(n-2d) +x^(n-3d) -x^(n-4d) + … } +(-1)^q x^r  ただし、n=qd+r
      └──────── q個 ───────┘
≡(-1)^q x^r  mod (x^d+1)

例
x^8+x^4+1
=(x^3+1)(x5-x^2)+x^2  +(x^3+1)x-x  +1
≡x^2-x+1  mod (x^3+1)
≡0  mod (x^2-x+1)


DATA 8 !1+x^4+x^8
DATA 1,0,0,0,1,0,0,0,1
READ aa
DIM A(0 TO aa)
MAT READ A
LET d=3 !x^3+1
DIM B(0 TO d-1)
MAT B=ZER
FOR i=0 TO aa
   IF A(i)<>0 THEN
      LET q=INT(i/d) !i=q*d+r
      LET r=MOD(i,d)
      PRINT A(i)*(-1)^q; "x^"; STR$(r)
      LET B(r)=B(r)+A(i)*(-1)^q
   END IF
NEXT i
MAT PRINT B; !余り B(0)+B(1)x+B(2)x^2+ …
END



問題
整式p(x)=x^11+x^10+x^9+x^8+x^7+x^6+x^5+x^4+x^3+x^2+x+1とする。
p(x^m)÷p(x)の余りを求めよ。

考察
(x-1)p(x)=x^12-1≡0 mod p(x)である。

たとえば、p(x^2)の場合、x^12≡1として、
p(x^2)
=x^22+x^20+x^18+x^16+x^14+x^12+x^10+x^8+x^6+x^4+x^2+1
=x^10+x^8 +x^6 +x^4 +x^2 +1   +x^10+x^8+x^6+x^4+x^2+1
=2(x^10+x^8+x^6+x^4+x^2+1)

また、
 ±0≡0,12 mod 12
 ±1≡1,11 mod 12
 ±2≡2,10 mod 12
 ±3≡3,9 mod 12
 ±4≡4,8 mod 12
 ±5≡5,7 mod 12
 ±6≡6 mod 12
なので、
 p(x^0)=p(x^12)
 p(x^1)=p(x^11)
 p(x^2)=p(x^10)
 p(x^3)=p(x^9)
 p(x^4)=p(x^8)
 p(x^5)=p(x^7)
 p(x^6)
と予想される。
ちなみに、
  p(x^10)
 =x^110+x^100+x^90+x^80+x^70+x^60+x^50+x^40+x^30+x^20+x^10+1
 =x^2  +x^4  +x^6 +x^8 +x^10+1   +x^2 +x^4 +x^6 +x^8 +x^10+1
 ≡2(1+x^2+x^4+x^6+x^8+x^10)
のように、計算してみると予想通りである。
また、12と互いに素、すなわち、1,5,7,11の場合、
 p(x^1)=p(x^5)=p(x^7)=p(x^11)≡0
とわかる。

よって、
 p(x^0)=p(x^12)≡12
 p(x^1)=p(x^5)=p(x^7)=p(x^11)≡0
 p(x^2)=p(x^10)≡2(1+x^2+x^4+x^6+x^8+x^10)
 p(x^3)=p(x^9)≡3(1+x^3+x^6+x^9)
 p(x^4)=p(x^8)≡4(1+x^4+x^8)
 p(x^6)≡6(1+x^6)
(終り)


LET m=2 !p(x^m)
LET k=11 !1+x+x^2+ … +x^k

DIM A(0 TO m*k)
FOR i=0 TO k
   LET A(m*i)=1
NEXT i

LET d=12 !x^12-1

DIM B(0 TO d-1)
MAT B=ZER
FOR i=0 TO m*k
   IF A(i)<>0 THEN
      LET q=INT(i/d) !i=q*d+r
      LET r=MOD(i,d)
      PRINT A(i); "x^"; STR$(r)
      LET B(r)=B(r)+A(i)
   END IF
NEXT i
MAT PRINT B; !余り B(0)+B(1)x+B(2)x^2+ …

END

 

Re: 整式の余り

 投稿者:山中和義  投稿日:2014年 3月12日(水)11時20分37秒
  > No.3338[元記事へ]

> 問題
> 整式p(x)=x^11+x^10+x^9+x^8+x^7+x^6+x^5+x^4+x^3+x^2+x+1とする。
> p(x^m)÷p(x)の余りを求めよ。

実際の計算は、パズル思考で(機械的に)、

被除数 p(x^m) の係数を、
    0  12  24  36  48  60  72  84  96 108 120 132
    1  13  25  37  49  61  73  85  97 109 121 133
    2  14  26  38  50  62  74  86  98 110 122 134
    3  15  27  39  51  63  75  87  99 111 123 135
    4  16  28  40  52  64  76  88 100 112 124 136
    5  17  29  41  53  65  77  89 101 113 125 137
    6  18  30  42  54  66  78  90 102 114 126 138
    7  19  31  43  55  67  79  91 103 115 127 139
    8  20  32  44  56  68  80  92 104 116 128 140
    9  21  33  45  57  69  81  93 105 117 129 141
   10  22  34  46  58  70  82  94 106 118 130 142
   11  23  35  47  59  71  83  95 107 119 131 143
と並べてみる。

p(x^2)÷p(x) の余り
 p(x^2)=x^22+x^20+x^18+x^16+x^14+x^12+x^10+x^8+x^6+x^4+x^2+1 なので、
    0  12  (2)x^0 ※係数2は、x^0とx^12の係数の和である。
    1  13
    2  14  (2)x^2
    3  15
    4  16  (2)x^4
    5  17
    6  18  (2)x^6
    7  19
    8  20  (2)x^8
    9  21
   10  22  (2)x^10
   11  23

p(x^3)÷p(x) の余り
 p(x^3)=x^33+x^30+x^27+x^24+x^21+x^18+x^15+x^12+x^9+x^6+x^3+1 なので、
    0  12  24  (3)x^0
    1  13  25
    2  14  26
    3  15  27  (3)x^3
    4  16  28
    5  17  29
    6  18  30  (3)x^6
    7  19  31
    8  20  32
    9  21  33  (3)x^9
   10  22  34
   11  23  35
など

と求めればよい!?(良い子は決して真似しないでください。。。; )


---------------------------------------

一般に、
(x^d-k) や その因数 で割る場合

次のように変形することで次数を下げることで余りを求めることができる。
x^n
=(x^d-k)x^(n-d) +kx^(n-d)
=(x^d-k)x^(n-d) +k(x^d-k)x^(n-2d) +k^2x^(n-2d)
=(x^d-k)x^(n-d) +k(x^d-k)x^(n-2d) +k^2(x^d-k)x^(n-3d) +k^2x^(n-3d)
=  :
=(x^d-k){x^(n-d) +kx^(n-2d) +k^2x^(n-3d) +k^3x^(n-4d) + … } +k^q x^r  ただし、n=qd+r
     └────────── q個 ─────────┘
≡k^q x^r  mod (x^d-k)
(終り)

例
x^4-13x^2+36
={(x^2-9)(x^2+9) +81} -13{(x^2-9)+9} +36
≡81-117+36  mod (x^2-9)
≡0

DATA 4 !36-3x^2+x^4
DATA 36,0,-13,0,1
READ aa
DIM A(0 TO aa)
MAT READ A

LET d=2 !x^2-9
LET k=9

DIM B(0 TO d-1)
MAT B=ZER !余り B(0)+B(1)x+B(2)x^2+ …
FOR J=0 TO aa
   IF A(J)<>0 THEN
      LET q=INT(J/d) !i=q*d+r
      LET r=MOD(J,d)
      PRINT k^q*A(J); "x^"; STR$(r)
      LET B(r)=B(r)+k^q*A(J)
   END IF
NEXT J
MAT PRINT B; !結果を表示する

END

 

Re: Project Euler Problem(プロジェクトオイラー)

 投稿者:山中和義  投稿日:2014年 3月19日(水)19時13分50秒
  > No.3275[元記事へ]

029
2≦a≦100と2≦b≦100を満たす整数a,bについて、a^bを全て考えてみよう。
いくつの異なる値が存在するか。
参考サイト http://odz.sakura.ne.jp/projecteuler/


考察
2≦a≦A、2≦b≦Bとして、kはa^k≦Aを満たす最大の整数とする。
k個の数からなる組{a, a^2, a^3, …, a^k}を考える。
例
 A=B=10のとき
 {2, 2^2=4, 2^3=8}、{3, 3^2=9}、{5}、{6}、{7}、{10}

a=2,3,5,6,7,10,11,12,13,…,[√A] のとき、k≧2
a>[√A] のとき、k=1

各要素のべき乗は、重複する数を生成する。
例
 a=2のとき
   |  2    3    4    5    …   B
 ----+-----------------------------------------------------
 2^1 |   2^2   2^3   2^4   2^5  …    2^B
 2^2 | (2^2)^2 (2^2)^3 (2^2)^4 (2^2)^5  …  (2^2)^B
 2^3 | (2^3)^2 (2^3)^3 (2^3)^4 (2^3)^5  …  (2^3)^B
            :
 2^k | (2^k)^2 (2^k)^3 (2^k)^4 (2^k)^5  …  (2^k)^B

 べき乗の部分に着目すると、

   | 2  3  4  5  … B
 ----+-------------------------------
 2^1 | 2  3  4  5  … B
 2^2 | 4  6  8  10 … 2B
 2^3 | 6  9  12  15 … 3B
         :
 2^k | 2k  3k  4k  5k … kB

 同じ数字の箇所は同じ数になるので、重複する数となる。

また、重複する個数はkとBに依存する。
(終り)


例
2≦a≦10、2≦b≦10のとき、2^k≦10から、k=1,2,3
積算表
 k\b |  2  3  4  5  6  7  8  9 10
 -----+-----------------------------
    1 |  2  3  4  5  6  7  8  9 10
    2 |  4  6  8 10 12 14 16 18 20
    3 |  6  9 12 15 18 21 24 27 30
より、
重複を除いた個数をG(k)とすると、
G(1)=9通り、G(2)=14通り、G(3)=19通り

a={2,2^2,2^4},{3,3^2},5,6,7,10より、
 a=2のとき、G(3)通り
 a=3のとき、G(2)通り
 a=5,6,7,10のとき、G(1)通り
なので、
 19*1+14*1+9*4=69通り
(終り)



!Project Euler Problem(プロジェクトオイラー) 029

LET A=100
LET B=100


LET M=0 !組のなかで数の個数が最大のもの
LET T=A
DO WHILE T>0
   LET M=M+1
   LET T=INT(T/2) !{2, 2^2, 2^3, …, 2^m}
LOOP
LET M=M-1
PRINT "M="; M !debug

!乗算表
!      2 3 4  …  x  …  q    …  B
!   1:
!   2:
!            :
!   p:                   pq=n
!            :
! k-1:                           (k-1)B
!   k:  → →    kx=n   → →
!            :
!   m:
!をつくって、G(k)を求める。

DIM G(M) !重複を除いた個数をG(k)とする
LET G(1)=B-1 !1段目
LET C=G(1)
FOR K=2 TO M !k段目
   LET T=INT((K-1)*B/K) !kxが(k-1)Bより大きな数はすべて重複しない
   FOR X=2 TO T !b列目
      LET N=K*X
      FOR P=1 TO K-1 !nをpqに分解する
         LET Q=N/P
         IF Q=INT(Q) AND (Q>=2 AND Q<=B) THEN EXIT FOR !重複する
      NEXT P
      IF P>K-1 THEN LET C=C+1 !重複しないなら
   NEXT X
   LET C=C+(B-T)

   LET G(K)=C
NEXT K
MAT PRINT G; !debug


!組(A=2,3,5,6,7,10,11,12,13,…)に応じて計算していく。

LET C=0

LET AA=INT(SQR(A))
DIM F(AA) !2~[√A]までの数(篩いに用いる)
MAT F=ZER

LET S=0 !組にすることで除外された数の個数
FOR J=2 TO AA !素因数分解して、因数の組み合わせで組に分ける
   IF F(J)=0 THEN !新しい組なら
      PRINT "A="; J !debug

      LET K=0
      LET T=J !{j^1, j^2, j^3, …, j^k}の要素は、k個
      DO WHILE T<=A
         IF T<=AA THEN LET F(T)=1 !同じ組である
         LET S=S+1
         LET K=K+1

         LET T=T*J !次へ
      LOOP
      PRINT K !debug

      LET C=C+G(K)

   END IF
NEXT J

LET C=C+(A-1-S)*G(1) !√Aより大きいものは、(B-1)通り

PRINT C; "通り" !9183

END


実行結果

M= 6
99  149  199  240  291  328

A= 2
6
A= 3
4
A= 5
2
A= 6
2
A= 7
2
A= 10
2
9183 通り

 

Re: Project Euler Problem(プロジェクトオイラー)

 投稿者:山中和義  投稿日:2014年 3月22日(土)09時30分5秒
  > No.3340[元記事へ]

045
40755は、三角数かつ五角数かつ六角数である。
次の三角数かつ五角数かつ六角数となる数を求めよ。
参考サイト http://odz.sakura.ne.jp/projecteuler/

3つの数を競い合わせる方法


!!OPTION ARITHMETIC RATIONAL !多桁の整数

DEF T(N)=N*(N+1)/2 !三角数
DEF P(N)=N*(3*N-1)/2 !五角数
DEF H(N)=N*(2*N-1) !六角数

LET N1=1
LET N2=1
LET N3=1

FOR K=1 TO 3 !1番目、2番目、3番目
   LET A=T(N1)
   LET B=P(N2)
   LET C=H(N3)

   DO UNTIL A=B AND B=C
      LET M=MAX(MAX(A,B),C) !一番大きな数に揃える
      DO WHILE A<M
         LET N1=N1+1
         LET A=T(N1)
      LOOP
      DO WHILE B<M
         LET N2=N2+1
         LET B=P(N2)
      LOOP
      DO WHILE C<M
         LET N3=N3+1
         LET C=H(N3)
      LOOP
   LOOP

   PRINT STR$(K);":"; A; N1;N2;N3 !1533776805

   LET N1=N1+1 !次へ
   LET N2=N2+1
   LET N3=N3+1
NEXT K

END



2次方程式を解く方法


!!OPTION ARITHMETIC RATIONAL !多桁の整数

LET N=1
FOR K=1 TO 3 !1番目、2番目、3番目

   DO
      LET X=N*(2*N-1) !六角数

      LET D=SQR(1+24*X) !五角数X=N(3N-1)/2より
      IF D=INT(D) THEN
         LET M=(1+D)/6
         IF M=INT(M) THEN

            LET D=SQR(1+8*X) !三角数X=N(N+1)/2より
            IF D=INT(D) THEN
               LET M=(1+D)/2
               IF M=INT(M) THEN EXIT DO
            END IF

         END IF
      END IF
      LET N=N+1
   LOOP
   PRINT STR$(K);":"; X ;N !1533776805

   LET N=N+1
NEXT K

END

 

闖入者

 投稿者:★  投稿日:2014年 3月22日(土)23時06分8秒
  http://userdisk.webry.biglobe.ne.jp/020/691/47/N000/000/004/139539424737280661228.gif

の 双対曲線 や  クレ モナ 変換 に 魅了された 少女 A が ↓ の 問題 提起 ;

----------------------------------------------------------------------------------------

(* 代数曲線 c --*---> c^*双対曲線--Cr--->Cr[c^*]

代数曲線 c --Cr--->Cr[c]----*----> (Cr[c])^*


      ↓の 托生 は 或る代数曲線 KARA 開始し

   上の如き ●双対化  や  ●クレ モナ 変換 Cr を したり

       ● 更に 其の 双対化 を 等等

           ■ 好き放題 に 少女 A が 為したものであります;

      (【放埒・放埓】ねっ! と 云われても )*)


TAKUSHOU = { -110592 x^2 + 3125 x^4 - 92160 x^2 y - 24320 x^2 y^2 -
     262144 y^3 + 6080 x^2 y^3 - 262144 y^4 + 1440 x^2 y^4 -
     98304 y^5 + 108 x^2 y^5 - 16384 y^6 - 1024 y^7 == 0,

     -x^2 + 16 y^3 - 8 y^4 + y^5 == 0,

   x^2 - 8 x^2 y + 16 x^2 y^2 - y^5 ==  0,

    -3125 x^2 + 110592 x^4 - 15000 x^2 y - 13200 x^2 y^2 + 1024 x^2 y^3 - 108 y^5 == 0};

<< Graphics`ImplicitPlot`
ImplicitPlot[TAKUSHOU, {x, -6, 6}, {y, -12, 8},
PlotStyle -> {{Thickness[0.012],
    RGBColor[1, 0, 0]}, {Thickness[0.012],
    RGBColor[0, 0, 1]}, {Thickness[0.012], RGBColor[0, 1, 0]},
   {Thickness[0.012], RGBColor[0.7, 0.6, 0]}},
AspectRatio -> Automatic]


(* 今回の TAKUSHOU は どれか 一つが 有理曲線なら 他 も ま  た 有理曲線 で  ある。

          (他もまた おまえも 有理曲線 かい!    <---   も   かい!)

    と 少女 A が 云うと A の 父 が □「「一蓮託生 定理」」□ と 命名した。

  (ちょっと 違うような 気がしたが 家族全員-{父} が @まっ いいか@ と)


TAKUSHOU を 視ると 次数も異なり 「長過ぎる! おまけに 次数 高過ぎる!!」等

http://www.wolframalpha.com/

が ===== 挿入すら 拒絶 するのも在り math.======== 嗚呼.......



●  どれか 一つが 有理曲線なら 他もまた 有理曲線である

      との 少女 A の 言明に従い


     一番それらしき 代数曲線を すぐさま 有理曲線化し

  他のも それを用いて どんどん 有理曲線 表示を 為して下さい。*)



   >管理人が考えた現代的例文】
>会社の不祥事が世間に公になった時、社員の反応はどうだったか。
>「愛社精神を持て」という社長の教育の賜物かどうか。
>「こんな会社と一蓮托生なんてまっぴらだ」と言って、
>仕事を休んでハローワークに行く若手社員も多かった。

    有理曲線って 何 ぁ--------- に ? と 云われる 方へ  過去に ↓ コピペ;

http://userdisk.webry.biglobe.ne.jp/020/691/47/N000/000/004/139390107886545715228.gif


http://userdisk.webry.biglobe.ne.jp/020/691/47/N000/000/004/139488844970565703225.gif



------------------------

初めて お邪魔致します

無謀にも 飯高先生の 日々の 掲示板に 数年に 亘り 投稿して いる モノ です

検索されれば ソレが 瞬時に 眼前に。


苦闘中ですので 助言いただければ 幸甚です。


私が 具現中のも 十進BASIC で なされれば  初学者 も

感動される 筈 です ので お願い致します。A
 

7^nの下3けた

 投稿者:山中和義  投稿日:2014年 3月23日(日)12時48分53秒
  大阪桐蔭中学 入試問題 2009年度(平成21年度)算数7番
たとえば7×7×7×7=2401のように、7を4回かけた数を7[4]のように表します。
よって、7[4]の下3けたは401となります。
ただし、7[1]、7[2]の下3けたはそれぞれ007、049として考えます。
このとき、次の問いに答えなさい。
(1) 7[8]を計算しなさい。
(2) 7[20]の下3けたを求めなさい。
(3) 7[2009]の下3けたを求めなさい。

答え
(1) 7[8]=7[4]×7[4]=2401×2401=5764801
(2) (1)より、7[8]の下3けたは801
    7[20]=7[8]×7[8]×7[4]=801×801×401=257282001 ∴7[20]=001
(3) 7[2009]は、7[20]を100回かけた数に7[8]をかけて、さらに7[1]をかけたものである。
    7[20]を100回かけた数の下3けたは001なので、801×7=5607 ∴7[2009]=607
(終り)

7のべき乗の下3けたを表示してみると、


!7^2009 mod 1000 の計算
LET x=1
FOR n=1 TO 2009
   LET x=MOD(x*7,1000)
   PRINT n; x
NEXT n
END



その2


!7^2009=(7^20)^100*7^9≡1^100*7^9≡7^9 mod 1000
LET x=7
LET c=1
DO UNTIL x=1 OR c>2009 !7^c≡1 mod 1000を満たすcを見つける
   LET x=MOD(x*7,1000)
   LET c=c+1
LOOP
PRINT c
LET m=MOD(2009,c) !2009=c*Q+mより、(7^c)^Q*(7^m)と分解する
PRINT m
PRINT MOD(7^m,1000) !7^c≡1 mod 1000なので
END



高校生による考察

7*7=49=50-1より、7^2000=(50-1)^1000
これを二項定理で展開すると、
 項 comb(1000,r)*50^r*(-1)^(1000-r)、r=0,1,2,3,…
の和となる。
r=3以上では、50^rが1000で割り切れるから、下3桁はすべて0となる。


OPTION ARITHMETIC RATIONAL !多桁整数
LET s=0
FOR r=2 TO 0 STEP -1 !r=3,2,1,0のとき
   LET s=s + comb(1000,r)*50^r*(-1)^(1000-r)
NEXT r
PRINT MOD(s*7^9,10^3) !残り7^9を加味して
END



その2 多項式(x-1)^rの展開とその値


OPTION ARITHMETIC RATIONAL !多桁整数
LET x=50 !7*7=49=50-1より、7^2008=(50-1)^1004
LET s=0 !二項定理で展開した式をホーナー法で計算する
FOR r=2 TO 0 STEP -1 !r=3以上では、50^rが10000で割り切れるから、下3桁はすべて0となる。
!!FOR r=1004 TO 0 STEP -1
   LET s=MOD(s*x + comb(1004,r)*(-1)^(1004-r), 10^3)
NEXT r
PRINT MOD(s*7,10^4) !残り7を加味して
END



その2-2 多項式(x-3)^rの展開とその値


OPTION ARITHMETIC RATIONAL !多桁整数
LET x=10 !7^2009=(10-3)^2009
LET s=0 !二項定理で展開した式をホーナー法で計算する
FOR r=2 TO 0 STEP -1 !10^3, 10^2, 10, 1
!!FOR r=2009 TO 0 STEP -1
   LET s=MOD(s*x + comb(2009,r)*(-3)^(2009-r), 10^3)
NEXT r
PRINT s
END

 

(無題)

 投稿者:★  投稿日:2014年 3月24日(月)00時28分21秒
  我々は 若き飯高先生の頃の血が逆流した 二重接線を 追体験し 其処に停留状態で 悲嘆中..先に進めず...

●2次関数と円x^2+y^2=r^2との共通接線  を 飯高先生が推奨された @十進BASIC@ を用いて

            具現された方に 邂逅しました(2014.3.23) ↓ ;

                 其れを 味読願います。

               (どの位 プログラムを組む愉しみを 味われたか 忖度しつつ)

-------------------------------------------------------------------------------------
!図形と方程式

SET WINDOW -8,8,-8,8 !表示領域を設定する ※調整が必要である
DRAW grid !XY座標

PUBLIC NUMERIC cEps !精度 ※調整が必要である
LET cEPS=1E-8
PUBLIC NUMERIC cINF !∞ ※調整が必要である
LET cINF=999999

PUBLIC NUMERIC gcCOLOR,gcSTYLE,gcLINESTYLE !描画色、線種
LET gcCOLOR=1 !黒色
LET gcLINESTYLE=1 !実線
!------------------------------ ここまでがサブルーチン


!●2次関数と円x^2+y^2=r^2との共通接線

LET A=1/2
LET B=0
LET C=-5
CALL gcDRAWFNC2(A,B,C,-8,8)

LET R=3 !x^2+y^2=r^2
CALL gcDRAWCIRCLE(0,0,-R^2,"",-1)


!2次関数y=Ax^2+Bx+C上の点(a,Aa^2+Ba+C)における接線
!y-f(a)=f'(a)(x-a) ∴y=(2Aa+B)x+(C-Aa^2)
!これが、円x^2+y^2=R^2と接するには、円の中心との距離が半径となる必要がある。
!| C-Aa^2 |/√{(2Aa+B)^2+(-1)^2}=R
!∴A^2a^4 -2(2A^2R^2+AC)a^2 -4ABR^2a -(B^2+1)R^2+C^2=0
!この4次方程式の実数解が2次関数上の接点である。

LET aa=A^2 !x^4の係数
LET bb=0 !x^3
LET cc=-2*(2*A^2*R^2+A*C) !x^2
LET dd=-4*A*B*R^2 !x
LET ee=-(B^2+1)*R^2+C^2 !1

DIM x(4)
CALL Solve4Equ(aa,bb,cc,dd,ee, x,K) !実数解を得る
PRINT K
MAT PRINT x;
FOR i=1 TO K
   CALL gcDRAWPOINT(x(i),gcFNC2VAL(x(i),A,B,C),STR$(i))

   LET L=2*A*x(i)+B !2次関数上の点における接線
   LET M=-1
   LET N=C-A*x(i)^2
   CALL gcDRAWLINE(L,M,N,"",-1)
NEXT i

END


!考察
!2次関数y=Ax^2+Bx+C上の点(a,Aa^2+Ba+C)における接線
!y-f(a)=f'(a)(x-a) ∴y=(2Aa+B)x+(C-Aa^2)
!これが、円(x-P)^2+(y-Q)^2=R^2と接するには、円の中心との距離が半径となる必要がある。
!| (2Aa+B)P-Q+C-Aa^2 |/√{(2Aa+B)^2+(-1)^2}=R
!((2Aa+B)P-Q+C-Aa^2)^2=R^2{(2Aa+B)^2+(-1)^2}
!{(BP-Q+C)+2APa-Aa^2}^2=R^2{4A^2a^2+4ABa+B^2+1}
!(BP-Q+C)^2+(BP-Q+C)(2APa-Aa^2)+(2APa-Aa^2)^2=R^2{4A^2a^2+4ABa+B^2+1}
!(BP-Q+C)^2+2AP(BP-Q+C)a-A(BP-Q+C)a^2 +4A^2P^2a^2-4A^2Pa^3+A^2a^4=R^2{4A^2a^2+4ABa+B^2+1}
!A^2a^4 -4A^2Pa^3 -{A(BP-Q+C)-4A^2(P^2-R^2)}a^2 +2AP(BP-Q+C-2ABR^2)a +(BP-Q+C)^2-(B^2+1)R^2=0


EXTERNAL SUB Solve4Equ(a4,a3,a2,a1,a0, x(),K) !4次方程式 Ax^4+Bx^3+Cx^2+Dx+E=0、A≠0 の解
!フェラーリ(Ferrari)の方法

!x=y-a3/(4*a4)を代入して、3次の項を消去すると、
!y^4+p*y^2+q*y+r=0
!ただし、
! p=-3*a3^2/(8*a4^2)+a2/a4
! q=a3^3/(8*a4^3)-a2*a3/(2*a4^2)+a1/a4
! r=-3*a3^4/(256*a4^4)+a2*a3^2/(16*a4^3)-a1*a3/(4*a4^2)+a0/a4

LET p=(-3*a3^2/8/a4 + a2)/a4
LET q=((a3^3/(2*a4) - 2*a2*a3)/(2*a4) + 2*a1)/(2*a4)
LET r=(((-3*a3^4/(4*a4) + 4*a2*a3^2)/(4*a4) - 4*a1*a3)/(4*a4) + 4*a0)/(4*a4)

!!!PRINT p;q;r !debug

!q=0のとき、
! 複2次式 (y^2 - (-p-√{p^2-4r})/2)(y^2 - (-p+√{p^2-4r})/2)=0 と因数分解される。
!q≠0のとき、
! y^4=-p*y^2-q*y-rとして、両辺にy^2*z+z^2/4を加えて、変形すると、
! (y^2+z/2)^2=(z-p){y-q/(2*(z-p))}^2 + {1/(4*(z-p))}(z^3-p*z^2-4*r*z+4*p*r-q^2)
! ここで、z^3-p*z^2-4*r*z+4*p*r-q^2=0となるzを1つ求めると、
! 同様に、複2次式
!  (y^2+z/2 - √(z-p){y-q/(2*(z-p))})(y^2+z/2 + √(z-p){y-q/(2*(z-p))})=0
! と因数分解できる。
!後は、この2次方程式を解けばよい。

IF q=0 THEN
   LET t=p^2-4*r !判別式
   IF t>0 THEN
      CALL Solve2Equ(1,0,-(-p-SQR(t))/2 ,y1,y2,K1)
      CALL Solve2Equ(1,0,-(-p+SQR(t))/2 ,y3,y4,K2)
   ELSEIF t=0 THEN !(y^2 + p/2)^2=0の形
      CALL Solve2Equ(1,0,p/2 ,y1,y2,K1)
      LET K2=0
   ELSE !2式とも虚数解
      LET K1=0
      LET K2=0
   END IF

ELSE
   CALL Solve3Equ(1,-p,-4*r,4*p*r-q^2, z1,z2,z3,KK)
   LET t=SQR(z1-p)

   CALL Solve2Equ(1,-t, q/(2*t)+z1/2, y1,y2,K1)
   CALL Solve2Equ(1, t,-q/(2*t)+z1/2, y3,y4,K2)

END IF

LET K=0 !実数解の個数
IF K1>0 THEN
   LET K=K+1
   LET x(K)=y1-a3/(4*a4) !1番目 x=y-a3/(4*a4)
   IF K1=2 THEN
      LET K=K+1
      LET x(K)=y2-a3/(4*a4) !2番目
   END IF
END IF
IF K2>0 THEN
   LET K=K+1
   LET x(K)=y3-a3/(4*a4) !3番目
   IF K2=2 THEN
      LET K=K+1
      LET x(K)=y4-a3/(4*a4) !4番目
   END IF
END IF
END SUB

!------------------------------


MERGE "FV.LIB" !関数とグラフ、図形と方程式
MERGE "EQU.LIB" !整式、方程式


=============================================

                 少女 A は ↑をみた刹那

            双方 の ■ 双対曲線を 多様な発想で求め;

c1; x^2 + y^2 - r^2==0                c1^* ;_________________==0
c2; y - (A*x^2 + B*x + C)==0          c2^* ;_________________==0

   c1^*∩c2^* を求め瞬時に図示可能と  方針を 述べた。


   云うだけ番長なら 誰でも叶う発想ね と カゲの声   が聴こえ 為した;

         c1^* ;(r^2 x^2+r^2 y^2-1)=0
         c2^* ; (4 A C y^2+4 A y-B^2 y^2-2 B x y-x^2)=0

         この交点なら 最高4 で 4本の共通接線ねっ! と 妹の a.

  例示の

LET A=1/2
LET B=0
LET C=-5

r=3 は 特殊すぎて 2本ねっと  と 妹の a.


4本の共通接線が 欲しい! と 欲求 され 少女 A が 期待にこたえた;

<< Graphics`ImplicitPlot`
{(-5 - 2 x - x^2/2 + y) (-9 + x^2 + y^2) ==
   0, (-x^2 + 2 y - 4 x y + 6 y^2) (-1 + 9 x^2 + 9 y^2) == 0,
  1.` - 0.3333333333333333` y == 0,
  1 + (0.32229741684803903` ) x + (0.08506166118876686` ) y == 0,
  1 + (0.2557143513185063` ) x - (0.213825353129292` ) y == 0,
  1 - (0.3318579220126996`) x + (0.03132779450462768` ) y == 0};
ImplicitPlot[%, {x, -8, 9}, {y, -5, 48 - 20},
PlotStyle -> {{Thickness[0.012],
    RGBColor[1, 0, 0]}, {Thickness[0.00712],
    RGBColor[0, 0, 1]}, {Thickness[0.01],
    RGBColor[0.3, 0.31, 0.3]}, {Thickness[0.01],
    RGBColor[0.3, 0.31, 0.3]}, {Thickness[0.01],
    RGBColor[0.3, 0.31, 0.3]}, {Thickness[0.01],
    RGBColor[0.3, 0.31, 0.3]},
   {Thickness[0.015], RGBColor[0.913, 0.3, 0.961]},
   {Thickness[0.015], RGBColor[0.913, 0.3, 0.961]}},
AspectRatio -> Automatic, PlotPoints -> 276 - 100]

グラフは 伊達に描くものではありません と。

  https://www.youtube.com/watch?v=cBphkk34zAU


    薬物  依存症の 少女 A の 両親が 依存した 顛末 の コピペ;

  http://www.wolframalpha.com/input/?i=%28-5+-+2+x+-+x%5E2/2+%2B+y%29+%3D%3D0%2C%28-9+%2B+x%5E2+%2B+y%5E2%29%3D%3D0

  http://www.wolframalpha.com/input/?i=%28-x%5E2+%2B+2+y+-+4+x+y+%2B+6+y%5E2%29%3D%3D0%2C+%28-1+%2B+9+x%5E2+%2B+9+y%5E2%29+%3D%3D+0

  双対が 円 と 双曲線 で 交点を ロハで と 在りがたや

  https://www.youtube.com/watch?v=4Hp9j8rgcm4

       \\\\\\\\\\\\\

       行間埋め子さんが 方針はずばり述べているが

       上の行間が空き過ぎ  故

       必ず 行間を丁寧に埋めて!!!! と 要望した。


       要望をシカトしないで 此処に投稿願います;

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


   特殊過ぎる

    例示の

LET A=1/2
LET B=0
LET C=-5

r=3 を 双対の視座で 具



\\\\\\\\\\\



     草の根 民間 レベル での 真の 相互尊重 に 休日フル利用で

                    感謝致します。

            それぞれの お国言葉で その感動 語句を

               付記願います.

           https://www.youtube.com/watch?v=NWBVfUiXIis

           <----土筆が 恥ずかしげに ...と


            https://www.youtube.com/watch?v=4IT_ZHGsQXw

            の 地方も在り....


      
 

Re: 7^nの下3けた

 投稿者:山中和義  投稿日:2014年 3月24日(月)09時54分31秒
  > No.3343[元記事へ]

問題
7^k(kは自然数)を10進法表示したとき、
表示の中のある部分に0が8個以上並ぶことが起こるという。
さて、これが起こるkはいくつか?

考察
オイラーの定理より、a>0、n>1のとき、(a,n)=1ならa^φ(n)≡1 mod n
(7,10^k)=1なので、7^φ(10^k)≡1 mod 10^k
k=1のとき、φ(10)=4より、7^4≡1 mod 10
k=2のとき、φ(100)=40より、7^40≡1 mod 100
k=3のとき、φ(1000)=400より、7^400≡1 mod 1000
k=4のとき、φ(10000)=4000より、7^4000≡1 mod 10000
  :
よって、01、001、0001、00001、… のように下のけたに0が並ぶ。
この場合、7^4=2401のように、7^4≡1 mod 100、7^40≡1 mod 1000、… となる。
(終り)

補足
(x,y)=1のとき、φ(xy)=φ(x)φ(y)
pは素数のとき、
φ(p)=p-1
φ(p^m)=p^m-p^(m-1)=(p-1)p^(m-1)
より、
φ(10)=φ(2*5)=φ(2)φ(5)=(2-1)(5-1)=4
φ(100)=φ(2^2*5^2)=(2^2-2)(5^2-5)=2*20=40
φ(1000)=φ(2^3*5^3)=(2^3-2^2)(5^3-5^2)=4*100=400
φ(10000)=φ(2^4*5^4)=(2^4-2^3)(5^4-5^3)=8*500=4000
(終り)


実際に、探索してみると、


OPTION ARITHMETIC RATIONAL !多桁の整数
FOR N=1 TO 9 !mod 10^n
   LET A=7
   LET K=0
   LET B=1 !a^k=b
   DO
      LET K=K+1
      LET B=MOD(B*A,10^N)
   LOOP UNTIL B=1 !a^k≡1
   PRINT N; K
NEXT N
END


 n  k
 ---------
  1  4
  2  4
  3  20
  4  100
  5  500
  6  5000
  7  50000
  8  500000
  9  5000000

となる。


数字列の途中に現れる0を考えると、

答え
1  4
2  20
3  74
4  154
5  499
6  510
7  4411
8  6984
9  33836
(終り)


9以上は困難であるが、、、


OPTION ARITHMETIC RATIONAL !多桁の整数

LET A=7

LET K=0 !a^k=b
LET B=1

LET N=1 !0がn個
LET S$=REPEAT$("0",N)
DO WHILE N<=10 !10個まで
   IF POS(STR$(B),S$)>0 THEN !最初に見つかったもの
      PRINT N; K

      LET N=N+1 !次へ
      LET S$=REPEAT$("0",N)
   ELSE
      LET K=K+1
      LET B=B*A
   END IF
LOOP

END


 

質問

 投稿者:GAI  投稿日:2014年 3月25日(火)17時30分25秒
  OPTION ARITHMETIC RATIONAL !多桁の整数

FOR A=2 TO 9

LET K=0 !a^k=b
LET B=1

LET N=1 !0がn個

LET S$=REPEAT$("7",N)
DO WHILE N<=7 !10個まで
IF POS(STR$(B),S$)>0 THEN !最初に見つかったもの
PRINT N; K

LET N=N+1 !次へ
LET S$=REPEAT$("7",N)
END IF

LET K=K+1
LET B=B*A
LOOP

PRINT
NEXT A

END


で計算させたら

7^175 が7が5個ならび、7^1857が7が6個並ぶ
という結果を出すのですが、
実際7^157を計算させると

7^175=
78011207912208158102404641279111807777771881820069326361118396985716038858440266
71779915606471699893312656644407347632248554716494939953912586437943

なる値で7が6個並んでしまいます。
これはどうしたことかわかりません。
 

Re: 質問

 投稿者:山中和義  投稿日:2014年 3月25日(火)19時56分18秒
  > No.3346[元記事へ]

GAIさんへのお返事です。

> 7^175=
> 78011207912208158102404641279111807777771881820069326361118396985716038858440266
> 71779915606471699893312656644407347632248554716494939953912586437943
>
> なる値で7が6個並んでしまいます。

バグです。ご迷惑をおかけしました。
元のプログラムを修正しておきます。
 

いわゆるコラッツの問題

 投稿者:山中和義  投稿日:2014年 3月28日(金)13時11分58秒
  2以上の自然数nに対して、
 その数が素数なら、10倍して1を足す。 合成数なら、最小の素因数で割る。
という操作を行い新しい自然数を作る。
このとき、任意の自然数から始めて、この操作を繰り返し行うと、
最終的には必ず43になる。

考察
合成数は、素数になる。

43以下の素数
  5 → 17 → 19 → 13 → ┐
                         ↓
              3 → 31 → ┐
                         ↓
                   41 → 23 → 11 → ┐
                                     ↓
                     2 → 7 → 29 → 37 → 43 → 43

43より大きい素数は、自分より小さい素数になる。
(終り)


OPTION ARITHMETIC RATIONAL !多桁の整数

FOR i=2 TO 1000
   IF prmdiv(i)=i THEN !素数なら

      LET N=i

      LET C=0 !回数
      DO
         LET C=C+1
         LET T=prmdiv(N)
         IF T=N THEN !素数
            PRINT " ";STR$(N);
            LET N=10*N+1
         ELSE
            PRINT " *";STR$(N);
            LET N=N/T
         END IF
      LOOP UNTIL prmdiv(N)=N AND (N<=43 OR N<i)
      PRINT N
      !PRINT C

   END IF
NEXT i
END


!UBASIC.LIB 抜粋

EXTERNAL FUNCTION prmdiv(n) !1より大きな最小の約数
OPTION ARITHMETIC RATIONAL !多桁の整数
IF n<>INT(n) THEN !整数以外なら
   PRINT "prmdiv関数でパラメータが不適当です。"
   STOP
ELSEIF n=0 THEN
   LET prmdiv=0
ELSE
   LET n=ABS(n) !絶対値をとる

   IF MOD(n,2)=0 THEN !2の倍数
      LET prmdiv=2
   ELSEIF MOD(n,3)=0 THEN !3の倍数
      LET prmdiv=3
   ELSE
      FOR i=5 TO INTSQR(n) STEP 6
         IF MOD(n,i)=0 THEN !5,11,17,23,29,…
            LET prmdiv=i
            EXIT FUNCTION
         ELSEIF MOD(n,i+2)=0 THEN !7,13,19,25,31,…
            LET prmdiv=i+2
            EXIT FUNCTION
         END IF !+1,+3,+5は2の倍数(偶数)、+1,+4は3の倍数、+5は5の倍数
      NEXT i
      LET prmdiv=n !その数自身
   END IF
END IF
END FUNCTION


実行結果

2 *21 7
3 31
5 *51 17
7 71 *711 *237 79 *791 113 *1131 *377 29
11 *111 37
13 131 *1311 *437 23
17 *171 *57 19
19 191 *1911 *637 *91 13
23 *231 *77 11
29 *291 97 971 *9711 *3237 *1079 83 *831 277 *2771 163 *1631 233 *2331 *777 *259 37
31 311 *3111 *1037 61 *611 47 *471 157 1571 *15711 5237 *52371 *17457 *5819 *529 23
37 *371 53 *531 *177 59 *591 197 *1971 *657 *219 73 *731 43
41 *411 137 *1371 457 *4571 653 *6531 *2177 311 *3111 *1037 61 *611 47 *471 157 1571 *15711 5237 *52371 *17457 *5819 *529 23
43 431 *4311 *1437 479 *4791 1597 15971 *159711 *53237 383 *3831 1277 *12771 *4257 *1419 *473 43
47 *471 157 1571 *15711 5237 *52371 *17457 *5819 *529 23
53 *531 *177 59 *591 197 *1971 *657 *219 73 *731 43
59 *591 197 *1971 *657 *219 73 *731 43
61 *611 47
67 *671 61
71 *711 *237 79 *791 113 *1131 *377 29
73 *731 43
79 *791 113 *1131 *377 29
83 *831 277 *2771 163 *1631 233 *2331 *777 *259 37
89 *891 *297 *99 *33 11
97 971 *9711 *3237 *1079 83

   :
   :

 

7^n の上位の数字の並び

 投稿者:山中和義  投稿日:2014年 3月30日(日)11時44分44秒
  > No.3345[元記事へ]

7^nを10進法表示して、上位の数字の並びに7が並ぶものを考える。
まず、7^1=7なので、1個は1である。
次に2個の場合、すなわち7^n=77…となるnを求める。


考察
a^nの概算を考える。
a^n=10^(n*LOG10(a)) より、
10^(n*LOG10(a)の小数部分)×10^(n*LOG10(a)の整数部分) ← A.BCD…×10^Eの形
     仮数           指標
(終り)


!a^nの概算
!※常用対数の精度を考慮する。
!※代入文の実行による丸め誤差を考慮する。
LET a=7
FOR n=0 TO 100
   PRINT n; 10^FP(n*LOG10(a)); "× 10^"; STR$( INT(n*LOG10(a)) )
NEXT n
END


実行結果

0  1 × 10^0
1  7 × 10^0
2  4.9 × 10^1
3  3.43 × 10^2
4  2.401 × 10^3
5  1.6807 × 10^4
6  1.17649 × 10^5
7  8.23543 × 10^5
8  5.764801 × 10^6
9  4.0353607 × 10^7
10  2.82475249 × 10^8
11  1.977326743 × 10^9
12  1.3841287201 × 10^10
13  9.6889010407 × 10^10
14  6.78223072849 × 10^11
15  4.747561509943 × 10^12
16  3.3232930569601 × 10^13
17  2.32630513987207 × 10^14
18  1.62841359791045 × 10^15
19  1.13988951853731 × 10^16
20  7.9792266297612 × 10^16
21  5.58545864083284 × 10^17
22  3.90982104858299 × 10^18
23  2.73687473400809 × 10^19
24  1.91581231380567 × 10^20
25  1.34106861966397 × 10^21
26  9.38748033764776 × 10^21
27  6.57123623635343 × 10^22
28  4.5998653654474 × 10^23
29  3.21990575581318 × 10^24
30  2.25393402906923 × 10^25
31  1.57775382034846 × 10^26
32  1.10442767424392 × 10^27
33  7.73099371970745 × 10^27
    :
    :




問題
a,bは自然数でaは10^k(kは負でない整数)の形ではないとする。
nは負でない整数として、a^nを10進法で表したとき、
その先頭にbを10進法で表したものがそのまま現れるnを求めよ。

考察
mは非負整数とする。
0≦c<10^mとして、a^n=b10^m+c ∴a^n/10^m=b+c/10^m
これより、b≦a^n/10^m<b+1
常用対数をとって、LOG10(b)≦n*LOG10(a)-m<LOG10(b+1)
m+LOG10(b)≦n*LOG10(a)<m+LOG10(b+1)
(終り)


LET a=7
LET b=77

LET S=LOG10(b)
LET T=LOG10(b+1)
LET W=LOG10(a)
LET m=0
DO
   LET n1=CEIL( (m+S)/W )
   LET n2=CEIL( (m+T)/W )
   IF n1<n2 THEN EXIT DO
   LET m=m+1
LOOP
!!!PRINT m; n1;n2 !debug
PRINT n1;"乗"

END

 

無題

 投稿者:永野護  投稿日:2014年 3月30日(日)16時47分9秒
  aを任意の正の有理数としたとき((a^n)+1)のn乗根は必ず無理数となるのでしょうか。
 

Re: 無題

 投稿者:山中和義  投稿日:2014年 3月30日(日)19時23分59秒
  > No.3350[元記事へ]

永野護さんへのお返事です。

> aを任意の正の有理数としたとき((a^n)+1)のn乗根は必ず無理数となるのでしょうか。

フェルマーの定理
 方程式 x^n+Y^n=z^n(nは3以上の自然数)を満たす自然数解(X,Y,Z)はない
なので、
3以上では無理数となると思います。

n=2のとき、ピタゴラス数で、
X^2+Y^2=Z^2 ∴(X/Y)^2+1=(Z/Y)^2 とすれば有理数になります。

例 3^2+4^2=5^2 ∴(3/4)^2+1=(5/4)^2 ∴√((3/4)^2+1)=5/4
 

無題

 投稿者:永野護  投稿日:2014年 3月31日(月)11時55分16秒
  丁寧な解説ありがとうございました。
参考にさせていただきます。
敬具
 

これって算数?

 投稿者:山中和義  投稿日:2014年 4月 4日(金)10時55分19秒
  問題
3で割って2余り、5で割って3余り、7で割って5余り、11で割って7余る4桁の自然数はいくつあるか。

答え
3で割ると2余るので、1を加えると3の倍数となる。
5で割ると3余るので、2を加えると5の倍数となる。
7で割ると5余るので、2を加えると7の倍数となる。
11で割ると7余るので、4を加えると11の倍数となる。
これに着目して、
 3,5,7,11の最小公倍数は、3×5×7×11=1155である。
と
  +3: 1  4  7 10 13 16 19 22 25 28 31 34 37
  +5: 2  7 12 17 22 27 32 37
  +7: 2  9 16 23 30 37
 +11: 4 15 26 37
より、
題意を満たす数は、1155-37=1118

残りは1155を加えていくと、
1118+1155=2273
2273+1155=3428
3428+1155=4583
4583+1155=5738
5738+1155=6893
6893+1155=8048
8048+1155=9203

したがって、8個となる。
(終り)

求める数が、0と最小公倍数のどちらに近いかで検索する回数が多くなったり少なかったりする。

次の例では真ん中あたりにあるので、どちらでも同じとなる。

 問題
 3で割って2余り、5で割って3余る2桁の整数はいくつあるか。
 プラス方向
  +3: 2 5 8
  +5: 3 8
 マイナス方向
  +3: 1 4 7
  +5: 2 7


1118を見つける方法
別解
7×11×13=1001より、11で割って7余る4桁の数で最小となるのは、1001+7=1008
5の倍数は一の位が0,5(5の倍数の判定)なので、5で割って3余るのは、3,8である。
これに注意して(5,3,7の倍数の順に絞り込みながら)、
まず、1008は、1+0+0+8=9(3の倍数の判定)なので、3で割リ切れる。題意を満たさない。
11×5=55なので、次は、1008+55=1063
これは、1+0+6+3=10なので、3で割って1余る。題意を満たさない。
続けて、1063+55=1118
これは、1+1+1+8=11 なので、3で割って2余る。
また、1118÷7=159余り5 なので、7で割って5余る。
以上より、題意を満たす4桁の数の最小は、1118である。
(終り)


算数やパズルとしてアプローチしてみたが、一般に、次のように解くことができる。


!連立1次合同式を解く

OPTION ARITHMETIC RATIONAL !多桁の整数

DATA 4
DATA 3,2 !3で割ると2余る
DATA 5,3 !5で割ると3余る
DATA 7,5 !7で割ると5余る
DATA 11,7 !11で割ると7余る
DATA 1000,10000 !1000以上10000未満の範囲

READ K
DIM A(K),B(K) !x≡a mod b
FOR i=1 TO K
   READ B(i),A(i)
NEXT i


LET S=1 !中国剰余定理(Chinese remainder theorem)より
FOR i=1 TO K
   LET S=S*B(i) !b1*b2* … *bn
NEXT i
!!!PRINT S !debug

LET R=0 !x=Σui*xi*ai (mod b1*b2* … *bn)
FOR i=1 TO K
   LET T=S/B(i) !ui*xi≡1 (mod bi)
   LET R=R+T*modinv(T,B(i))*A(i)
NEXT i
LET R=MOD(R,S) !解
!!!PRINT R !debug


READ P,Q ![p,q)の範囲で検索する
LET C=0
LET N=CEIL((P-R)/S)*S+R
DO WHILE N<Q
   LET C=C+1
   PRINT N
   LET N=N+S
LOOP
PRINT C; "個"


!初項r、公差sの等差数列  項数k個 r,r+s,r+2s,…,r+(k-1)s
PRINT CEIL((Q-R)/S)-CEIL((P-R)/S); "個"

END


!UBASIC.LIB 抜粋

EXTERNAL FUNCTION modinv(a,n) !nを法としたaの逆元 a*x≡1 (mod n)
OPTION ARITHMETIC RATIONAL !多桁の整数
LET d0=a !(a,1)
LET x0=1
LET d1=n !(n,0)
LET x1=0
DO WHILE d1<>0 !拡張ユークリッドの互除法によりa*x+b*y=cの解を求める
   LET t=INT(d0/d1)
   LET T1=d0 !(d0,x0)=(d1,x1)、(d1,x1)=(d0-t*d1,x0-t*x1)
   LET T2=x0
   LET d0=d1 !次へ
   LET x0=x1
   LET d1=T1-t*d1
   LET x1=T2-t*x1
LOOP
IF d0=1 THEN !GCD(a,n)=1なら
   IF x0<0 THEN LET x0=x0+n !mod(x0,n)
   LET modinv=x0
ELSE
   LET modinv=0
END IF
END FUNCTION

 

nアーム回動リンク

 投稿者:lark12_long  投稿日:2014年 4月 5日(土)09時28分17秒
  こんなん、作ってみました
ヤコビアン行列の設定について、納得しないままですが、
一応それらしい動きはしてます
文法オプションは、マイクロソフトbasicです


'
'
'  nアーム回動リンク.bas
'
'     nアームリンクに於いて、手先目標位置をマウスで与えた時の、
'     アームの動きを、ヤコビアン、逆ヤコビアン行列を使ってシミュレーション
'
'
'    H26-04-03 完成
'
'
randomize
width=1260
height=640
set bitmap size width,-height
reft=0
right=width*1.5
bottom=0
top=height*1.5
set window left,right,bottom,top

xbase=700        '表示x基点
ybase=400        '表示y基点
pai=3.14156      '円周率
n=7              '関節、アーム数
option base 1

dim l(n)         '各アーム長さ
dim rd(3)        '手先目標位置座標 rd(1) x rd(2) y
dim px(n)        '各関節のx座標
dim py(n)        '各関節のy座標
dim dp(n)        '手先目標位置と、手先位置との偏差  dp(1)=rd(1)-px(n) dp(2)=rd(2)-py(n)
dim q(n)         'q(1)=c1 q(2)=c2 q(3)=c3 q(4)=c4... q(n)=cn
dim dq(n)        '各角度調整量
dim s(n)         's(i)=sin(q(1)+q(2)+....+q(i))
dim c(n)         'c(i)=cos(q(1)+q(2)+....+q(i))
dim ja(n,n)      'ヤコビアン行列
dim invj(n,n)    '逆ヤコビアン行列

'初期設定
l0=110                 '土台固定アーム長さ
for i=1 to n
   l(i)=120*(rnd+0.5)   'アーム1~n長さ
next i


'各関節初期角度
for i=1 to n
   q(i)=10*pai/180       '度からラジアンに変換
next i

call sici               's(i),c(i)の計算

'逆行列化コマンド、mat invj=inv(ja)が
'使える様にする為にヤコビアン行列を,正方行列とする為に、
'ja(3,1)~ja(3,n)、ja(n,1)~ja(n,n)にrndを設定
for i=3 to n
   for j=1 to n
     ja(i,j)=rnd
   next j
next i

call position     '関節1~5、手先の位置の計算
call draw         '表示
call cal1         'シミュレーション計算

'---------------------------------------------
sub cal1
  do while zz=0                           '無限ループ
      mouse poll xm,ym,left,right
      rd(1)=xm-xbase                      '手先目標位置x座標
      rd(2)=ym-ybase-l0                   '手先目標位置y座標

     '位置の計算
      call position                       '関節1~n、手先の位置の計算

     '位置偏差の計算
      dp(1)=rd(1)-px(n)                   '手先目標位置とのx成分偏差
      dp(2)=rd(2)-py(n)                   '手先目標位置とのy成分偏差

     '誤差の評価
      pe=dp(1)^2+dp(2)^2
      if pe<2 then
         call check                       '誤差範囲に収束したら表示
      end if

      call sici                           's(i),c(i)の計算

     'ヤコビアン行列を設定
      ja(1,n)=-l(n)*s(n)
      ja(2,n)=l(n)*c(n)
      for i=n-1 to 1 step -1
        ja(1,i)=ja(1,i+1)-l(i)*s(i)
        ja(2,n)=ja(2,i+1)+l(i)*c(i)
      next i

      mat invj=inv(ja)   'ヤコビアン逆行列計算

      kp=0.03            '修正ゲイン
      '各関節角度修正量計算
      'dq=kp*invj*dp     '行列dq=スカラkp*行列invj*行列dp
      mat invj=kp*invj
      mat dq=invj*dp     '各関節角度修正量

     '各関節角度の修正更新
      mat q=q+dq
      for i=1 to n
        q(i)=mod(q(i),(pai*2))    '360度以内に正規化
      next i
   loop

end sub
'---------------------------------------------
sub sici
    's(i),c(i)の計算
    '関節iの角度を、l(i-1)と成す角度と定義することにより、
    '関節iのx軸と成す角度はΣq(i)と表現出来、
    's(i)=sin(q(1)+q(2)+....+q(i))
    'c(i)=cos(q(1)+q(2)+....+q(i))
    'となる

      for i=1 to n
        cw=0
        for j=1 to i
          cw=cw+q(j)
        next j
        s(i)=sin(cw)     's(i)=sin(q(1)+q(2)+...+q(i))
        c(i)=cos(cw)     'c(i)=cos(q(1)+q(2)+...+q(i))
      next i
end sub
'---------------------------------------------
sub position
   '関節1~nのx、y座標を計算、i=nのときは手先のxy座標となる
   px(1)=l(1)*c(1)
   py(1)=l(1)*s(1)
   for i=2 to n
     px(i)=px(i-1)+l(i)*c(i)
     py(i)=py(i-1)+l(i)*s(i)
   next i
end sub
'---------------------------------------------
sub check
  '収束したら表示する
  call draw
end sub
'---------------------------------------------
sub draw
   set draw mode hidden
   set line width 4
   line(0,0)-(2000,960),1,bf                               '画面クリヤ
   line(100,ybase)-(1700,ybase),5                          'ベースライン
   circle(0+xbase,l0+ybase),10,4,,,,f                      '固定アームの関節

   '各関節表示
   for i=1 to n
     circle(px(i)+xbase,py(i)+ybase+l0),10,4,,,,f
   next i

   '各アームの表示
   line(xbase,ybase)-(xbase,ybase+l0),5                    '固定アーム
   'アーム1~n表示
   for i=1 to n
     line-(px(i)+xbase,py(i)+ybase+l0),6
   next i
   circle(xm,ym),10,5,,,,f                                 '手先目標位置

   '各関節角度表示
   xb=1400
   yb=900
   set text color 5
   set text font "MS明朝",20

   for i=1 to n
     plot text, at xb,yb-50*(i-1):"c"
     plot text, at xb+15,yb-50*(i-1),using "##":i
     plot text, at xb+50,yb-50*(i-1):"="
     cw=0
     for j=1 to i
       cw=cw+q(j)
     next j
     cw=mod(cw,(2*pai))*180/pai                           '360度以内に正規化し、度に変換
     plot text, at xb+110,yb-50*(i-1),using"#####.#":cw
   next i

   set draw mode explicit
end sub
'---------------------------------------------
 

Re: これって算数?の点検で

 投稿者:GAI  投稿日:2014年 4月 5日(土)10時46分20秒
  > No.3353[元記事へ]

山中和義さんへのお返事です。

> 問題
> 3で割って1余り、4で割って2余り、5で割って3余り、8で割って4余る4桁の自然数はいくつあるか。
  題意を満たす数は、存在しない。

従って 0個
であるはずなのですが

次のプログラムで実行してみたら
>
> !連立1次合同式を解く
>
> OPTION ARITHMETIC RATIONAL !多桁の整数
>
> DATA 4
> DATA 3,1 !3で割ると1余る
> DATA 4,2 !4で割ると2余る
> DATA 5,3 !5で割ると3余る
> DATA 8,4 !8で割ると4余る
> DATA 1000,10000 !1000以上10000未満の範囲
>
> READ K
> DIM A(K),B(K) !x≡a mod b
> FOR i=1 TO K
>    READ B(i),A(i)
> NEXT i
>
>
> LET S=1 !中国剰余定理(Chinese remainder theorem)より
> FOR i=1 TO K
>    LET S=S*B(i) !b1*b2* … *bn
> NEXT i
> !!!PRINT S !debug
>
> LET R=0 !x=Σui*xi*ai (mod b1*b2* … *bn)
> FOR i=1 TO K
>    LET T=S/B(i) !ui*xi≡1 (mod bi)
>    LET R=R+T*modinv(T,B(i))*A(i)
> NEXT i
> LET R=MOD(R,S) !解
> !!!PRINT R !debug
>
>
> READ P,Q ![p,q)の範囲で検索する
> LET C=0
> LET N=CEIL((P-R)/S)*S+R
> DO WHILE N<Q
>    LET C=C+1
>    PRINT N
>    LET N=N+S
> LOOP
> PRINT C; "個"
>
>
> !初項r、公差sの等差数列  項数k個 r,r+s,r+2s,…,r+(k-1)s
> PRINT CEIL((Q-R)/S)-CEIL((P-R)/S); "個"
>
> END
>
>
> !UBASIC.LIB 抜粋
>
> EXTERNAL FUNCTION modinv(a,n) !nを法としたaの逆元 a*x≡1 (mod n)
> OPTION ARITHMETIC RATIONAL !多桁の整数
> LET d0=a !(a,1)
> LET x0=1
> LET d1=n !(n,0)
> LET x1=0
> DO WHILE d1<>0 !拡張ユークリッドの互除法によりa*x+b*y=cの解を求める
>    LET t=INT(d0/d1)
>    LET T1=d0 !(d0,x0)=(d1,x1)、(d1,x1)=(d0-t*d1,x0-t*x1)
>    LET T2=x0
>    LET d0=d1 !次へ
>    LET x0=x1
>    LET d1=T1-t*d1
>    LET x1=T2-t*x1
> LOOP
> IF d0=1 THEN !GCD(a,n)=1なら
>    IF x0<0 THEN LET x0=x0+n !mod(x0,n)
>    LET modinv=x0
> ELSE
>    LET modinv=0
> END IF
> END FUNCTION
>

>


実行結果
1408
1888
2368
2848
3328
3808
4288
4768
5248
5728
6208
6688
7168
7648
8128
8608
9088
9568
18 個
18 個

で明らかに1408は条件を満たしません。?
 

Re: これって算数?の点検で

 投稿者:山中和義  投稿日:2014年 4月 5日(土)12時11分28秒
  > No.3355[元記事へ]

GAIさんへのお返事です。

> 問題
> 3で割って1余り、4で割って2余り、5で割って3余り、8で割って4余る4桁の自然数はいくつあるか。

> 題意を満たす数は、存在しない。


中国剰余定理、ガウスの方法は、3,4,5,8は互いに素でないため使えません。
前述のプログラムは、これによる解法です。

より一般的な解法は、走査して条件を満たすかどうか確認するしかありません。


!連立1次合同式

OPTION ARITHMETIC RATIONAL !多桁の整数

DEF LCM(a,b)=a*b/GCD(a,b) !最小公倍数

DATA 4
DATA 3,1 !x≡1 mod 3
DATA 4,2 !x≡2 mod 4
DATA 5,3 !x≡3 mod 5
DATA 8,4 !x≡4 mod 8

READ K
DIM A(K),B(K) !x≡a mod b
FOR i=1 TO K
   READ B(i),A(i)
NEXT i

LET L=B(1) !最小公倍数を求める
FOR i=2 TO K
   LET L=LCM(L,B(i))
NEXT i

LET C=0
FOR X=A(K) TO L STEP B(K) !1つの合同式( x≡a[k] mod b[k] )を満たす数が
   FOR i=1 TO K-1 !他の合同式を満たすかどうか確認する
      IF MOD(X,B(i))<>A(i) THEN EXIT FOR
   NEXT i
   IF i>K-1 THEN !条件を満たす
      LET C=C+1
      PRINT X; "+"; L; "k" !解
   END IF
NEXT X
IF C=0 THEN PRINT "解なし"

END

 

ものさしの目盛り

 投稿者:山中和義  投稿日:2014年 4月12日(土)09時41分49秒
  問題
自然数を直線状に並べます。
その状態で、連続して並んだいくつかの自然数の合計をとります。
合計をとる自然数はいくつ選んでもかまいません。
1つだけでも、全部でもかまいません。
ただし、続いて並んでいなければならず、飛び飛びに合計することはできません。

(1) 5個の自然数をうまく選んで並べると、1から13までの合計をつくることができます。
(2) 6個の自然数をうまく選んで並べると、1から17までの合計をつくることができます。
(3) 7個の自然数をうまく選んで並べると、1から23までの合計をつくることができます。

例
1個の場合
 1 として、1
2個の場合
 1,2 として、3
3個の場合
 1,3,2 として、6
4個の場合
 1,1,4,3 として、9
 1,3,3,2 として、9

http://www.geocities.co.jp/Berkeley-Labo/6317/jougi.htm
http://math.a.la9.jp/jyougi.htm
http://oeis.org/A004137


考察
p進法を利用した数字の並び
 ① ※丸数字がk個並ぶ 1からkまで 通常の目盛り
 1② 2k+1
 11③ 3k+2
 111④ 4k+3
 1111⑤ 5k+4
  :
さらに、
 ②1 2k+1
 1③2 3k+3
 11④3 4k+5
 111⑤4 5k+7
 1111⑥5 6k+9
  :
と展開できる。これは、いわゆる近似解である。
(終り)


数字の並びの組み合わせは、次の問題と同値なので、それを元に作成する。
 問題:n個の球をm個の箱に分ける方法 (5)
 http://members3.jcom.home.ne.jp/zakii/enumeration/10_balls_boxes.htm



LET N=13
LET M=5

DIM B(M) !各箱の中の球の個数
MAT B=CON

PUBLIC NUMERIC C !場合の数
LET C=0

CALL try(2,N-M, N,M,B) !※1の位置を固定する
PRINT C;"通り"

END


EXTERNAL SUB try(P,T, N,M,B())
IF P=M THEN !R番目なら
   LET B(P)=B(P)+T !set it

   FOR i=1 TO INT(M/2) !対称性(直線状)
      IF B(i)<>B(M-i+1) THEN EXIT FOR
   NEXT i
   IF B(i)<B(M-i+1) OR i>INT(M/2) THEN

      DIM F(N) !1~nの数字
      MAT F=ZER
      FOR i=1 TO M !i番目から
         FOR K=0 TO M-i !続くk個の数字
            LET S=0
            FOR X=0 TO K !その和
               LET S=S+B(i+X)
            NEXT X
            LET F(S)=1
         NEXT K
      NEXT i
      FOR i=1 TO N !すべて表されるかどうか確認する
         IF F(i)=0 THEN EXIT FOR
      NEXT i
      IF i>N THEN

         LET C=C+1 !結果を表示する
         MAT PRINT B;

      END IF

   END IF

   LET B(P)=B(P)-T !restore it

ELSE
   FOR i=0 TO T !p番目
      LET B(P)=B(P)+i !set it
      CALL try(P+1,T-i, N,M,B)
      LET B(P)=B(P)-i !restore it
   NEXT i

END IF
END SUB


実行結果 (1)

1  1  4  4  3

1  3  1  6  2

1  5  3  2  2

3 通り

 

助言頂きたく思います

 投稿者:lark12_long  投稿日:2014年 4月13日(日)00時59分45秒
  nアーム回動リンクを、2014年 4月 5日(土)09時28分17秒に、
投稿した、lark12_longと申します

逆行列を求める、mat invj=inv(ja)は、jaが正方行列でなければ
ならず、正方行列とする為に、思いつきで、
ja(3,1)~ja(3,n)、ja(n,1)~ja(n,n)にrndを設定しました

最初は、1を設定したら、引数が特異行列エラーとなり
試しに、ja(3,1)~ja(3,n)、ja(n,1)~ja(n,n)にrndを設定
したら、エラーになりません

この手法が、正しいのか誤りなのか、理解出来ていません

どなたか、助言頂ければと思います
 

Re: 助言頂きたく思います

 投稿者:島村1243  投稿日:2014年 4月14日(月)08時45分54秒
  > No.3358[元記事へ]

lark12_longさんへのお返事です。

> 逆行列を求める、mat invj=inv(ja)は、jaが正方行列でなければ
> ならず、正方行列とする為に、思いつきで、
> ja(3,1)~ja(3,n)、ja(n,1)~ja(n,n)にrndを設定しました

「非正方行列の逆行列」でネット検索したら、数学手法として「擬似行列」という方法が有る様です。それをご覧になっては如何ですか。
 

Re: 助言頂きたく思います

 投稿者:山中和義  投稿日:2014年 4月14日(月)15時34分14秒
  > No.3358[元記事へ]

lark12_longさんへのお返事です。

> nアーム回動リンク

擬似逆行列で求めることができるようです。

FULL BASIC仕様のコーディングにしてあります。


!平面nリンクマニピュレー タのヤコビアンを求めよ。

SET WINDOW -16,16,-16,16 !表示領域 ※ワールド座標系

LET N=4 !nリンク

DIM L(N) !各腕の長さ
DATA 8,5,5,3
MAT READ L

DIM Q(N) !各関節の角度 ※単位は度、ワールド座標系
DATA 30,30,30,30
MAT READ Q

CALL PrintOut(N,L,Q, PX,PY,QQ)

DO
   mouse poll mx,my,left,right !目標の位置(x,y)
   IF right=1 THEN STOP !右ボタンが押下されるまで

   !逆運動学

   DIM J(2,N) !ヤコビアン
   LET J(1,N)=-L(N)*SIN(RAD(QQ))
   LET J(2,N)= L(N)*COS(RAD(QQ))
   FOR i=N-1 TO 1 STEP -1
      LET QQ=QQ-Q(i+1)
      LET J(1,i)=J(1,i+1)-L(i)*SIN(RAD(QQ))
      LET J(2,i)=J(2,i+1)+L(i)*COS(RAD(QQ))
   NEXT i

   DIM JT(N,2),W(2,2),JJ(N,2)
   MAT JT=TRN(J)
   MAT W=J*JT
   MAT W=INV(W)
   MAT JJ=JT*W !擬似逆行列A^+=A^t*(A*A^t)^(-1)

   DIM r(2) !位置誤差
   LET r(1)=mx-PX
   LET r(2)=my-PY

   DIM dQ(N) !⊿θ=kJ^(-1)⊿x
   MAT dQ=JJ*r
   FOR i=1 TO N !θ←θ+⊿θ
      LET Q(i)=MOD(Q(i)+5*dQ(i),360)
   NEXT i

   CALL PrintOut(N,L,Q, PX,PY,QQ) !手先位置
LOOP

END


EXTERNAL SUB PrintOut(N,L(),Q(), PX,PY,QQ) !順運動学で手先位置を算出する。表示する
SET DRAW mode hidden !ちらつき防止の開始
CLEAR
DRAW grid(2,2) !座標

LET PX=0 !原点(0,0)
LET PY=0
LET QQ=0 !Σθ
FOR i=1 TO N !n個の関節
   LET QQ=QQ+Q(i)
   LET X=PX+L(i)*COS(RAD(QQ)) !x=L[1]cos(Q[1])+L[2]cos(Q[1]+Q[2])+ …
   LET Y=PY+L(i)*SIN(RAD(QQ)) !y=L[1]sin(Q[1])+L[2]sin(Q[1]+Q[2])+ …
   PLOT LINES: PX,PY; X,Y
   PLOT TEXT ,AT PX,PY: USING$("####.##",Q(i))&"°"

   LET PX=X !次へ
   LET PY=Y
NEXT i

SET DRAW mode explicit !ちらつき防止の終了
END SUB

 

nアーム回動リンク

 投稿者:lark12_long  投稿日:2014年 4月15日(火)06時57分0秒
  山中和義様

nアーム回動リンクについて、御助言有難うございました

擬似逆行列を教示頂き有難うございました。

実際にプログラムとして示して頂き、大変助かっています

洗練されたプログラム技術も、大いに参考となりました
関節近傍に、角度を表示する手法他、参考になりました

実際にプログラム動かすと、
非常にスムースな動きとなるものなんですね

手先目標位置が、拘束範囲を超えた時の動き、
ある意味、面白いと思いました。

lark12_long
 

連続引き摺リンク

 投稿者:lark12_long  投稿日:2014年 4月18日(金)07時39分56秒
  '
'  連続引き摺リンク.bas
'  (芋ずるリンク)
'
' 平面上に配置された、アームと関節にて接続される、リンクの端を、
'  引き摺った時の様子となってると思うのですが
'  如何でしょうか、ご意見等お聞かせください
'  平面とリンク、関節共に摩擦は無いものとします
'
'  H26-04-15   lark12_long
'
width=1260
height=640
set bitmap size width,height
reft=0
right=width*1.5
bottom=0
top=height*1.5
set window left,right,bottom,top

'---------------------------------------------------------------------------
xbase=100
ybase=200

n=10              'リンク関節数
rn=10             '関節の半径

dim x(n)          '関節のx座標
dim y(n)          '関節のx座標
dim r(n)          '各アームの長さ
dim q(n)          '各関節の角度


  '各アームの長さ
  for i=0 to n-1
    r(i)=100*(rnd+0.5)
  next i

  '各関節の角度
  for i=1 to n-1
    q(i)=rad(30)
  next i

  '各関節の初期位置計算
  px=0                        '原点(0,0)
  py=0
  qq=0                        'Σθ

  for i=0 to n-1              'n個の関節
     qq=qq+q(i)
     x(i)=px+r(i)*cos(qq)     'x=l1*cos(q1)+l2*cos(q1+q2)+l3*cos(q1+q2+q3)+....
     y(i)=py+r(i)*sin(qq)     'y=l1*sin(q1)+l2*sin(q1+q2)+l3*sin(q1+q2+q3)+...
     px=x(i)                  'px更新
     py=y(i)                  'py更新
  next i

'繰り返し計算
do
    call cal        'リンクの動作シミュレーション計算
    call draw       '状態描画
loop

'---------------------------------------------------------------------------

'リンクの動作シミュレーション計算
sub cal

  '端点の移動
   mouse poll xm,ym,left,right
   x(n-1)=xm-xbase
   y(n-1)=ym-ybase
   if right=1 then stop       'マウス右クリックで停止

   '連続アームの移動
   for i=1 to n-1
     l=sqr( (x(i)-x(i-1) )^2+(y(i)-y(i-1) )^2 )  '関節間アームの現在長さ
     cosc=(x(i)-x(i-1) )/l                       '現在のアームとx軸との余弦値
     sinc=(y(i)-y(i-1) )/l                       '現在のアームとy軸との正弦値
     x(i-1)=x(i)-r(i-1)*cosc  'x(i-1)をx(i)と真のアーム長さr(i-1)と余弦値を使って算出
     y(i-1)=y(i)-r(i-1)*sinc  'y(i-1)をy(i)と真のアーム長さr(i-1)と正弦値を使って算出
   next i

end sub
'---------------------------------------------------------------------------
'動作描画
sub draw
  set draw mode hidden
  set line width 4
  line(0,0)-(2000,960),1,bf    '画面クリヤ

  'アーム、関節表示更新
  for i=0 to n-2
   line(x(i)+xbase,y(i)+ybase)-(x(i+1)+xbase,y(i+1)+ybase),4
   circle (x(i)+xbase,y(i)+ybase),10,4,,,,f
  next i

  '移動端点の表示更新
  circle (x(n-1)+xbase,y(n-1)+ybase),10,5,,,,f

  set draw mode explicit

end sub
'---------------------------------------------------------------------------
 

Re: 連続引き摺リンク

 投稿者:山中和義  投稿日:2014年 4月19日(土)10時05分25秒
  > No.3362[元記事へ]

lark12_longさんへのお返事です。

> 連続引き摺リンク.bas
> 如何でしょうか、ご意見等お聞かせください

xbase,ybaseの意味が解りません。
平面nリンクなら、根元と考えられますが、
今回はへびなどが動く場合ですので、この場合は何でしょうか。

また、関節を扱っているのに、関節の角度Q(k)での制御が見えません。

 

Re: 連続引き摺リンク

 投稿者:lark12_long  投稿日:2014年 4月20日(日)07時37分17秒
  Re: 連続引き摺リンク

山中和義 様

ご意見ありがとうございます

xbase,ybaseは、表示するときの、画面上の基点を意味します
但し、本プログラムの場合、xbasse=0,ybase=0で
特に問題は無いので不要と言うことになりますね

>また、関節を扱っているのに、
>関節の角度Q(k)での制御が見えません。

x(i),y(i)の位置が変わったことにより、
x(i),y(i)とx(i-1),y(i-1)との距離は、真の長さr(i-1)より、
lに変わります

次にlに変わったことにより、
x(i),y(i)とx(i-1),y(i-1)との成す角度は変わり、
その余弦値はcosc、正弦値はsincとなります

角度が変わったので、x(i-1),y(i-1)の位置を、
x(i),y(i)を基点として、x(i-1),y(i-1)を、
x(i-1)=x(i)-r(i-1)*cosc
y(i-1)=y(i)-r(i-1)*sinc
と修正します

こうすることにより、l->r(i-1)に漸近し、角度cosc,sincも
cosc=(x(i)-x(i-1) )/r(i-1)
sinc=(y(i)-y(i-1) )/r(i-1)
に漸近します

動作としては、以上ですが、
これが物理現象と一致してるかどかは、理解できていません

lark12_long
 

ランフォード問題(Langford's Problem)

 投稿者:山中和義  投稿日:2014年 4月24日(木)09時58分14秒
  問題
4024個の数 1,1,2,2,3,3,…,2012,2012 をうまく一列に並べると、
1≦n≦2012を満たす全ての自然数nに対して、
2つのnの間には(n-1)個の数があるようにすることが出来ることを示してください。

また、2013,2014,2015ではどうでしょうか。

考察
L(2,0)=00より、V(2,1)=11

L(2,3)=31213200より、それぞれの数を+1する。
V(2,4)=42324311

L(2,4)=4131243200より、
V(2,5)=5242354311

参考サイト
 私的数学塾 http://www004.upp.so-net.ne.jp/s_honma/index.htm 内
  クイズ&パズル
   4022個の自然数  http://www004.upp.so-net.ne.jp/s_honma/relax/number25.html

 問題
 4022個の数 1,1,2,2,3,3,…,2011,2011 をうまく一列に並べると、
 1≦n≦2011を満たす全ての自然数nに対して、
 2つのnの間にはn個の数があるようにすることが出来ることを示してください。
 答え
 L(2,n)で、kが2以上の整数ならn=4k-1とn=4kのそれぞれの1つの解が示される。下記のプログラムを参照のこと。
 (終り)

なので、

よって、V(2,n+1)も示される。
(終り)


類題
組合せの問題 http://www004.upp.so-net.ne.jp/s_honma/relax/permutation4.htm

 問題
 1~8の数字の書かれたカードがある。
 2枚ずつペアを作り、カードの数字の差がそれぞれ1,2,3,4になるような組合わせを求めよ。

 問題
 1~2nの数字の書かれたカードがある。
 2枚ずつペアを作り、カードの数字の差がそれぞれ1~nになる組み合わせの総数を求めよ。



LET n=7

PRINT "N="; n

LET k=CEIL(n/4)
PRINT k !debug
IF k>1 AND MOD(n,4)=3 THEN !4k-1の場合
   FOR i=4*k-4 TO 2*k STEP -2
      PRINT i;
   NEXT i
   PRINT 4*k-2;
   FOR i=2*k-3 TO 1 STEP -2
      PRINT i;
   NEXT i
   PRINT 4*k-1;
   FOR i=1 TO 2*k-3 STEP 2
      PRINT i;
   NEXT i
   FOR i=2*k TO 4*k-4 STEP 2
      PRINT i;
   NEXT i
   PRINT 2*k-1;
   FOR i=4*k-3 TO 2*k+1 STEP -2
      PRINT i;
   NEXT i
   PRINT 4*k-2;
   FOR i=2*k-2 TO 2 STEP -2
      PRINT i;
   NEXT i
   PRINT 2*k-1;
   PRINT 4*k-1;
   FOR i=2 TO 2*k-2 STEP 2
      PRINT i;
   NEXT i
   FOR i=2*k+1 TO 4*k-3 STEP 2
      PRINT i;
   NEXT i
   PRINT

ELSEIF k>1 AND MOD(n,4)=0 THEN !4kの場合
   FOR i=4*k-2 TO 2*k STEP -2
      PRINT i;
   NEXT i
   PRINT 4*k-1;
   FOR i=2*k-3 TO 1 STEP -2
      PRINT i;
   NEXT i
   PRINT 4*k;
   FOR i=1 TO 2*k-3 STEP 2
      PRINT i;
   NEXT i
   FOR i=2*k TO 4*k-2 STEP 2
      PRINT i;
   NEXT i
   PRINT 2*k-1;
   FOR i=4*k-3 TO 2*k+1 STEP -2
      PRINT i;
   NEXT i
   PRINT 4*k-1;
   FOR i=2*k-2 TO 2 STEP -2
      PRINT i;
   NEXT i
   PRINT 2*k-1;
   PRINT 4*k;
   FOR i=2 TO 2*k-2 STEP 2
      PRINT i;
   NEXT i
   FOR i=2*k+1 TO 4*k-3 STEP 2
      PRINT i;
   NEXT i

ELSE
   PRINT "ありません。"
END IF

END

 

Re: ランフォード問題(Langford's Problem)

 投稿者:山中和義  投稿日:2014年 4月24日(木)19時21分30秒
  > No.3365[元記事へ]

> 問題
> 8個の数 1,1,2,2,3,3,…,4,4 をうまく一列に並べると、
> 1≦n≦4を満たす全ての自然数nに対して、
> 2つのnの間には(n-1)個の数があるようにすることが出来ることを示してください。

> 類題
> 1~8の数字の書かれたカードがある。
> 2枚ずつペアを作り、カードの数字の差がそれぞれ1,2,3,4になるような組合わせを求めよ。

参考サイト
 私的数学塾 http://www004.upp.so-net.ne.jp/s_honma/index.htm 内
  お茶の時間
   クイズ&パズル
    組合せの問題 http://www004.upp.so-net.ne.jp/s_honma/relax/permutation4.htm

差が4の場合
 xが空きとすると、4通りの位置に置ける
 12345678←位置
 4xxx4xxx
 x4xxx4xx
 xx4xxx4x
 xxx4xxx4
より、
1から2nまでの数を扱うので、計算量O( (2n)!/(n-1)! )


LET t0=TIME
LET N=4
PUBLIC NUMERIC C !解の個数
LET C=0
DIM F(2*N) !数字1~2n
MAT F=ZER
CALL try(N, N,F) !差がn,…,3,2,1 ※N+1
IF C=0 THEN PRINT "解なし"
PRINT TIME-t0
END

EXTERNAL SUB try(P, N,F()) !バックトラック法で検索する
FOR i=1 TO 2*N-P !未使用の数字が候補である
   IF F(i)=0 AND F(i+P)=0 THEN !組(i,i+p)は条件を満たす
      LET F(i)=P !使用中 ※P-1
      LET F(i+P)=P !※P-1

      IF P=1 THEN !すべて並んだなら ※2
         LET C=C+1
         PRINT "No.";C

         MAT PRINT F;

         FOR s=1 TO N !差が1~nの順に
            FOR x=1 TO 2*N
               IF F(x)=s THEN
                  PRINT "(";x;",";x+s;") "; !ペア
                  EXIT FOR
               END IF
            NEXT x
         NEXT s
         PRINT
      ELSE
         CALL try(P-1, N,F) !次へ
      END IF

      LET F(i)=0 !元に戻す
      LET F(i+P)=0
   END IF
NEXT i
END SUB


実行結果

No. 1
4  2  3  2  4  3  1  1

( 7 , 8 ) ( 2 , 4 ) ( 3 , 6 ) ( 1 , 5 )
No. 2
4  1  1  3  4  2  3  2

( 2 , 3 ) ( 6 , 8 ) ( 4 , 7 ) ( 1 , 5 )
No. 3
3  4  2  3  2  4  1  1

( 7 , 8 ) ( 3 , 5 ) ( 1 , 4 ) ( 2 , 6 )
No. 4
1  1  4  2  3  2  4  3

( 1 , 2 ) ( 4 , 6 ) ( 5 , 8 ) ( 3 , 7 )
No. 5
2  3  2  4  3  1  1  4

( 6 , 7 ) ( 1 , 3 ) ( 2 , 5 ) ( 4 , 8 )
No. 6
1  1  3  4  2  3  2  4

( 1 , 2 ) ( 5 , 7 ) ( 3 , 6 ) ( 4 , 8 )

 

Re: ランフォード問題(Langford's Problem)

 投稿者:山中和義  投稿日:2014年 4月24日(木)19時56分48秒
  > No.3366[元記事へ]

問題 L(2,n)
2n個の数 1,1,2,2,3,3,…,n,n をうまく一列に並べると、
1≦k≦nを満たす全ての自然数kに対して、
2つのkの間にはk個の数があるようにすることが出来ることを示してください。

考察
n≡0, 3 mod 4 の場合に限る。

http://oeis.org/A014552
http://oeis.org/A176127
(終り)


問題 V(2,n)
2n個の数 1,1,2,2,3,3,…,n,n をうまく一列に並べると、
1≦k≦nを満たす全ての自然数kに対して、
2つのkの間には(k-1)個の数があるようにすることが出来ることを示してください。

http://oeis.org/A004075


考察
1からnまでのn個の数の並べ方は、n!通り。
この数字の並びを左から見て、その順番に左詰めに並べていく。
例 n=4で、並びが1234の場合
 4×2=8個の枠○○○○○○○○について、
 1は、1○1○○○○○
 2は、121○2○○○
 3は、12132○○3
 4は、並べられない
(終り)

計算量O( n!)


!L(m,n)、V(m,n)
!赤字部分の t+1 を t に置き換えると、V(m,n)となる。

LET t0=TIME

PUBLIC NUMERIC m,n, mn !L(m,n)
LET m=2
LET n=7

DIM a(n)
FOR i=1 TO n !最初の並び 1,2,3,…,n
   LET a(i)=i
NEXT i

PUBLIC NUMERIC d(1000) !L(m,n)の並び
LET mn=m*n
MAT d=ZER(mn)

PUBLIC NUMERIC ANSWER_COUNT !場合の数
LET ANSWER_COUNT=0
CALL perm(a,1, 1)
IF ANSWER_COUNT=0 THEN PRINT "解なし"

PRINT "計算時間=";TIME-t0

END


EXTERNAL SUB perm(a(),k, P) !辞書順序ではなくn-順列(n!通り)を生成する
FOR i=k TO n
   LET t=a(i) !a[i]とa[k]を入れ替える

   LET W=P+(t+1) !左詰め位置pに数字tが埋められるか ※
   FOR J=1 TO m-1 !1つ目は可能なので、2つ目以降を確認する
      IF W>mn OR d(W)<>0 THEN EXIT FOR
      LET W=W+(t+1) !※
   NEXT J
   IF J=m THEN !埋められるなら

      FOR W=P+(t+1)*(m-1) TO P STEP -(t+1) !set it ※
         LET d(W)=t
      NEXT W


      IF k=n THEN !すべて並んだなら
         LET ANSWER_COUNT=ANSWER_COUNT+1 !並びを表示する
         PRINT "No."; ANSWER_COUNT
         MAT PRINT d;
      ELSE
         LET a(i)=a(k) !!!!
         LET a(k)=t

         FOR J=P+1 TO mn !空き位置を探す
            IF d(J)=0 THEN EXIT FOR
         NEXT J
         CALL perm(a,k+1, J) !次へ

         LET tt=a(k) !元に戻す ※t
         LET a(k)=a(i)
         LET a(i)=tt
      END IF


      FOR W=P+(t+1)*(m-1) TO P STEP -(t+1) !restore it ※
         LET d(W)=0
      NEXT W

   ELSE !※※枝刈りの状況を表示する
   !   FOR X=1 TO k-1
   !      PRINT a(X);
   !   NEXT X
   !   PRINT t
   END IF
NEXT i
END SUB

 

Re: ランフォード問題(Langford's Problem)

 投稿者:山中和義  投稿日:2014年 4月25日(金)11時28分46秒
  > No.3367[元記事へ]

きれいな並びがないか。。。

L(2,4k+3)とL(2,4k+4)の関係

次のような並びにすると、半分の数の検索で済む。パズルとしては楽になる。

k=0,1,2,3,…とする。

n=4k+3のとき
[(n+1)/2]からnまでの[(n+1)/2]個の数を順に並べる。
残りの数(1から[(n+1)/2]-1まで)を埋める。
例 n=7のとき
 4567○4○5○6○7○○として、1~3を考える。

n=4k+4のとき
同様に、上半分の数を埋める。
下半分の数(残りの数)は、上記の右半分の並びを右へ1枠ずらせばよい。
例 n=8のとき
 4567○4○5○6○7○○
      \ \ \ \ \\
 456784○5○6○7○8○○


N=3
2  3  1  2  1  3
N=4
2  3  4  2  1  3  1  4


N=7
4  5  6  7  1  4  1  5  3  6  2  7  3  2
N=8
4  5  6  7  8  4  1  5  1  6  3  7  2  8  3  2


N=11
6  7  8  9  10  11  5  6  1  7  1  8  5  9  4  10  3  11  2  4  3  2
N=12
6  7  8  9  10  11  12  6  5  7  1  8  1  9  5  10  4  11  3  12  2  4  3  2


以下、n=4k+3のみ

N= 15
8  9  10  11  12  13  14  15  7  8  1  9  1  10  5  11  7  12  6  13  5  14  4  15  3  6  2  4  3  2

N= 19
10  11  12  13  14  15  16  17  18  19  9  10  5  11  1  12  1  13  5  14  9  15  7  16  8  17  4  18  6  19  7  4  3  8  2  6  3  2

N= 23
12  13  14  15  16  17  18  19  20  21  22  23  11  12  7  13  3  14  9  15  3  16  7  17  11  18  10  19  9  20  5  21  8  22  4  23  5  10  6  4  2  8  1  2  1  6

N= 27
14  15  16  17  18  19  20  21  22  23  24  25  26  27  13  14  7  15  3  16  11  17  3  18  7  19  9  20  13  21  12  22  11  23  10  24  9  25  5  26  8  27  4  12  5  10  6  4  2  8  1  2  1  6

N= 31
16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  15  16  11  17  7  18  13  19  1  20  1  21  7  22  11  23  15  24  14  25  13  26  12  27  5  28  10  29  9  30  5  31  8  14  4  12  6  10  9  4  3  8  2  6  3  2

N= 35
18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  17  18  13  19  7  20  15  21  1  22  1  23  7  24  11  25  13  26  17  27  16  28  15  29  14  30  11  31  12  32  5  33  10  34  9  35  5  16  8  14  4  12  6  10  9  4  3  8  2  6  3  2

N= 39
20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  19  20  15  21  11  22  17  23  5  24  1  25  1  26  5  27  11  28  15  29  19  30  18  31  17  32  16  33  13  34  14  35  3  36  12  37  3  38  9  39  10  18  13  16  7  14  8  12  9  4  6  10  7  2  4  8  2  6

N= 43
22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  21  22  17  23  13  24  19  25  7  26  1  27  1  28  15  29  7  30  13  31  17  32  21  33  20  34  19  35  18  36  15  37  16  38  11  39  14  40  3  41  12  42  3  43  10  20  11  18  9  16  8  14  4  12  6  10  5  4  9  8  2  6  5  2

N= 47
24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  23  24  19  25  13  26  21  27  7  28  1  29  1  30  17  31  7  32  13  33  15  34  19  35  23  36  22  37  21  38  20  39  17  40  18  41  15  42  16  43  11  44  14  45  3  46  12  47  3  22  10  20  11  18  9  16  8  14  4  12  6  10  5  4  9  8  2  6  5  2

N= 51
26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  25  26  21  27  17  28  23  29  9  30  5  31  7  32  19  33  5  34  9  35  7  36  17  37  21  38  25  39  24  40  23  41  22  42  19  43  20  44  15  45  18  46  13  47  16  48  3  49  14  50  3  51  12  24  15  22  13  20  11  18  10  16  4  14  8  12  2  4  6  2  11  10  1  8  1  6

N= 55
28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  27  28  23  29  19  30  25  31  9  32  5  33  7  34  21  35  5  36  9  37  7  38  17  39  19  40  23  41  27  42  26  43  25  44  24  45  21  46  22  47  17  48  20  49  15  50  18  51  13  52  16  53  3  54  14  55  3  26  12  24  15  22  13  20  11  18  10  16  4  14  8  12  2  4  6  2  11  10  1  8  1  6

N= 59
?????????????????????

N= 63
32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  31  32  27  33  23  34  29  35  17  36  13  37  3  38  25  39  3  40  1  41  1  42  21  43  13  44  17  45  23  46  27  47  31  48  30  49  29  50  28  51  25  52  26  53  21  54  24  55  19  56  22  57  7  58  20  59  15  60  18  61  7  62  16  63  11  30  14  28  19  26  12  24  15  22  10  20  11  18  9  16  8  14  4  12  6  10  5  4  9  8  2  6  5  2

N= 67
34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  33  34  29  35  25  36  31  37  17  38  13  39  3  40  27  41  3  42  1  43  1  44  23  45  13  46  17  47  21  48  25  49  29  50  33  51  32  52  31  53  30  54  27  55  28  56  23  57  26  58  21  59  24  60  19  61  22  62  7  63  20  64  15  65  18  66  7  67  16  32  11  30  14  28  19  26  12  24  15  22  10  20  11  18  9  16  8  14  4  12  6  10  5  4  9  8  2  6  5  2

N= 71
?????????????????????

N= 75
38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  37  38  33  39  29  40  35  41  23  42  19  43  13  44  31  45  7  46  1  47  1  48  27  49  7  50  13  51  25  52  19  53  23  54  29  55  33  56  37  57  36  58  35  59  34  60  31  61  32  62  27  63  30  64  25  65  28  66  21  67  26  68  15  69  24  70  17  71  22  72  3  73  20  74  3  75  18  36  15  34  21  32  16  30  17  28  14  26  11  24  12  22  4  20  10  18  9  4  8  16  11  14  6  12  5  10  9  8  2  6  5  2

N= 79
?????????????????????

N= 83
42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  41  42  37  43  33  44  39  45  27  46  23  47  19  48  35  49  13  50  7  51  3  52  31  53  3  54  7  55  29  56  13  57  19  58  23  59  27  60  33  61  37  62  41  63  40  64  39  65  38  66  35  67  36  68  31  69  34  70  29  71  32  72  25  73  30  74  15  75  28  76  21  77  26  78  11  79  24  80  17  81  22  82  15  83  20  40  11  38  25  36  18  34  21  32  16  30  17  28  14  26  9  24  12  22  1  20  1  8  10  18  9  16  5  14  6  12  8  4  5  10  2  6  4  2

N= 87
44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  43  44  39  45  35  46  41  47  29  48  23  49  19  50  37  51  13  52  7  53  3  54  33  55  3  56  7  57  31  58  13  59  19  60  23  61  27  62  29  63  35  64  39  65  43  66  42  67  41  68  40  69  37  70  38  71  33  72  36  73  31  74  34  75  27  76  32  77  25  78  30  79  15  80  28  81  21  82  26  83  11  84  24  85  17  86  22  87  15  42  20  40  11  38  25  36  18  34  21  32  16  30  17  28  14  26  9  24  12  22  1  20  1  8  10  18  9  16  5  14  6  12  8  4  5  10  2  6  4  2

N= 91
?????????????????????

N= 95
48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  47  48  43  49  39  50  45  51  33  52  29  53  25  54  41  55  17  56  13  57  9  58  37  59  1  60  1  61  35  62  9  63  13  64  17  65  31  66  25  67  29  68  33  69  39  70  43  71  47  72  46  73  45  74  44  75  41  76  42  77  37  78  40  79  35  80  38  81  31  82  36  83  27  84  34  85  19  86  32  87  23  88  30  89  21  90  28  91  3  92  26  93  3  94  24  95  19  46  22  44  27  42  20  40  23  38  21  36  18  34  15  32  16  30  7  28  14  26  6  24  12  22  7  20  10  6  15  18  11  16  8  14  5  12  2  10  4  2  5  8  11  4

N= 99
?????????????????????

N= 103
?????????????????????


 

はじめまして。。

 投稿者:根無草  投稿日:2014年 4月27日(日)07時16分59秒
  ビギナーです。よろしく、ご指導ねがいます。  

Re: これって算数?

 投稿者:山中和義  投稿日:2014年 4月30日(水)19時27分36秒
  問題
1000個近いキャンディを子供達へ、
7個ずつ配ると4個余り、5個ずつ配ると3個余り、3個ずつにすると2個余ったという。
最初にキャンディは何個あったのか?

答え
1000÷3の余りを求める。3の倍数の判定から、1
1000÷5の余りを求める。5の倍数の判定から、0
1000÷7の余りを求める。筆算で求めて、6

    ___142_
  7 ) 1000
      _7_
       30
      _28_
        20
       _14_
         6

または、1001=7×11×13より、6 ※受験なれしている


1000個のとき、分配状況を図示すると、
③………③③○
 ⑤……⑤⑤
  ⑦…⑦⑦○○○○○○

題意を満たさない。

そこで1つ増やしてみると、
1001個のとき、
③………③③ ○○
 ⑤……⑤⑤ ○
  ⑦…⑦⑦⑦

題意を満たさない。

そこで1つ減らしてみると、
999個のとき、
③………③③
 ⑤……⑤ ○○○○
  ⑦…⑦⑦○○○○○

同様に、±2,±3,±4,…を考える。
1002個のとき、
③………③③③
 ⑤……⑤⑤ ○○
  ⑦…⑦⑦⑦○

題意を満たさない。

998個のとき、
③………③ ○○
 ⑤……⑤ ○○○
  ⑦…⑦⑦○○○○

題意を満たす。
(終り)


●中学生向け(後半部分)
余りの規則性より、

 個数  3 5 7
 -----------
  998  2 3 4 ← 答え
  999  0 4 5
 1000  1 0 6
 1001  2 1 0
 1002  0 2 1

を得る。



LET N=1000
FOR K=0 TO N !n±k
   FOR S=1 TO -1 STEP -2 !符号
      LET M=N+S*K
      IF MOD(M,7)=4 THEN !題意を満たすなら
         IF MOD(M,5)=3 THEN
            IF MOD(M,3)=2 THEN
               PRINT M
               STOP
            END IF
         END IF
      END IF
   NEXT S
NEXT K
END


実行結果

998

 

BASIC誕生50年

 投稿者:nagram  投稿日:2014年 5月 1日(木)15時21分53秒
  Gigazineというニュースサイトで、BASICが誕生して本日でちょうど50年になると紹介しています。
http://gigazine.net/news/20140501-fifty-years-of-basic/
1964年5月1日にダートマス大学のジョン・ケメニーとトーマス・カーツが初めてBASICの命令を実行することに成功したそうです。
二人の教授に感謝。

10 PRINT "Hello World!"
20 END
 

n連勝

 投稿者:山中和義  投稿日:2014年 5月 4日(日)14時13分31秒
  問題
1対1で、勝ち負けが決まる試合をします。
8人でトーナメントをすると、だれか1人が必ず1位になり、その人は3連勝しています。
つまり、8人いれば3連勝している人を100%の確率で、有限時間の間に作り出すことができます。

では、100連勝している人を100%の確率で、有限時間の間に生み出すためには、
最低でも何人必要でしょうか。ただし、トーナメント形式をとる必要はありません。


答え
(n+1)人の試合

アルゴリズム
(1) 誰か1人を仲間外れにしておく。
(2) 残りn人は全員看板(数字は「勝ち数」を意味する)を持ち、0と記入しておく。
(3) 以下のルールでひたすら試合を繰り返す。
 (a) 同じ数字を掲げた人と出会ったら試合をする。
 (b) 勝った人は看板の数字に1を足す。
 (c) 負けた人は看板の数字を0に戻す。
(4) やがて、看板の数字が0から(n-1)までのものが1つずつになる。
(5) 仲間外れにしていた1人が看板を持ち、0と記入する。
(6) 以下のルールでひたすら試合を繰り返す。
 (a) 同じ数字を掲げた人と出会ったら試合をする。
 (b) 勝った人は看板の数字に1を足す。
 (c) 負けた人は看板を捨てる。
(7) 最後の試合に勝った人がn連勝となる。
(終り)


●(3),(4)について
k人が 2^(k-1)-1 試合を行って、ひとりが (k-1)連勝となる。 残りは、0連勝となる。
証明
k=2のとき、
   ABc
 0:00
 1:01
のような、1試合を行う。

k=3のとき、
   ABCd
 0:000
 1:010
 2:011
 3:002
のような、3試合を行う。

k=4のとき、
   ABCDe
 0:0000
 1:0100
 2:0110
 3:0020
 4:0120
 5:0121
 6:0022
 7:0003
のような、7試合を行う。

k=m≧2のとき、
 m人が 2^(m-1)-1 試合を行って、ひとりが (m-1)連勝となる。 残りは、0連勝となる。
 ┌─── m 人 ───┐
  0,0,0, …, 0,0,(m-1)
と仮定する。

k=m+1のとき、
 ┌─── (m+1) 人 ───┐
  0,0,0, …, 0,0,0,     0

まず、最初のm人に対して、2^(m-1)-1 試合を行って、
 ┌─── (m+1) 人 ───┐
  0,0,0, …, 0,0,(m-1), 0

次に、0連勝のm人( (m-1)連勝の1人を除いたもの)に対して、2^(m-1)-1 試合を行って、
 ┌─── (m+1) 人 ───┐
  0,0,0, …, 0,0,(m-1), (m-1)

とできる。

(m-1)連勝どうしで、もう1試合して、
 ┌─── (m+1) 人 ───┐
  0,0,0, …, 0,0,0,      m

よって、
(2^(m-1)-1)+(2^(m-1)-1)+1=2^m-1 試合を行って、ひとりが m連勝となる。 残りは、0連勝となる。
(終り)


これより、
      ┌──── n 人 ────┐
       A B C      D     E     F
k=n  のとき、0,0,0, …, 0,    0,    (n-1)
      ┌── (n-1) 人 ──┐
k=n-1のとき、0,0,0, …, 0,    (n-2),(n-1)
      ┌─ (n-2) 人 ─┐
k=n-2のとき、0,0,0, …, (n-3),(n-2),(n-1)
   :
   :
      ┌3人┐
k=3  のとき、0,0,2, …, (n-3),(n-2),(n-1)
      ┌2┐
k=2  のとき、0,1,2, …, (n-3),(n-2),(n-1)


よって、Σ[k=1,n]{ 2^(k-1)-1 } = 2^n-1-n 試合


●(6)について
       ┌┴┐
      ┌┴┐F  Fは(n-1)勝
     ┌┴┐E  Eは(n-2)勝
    ┌┴┐D  Dは(n-3)勝
     :
   ┌┴┐
  ┌┴┐C  Cは2勝
 ┌┴┐B  Bは1勝
 g   A  Aは0勝
の n 試合


●(7)について
全体で、(2^n-1-n) + n = 2^n-1 試合




具体的に見てみると、

・n=1の場合
(3),(4)について、
   Ab
 0:0
のような、0試合

(6)について、
 ┌┴┐
 b   A
の1試合

よって、0+1=1試合


・n=2の場合
(3),(4)について、
   ABc
 0:00
 1:01 A-Bより(右側が「勝つ」とした)
のような、1試合

(6)について、
  ┌┴┐
 ┌┴┐B  Bは1勝
 c   A  Aは0勝
の2試合

よって、1+2=3試合


・n=3の場合
(3),(4)について、
   ABCd
 0:000
 1:010 A-Bより(右側が「勝つ」とした)
 2:011 A-Cより
 3:002 B-Cより
 4:012 A-Bより
のような、4試合

(6)について、
   ┌┴┐
  ┌┴┐C  Cは2勝
 ┌┴┐B  Bは1勝
 d   A  Aは0勝
の3試合

よって、4+3=7試合


・n=4の場合
(3),(4)について、
    ABCDe
  0:0000
  1:0100
  2:0110
  3:0111
  4:0021
  5:0121
  6:0022
  7:0003
  8:0103
  9:0113
 10:0023
 11:0123
のような、11試合

(6)について、
    ┌┴┐
   ┌┴┐D  Dは3勝
  ┌┴┐C  Cは2勝
 ┌┴┐B  Bは1勝
 e   A  Aは0勝
の4試合

よって、11+4=15試合



!(3),(4)について
LET N=7 !n連勝
DIM P(N) !n人の看板
MAT P=ZER
LET C=0 !試合の回数
LET K=N !※右側yが「勝つ」として、Pの並びは0,1,2,3,…,(n-1)
DO
   FOR X=1 TO K-1 !xとyとの試合
      FOR Y=X+1 TO K
         IF P(Y)=P(X) THEN
            LET P(Y)=P(Y)+1 !試合の結果を反映させる
            LET P(X)=0

            LET C=C+1
            PRINT C !結果を表示する
            MAT PRINT P;
         END IF
      NEXT Y
   NEXT X

   IF P(K)=K-1 THEN
      PRINT K-1;"連勝をつくりました。"
      PRINT
      LET K=K-1
      IF K=1 THEN
         LET S=0 !Σ
         FOR i=1 TO N
            LET S=S +2^(i-1)-1
         NEXT i
         PRINT S

         PRINT 2^N-1 -N !必要な試合の回数

         STOP
      END IF
   END IF
LOOP
END


実行結果

1
0  1  0  0  0  0

2
0  1  1  0  0  0

3
0  1  1  1  0  0

4
0  1  1  1  1  0

5
0  1  1  1  1  1

6
0  0  2  1  1  1

7
0  0  2  0  2  1

8
0  1  2  0  2  1

9
0  1  2  1  2  1

10
0  0  2  2  2  1

11
0  0  0  3  2  1

12
0  1  0  3  2  1

13
0  1  1  3  2  1

14
0  0  2  3  2  1

15
0  0  0  3  3  1

16
0  0  0  0  4  1

17
0  1  0  0  4  1

18
0  1  1  0  4  1

19
0  1  1  1  4  1

20
0  0  2  1  4  1

21
0  0  2  0  4  2

22
0  1  2  0  4  2

23
0  1  2  1  4  2

24
0  0  2  2  4  2

25
0  0  0  3  4  2

26
0  1  0  3  4  2

27
0  1  1  3  4  2

28
0  0  2  3  4  2

29
0  0  0  3  4  3

30
0  0  0  0  4  4

31
0  0  0  0  0  5

5 連勝をつくりました。

32
0  1  0  0  0  5

33
0  1  1  0  0  5

34
0  1  1  1  0  5

35
0  1  1  1  1  5

36
0  0  2  1  1  5

37
0  0  2  0  2  5

38
0  1  2  0  2  5

39
0  1  2  1  2  5

40
0  0  2  2  2  5

41
0  0  0  3  2  5

42
0  1  0  3  2  5

43
0  1  1  3  2  5

44
0  0  2  3  2  5

45
0  0  0  3  3  5

46
0  0  0  0  4  5

4 連勝をつくりました。

47
0  1  0  0  4  5

48
0  1  1  0  4  5

49
0  1  1  1  4  5

50
0  0  2  1  4  5

51
0  1  2  1  4  5

52
0  0  2  2  4  5

53
0  0  0  3  4  5

3 連勝をつくりました。

54
0  1  0  3  4  5

55
0  1  1  3  4  5

56
0  0  2  3  4  5

2 連勝をつくりました。

57
0  1  2  3  4  5

1 連勝をつくりました。

57
57

 

Re: n連勝

 投稿者:山中和義  投稿日:2014年 5月 5日(月)12時38分19秒
  > No.3372[元記事へ]

>k人が 2^(k-1)-1 試合を行って、ひとりが (k-1)連勝となる。 残りは、0連勝となる。
> Σ[k=1,n]{ 2^(k-1)-1 } = 2^n-1-n 試合

試合回数について
次のシミュレーションは、看板の並びを考えると、n! 通りの結果を得ることはわかる。
すべてに対して、同じ回数ではあるが、数理は見えない。

先のプログラムのように、特別な試合結果なら、明解となる。


!(3),(4)について
RANDOMIZE
LET N=7 !n連勝
DIM P(N) !n人の看板
MAT P=ZER
LET C=0 !試合の回数
DO
   LET FLG=0 !試合の有無

   FOR X=1 TO N-1 !xとyとの試合
      FOR Y=X+1 TO N
         IF P(Y)=P(X) THEN !試合の結果を反映させる
            LET FLG=1

            IF RND<0.5 THEN !確率的勝負 50%
               LET P(Y)=P(Y)+1
               LET P(X)=0
            ELSE
               LET P(X)=P(X)+1
               LET P(Y)=0
            END IF

            LET C=C+1
            PRINT "No.";C; " ";X;"-";Y !結果を表示する
            MAT PRINT P;
         END IF
      NEXT Y
   NEXT X

   IF FLG=0 THEN EXIT DO !試合がなかった場合は終了する
LOOP
PRINT 2^N-1-N !必要な試合の回数
END


実行結果

No. 1   1 - 2
0  1  0  0  0  0

No. 2   1 - 3
1  1  0  0  0  0

No. 3   3 - 4
1  1  1  0  0  0

No. 4   4 - 5
1  1  1  1  0  0

No. 5   5 - 6
1  1  1  1  0  1

No. 6   1 - 2
0  2  1  1  0  1

No. 7   1 - 5
1  2  1  1  0  1

No. 8   1 - 6
2  2  1  1  0  0

No. 9   3 - 4
2  2  0  2  0  0

No. 10   3 - 5
2  2  0  2  1  0

No. 11   3 - 6
2  2  1  2  1  0

No. 12   1 - 2
3  0  1  2  1  0

No. 13   2 - 6
3  1  1  2  1  0

No. 14   3 - 5
3  1  0  2  2  0

No. 15   3 - 6
3  1  1  2  2  0

No. 16   4 - 5
3  1  1  3  0  0

No. 17   5 - 6
3  1  1  3  1  0

No. 18   1 - 4
0  1  1  4  1  0

No. 19   1 - 6
1  1  1  4  1  0

No. 20   2 - 3
1  0  2  4  1  0

No. 21   2 - 6
1  0  2  4  1  1

No. 22   5 - 6
1  0  2  4  2  0

No. 23   2 - 6
1  1  2  4  2  0

No. 24   3 - 5
1  1  0  4  3  0

No. 25   3 - 6
1  1  1  4  3  0

No. 26   1 - 2
2  0  1  4  3  0

No. 27   2 - 6
2  1  1  4  3  0

No. 28   2 - 3
2  0  2  4  3  0

No. 29   2 - 6
2  1  2  4  3  0

No. 30   1 - 3
0  1  3  4  3  0

No. 31   1 - 6
0  1  3  4  3  1

No. 32   2 - 6
0  2  3  4  3  0

No. 33   3 - 5
0  2  0  4  4  0

No. 34   3 - 6
0  2  0  4  4  1

No. 35   4 - 5
0  2  0  0  5  1

No. 36   1 - 3
0  2  1  0  5  1

No. 37   1 - 4
0  2  1  1  5  1

No. 38   3 - 4
0  2  2  0  5  1

No. 39   1 - 4
1  2  2  0  5  1

No. 40   1 - 6
2  2  2  0  5  0

No. 41   2 - 3
2  3  0  0  5  0

No. 42   3 - 4
2  3  1  0  5  0

No. 43   4 - 6
2  3  1  1  5  0

No. 44   3 - 4
2  3  0  2  5  0

No. 45   3 - 6
2  3  0  2  5  1

No. 46   1 - 4
0  3  0  3  5  1

No. 47   2 - 4
0  0  0  4  5  1

No. 48   1 - 2
0  1  0  4  5  1

No. 49   1 - 3
0  1  1  4  5  1

No. 50   2 - 3
0  2  0  4  5  1

No. 51   1 - 3
1  2  0  4  5  1

No. 52   1 - 6
2  2  0  4  5  0

No. 53   3 - 6
2  2  1  4  5  0

No. 54   1 - 2
3  0  1  4  5  0

No. 55   2 - 6
3  1  1  4  5  0

No. 56   2 - 3
3  2  0  4  5  0

No. 57   3 - 6
3  2  0  4  5  1

57

 

Win版のバージョン番号

 投稿者:島村1243  投稿日:2014年 5月 7日(水)19時10分4秒
  Windowsインストーラー版 BASIC776setup.exe をインストールし、メニューhelpでバージョンを確認したら「775」となっていました。
 

3D回転処理

 投稿者:lark12_long  投稿日:2014年 5月 8日(木)06時36分15秒
  動作図に示すプログラムを作成しました

プログラムソースは、グッチャリしてるので、掲示致しませんが、
下記疑問点を、解決できません

どなたか、スマートなプログラム事例を、示して頂けると、嬉しいです

左上の、x+~z-は、
マウス左クリックで、立方体及び座要軸を、各軸周りに回転
マウス右クリックで、立方体のみを、各座標軸周りに回転
させます

左下の、x+~z-は、
マウス右クリックで、立方体を各軸方向に平行移動させます

疑問点

 立方体のx、y、z軸周りの回転は、画面表示上の各軸周りに回転するが、
 座標系の回転に於いては、立方体、座標軸共に、x軸周り回転は
 画面表示上のx軸周りに回転するが、
 y、z軸周りの回転は、画面上の軸周りに、回転しない

 z軸周りの回転は、画面に対しての垂線周りに回転する

 立方体の各軸方向への平行移動は、画面上の各軸に沿って平行移動する

lark12_long
 

Re: Win版のバージョン番号

 投稿者:白石和夫  投稿日:2014年 5月 8日(木)08時23分14秒
  > Windowsインストーラー版 BASIC776setup.exe をインストールし、メニューhelpでバージョンを確認したら「775」となっていました。

バージョン番号を更新するのを忘れていました。

変更点は,
POINT STYLE, LINE STYLE,AREA STYLE INDEX, LINE WIDTH に
0(不正な数値)を指定したときの挙動の誤りの修正です。

10 SET LINE STYLE 0
20 ASK LINE STYLE n
30 PRINT n
40 END
の実行結果が,
オプション―互換性―描画―図形関連SET文の不正な引数
が「続行不能例外として扱う」のとき,
EXTYPE 11062 のエラー,
「続行可能例外として扱う(JIS)」のとき,
1
であれば,Ver. 7.7.6 です。

Ver. 7.7.5(以前)では,例外を生成することなく実行結果は
256
になります。





 

Re: 3D回転処理

 投稿者:山中和義  投稿日:2014年 5月 9日(金)20時39分8秒
  > No.3375[元記事へ]

lark12_longさんへのお返事です。

> どなたか、スマートなプログラム事例を、示して頂けると、嬉しいです

XYZ軸の形をした図形をワールド座標の原点で回転させて、
その図形をもとに、「任意軸での回転」と「方向ベクトルに沿う移動」で立方体の位置を求めています。


SET WINDOW -3,3,-3,3 !表示領域

DIM AX(3,4) !XYZ軸の形をした図形
DATA 1,0,0 !X
DATA 0,1,0 !Y
DATA 0,0,1 !Z
FOR i=1 TO 3
   FOR J=1 TO 3
      READ AX(i,J) !x,y,z
      LET AX(i,4)=1 !w
   NEXT J
NEXT i

DIM BX(8,4) !立方体の8頂点
DATA -1,-1, 1 !上面
DATA  1,-1, 1
DATA  1, 1, 1
DATA -1, 1, 1
DATA -1,-1,-1 !下面
DATA  1,-1,-1
DATA  1, 1,-1
DATA -1, 1,-1
FOR i=1 TO 8
   FOR J=1 TO 3
      READ BX(i,J) !x,y,z
      LET BX(i,4)=1 !w
   NEXT J
NEXT i

DIM T(8,4) !(x',y',z')
DIM M(4,4)

DATA "+X","-X","+Y","-Y","+Z","-Z" !ボタン
DIM BTN$(6)
MAT READ BTN$

DO

   SET DRAW mode hidden !ちらつき防止(開始)
   CLEAR

   CALL button(-2.8,2.8, 0.6,0.3, 6, BTN$,S) !軸の回転メニュー
   SELECT CASE S
   CASE 0 !+x
      CALL D3ROTATE(RAD(5),AX(1,1),AX(1,2),AX(1,3), M) !5度ずつ
   CASE 1 !-x
      CALL D3ROTATE(RAD(-5),AX(1,1),AX(1,2),AX(1,3), M)
   CASE 2 !+y
      CALL D3ROTATE(RAD(5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 3 !-y
      CALL D3ROTATE(RAD(-5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 4 !+z
      CALL D3ROTATE(RAD(5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE 5 !-z
      CALL D3ROTATE(RAD(-5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE ELSE
      MAT M=IDN
   END SELECT
   MAT T=AX*M
   MAT AX=T
   MAT T=BX*M
   MAT BX=T


   CALL button(-2.0,2.8, 0.6,0.3, 6, BTN$,S) !図形の回転メニュー
   SELECT CASE S
   CASE 0 !+x
      CALL D3ROTATE(RAD(5),AX(1,1),AX(1,2),AX(1,3), M) !5度ずつ
   CASE 1 !-x
      CALL D3ROTATE(RAD(-5),AX(1,1),AX(1,2),AX(1,3), M)
   CASE 2 !+y
      CALL D3ROTATE(RAD(5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 3 !-y
      CALL D3ROTATE(RAD(-5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 4 !+z
      CALL D3ROTATE(RAD(5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE 5 !-z
      CALL D3ROTATE(RAD(-5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE ELSE
      MAT M=IDN
   END SELECT
   MAT T=BX*M
   MAT BX=T


   CALL button(-2.0,0.0, 0.6,0.3, 6, BTN$,S) !図形の平行移動メニュー
   SELECT CASE S
   CASE 0 !+x
      CALL VEC3NORMALIZE(AX(1,1),AX(1,2),AX(1,3), xx,yy,zz) !方向ベクトル
   CASE 1 !-x
      CALL VEC3NORMALIZE(-AX(1,1),-AX(1,2),-AX(1,3), xx,yy,zz)
   CASE 2 !+y
      CALL VEC3NORMALIZE(AX(2,1),AX(2,2),AX(2,3), xx,yy,zz)
   CASE 3 !-y
      CALL VEC3NORMALIZE(-AX(2,1),-AX(2,2),-AX(2,3), xx,yy,zz)
   CASE 4 !+z
      CALL VEC3NORMALIZE(AX(3,1),AX(3,2),AX(3,3), xx,yy,zz)
   CASE 5 !-z
      CALL VEC3NORMALIZE(-AX(3,1),-AX(3,2),-AX(3,3), xx,yy,zz)
   CASE ELSE
      LET xx=0
      LET yy=0
      LET zz=0
   END SELECT
   CALL D3SHIFT(xx*0.05,yy*0.05,zz*0.05, M) !0.05ずつ
   MAT T=BX*M
   MAT BX=T


   !XYZ軸を描く

   ! (x,y,z) → (x,y)
   !  Y
   !  ↑
   !  Z→X
   ! のXY平面へ投影する。

   SET LINE COLOR 4 !X軸
   PLOT LINES: AX(1,1),AX(1,2); 0,0
   PLOT TEXT, AT AX(1,1),AX(1,2): "x"
   SET LINE COLOR 3 !Y軸
   PLOT LINES: AX(2,1),AX(2,2); 0,0
   PLOT TEXT, AT AX(2,1),AX(2,2): "y"
   SET LINE COLOR 2 !Z軸
   PLOT LINES: AX(3,1),AX(3,2); 0,0
   PLOT TEXT, AT AX(3,1),AX(3,2): "z"


   !立方体を描く
   SET LINE COLOR 1
   FOR i=1 TO 3 !上面
      PLOT LINES: BX(i,1),BX(i,2); BX(i+1,1),BX(i+1,2)
   NEXT i
   PLOT LINES: BX(4,1),BX(4,2); BX(1,1),BX(1,2)
   FOR i=1 TO 4 !側面
      PLOT LINES: BX(i,1),BX(i,2); BX(i+4,1),BX(i+4,2)
   NEXT i
   FOR i=5 TO 7 !下面
      PLOT LINES: BX(i,1),BX(i,2); BX(i+1,1),BX(i+1,2)
   NEXT i
   PLOT LINES: BX(8,1),BX(8,2); BX(5,1),BX(5,2)


   SET DRAW mode explicit !ちらつき防止(終了)

   WAIT DELAY 0.1

LOOP

SUB button(x,y, dx,dy, n, btn$(),s) !左上位置(x,y)、大きさdx,dy、n個のボタン
   LET xx=x
   LET yy=y
   FOR i=1 TO n
      PLOT LINES: xx,yy; xx+dx,yy !枠を描く
      PLOT LINES: xx+dx,yy; xx+dx,yy-dy
      PLOT LINES: xx+dx,yy-dy; xx,yy-dy
      PLOT LINES: xx,yy-dy; xx,yy
      PLOT TEXT ,AT xx+dx/3,yy-4*dy/5: btn$(i) !名前 ※調整が必要
      LET yy=yy-dy
   NEXT i

   mouse poll mx,my,left,right !マウスポインタの位置を得る

   LET s=-1
   FOR K=0 TO 6-1
      IF ABS(mx-(x+dx/2))<dx/2 AND ABS(my-((y-dy*K)-dy/2))<dy/2 THEN LET s=K !k番目のボタン内なら
   NEXT K
   !!!PRINT s !debug
END SUB

END


EXTERNAL SUB VEC3NORMALIZE(Vx,Vy,Vz, x,y,z) !単位ベクトルへ
LET l=SQR(Vx*Vx+Vy*Vy+Vz*Vz)
IF l<>0 THEN
   LET x=Vx/l
   LET y=Vy/l
   LET z=Vz/l
END IF
END SUB

EXTERNAL SUB D3ROTATE(a,Vx,Vy,Vz, M(,)) !任意軸(位置ベクトル(Vx,Vy,Vz) )まわりの回転
CALL VEC3NORMALIZE(Vx,Vy,Vz, x,y,z)
LET c=COS(a)
LET s=SIN(a)
MAT M=ZER
LET M(1,1)=x*x*(1-c)+c
LET M(1,2)=x*y*(1-c)+z*s
LET M(1,3)=z*x*(1-c)-y*s
LET M(2,1)=x*y*(1-c)-z*s
LET M(2,2)=y*y*(1-c)+c
LET M(2,3)=y*z*(1-c)+x*s
LET M(3,1)=z*x*(1-c)+y*s
LET M(3,2)=y*z*(1-c)-x*s
LET M(3,3)=z*z*(1-c)+c
LET M(4,4)=1
END SUB


EXTERNAL SUB D3SCALE(a,b,c, M(,)) !拡大・縮小
MAT M=IDN
LET M(1,1)=a
LET M(2,2)=b
LET M(3,3)=c
END SUB


EXTERNAL SUB D3SHIFT(l,m,n, A(,)) !平行移動
MAT A=IDN
LET A(4,1)=l
LET A(4,2)=m
LET A(4,3)=n
END SUB


 

3D回転処理

 投稿者:lark12_long  投稿日:2014年 5月12日(月)05時18分45秒
  山中和義様
早速、模範プグラム提示いただき有難うございました
任意の単位ベクトル周りにθ回転する行列を使う事しりました

横長の広角画面表示に改造しました
今後、これを使用して、3D空間の運動等の、シミュレーション実験を、しようと思ってます
 

x^3+y^3+z^3=6xyzの自然数解

 投稿者:山中和義  投稿日:2014年 5月14日(水)19時15分29秒
  問題
x,y,zは自然数とするとき、x^3+y^3+z^3=6xyzを満たすx,y,zを求めよ。

考察
1≦x≦y≦zとする。

●mを自然数とすると、(x,y,z)=(m,2m,3m)は題意を満たす。

整数解では、(x,y,z)=(n,2n,3n)、(-n,n,0)が自明である。


●x^3+y^3+z^3=6xyzより、右辺は偶数なので、左辺も偶数である。

(x,y,z)=(偶数,偶数,偶数)
(x,y,z)=(偶数,奇数,奇数)
(x,y,z)=(奇数,偶数,奇数)
(x,y,z)=(奇数,奇数,偶数)


●zの範囲
x,yを固定すると、z{z^2+(-6xy)}=-(x^3+y^3)<0より、z^2+(-6xy)<0 ∴z<√(6xy)


以上をもとに、コーディングすると、


OPTION ARITHMETIC RATIONAL !多桁の整数

DEF GCD3(X,Y,Z)=GCD(GCD(X,Y),Z)

LET T=2000 !上限

!(x,y,z)=(奇数,偶数,奇数)
FOR X=1 TO T STEP 2
   FOR Y=X+1 TO 2*T STEP 2
      LET P=6*X*Y
      LET Q=X^3+Y^3

      LET Z=Y+1
      LET W=Z^2-P
      DO WHILE W<0
         IF Z*W=-Q THEN
            IF GCD3(X,Y,Z)=1 THEN PRINT X;Y;Z
         END IF
         LET Z=Z+2
         LET W=Z^2-P
      LOOP
   NEXT Y
NEXT X

END



または、


OPTION ARITHMETIC RATIONAL !多桁の整数

DEF GCD3(X,Y,Z)=GCD(GCD(X,Y),Z)

FOR Z=1 TO 6000 STEP 2 !上限
   FOR X=1 TO Z STEP 2
      FOR Y=X+1 TO Z STEP 2
         IF X^3+Y^3+Z^3=6*X*Y*Z THEN
            IF GCD3(X,Y,Z)=1 THEN PRINT X;Y;Z
         END IF
      NEXT Y
   NEXT X
NEXT Z

END



(x,y,z)=(1,2,3)、(1817,3258,5275)、(4904676969,10840875082,15051171563)、…

2番目以降を求めるのに苦労する。



考察
x^3+y^3+z^3=6xyzをz≠0という仮定のもと変形すると、(x/z)^3+(y/z)^3+1-6(x/z)(y/z)=0
よって、x^3+y^3+z^3=6xyzの整数解は、
 X^3+Y^3-6XY+1=0の有理数解(X,Y)が求まれば、x=Xz,y=Yzとなる整数x,y,z
として得られる。

ところで、x^3+y^3+z^3=6xyzの自明な整数解は、
 z=0のとき、x^3+y^3=0
 ∴(x+y)(x^2-xy+y^2)=(x+y){(x-y)^2+xy}=0 ∴x+y=0 ∴x=-y
 これより、(n,-n,0)

 z=1のとき、x^3+y^3+1=6xy (2,3,1) これより、(2n,3n,n)
である。

(2,3,1)、(1,-1,0)として、x,y,zを並び替えて、
(X,Y)=(2,3),(3,2),(1/2,3/2),(3/2,1/2),(1/3,2/3),(2/3,1/3),(0,-1),(-1,0)
の8点が対応する。

3次曲線Eの有理点P[1],P[2],…,P[n]から2点を結んでEとのもう1つの交点をとる。
この操作を繰り返すことにより、Eの有理点が得られる。
(終り)


OPTION ARITHMETIC RATIONAL !有理数

LET XB=3/1
LET YB=2/1

LET X1=-1/1 !赤色の線
LET Y1= 0/1
CALL try(X1,Y1, XB,YB,  XX,YY)

LET X1= 0/1 !緑色の線
LET Y1=-1/1
CALL try(X1,Y1, XX,YY,  X3,Y3)


CALL try(X3,Y3, XB,YB,  X3,Y3) !青色の線
CALL try(X3,Y3, XX,YY,  X3,Y3) !茶色の線
PRINT


CALL try(X3,Y3, XB,YB,  X3,Y3) !?色の線
CALL try(X3,Y3, XX,YY,  X3,Y3) !?色の線
PRINT


CALL try(X3,Y3, XB,YB,  X3,Y3) !?色の線
CALL try(X3,Y3, XX,YY,  X3,Y3) !?色の線
PRINT


CALL try(X3,Y3, XB,YB,  X3,Y3) !?色の線
CALL try(X3,Y3, XX,YY,  X3,Y3) !?色の線
PRINT


END


!点(x1,y1)、(x2,y2)を通る直線と曲線X^3+Y^3+1-6XY=0との交点を求める
EXTERNAL SUB try(X1,Y1, X2,Y2,  X3,Y3)
OPTION ARITHMETIC RATIONAL !有理数
IF X2-X1=0 THEN !y軸に平行
!x=x1=mと連立させて、M^3+Y^3-6MY+1=0 解と係数の関係より、Y1+Y2+Y3=0
   LET X3=X1
   LET Y3=-(Y1+Y2)
   PRINT "("; STR$(X1); ","; STR$(Y1); ")と("; STR$(X2); ","; STR$(Y2); ")を通る直線"
   PRINT X3;Y3
ELSE
   LET M=(Y2-Y1)/(X2-X1) !2点を通る直線 y={(y2-y1)/(x2-x1)}(x-x1)+y1=mx+n
   LET N=-M*X1+Y1
   !!!PRINT M;N !debug

   !y=mx+nと連立させて、残りの解を得る。
   !X^3+(MX+N)^3+1-6X(MX+N)=0 ∴(M^3+1)X^3+(3M^2N-6M)X^2+(3MN^2-6N)X+(N^3+1)=0
   !解と係数の関係より、X^2について、X1+X2+X3=-(3M^2N-6M)/(M^3+1)
   IF M^3+1=0 THEN !2次式になる
      PRINT "解なし"
      STOP
   ELSE
      LET X3=-(3*M^2*N-6*M)/(M^3+1)-(X1+X2)
      LET Y3=M*X3+N
      PRINT "("; STR$(X1); ","; STR$(Y1); ")と("; STR$(X2); ","; STR$(Y2); ")を通る直線"
      PRINT X3;Y3
   END IF
END IF
END SUB


実行結果

(-1,0)と(3,2)を通る直線
1/3  2/3
(1/3,2/3)と(0,-1)を通る直線
1/2  3/2
(1/2,3/2)と(3,2)を通る直線
-52/21  19/21
(-52/21,19/21)と(1/3,2/3)を通る直線
5275/3258  1817/3258

(5275/3258,1817/3258)と(3,2)を通る直線
124904/2847511 -3096807/2847511
(124904/2847511,-3096807/2847511)と(1/3,2/3)を通る直線
4904676969/10840875082  15051171563/10840875082

(4904676969/10840875082,15051171563/10840875082)と(3,2)を通る直線
-458665691607396/203863624933571  150777667094725/203863624933571
(-458665691607396/203863624933571,150777667094725/203863624933571)と(1/3,2/3)を通る直線
81821352777652044467/46875396961726681714  29381282043563909553/46875396961726681714

(81821352777652044467/46875396961726681714,29381282043563909553/46875396961726681714)と(3,2)を通る直線
6593378373315887264027696/71494678266896520634735569 -84573893519721693268169777/71494678266896520634735569
(6593378373315887264027696/71494678266896520634735569,-84573893519721693268169777/71494678266896520634735569)と(1/3,2/3)を通る直線
214674741825814609600406026499153/518752964649250744517842481308050  666161010410184261713443501009747/518752964649250744517842481308050



 

輪投げの点数

 投稿者:エステー  投稿日:2014年 5月18日(日)13時57分49秒
   輪投げの点数を集計して、合計点数の多い順に並べるプログラムを作りまし
た。合計欄の右横に順位を記入したいのですが、どのようなプログラムをつく
ればよいのかわかりません。どなたかそのプログラムをご教示願えないでしょ
うか。同じ合計点数の人は同じ順位にし、実行結果の順位欄のように番号をつ
けたいのです。よろしくお願いします。


PRINT "   "
PRINT "輪投げの点数の集計"
PRINT "   "

!人数と回数の入力---------------------------------
LET c=11  ! 出席人数
LET d=5   ! ゲームの回数

PRINT "出席人数=";c;"人"
PRINT "輪投げの回数=";d;"回"

DIM T(c,d+1),N$(c)

FOR I=1 TO c
   READ N$(I)
   FOR J=1 TO d
      READ T(I,J)
      LET T(I,d+1)=T(I,d+1)+T(I,J)
   NEXT J
NEXT I

FOR I=1 TO c
   FOR J=I+1 TO c
      IF T(I,d+1)>T(J,d+1) THEN GOTO 10
      LET M$=N$(I)
      LET N$(I)=N$(J)
      LET N$(J)=M$

      FOR K=1 TO d+1
         LET A=T(I,K)
         LET T(I,K)=T(J,K)
         LET T(J,K)=A
      NEXT K
10
      NEXT J
   NEXT I

   PRINT "   "
   PRINT TAB (20);"1回";TAB (27);"2回";TAB (34);"3回";
   PRINT TAB (41);"4回";TAB (48);"5回";TAB (55);"合計";TAB (62);"順位"


   FOR I=1 TO c
      PRINT I;" ";N$(I);
      FOR J=1 TO 6
         PRINT TAB (J*7+c+3);T(I,J);
      NEXT J
      PRINT
   NEXT I

   !氏名と点数の入力--------------------------------
   DATA エーさん  ,23  ,20  ,28  ,15  ,5
   DATA ビーさん  ,10  ,5  ,22  ,23  ,18
   DATA シーさん  ,18  ,21  ,11  ,0  ,14
   DATA デーさん  ,15  ,20  ,25  ,22  ,20
   DATA イーさん  ,18  ,22  ,10  ,24  ,17
   DATA エフさん  ,22  ,10  ,5  ,0  ,19
   DATA ジーさん  ,15  ,25  ,23  ,10  ,8
   DATA アイさん  ,22  ,11  ,8  ,26  ,015
   DATA ケーさん  ,8  ,6  ,19  ,22  ,18
   DATA エルさん  ,16  ,5  ,13  ,26  ,13
   DATA エムさん  ,10  ,8, 15  , 21  ,19
   !------------------------------------------------

END



実行結果(順位の欄は、手書きで書き加えた数字です)
                   1回   2回   3回   4回   5回   合計   順位
1  デーさん         15     20     25     22     20     102  1
2  イーさん         18     22     10     24     17     91    2
3  エーさん         23     20     28     15     5      91    2
4  アイさん         22     11     8      26     15     82    3
5  ジーさん         15     25     23     10     8      81    4
6  ビーさん         10     5      22     23     18     78    5
7  エムさん         10     8      15     21     19     73    6
8  エルさん         16     5      13     26     13     73    6
9  ケーさん         8      6      19     22     18     73    6
10  シーさん        18     21     11     0      14     64    7
11  エフさん        22     10     5      0      19     56    8
 

Re: 輪投げの点数

 投稿者:山中和義  投稿日:2014年 5月18日(日)17時32分59秒
  > No.3380[元記事へ]

エステーさんへのお返事です。

>  輪投げの点数を集計して、合計点数の多い順に並べるプログラムを作りまし
> た。合計欄の右横に順位を記入したいのですが、どのようなプログラムをつく
> ればよいのかわかりません。どなたかそのプログラムをご教示願えないでしょ
> うか。同じ合計点数の人は同じ順位にし、実行結果の順位欄のように番号をつ
> けたいのです。よろしくお願いします。


T(i,d+1)が並び替えられているので、それを使いましょう。


   PRINT TAB (20);"1回";TAB (27);"2回";TAB (34);"3回";
   PRINT TAB (41);"4回";TAB (48);"5回";TAB (55);"合計";TAB (62);"順位"


   LET K=1 !順位
   LET W=T(1,d+1) !その値

   FOR I=1 TO c
      PRINT I;" ";N$(I);
      FOR J=1 TO 6
         PRINT TAB (J*7+c+3);T(I,J);
      NEXT J
      IF T(I,d+1)<W THEN !小さい値なら
         LET K=K+1 !順位を下げる
         LET W=T(I,d+1)
      END IF

      PRINT TAB(62); K !表示する
   NEXT I

   !氏名と点数の入力--------------------------------
   DATA エーさん  ,23  ,20  ,28  ,15  ,5

 

輪投げの点数

 投稿者:エステー  投稿日:2014年 5月19日(月)09時44分54秒
  山中和義 様
 さっそくプログラムを提示していただき有難う御座いました。
自分なりにいろいろ作ってみたのですが、どうしてもうまく
いきません出した。5月末に行われる輪投げ大会(人数30人位)
で、このプログラムを使って点数を集計する予定です。
本当に有難うございました。今後もよろしくお願いします。
 

プログラムの移植のお願い

 投稿者:GAI  投稿日:2014年 5月20日(火)20時34分18秒
  http://www.nakanihon.co.jp/gijyutsu/Shimada/Computational%20geometry/chapter040901.html

を読んでいたら
1989年、当時高校生であった高田英行君が発見した定理として命名された問題です「安藤清、佐藤敏明共著、「初等幾何学」新数学入門シリーズ4、一松 信編集、森北出版、1994.」。点が込み入っていますので、用器画的に正確な作図をするのは難しいところです。この場合にも、円に内接する任意の五点を、乱数を使って決めるプログラムで描かせました。
 ミケルの五点円と似たところがあります。データとして与える初期値の五点は、円上にあるとして作図をはじめます。任意の五点A,B,C,D,Eは、円の中心角を乱数比で分解して決めました。今度は、五本の対角線の交点F,G,H,I,Jを求めます。この点と対辺の二点とを通る五つの円を描き、その円の交点U,V,W,X,Yを求めます。この五点が一つの円上に載ると言うものです。

これをG-BASIC という言語でプログラムされているのを、十進BASICへ移植して頂けませんか?

10 rem 高田の5点円
20 rem --- 円に内接する任意の五角形の生成から始める
30 CLG
40 DEF2PT P: DEF2CR C : DEF2ED E: DEF2LN L
50 DIM ANG[5],PR[5]
60 ANG[1]=RND(0)
70 FOR I=2 TO 5: ANG[I]=1+2*RND(0)+ANG[I-1] : NEXT
80 ANG0=360/(ANG[5]+1)
90 FOR I=1 TO 5: ANG[I]=ANG0*ANG[I] : NEXT
100 R=200: C=R*C
110 FOR I=1 TO 5
120 LET P=R*COS(ANG[I]), R*SIN(ANG[I]): PR[I]=P
130 NEXT
140 E12=PR[1]@PR[2] : E13=PR[1]@PR[3]
150 E14=PR[1]@PR[4] : E15=PR[1]@PR[5]
160 E23=PR[2]@PR[3] : E24=PR[2]@PR[4]
170 E25=PR[2]@PR[5] : E34=PR[3]@PR[4]
180 E35=PR[3]@PR[5] : E45=PR[4]@PR[5]
190 P12=E13&E25 : P23=E24&E13 : P34=E35&E24
200 P45=E14&E35 : P51=E14&E25
210 GROFF: L1=LBSEC(PR[1],PR[2])
211 L2=LBSEC(PR[1],P12)
220 P0=L1&L2: R0=DIS(P0,PR[1]) : LET C1=P0,R0
221 GRON: C1=C1
230 GROFF: L1=LBSEC(PR[2],PR[3])
231 L2=LBSEC(PR[2],P23)
240 P0=L1&L2: R0=DIS(P0,PR[2]) : LET C2=P0,R0
241 GRON: C2=C2
250 GROFF: L1=LBSEC(PR[3],PR[4])
251 L2=LBSEC(PR[3],P34)
260 P0=L1&L2: R0=DIS(P0,PR[3]) : LET C3=P0,R0
261 GRON: C3=C3
270 GROFF: L1=LBSEC(PR[4],PR[5])
271 L2=LBSEC(PR[4],P45)
280 P0=L1&L2: R0=DIS(P0,PR[4]) : LET C4=P0,R0
281 GRON: C4=C4
290 GROFF: L1=LBSEC(PR[5],PR[1])
291 L2=LBSEC(PR[5],P51)
300 P0=L1&L2: R0=DIS(P0,PR[5]) : LET C5=P0,R0
301 GRON: C5=C5
310 PU=C1&C2 : PV=C2&C3 : PW=C3&C4 : PX=C4&C5
311 PY=C5&C1
320 GROFF: L1=LBSEC(PU,PV) : L2=LBSEC(PU,PX)
330 P0=L1&L2: R0=DIS(P0,PU) : LET CT=P0,R0
331 GRON: CT=CT
340 LET X,Y=PR[1]: DPTEXT X,Y,"A"
350 LET X,Y=PR[2]: DPTEXT X,Y,"B"
360 LET X,Y=PR[3]: DPTEXT X,Y,"C"
370 LET X,Y=PR[4]: DPTEXT X,Y,"D"
380 LET X,Y=PR[5]: DPTEXT X,Y,"E"
390 LET X,Y=P12: DPTEXT X,Y,"F"
400 LET X,Y=P23: DPTEXT X,Y,"G"
410 LET X,Y=P34: DPTEXT X,Y,"H"
420 LET X,Y=P45: DPTEXT X,Y,"I"
430 LET X,Y=P51: DPTEXT X,Y,"J"
440 LET X,Y=PU: DPTEXT X,Y,"U"
450 LET X,Y=PV: DPTEXT X,Y,"V"
460 LET X,Y=PW: DPTEXT X,Y,"W"
470 LET X,Y=PX: DPTEXT X,Y,"X"
480 LET X,Y=PY: DPTEXT X,Y,"Y"
490 DPTEXT -300, 200, "高田の五点円"



 

Re: プログラムの移植のお願い

 投稿者:SECOND  投稿日:2014年 5月21日(水)17時03分23秒
  > No.3383[元記事へ]

GAIさんへのお返事です。

> http://www.nakanihon.co.jp/gijyutsu/Shimada/Computational%20geometry/chapter040901.html
>
> を読んでいたら
> 1989年、当時高校生であった高田英行君が発見した定理として命名された問題です「安藤清、佐藤敏明共著、「初等幾何学」新数学入門シリーズ4、一松 信編集、森北出版、1994.」。点が込み入っていますので、用器画的に正確な作図をするのは難しいところです。この場合にも、円に内接する任意の五点を、乱数を使って決めるプログラムで描かせました。
>  ミケルの五点円と似たところがあります。データとして与える初期値の五点は、円上にあるとして作図をはじめます。任意の五点A,B,C,D,Eは、円の中心角を乱数比で分解して決めました。今度は、五本の対角線の交点F,G,H,I,Jを求めます。この点と対辺の二点とを通る五つの円を描き、その円の交点U,V,W,X,Yを求めます。この五点が一つの円上に載ると言うものです。
>
!これをG-BASIC という言語でプログラムされているのを、十進BASICへ移植して頂けませんか?

!                                              !10 rem 高田の5点円
!                                              !20 rem --- 円に内接する任意の五角形の生成から始める
OPTION ARITHMETIC COMPLEX
SET WINDOW -400,400,-400,400
RANDOMIZE
SET TEXT background "opaque"
!                                              !30 CLG
!                                              !40 DEF2PT P: DEF2CR C : DEF2ED E: DEF2LN L
DIM ANG(5), PR(5)                              !50 DIM ANG[5],PR[5]

LET ANG(1)=2*RND                               !60 ANG[1]=RND(0) ←2* の脱落
FOR i=2 TO 5                                   !70 FOR I=2 TO 5: ANG[I]=1+2*RND(0)+ANG[I-1] : NEXT
   LET ANG(i)=1+2*RND+ANG(i-1)
NEXT i
LET ANG0=2*PI/(ANG(5)+1)                       !80 ANG0=360/(ANG[5]+1)
!
FOR i=1 TO 5                                   !90 FOR I=1 TO 5: ANG[I]=ANG0*ANG[I] : NEXT
   LET ANG(i)=ANG0*ANG(i)
NEXT i
!
LET R=200                                      !100 R=200: C=R*C
DRAW circle WITH SCALE(R)
FOR i=1 TO 5                                   !110 FOR I=1 TO 5
   LET PR(i)=R*EXP(COMPLEX(0,ANG(i)))          !120 LET P=R*COS(ANG[I]), R*SIN(ANG[I]): PR[I]=P
NEXT i                                         !130 NEXT
!
!                                              !140 E12=PR[1]@PR[2] : E13=PR[1]@PR[3]
!                                              !150 E14=PR[1]@PR[4] : E15=PR[1]@PR[5]
!                                              !160 E23=PR[2]@PR[3] : E24=PR[2]@PR[4]
!                                              !170 E25=PR[2]@PR[5] : E34=PR[3]@PR[4]
!                                              !180 E35=PR[3]@PR[5] : E45=PR[4]@PR[5]
PLOT LINES: PR(1);PR(2);PR(3);PR(4);PR(5);
PLOT LINES: PR(1);PR(3);PR(5);PR(2);PR(4);PR(1)
!
!                                              !190 P12=E13&E25 : P23=E24&E13 : P34=E35&E24
!                                              !200 P45=E14&E35 : P51=E14&E25
LET P12=xpt2L( PR(1),PR(3), PR(2),PR(5))
LET P23=xpt2L( PR(2),PR(4), PR(1),PR(3))
LET P34=xpt2L( PR(3),PR(5), PR(2),PR(4))
LET P45=xpt2L( PR(1),PR(4), PR(3),PR(5))
LET P51=xpt2L( PR(1),PR(4), PR(2),PR(5))
! PLOT POINTS: P12; P23; P34; P45; P51

FUNCTION xpt2L(a,b, c,d)                       !直線a~b 直線c~d の交点
   LET L1=b-a
   LET a_=a/L1
   LET c_=c/L1
   LET d_=d/L1
   LET x=(im(a_)-im(c_))*re(d_-c_)/im(d_-c_)+re(c_)
   LET xpt2L=COMPLEX(x,im(a_))*L1
END FUNCTION

SUB LBSEC(a,b, c,d)                            !直線a~b に垂直で a~b の中点を通る直線 → c~d
   LET c=(a+b)/2
   LET d=(b-a)*COMPLEX(0,1)+c
END SUB

CALL LBSEC( PR(1),PR(2), a,b)                  !210 GROFF: L1=LBSEC(PR[1],PR[2])
CALL LBSEC( PR(1),P12,   c,d)                  !211 L2=LBSEC(PR[1],P12)
LET P1=xpt2L(a,b, c,d)                         !220 P0=L1&L2: R0=DIS(P0,PR[1]) : LET C1=P0,R0
LET R1=ABS(PR(1)-P1)
DRAW circle WITH SCALE(R1)*SHIFT(P1)           !221 GRON: C1=C1

CALL LBSEC( PR(2),PR(3), a,b)                  !230 GROFF: L1=LBSEC(PR[2],PR[3])
CALL LBSEC( PR(2),P23  , c,d)                  !231 L2=LBSEC(PR[2],P23)
LET P2=xpt2L(a,b, c,d)                         !240 P0=L1&L2: R0=DIS(P0,PR[2]) : LET C2=P0,R0
LET R2=ABS( PR(2)-P2)
DRAW circle WITH SCALE(R2)*SHIFT(P2)           !241 GRON: C2=C2
!
!                                              !250 GROFF: L1=LBSEC(PR[3],PR[4])
!                                              !251 L2=LBSEC(PR[3],P34)
!                                              !260 P0=L1&L2: R0=DIS(P0,PR[3]) : LET C3=P0,R0
!                                              !261 GRON: C3=C3
CALL LBSEC( PR(3),PR(4), a,b)
CALL LBSEC( PR(3),P34  , c,d)
LET P3=xpt2L(a,b, c,d)
LET R3=ABS( PR(3)-P3)
DRAW circle WITH SCALE(R3)*SHIFT(P3)
!                                              !270 GROFF: L1=LBSEC(PR[4],PR[5])
!                                              !271 L2=LBSEC(PR[4],P45)
!                                              !280 P0=L1&L2: R0=DIS(P0,PR[4]) : LET C4=P0,R0
!                                              !281 GRON: C4=C4
CALL LBSEC( PR(4),PR(5), a,b)
CALL LBSEC( PR(4),P45  , c,d)
LET P4=xpt2L(a,b, c,d)
LET R4=ABS( PR(4)-P4)
DRAW circle WITH SCALE(R4)*SHIFT(P4)
!                                              !290 GROFF: L1=LBSEC(PR[5],PR[1])
!                                              !291 L2=LBSEC(PR[5],P51)
!                                              !300 P0=L1&L2: R0=DIS(P0,PR[5]) : LET C5=P0,R0
!                                              !301 GRON: C5=C5
CALL LBSEC( PR(5),PR(1), a,b)
CALL LBSEC( PR(5),P51  , c,d)
LET P5=xpt2L(a,b, c,d)
LET R5=ABS( PR(5)-P5)
DRAW circle WITH SCALE(R5)*SHIFT(P5)
!
!                                              !310 PU=C1&C2 : PV=C2&C3 : PW=C3&C4 : PX=C4&C5
!                                              !311 PY=C5&C1
LET PU=xpt2C(P1,R1, P2,R2)
LET PV=xpt2C(P2,R2, P3,R3)
LET PW=xpt2C(P3,R3, P4,R4)
LET PX=xpt2C(P4,R4, P5,R5)
LET PY=xpt2C(P5,R5, P1,R1)
PLOT POINTS: PU; PV; PW; PX; PY

FUNCTION xpt2C(p0,r0, p1,r1)                   !円(中心p0,半径r0) と 円(中心p1,半径r1) の
   LET p01=p1-p0                               !交点2個から、原点に近い方。
   LET ux=(r0^2+ABS(p01)^2-r1^2)/(2*ABS(p01))
   LET uy=SQR(r0^2-ux^2)
   LET u=COMPLEX(ux,uy)
   LET p=p0+u*p01/ABS(p01)
   LET p_=p0+conj(u)*p01/ABS(p01)
   LET xpt2C=p
   IF ABS(p_)< ABS(p) THEN LET xpt2C=p_
END FUNCTION

!                                              !320 GROFF: L1=LBSEC(PU,PV) : L2=LBSEC(PU,PX)
!                                              !330 P0=L1&L2: R0=DIS(P0,PU) : LET CT=P0,R0
!                                              !331 GRON: CT=CT
CALL LBSEC( PU,PV, a,b)
CALL LBSEC( PU,PX, c,d)
LET P0=xpt2L(a,b, c,d)
LET R0=ABS( PU-P0)
DRAW circle WITH SCALE(R0)*SHIFT(P0)
!
!                                              !340 LET X,Y=PR[1]: DPTEXT X,Y,"A"
!                                              !350 LET X,Y=PR[2]: DPTEXT X,Y,"B"
!                                              !360 LET X,Y=PR[3]: DPTEXT X,Y,"C"
!                                              !370 LET X,Y=PR[4]: DPTEXT X,Y,"D"
!                                              !380 LET X,Y=PR[5]: DPTEXT X,Y,"E"
!                                              !390 LET X,Y=P12: DPTEXT X,Y,"F"
!                                              !400 LET X,Y=P23: DPTEXT X,Y,"G"
!                                              !410 LET X,Y=P34: DPTEXT X,Y,"H"
!                                              !420 LET X,Y=P45: DPTEXT X,Y,"I"
!                                              !430 LET X,Y=P51: DPTEXT X,Y,"J"
!                                              !440 LET X,Y=PU: DPTEXT X,Y,"U"
!                                              !450 LET X,Y=PV: DPTEXT X,Y,"V"
!                                              !460 LET X,Y=PW: DPTEXT X,Y,"W"
!                                              !470 LET X,Y=PX: DPTEXT X,Y,"X"
!                                              !480 LET X,Y=PY: DPTEXT X,Y,"Y"
!                                              !490 DPTEXT -300, 200, "高田の五点円"
PLOT TEXT,AT PR(1):"A"
PLOT TEXT,AT PR(2):"B"
PLOT TEXT,AT PR(3):"C"
PLOT TEXT,AT PR(4):"D"
PLOT TEXT,AT PR(5):"E"
PLOT TEXT,AT P12:"F"
PLOT TEXT,AT P23:"G"
PLOT TEXT,AT P34:"H"
PLOT TEXT,AT P45:"I"
PLOT TEXT,AT P51:"J"
PLOT TEXT,AT PU:"U"
PLOT TEXT,AT PV:"V"
PLOT TEXT,AT PW:"W"
PLOT TEXT,AT PX:"X"
PLOT TEXT,AT PY:"Y"
PLOT TEXT,AT -300, 200: "高田の五点円"

END
 

Re: プログラムの移植のお願い

 投稿者:SECOND  投稿日:2014年 5月21日(水)21時52分43秒
  > No.3384[元記事へ]

!------------------------------------------------
!整理したもの

REM 高田の5点円
REM --- 円に内接する任意の五角形の生成から始める
!
OPTION ARITHMETIC COMPLEX
SET WINDOW -400,400,-400,400
RANDOMIZE
SET TEXT background "opaque"
DIM ANG(5), PR(5)
!
LET R=200
DRAW circle WITH SCALE(R)                        !5角形の外接円を描く
LET ANG(1)=2*RND
FOR i=2 TO 5
   LET ANG(i)=1+2*RND+ANG(i-1)                   !ANG()= RND が不変なら等しい間隔の、加算値
NEXT i
LET ANG0=2*PI/(ANG(5)+1)                         !(ANG(5)+1)= 1周分の間隔の総和
FOR i=1 TO 5
   LET PR(i)=R*EXP(COMPLEX(0,ANG0*ANG(i)))       !PR()= 不規則な、5分割の、円周上の点
NEXT i
!
PLOT LINES: PR(1);PR(2);PR(3);PR(4);PR(5);       !5角形と
PLOT LINES: PR(1);PR(3);PR(5);PR(2);PR(4);PR(1)  !その対角線を描く
!
LET P12=xpt2L( PR(1),PR(3), PR(2),PR(5))         !P12= 直線PR(1)~PR(3) 直線PR(2)~PR(5) の交点
LET P23=xpt2L( PR(2),PR(4), PR(1),PR(3))
LET P34=xpt2L( PR(3),PR(5), PR(2),PR(4))
LET P45=xpt2L( PR(1),PR(4), PR(3),PR(5))
LET P51=xpt2L( PR(1),PR(4), PR(2),PR(5))
! PLOT POINTS: P12; P23; P34; P45; P51
!
CALL circ3p(PR(1),PR(2),P12, P1,R1)     !3点 PR(1),PR(2),P12 を通る円を描き、中心:P1 半径:R1を返す。
CALL circ3p(PR(2),PR(3),P23, P2,R2)
CALL circ3p(PR(3),PR(4),P34, P3,R3)
CALL circ3p(PR(4),PR(5),P45, P4,R4)
CALL circ3p(PR(5),PR(1),P51, P5,R5)
!
LET PU=xpt2C(P1,R1, P2,R2)              !PU= 円(中心P1,半径R1) と 円(中心P2,半径R2) の交点
LET PV=xpt2C(P2,R2, P3,R3)              !    交点は2個あるが、原点に近い方1つ返す。
LET PW=xpt2C(P3,R3, P4,R4)
LET PX=xpt2C(P4,R4, P5,R5)
LET PY=xpt2C(P5,R5, P1,R1)
PLOT POINTS: PU; PV; PW; PX; PY
!
CALL circ3p(PU,PV,PX, P0,R0)            !3点 PU,PV,PX を通る円を描き、中心:P0 半径:R0を返す。
!
PLOT TEXT,AT PR(1):"A"
PLOT TEXT,AT PR(2):"B"
PLOT TEXT,AT PR(3):"C"
PLOT TEXT,AT PR(4):"D"
PLOT TEXT,AT PR(5):"E"
PLOT TEXT,AT P12:"F"
PLOT TEXT,AT P23:"G"
PLOT TEXT,AT P34:"H"
PLOT TEXT,AT P45:"I"
PLOT TEXT,AT P51:"J"
PLOT TEXT,AT PU:"U"
PLOT TEXT,AT PV:"V"
PLOT TEXT,AT PW:"W"
PLOT TEXT,AT PX:"X"
PLOT TEXT,AT PY:"Y"
PLOT TEXT,AT -300, 200: "高田の五点円"

FUNCTION xpt2L(a,b, c,d)                       !直線a~b 直線c~d の交点
   LET L1=b-a
   LET a_=a/L1
   LET c_=c/L1
   LET d_=d/L1
   LET x=(im(a_)-im(c_))*re(d_-c_)/im(d_-c_)+re(c_)
   LET xpt2L=COMPLEX(x,im(a_))*L1
END FUNCTION

SUB LBSEC(a,b, c,d)                            !直線a~b に垂直で a~b の中点を通る直線 → c~d
   LET c=(a+b)/2
   LET d=(b-a)*COMPLEX(0,1)+c
END SUB

SUB circ3p(u,v,w, C,R)                         !3点 u,v,w に接する円を描き、中心C 半径R を返す。
   CALL LBSEC( u,v, a,b)
   CALL LBSEC( u,w, c,d)
   LET C=xpt2L(a,b, c,d)
   LET R=ABS(u-C)
   DRAW circle WITH SCALE(R)*SHIFT(C)
END SUB

FUNCTION xpt2C(p0,r0, p1,r1)                   !円(中心p0,半径r0) と 円(中心p1,半径r1) の交点
   LET p01=p1-p0
   LET ux=(r0^2+ABS(p01)^2-r1^2)/(2*ABS(p01))
   LET uy=SQR(r0^2-ux^2)
   LET u=COMPLEX(ux,uy)
   LET p=p0+u*p01/ABS(p01)
   LET p_=p0+conj(u)*p01/ABS(p01)
   LET xpt2C=p
   IF ABS(p_)< ABS(p) THEN LET xpt2C=p_        !交点2個 p p_ から原点に近い方が返り値。
END FUNCTION

END
 

3D回転処理に付いて

 投稿者:lark12_long  投稿日:2014年 5月24日(土)08時59分45秒
  山中和義様

2014年 5月 9日(金)20時39分8秒
に、山中和義様より、Re: 3D回転処理として、
プログラム事例を提供して頂きました

提供頂いたプログラムでは、立方体の頂点座標xyz値を、
bx(i,1)、bx(i,2)、bx(i,3)に格納し、
回転処理結果も、bx(i,1)、bx(i,2)、bx(i,3)に
更新された値が格納されます

立方体の原始データbx()は初期状態を維持したまま、
回転処理は、表示のみにしたいと思い、立方体の表示データとして
bxw()設け、色々試してみたのですが、
うまく行かず、メゲています

方法を教示頂きたく思います

lark12_long




 

Re: 3D回転処理に付いて

 投稿者:山中和義  投稿日:2014年 5月24日(土)10時45分19秒
  > No.3386[元記事へ]

lark12_longさんへのお返事です。

> 立方体の原始データbx()は初期状態を維持したまま、
> 回転処理は、表示のみにしたいと思い、


座標変換 (x',y',z',w')=(x,y,z,w)M[1]M[2]M[3] … M[n] より、

前回の場合
 1回目の操作 (x',y',z',w')=(x,y,z,w) M[1]
 2回目の操作 (x",y",z",w")=(x',y',z',w') M[2]=( (x,y,z,w) M[1] ) M[2]
 3回目の操作 (x"',y"',z"',w"')=(x",y",z",w") M[3]=( ( (x,y,z,w) M[1] ) M[2] ) M[3]
   :

 累積するのは、変換された図形の座標とする。

今回の場合
 1回目の操作 (x',y',z',w')=(x,y,z,w) M[1]
 2回目の操作 (x',y',z',w')=(x,y,z,w) ( M[1..2] )=(x,y,z,w) ( M[1] M[2] )
 3回目の操作 (x',y',z',w')=(x,y,z,w) ( M[1..3] )=(x,y,z,w) ( M[1] M[2] M[3] )
   :
 n回目の操作 (x',y',z',w')=(x,y,z,w)( ( ( ( M[1] M[2] ) M[3] ) … ) M[n] )

 累積するのは、変換行列とする。



SET WINDOW -3,3,-3,3 !表示領域

DIM AX(3,4) !XYZ軸の形をした図形(3本の方向ベクトル、3本の矢)
DATA 1,0,0 !X
DATA 0,1,0 !Y
DATA 0,0,1 !Z
FOR i=1 TO 3
   FOR J=1 TO 3
      READ AX(i,J) !x,y,z
      LET AX(i,4)=1 !w
   NEXT J
NEXT i

DIM BX(8,4) !立方体の8頂点
DATA -1,-1, 1 !上面
DATA  1,-1, 1
DATA  1, 1, 1
DATA -1, 1, 1
DATA -1,-1,-1 !下面
DATA  1,-1,-1
DATA  1, 1,-1
DATA -1, 1,-1
FOR i=1 TO 8
   FOR J=1 TO 3
      READ BX(i,J) !x,y,z
      LET BX(i,4)=1 !w
   NEXT J
NEXT i

DIM T(50,4) !(x',y',z',w')=(x,y,z,w)M による座標変換
DIM MA(4,4),MB(4,4), M(4,4)
MAT MA=IDN !図形Aに対する累積された変換
MAT MB=IDN !図形Bに対する累積された変換

DATA "+RX","-RX","+RY","-RY","+RZ","-RZ" !ボタン
DATA "+TX","-TX","+TY","-TY","+TZ","-TZ" !ボタン
DIM BTN1$(6),BTN2$(6)
MAT READ BTN1$
MAT READ BTN2$

DO

   SET DRAW mode hidden !ちらつき防止(開始)
   CLEAR

   MAT T=AX*MA !軸の傾き

   CALL button(-2.8,2.8, 0.6,0.3, 6, BTN1$,  S,S2) !回転メニュー
   SELECT CASE S
   CASE 1 !+x
      CALL D3ROTATE(RAD(5),T(1,1),T(1,2),T(1,3), M) !5度ずつ
   CASE 2 !-x
      CALL D3ROTATE(RAD(-5),T(1,1),T(1,2),T(1,3), M)
   CASE 3 !+y
      CALL D3ROTATE(RAD(5),T(2,1),T(2,2),T(2,3), M)
   CASE 4 !-y
      CALL D3ROTATE(RAD(-5),T(2,1),T(2,2),T(2,3), M)
   CASE 5 !+z
      CALL D3ROTATE(RAD(5),T(3,1),T(3,2),T(3,3), M)
   CASE 6 !-z
      CALL D3ROTATE(RAD(-5),T(3,1),T(3,2),T(3,3), M)
   CASE ELSE
      MAT M=IDN
   END SELECT
   MAT MB=MB*M
   IF S2=2 THEN !左ボタン押下で軸も回転させる
      MAT MA=MA*M
   END IF


   CALL button(-2.0,0.0, 0.6,0.3, 6, BTN2$,  S,S2) !図形の平行移動メニュー
   SELECT CASE S
   CASE 1 !+x
      CALL VEC3NORMALIZE(T(1,1),T(1,2),T(1,3), xx,yy,zz) !方向ベクトル
   CASE 2 !-x
      CALL VEC3NORMALIZE(-T(1,1),-T(1,2),-T(1,3), xx,yy,zz)
   CASE 3 !+y
      CALL VEC3NORMALIZE(T(2,1),T(2,2),T(2,3), xx,yy,zz)
   CASE 4 !-y
      CALL VEC3NORMALIZE(-T(2,1),-T(2,2),-T(2,3), xx,yy,zz)
   CASE 5 !+z
      CALL VEC3NORMALIZE(T(3,1),T(3,2),T(3,3), xx,yy,zz)
   CASE 6 !-z
      CALL VEC3NORMALIZE(-T(3,1),-t(3,2),-T(3,3), xx,yy,zz)
   CASE ELSE
      LET xx=0
      LET yy=0
      LET zz=0
   END SELECT
   CALL D3SHIFT(xx*0.05,yy*0.05,zz*0.05, M) !0.05ずつ
   MAT MB=MB*M


   !XYZ軸を描く

   ! ワールド座標(x,y,z) → スクリーン座標(x,y)
   !   Y
   !   ↑
   !   Z→X
   !  のXY平面(スクリーン座標)へ投影する。

   MAT T=AX*MA !図形を回転させる

   SET LINE COLOR 4 !X軸
   PLOT LINES: 0,0; T(1,1),T(1,2)
   PLOT TEXT, AT T(1,1),T(1,2): "x"
   SET LINE COLOR 3 !Y軸
   PLOT LINES: 0,0; T(2,1),T(2,2)
   PLOT TEXT, AT T(2,1),T(2,2): "y"
   SET LINE COLOR 2 !Z軸
   PLOT LINES: 0,0; T(3,1),T(3,2)
   PLOT TEXT, AT T(3,1),T(3,2): "z"


   !立方体を描く

   MAT T=BX*MB !図形を回転させる

   SET LINE COLOR 1
   FOR i=1 TO 3 !上面
      PLOT LINES: T(i,1),T(i,2); T(i+1,1),T(i+1,2)
   NEXT i
   PLOT LINES: T(4,1),T(4,2); T(1,1),T(1,2)
   FOR i=1 TO 4 !側面の稜線
      PLOT LINES: T(i,1),T(i,2); T(i+4,1),T(i+4,2)
   NEXT i
   FOR i=5 TO 7 !下面
      PLOT LINES: T(i,1),T(i,2); T(i+1,1),T(i+1,2)
   NEXT i
   PLOT LINES: T(8,1),T(8,2); T(5,1),T(5,2)


   SET DRAW mode explicit !ちらつき防止(終了)

   WAIT DELAY 0.1

LOOP


SUB button(x,y, dx,dy, n, btn$(),  s,s2) !左上位置(x,y)、大きさdx,dy、n個のボタン
   mouse poll mx,my,left,right !マウスポインタの状態を得る

   LET s2=left*2+right !0:なし、1:右、2:左、3:左右

   LET s=-1 !マウスポインタが、どのボタンと重なっているか

   LET x1=x !左上
   LET y1=y
   FOR k=1 TO n !タイル貼り
      LET x2=x1+dx !右下
      LET y2=y1-dy

      IF (mx>=MIN(x1,x2) AND mx<=MAX(x1,x2)) AND (my>=MIN(y1,y2) AND my<=MAX(y1,y2)) THEN
         LET s=k !k番目のボタン内なら
      END IF

      PLOT LINES: x1,y1; x2,y1 !枠を描く
      PLOT LINES: x2,y1; x2,y2
      PLOT LINES: x2,y2; x1,y2
      PLOT LINES: x1,y2; x1,y1
      PLOT TEXT ,AT x1+dx/5,y1-4*dy/5: btn$(k) !名前 ※調整が必要

      LET y1=y2 !次へ
   NEXT k

   !!!PRINT s !debug
END SUB

END


EXTERNAL SUB VEC3NORMALIZE(Vx,Vy,Vz, x,y,z) !単位ベクトルへ正規化する
LET l=SQR(Vx*Vx+Vy*Vy+Vz*Vz)
IF l<>0 THEN
   LET x=Vx/l
   LET y=Vy/l
   LET z=Vz/l
END IF
END SUB

EXTERNAL SUB D3ROTATE(a,Vx,Vy,Vz, M(,)) !任意軸(位置ベクトル(Vx,Vy,Vz) )まわりの回転
CALL VEC3NORMALIZE(Vx,Vy,Vz, x,y,z)
LET c=COS(a)
LET s=SIN(a)
MAT M=ZER
LET M(1,1)=x*x*(1-c)+c
LET M(1,2)=x*y*(1-c)+z*s
LET M(1,3)=z*x*(1-c)-y*s
LET M(2,1)=x*y*(1-c)-z*s
LET M(2,2)=y*y*(1-c)+c
LET M(2,3)=y*z*(1-c)+x*s
LET M(3,1)=z*x*(1-c)+y*s
LET M(3,2)=y*z*(1-c)-x*s
LET M(3,3)=z*z*(1-c)+c
LET M(4,4)=1
END SUB


EXTERNAL SUB D3SCALE(a,b,c, M(,)) !拡大・縮小
MAT M=IDN
LET M(1,1)=a
LET M(2,2)=b
LET M(3,3)=c
END SUB


EXTERNAL SUB D3SHIFT(l,m,n, A(,)) !平行移動
MAT A=IDN
LET A(4,1)=l
LET A(4,2)=m
LET A(4,3)=n
END SUB




前回 ※サブルーチン部分は省略

SET WINDOW -3,3,-3,3 !表示領域

DIM AX(3,4) !XYZ軸の形をした図形(3本の方向ベクトル、3本の矢)
DATA 1,0,0 !X
DATA 0,1,0 !Y
DATA 0,0,1 !Z
FOR i=1 TO 3
   FOR J=1 TO 3
      READ AX(i,J) !x,y,z
      LET AX(i,4)=1 !w
   NEXT J
NEXT i

DIM BX(8,4) !立方体の8頂点
DATA -1,-1, 1 !上面
DATA  1,-1, 1
DATA  1, 1, 1
DATA -1, 1, 1
DATA -1,-1,-1 !下面
DATA  1,-1,-1
DATA  1, 1,-1
DATA -1, 1,-1
FOR i=1 TO 8
   FOR J=1 TO 3
      READ BX(i,J) !x,y,z
      LET BX(i,4)=1 !w
   NEXT J
NEXT i

DIM T(50,4) !(x',y',z',w')=(x,y,z,w)M による座標変換
DIM M(4,4)

DATA "+RX","-RX","+RY","-RY","+RZ","-RZ" !ボタン
DATA "+TX","-TX","+TY","-TY","+TZ","-TZ" !ボタン
DIM BTN1$(6),BTN2$(6)
MAT READ BTN1$
MAT READ BTN2$

DO

   SET DRAW mode hidden !ちらつき防止(開始)
   CLEAR

   CALL button(-2.8,2.8, 0.6,0.3, 6, BTN1$,  S,S2) !回転メニュー
   SELECT CASE S
   CASE 1 !+x
      CALL D3ROTATE(RAD(5),AX(1,1),AX(1,2),AX(1,3), M) !5度ずつ
   CASE 2 !-x
      CALL D3ROTATE(RAD(-5),AX(1,1),AX(1,2),AX(1,3), M)
   CASE 3 !+y
      CALL D3ROTATE(RAD(5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 4 !-y
      CALL D3ROTATE(RAD(-5),AX(2,1),AX(2,2),AX(2,3), M)
   CASE 5 !+z
      CALL D3ROTATE(RAD(5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE 6 !-z
      CALL D3ROTATE(RAD(-5),AX(3,1),AX(3,2),AX(3,3), M)
   CASE ELSE
      MAT M=IDN
   END SELECT
   MAT T=BX*M !図形を回転させる
   MAT BX=T
   IF S2=2 THEN !左ボタン押下で軸も回転させる
      MAT T=AX*M
      MAT AX=T
   END IF


   CALL button(-2.0,0.0, 0.6,0.3, 6, BTN2$,  S,S2) !図形の平行移動メニュー
   SELECT CASE S
   CASE 1 !+x
      CALL VEC3NORMALIZE(AX(1,1),AX(1,2),AX(1,3), xx,yy,zz) !方向ベクトル
   CASE 2 !-x
      CALL VEC3NORMALIZE(-AX(1,1),-AX(1,2),-AX(1,3), xx,yy,zz)
   CASE 3 !+y
      CALL VEC3NORMALIZE(AX(2,1),AX(2,2),AX(2,3), xx,yy,zz)
   CASE 4 !-y
      CALL VEC3NORMALIZE(-AX(2,1),-AX(2,2),-AX(2,3), xx,yy,zz)
   CASE 5 !+z
      CALL VEC3NORMALIZE(AX(3,1),AX(3,2),AX(3,3), xx,yy,zz)
   CASE 6 !-z
      CALL VEC3NORMALIZE(-AX(3,1),-AX(3,2),-AX(3,3), xx,yy,zz)
   CASE ELSE
      LET xx=0
      LET yy=0
      LET zz=0
   END SELECT
   CALL D3SHIFT(xx*0.05,yy*0.05,zz*0.05, M) !0.05ずつ
   MAT T=BX*M
   MAT BX=T


   !XYZ軸を描く

   ! ワールド座標(x,y,z) → スクリーン座標(x,y)
   !   Y
   !   ↑
   !   Z→X
   !  のXY平面(スクリーン座標)へ投影する。

   SET LINE COLOR 4 !X軸
   PLOT LINES: 0,0; AX(1,1),AX(1,2)
   PLOT TEXT, AT AX(1,1),AX(1,2): "x"
   SET LINE COLOR 3 !Y軸
   PLOT LINES: 0,0; AX(2,1),AX(2,2)
   PLOT TEXT, AT AX(2,1),AX(2,2): "y"
   SET LINE COLOR 2 !Z軸
   PLOT LINES: 0,0; AX(3,1),AX(3,2)
   PLOT TEXT, AT AX(3,1),AX(3,2): "z"


   !立方体を描く
   SET LINE COLOR 1
   FOR i=1 TO 3 !上面
      PLOT LINES: BX(i,1),BX(i,2); BX(i+1,1),BX(i+1,2)
   NEXT i
   PLOT LINES: BX(4,1),BX(4,2); BX(1,1),BX(1,2)
   FOR i=1 TO 4 !側面の稜線
      PLOT LINES: BX(i,1),BX(i,2); BX(i+4,1),BX(i+4,2)
   NEXT i
   FOR i=5 TO 7 !下面
      PLOT LINES: BX(i,1),BX(i,2); BX(i+1,1),BX(i+1,2)
   NEXT i
   PLOT LINES: BX(8,1),BX(8,2); BX(5,1),BX(5,2)


   SET DRAW mode explicit !ちらつき防止(終了)

   WAIT DELAY 0.1

LOOP


  :(以下省略)
  :

 

3D回転処理に付いて

 投稿者:lark12_long  投稿日:2014年 5月26日(月)19時06分9秒
  山中和義様

早速プログラム提供頂き有難う御座いました

原始データを、弄ることなく表示のみが、
回転できる為、原始データの物理的関係は、
維持されるので、動作シミュレーションも
正しく実行できる様になりました

土星の膠着円盤もどきのシミュレーションを
行ってみました

lark12_long
 

半円の重心

 投稿者:永野護  投稿日:2014年 6月 4日(水)17時38分42秒
  円の重心は円の中心。それでは半円の重心はどこにあるのでしょうか。
考えてみたけれどわかりませんでした。
わかる方、ご教示ください。
よろしくお願いします。
 

半円の重心

 投稿者:永野護  投稿日:2014年 6月 5日(木)15時50分10秒
  答えをネットで見つけました。
質問を撤回します。
すみませんでした。
 

共通の整数解α,β,γをもつ3次方程式と4次方程式

 投稿者:山中和義  投稿日:2014年 6月12日(木)19時01分7秒
  問題
ある3つの整数解を持つ3次方程式を、x^3+5x^2+Ax+B=0 とする。
さらに、その解を全て含む4次方程式を、x^4+11x^3-4x^2+Cx+D=0 とする。
このとき、A,B,C,Dを求めよ。

答え
3次方程式の3つの整数解を、α,β,γとする。ここで、α≦β≦γとしてよい。
4次方程式の4つの整数解は、α,β,γ,δとおける。

解と係数の関係より、
α+β+γ=-5、α+β+γ+δ=-11
これより、δ=-6

αβ+αγ+αδ+βγ+βδ+γδ=-4 ∴αβ+βγ+γα+(α+β+γ)δ=-4
これより、αβ+βγ+γα=-4-(-5)*(-6)=-34

また、α^2+β^2+γ^2=(α+β+γ)^2-2(αβ+βγ+γα)より、
α^2+β^2+γ^2=(-5)^2-2*(-34)=93
93=2^2+5^2+8^2 なので、α+β+γ=-5に注意して、α=-8、β=-2、γ=5

したがって、3次方程式は(x+8)(x+2)(x-5)=0、4次方程式は(x+8)(x+6)(x+2)(x-5)=0 となる。
展開して、x^3+5x^2-34x-80=0、x^4+11x^3-4x^2-284x-480=0
(終り)


x^2+y^2+z^2=n に帰着させる。

x^2+y^2+z^2=93を満たす0≦x≦y≦zとする整数解
93=x^2+y^2+z^2≧3x^2 ∴6>x
93=x^2+y^2+z^2≧y^2+z^2≧2y^2 ∴7>y
93=x^2+y^2+z^2≧z^2 ∴10>z

!x^3+Ax^2+□x+□=0、x^4+Px^3+Qx^2+□x+□=0
LET A=5
LET P=11
LET Q=-4
LET N=(-A)^2-2*(Q-(-A)*(-P+A))
PRINT "N=";N
FOR x=0 TO SQR(N/3) !0≦x≦[√(n/3)]、x≦y≦[√(n/2)]
   FOR y=x TO SQR(N/2)
   !2次方程式Z^2+(x^2+y^2-n)=0を解の公式を使って解く
      LET D=0^2-4*1*(x^2+y^2-N) !判別式
      LET DD=SQR(D)
      IF DD=INT(DD) THEN !整数解
         LET Z=(-0+DD)/(2*1) !解の公式
         IF y<=Z THEN PRINT x;y;Z
      END IF
   NEXT y
NEXT x
END

 

Re: 共通の整数解α,β,γをもつ3次方程式と4次方程式

 投稿者:山中和義  投稿日:2014年 6月13日(金)14時15分6秒
  > No.3391[元記事へ]

> 問題
> ある3つの整数解を持つ3次方程式を、x^3+5x^2+Ax+B=0 とする。
> さらに、その解を全て含む4次方程式を、x^4+11x^3-4x^2+Cx+D=0 とする。
> このとき、A,B,C,Dを求めよ。

3次方程式の3つの整数解
→ 微分、解の公式と判別式、2次関数の最大値・最小値(平方完成)
に帰着させる。


(x^3+5x^2+Ax+B)(x-δ)=x^4+(5-δ)x^3+(A-5δ)x^2+(B-Aδ)x-Bδ と
x^4+11x^3-4x^2+Cx+D とで係数を比較すると、5-δ=11、A-5δ=-4 ∴δ=-6、A=-34

f(x)=x^3+5x^2-34x+B=0 とする。3つの整数解を、α,β,γとする。

f'(x)=3x^2+10x-34より、f'(x)=0の2解は、x=(-5±√127)/3 ※極大値・極小値を与えるxの値
よって、まん中の解は、-5≦β≦2
また、f(x)=(x-β){x^2+(β+5)x+(β^2+5β-34)} と因数分解される。

α,γについて、
x^2+(β+5)x+(β^2+5β-34)を解くと、x=(-(β+5)±√(-3β^2-10β+161))/2なので、
D=-3β^2-10β+161が平方数にならなければいけない。

D=-3(β+5/3)^2+169+1/3と変形して、
-5≦β≦2の範囲では、
 β=-5/3のとき、最大値169+1/3
 β=2のとき、最小値129
をとるので、
Dが平方数ならば、-3β^2-10β+161=144 または -3β^2-10β+161=169
前者の解はβ=(-5±√76)/3、後者の解はβ=-2,-4/3
これより、β=-2

f(β)=f(-2)=(-2)^3+5(-2)^2-34(-2)+B=0 より、B=-80


LET A=5 !x^3+Ax^2+□x+□=0、x^4+Px^3+Qx^2+□x+□=0
LET P=11
LET Q=-4

LET B=Q-(-A)*(-P+A) !f(x)=x^3+Ax^2+Bx+□
PRINT B

CALL Solve2EQU(3,2*A,B, x1,x2,K) !f'(x)
PRINT K; x1;x2 !debug
LET xx1=IP(x1) !βの範囲
LET xx2=IP(x2)
PRINT xx1;xx2

!f(x)=(x-β){x^2+(β+A)x+(β^2+Aβ+B)}と因数分解される。
!x^2+(β+A)x+(β^2+Aβ+B)=0の2つの解はα,γ
!判別式D=(β+A)^2-4(β^2+Aβ+B)=(-3)β^2+(-2A)β+(A^2-4B)=-3(β+A/3)^2+(A^2-4B)-A^2/3
DEF G(X)=(AA*X+BB)*X+CC !判別式Dは、上に凸
LET AA=-3
LET BB=-2*A
LET CC=A^2-4*B

LET x3=-A/3 !軸
PRINT x3 !debug
IF x3>=xx1 AND x3<=xx2 THEN LET MX=G(x3) ELSE LET MX=MAX(G(xx1),G(xx2)) !最大値
LET MN=MIN(G(xx1),G(xx2)) !最小値
PRINT MN;MX

DEF F(X)=((X+A)*X+B)*X
FOR T=CEIL(SQR(MN)) TO SQR(MX) !Dが平方数、すなわちD=t^2
   PRINT T
   CALL Solve2EQU(AA,BB,CC-T*T, x1,x2,K)
   PRINT K; x1;x2 !βの候補
   PRINT -F(x1); -F(x2) !C=-f(β)

   PRINT (-(x1+A)-T)/2; (-(x1+A)+T)/2 !α
   PRINT (-(x2+A)-T)/2; (-(x2+A)+T)/2 !γ
NEXT T

END


EXTERNAL SUB Solve2Equ(a,b,c, x1,x2,K) !2次方程式 Ax^2+Bx+Cx=0、A≠0 の解
IF a=0 THEN
   PRINT "2次の係数が0なので、2次方程式ではありません。"; a;b;c
   LET K=-1
ELSE
   LET D=b^2-4*a*c !判別式
   IF D>=0 THEN !実数解なら
      LET x1=(-b-SQR(D))/(2*a) !1つの解
      IF D=0 THEN !重解なら
      !!!!!!!!!!LET x2=x1
         LET K=1
      ELSE
         LET x2=(-b+SQR(D))/(2*a) !もう1つの解
         LET K=2
      END IF
   ELSE !虚数解なら
      LET x1=-b/(2*a) !実部
      LET x2=SQR(-D)/(2*a) !虚部
      LET K=0
   END IF
END IF
END SUB


実行結果

-34
2 -5.42314255652822  2.08980922319488
-5  2
-1.66666666666667
129  169.333333333333
12
2  1.23926596236045 -4.57259929569378
32.5529020577708 -164.404753909623
-9.11963298118023  2.88036701881978
-6.21370035215311  5.78629964784689
13
2 -1.33333333333333 -2
-51.8518518518517 -80
-8.33333333333334  4.66666666666667
-8  5



類題 一橋大学 2005年 前期
kは整数であり、3次方程式x^3-13x+k=0は3つの異なる整数解をもつ。kとこれらの整数解をすべて求めよ。
答え
k=-12のとき、3解は-3,-1,4
k=12のとき、3解は-4,1,3

 

Re: 共通の整数解α,β,γをもつ3次方程式と4次方程式

 投稿者:山中和義  投稿日:2014年 6月15日(日)21時08分11秒
  > No.3392[元記事へ]

『謎解きはディナーのあとで』より

あらすじ
ディナーのとき、麗子お嬢様は珈琲をこぼして答案が汚してしまった。
そこで、答案の復元を依頼した。


答案用紙 ※消し線部分が珈琲のしみで見えなくなっている。
 問題
 3つの整数 α,β,γ を解にもつ3次方程式がある。
 さらに、その解を全てもち、もう1つの解を d とする4次方程式がある。
 このとき、3次方程式と4次方程式を展開した形で求めよ。
 答え
 (x-α)(x-β)(x-γ)=0 を展開して、x^3+Ax^2 +Bx+C =0
 (x-α)(x-β)(x-γ)(x-d)=0 を展開して、x^4+Px^3+Qx^2 +Rx+S =0
(終り)


執事の景山「失礼ですがお嬢様。お嬢様の目は節穴でございますか?」 毒舌が爆発する!

x^3+Ax^2+▲x+△=0
x^4+Px^3+Qx^2+■x+□=0

組立除法
  1   P     Q          ■               □                  |  d
      d     d^2+Pd     d^3+Pd^2+Qd      d^3+Pd^2+Qd+■
------------------------------------------------------------------
  1   d+P   d^2+Pd+Q   d^3+Pd^2+Qd+■   d^4+Pd^3+Qd^2+■d+□ = 0

これより、4次方程式は、(x-d)(x^3+(d+P)x^2+(d^2+Pd+Q)x+(d^3+Pd^2+Qd+■))=0 と因数分解される。
3次方程式の部分は、x^3+Ax^2+▲x+△=0 なので、
係数を比較して、d+P=A、d^2+Pd+Q=▲ ∴d=A-P、▲=Ad+Q

したがって、x^3+Ax^2+(A(A-P)+Q)x+△=0


改めて、f(x)=x^3+Ax^2+Bx+△=0とおき、3つの整数解をα,β,γ(α≦β≦γ)とする。

組立除法
  1   A      B            △    |  α
      α     α^2+Aα
-------------------------------------
  1   α+A   α^2+Aα+B

これより、β,γは、x^2+(α+A)x+(α^2+Aα+B)=0の実数解である。
よって、判別式D=(α+A)^2-4(α^2+Aα+B)=-3α^2-2Aα+A^2-4B≧0
∴x1≦α≦x2
また、解と係数の関係から、3α≦α+β+γ=-Aより、α≦-A/3

α=x1のとき、
 x^2+(α+A)x+(α^2+Aα+B)=0を解く。整数解 かつ α≦β≦γ を満たすなら適している。
α=x1+1のとき、
 ・・・
α=x1+2のとき、
 ・・・

  :
  :



LET A=5 !x^3+Ax^2+□x+□=0、x^4+Px^3+Qx^2+□x+□=0
LET P=11
LET Q=-4

LET B=A*(A-P)+Q !f(x)=x^3+Ax^2+Bx+□
PRINT B

CALL Solve2EQU(-3,-2*A,A^2-4*B, x1,x2,K) !D=-3α^2-2Aα+A^2-4B=0
PRINT K; x1;x2 !debug
PRINT IP(x2);IP(x1) !αの範囲
PRINT -A/3

FOR AA=IP(x2) TO MIN(x1,-A/3) !αを固定する
   CALL Solve2EQU(1,AA+A,AA^2+A*AA+B, BB,CC,K) !β,γは、x^2+(α+A)x+(α^2+Aα+B)=0の解
   IF BB=INT(BB) AND CC=INT(CC) THEN !整数なら
      IF BB>=AA AND BB<=CC THEN !α≦β≦γなら
         PRINT AA;BB;CC
         PRINT -AA*BB*CC !□
      END IF
   END IF
NEXT AA

END


EXTERNAL SUB Solve2Equ(a,b,c, x1,x2,K) !2次方程式 Ax^2+Bx+Cx=0、A≠0 の解
IF a=0 THEN
   PRINT "2次の係数が0なので、2次方程式ではありません。"; a;b;c
   LET K=-1
ELSE
   LET D=b^2-4*a*c !判別式
   IF D>=0 THEN !実数解なら
      LET x1=(-b-SQR(D))/(2*a) !1つの解
      IF D=0 THEN !重解なら
      !!!!!!!!!!LET x2=x1
         LET K=1
      ELSE
         LET x2=(-b+SQR(D))/(2*a) !もう1つの解
         LET K=2
      END IF
   ELSE !虚数解なら
      LET x1=-b/(2*a) !実部
      LET x2=SQR(-D)/(2*a) !虚部
      LET K=0
   END IF
END IF
END SUB


実行結果

-34
2  5.84628511305643 -9.17961844638976
-9  5
-1.66666666666667
-8 -2  5
-80

 

三角形ABCの各辺の中点で内接する楕円

 投稿者:山中和義  投稿日:2014年 6月17日(火)10時36分1秒
  三角形ABCの各辺の中点で内接する楕円

三角形の3点を、複素平面上の複素数A,B,Cとする。
複素数係数の3次方程式 f(x)=(x-A)(x-B)(x-C)=0 を考える。
f'(x)=3x^2-2(A+B+C)x+(AB+BC+CA)=0 の2解は、楕円の焦点となる。
f''(x)=6x-2(A+B+C)=0 の1解は、楕円の中点で、三角形の重心となる。

例
A(5,3)、B(-7,1)、C(2,-4)のとき、
 f(x)=x^3-26x+(140-120i)=0なので、f'(x)=3x^2-26=0 ∴x=±(√78)/3
 焦点は、( ±(√78)/3, 0 )
A(5,1)、B(1,3)、C(-6,-4)のとき、
 f(x)=x^3-(18+32i)x+(-52+104i)=0なので、f'(x)=3x^2-(18+32i)=0
 ∴x=±√{54+96i)}/3 =±( √{3(√337)+27} + ( √{3(√337)-27} )i )/3
 焦点は、( ±√{3(√337)+27}/3 , ±( √{3(√337)-27}/3 )



OPTION ARITHMETIC COMPLEX !複素平面
LET i=COMPLEX(0,1) !虚数単位
SET WINDOW -8,8,-8,8 !表示領域
DRAW grid !座標を表示する

LET OA=COMPLEX(5,3) !点A(5,3)
LET OB=COMPLEX(-7,1) !点B(-7,1)
LET OC=COMPLEX(2,-4) !点C(2,-4)

!LET OA=COMPLEX(5,1) !点A(5,1)
!LET OB=COMPLEX(1,3) !点B(1,3)
!LET OC=COMPLEX(-6,-4) !点C(-6,-4)

!LET OA=6*EXP(0*i) !正三角形
!LET OB=6*EXP(2*PI/3*i)
!LET OC=6*EXP(4*PI/3*i)

DRAW disk WITH SCALE(0.1)*SHIFT(OA)
PLOT TEXT ,AT OA: "A"
DRAW disk WITH SCALE(0.1)*SHIFT(OB)
PLOT TEXT ,AT OB: "B"
DRAW disk WITH SCALE(0.1)*SHIFT(OC)
PLOT TEXT ,AT OC: "C"
PLOT LINES: OA; OB; OC; OA !三角形ABCを描く


LET OD=(OA+OB)/2 !辺ABの中点
LET OE=(OB+OC)/2 !辺BCの中点
LET OF=(OC+OA)/2 !辺CAの中点
DRAW disk WITH SCALE(0.1)*SHIFT(OD)
DRAW disk WITH SCALE(0.1)*SHIFT(OE)
DRAW disk WITH SCALE(0.1)*SHIFT(OF)


LET P=-(OA+OB+OC) !f(x)=x^3+Px^2+Qx+R
LET Q=OA*OB+OB*OC+OC*OA
PRINT P; Q; -OA*OB*OC
CALL Solve2EQU(3,2*P,Q, x1,x2) !f'(x)の解
PRINT x1; x2
DRAW disk WITH SCALE(0.1)*SHIFT(x1)
DRAW disk WITH SCALE(0.1)*SHIFT(x2)


IF x1-x2=0 THEN !円になる場合
   LET m=0
ELSE
   LET m=arg(x1-x2) !傾き(-π,π]
END IF
LET C=(x1+x2)/2 !中心 Re(x1)

LET F=ABS(x1-x2)/2 !焦点F(f,0)、F'(-f,0)とする
LET A=(ABS(x1-OD)+ABS(x2-OD))/2 !2焦点までの距離の和2aの楕円は
LET B=SQR(A^2-F^2) !標準形(x/a)^2+(y/b)^2=1である
DRAW Elipse(A,B) WITH ROTATE(m)*SHIFT(C) !それを中心Cでm傾ける
PRINT F; A;B

PRINT C; (OA+OB+OC)/3 !重心

END

EXTERNAL SUB Solve2EQU(A,B,C, x1,x2) !2次方程式Ax^2+Bx+C=0を解く
OPTION ARITHMETIC COMPLEX !複素平面
LET D=B^2-4*A*C
LET x1=(-B-SQR(D))/(2*A)
LET x2=(-B+SQR(D))/(2*A) !共役
END SUB

EXTERNAL PICTURE Elipse(A,B) !標準形楕円を描く x^2/a^2+y^2/b^2=1
OPTION ARITHMETIC COMPLEX !複素平面
FOR T=0 TO 360 !弧を描く
   LET X=A*COS(RAD(T))
   LET Y=B*SIN(RAD(T))
   PLOT LINES: X,Y;
NEXT T
PLOT LINES
DRAW disk WITH SCALE(0.1)*SHIFT(0,0) !中心を描く
IF A>=B THEN !焦点を描く
   LET C=SQR(A^2-B^2)
   DRAW disk WITH SCALE(0.1)*SHIFT( C,0)
   DRAW disk WITH SCALE(0.1)*SHIFT(-C,0)
ELSE
   LET C=SQR(B^2-A^2)
   DRAW disk WITH SCALE(0.1)*SHIFT(0, C)
   DRAW disk WITH SCALE(0.1)*SHIFT(0,-C)
END IF
END PICTURE


実行結果

0 -26 ( 140 -120)
-2.94392028877595  2.94392028877595
2.94392028877595  3.60555127546399  2.08166599946613
0  0


 

Re: 三角形ABCの各辺の中点で内接する楕円

 投稿者:GAI  投稿日:2014年 6月18日(水)06時54分9秒
  > No.3394[元記事へ]

山中和義さんへのお返事です。


>  f(x)=x^3-(18+32i)x+(-52+104i)=0なので、f'(x)=3x^2-(18+32i)=0
>  ∴x=±√{54+96i)}/3 =±( √{3(√337)+27} + ( √{3(√337)-27} )i )/3
               *この部分の計算の動かし方を教えて下さい。



 

Re: 三角形ABCの各辺の中点で内接する楕円

 投稿者:山中和義  投稿日:2014年 6月18日(水)12時27分16秒
  > No.3395[元記事へ]

GAIさんへのお返事です。

> ∴x=±√{54+96i)}/3 =±( √{3(√337)+27} + ( √{3(√337)-27} )i )/3

SQR(x+y*i)=SQR({SQR(x^2+y^2)+x}/2) + SGN(y)*SQR({SQR(x^2+y^2)-x}/2)*i
を使います。

x=54, y=96として、x^2+y^2=12132=36*337 ∴√(x^2+y^2)=(√12132)=6(√337)
これから、{√(x^2+y^2)±x}/2=(6(√337)±54)/2=3(√337)±27


http://homepage2.nifty.com/sintakenoko/Note/np211.pdf

 

立方体

 投稿者:永野護  投稿日:2014年 6月20日(金)17時20分43秒
  一辺が5cmの立方体があります。この立方体の中心Oからの距離をrとしたとき
rにおける密度がr^2+rであるとします。
この立方体の重量はいくらでしょうか。
この問題の解き方を教えていただけないでしょうか。
よろしくお願いします。
 

Re: 立方体

 投稿者:島村1243  投稿日:2014年 6月21日(土)06時40分33秒
  永野護さんへのお返事です。

> 一辺が5cmの立方体があります。この立方体の中心Oからの距離をrとしたとき
> rにおける密度がr^2+rであるとします。
> この立方体の重量はいくらでしょうか。

立方体の中心点oを、x,y,z直角座標の原点とし、立方体の1辺の長さを2aとする。
 r=sqr(x^2+y^2+z^2)
rの位置における微小体積を⊿vとすると
 ⊿v=⊿x*⊿y*⊿z
rの位置の密度が(r^2+r)だから、その微小体積の重量⊿wは
 ⊿w=(r^2+r)*⊿v
     =(x^2+y^2+z^2+sqr(x^2+y^2+z^2))*⊿x*⊿y*⊿z
上記の⊿wを
 x=-a~a
 y=-a~a
 z=-a~a
の範囲で3重積分すれば、立方体の全重量が出ると思います。
上記積分を解析的に得る方法、又は数値計算で得るプログラムは、他の方にお願いします。
 

立方体

 投稿者:永野護  投稿日:2014年 6月21日(土)14時54分59秒
  島村様、丁寧な回答ありがとうございました。
敬具
 

Re: 中学生プログラミングコンテスト

 投稿者:山中和義  投稿日:2014年 6月22日(日)16時05分36秒
  > No.3317[元記事へ]

>  福島工業高等専門学校 情報処理教育センター
>  http://www.fukushima-nct.ac.jp/information/htdocs/index.php?page_id=25
>
> 予想問題


問題
11からnまでの連続する奇数の和が416になったときのnの値を求めなさい。

答え
1=1=1^2
1+3=4=2^2
1+3+5=9=3^2
1+3+5+7=16=4^2
1+3+5+7+9=25=5^2
1+3+5+7+9+11=36=6^2
 :
より、1+3+5+7+9+11+ … +(2k-1)=k^2
k^2=(1+3+5+7+9)+(11+ … +(2k-1))=25+416=441なので、k=21
したがって、n=2k-1=2*21-1=41
(終り)


LET N=11
LET S=N !和
DO UNTIL S=416
   LET N=N+2 !連続する奇数
   LET S=S+N
LOOP
PRINT N
END


別解

LET S=0 !和
FOR N=11 TO 416 STEP 2 !連続する奇数 ※高々416
   LET S=S+N
   IF S=416 THEN EXIT FOR !条件を満たす
NEXT N
PRINT N
END



-------------------------------------------

問題 広島学院中学 2011年
88888888888888888888÷37を計算したときのあまりを求めよ。
※8が20個並ぶ
答え
   __024__
37 ) 888
    _0_
     88
    _74_
     148
    _148_
       0
より、
 888│888│888│888│888│888│88
と繰り返す。
よって、88÷37=2あまり14



!多桁整数÷整数
DATA 8,8,8,8,8, 8,8,8,8,8, 8,8,8,8,8, 8,8,8,8,8 !10進法表記 ※上の位から
LET R=0
FOR i=1 TO 20 !筆算
   READ A !各位の数字
   LET R=MOD(R*10+A,37)
NEXT i
PRINT R
END



-------------------------------------------

問題 逗子開成中学 2008年
1.11+2.22+3.33+4.44+5.55+6.66+7.77+8.88+9.99を計算しなさい。

答え

PRINT 1.11+2.22+3.33+4.44+5.55+6.66+7.77+8.88+9.99
END


PRINT 1.11*(1+2+3+4+5+6+7+8+9)
END


LET S=1+2+3+4+5+6+7+8+9 !一の位、小数点第1位、小数点第2位の数字の和
PRINT 1*S +0.1*S +0.01*S
END


!  1.11+2.22+3.33+4.44+5.55+6.66+7.77+8.88+9.99
!+ 9.99+8.88+7.77+6.66+5.55+4.44+3.33+2.22+1.11
!-----------------------------------------------
!  11.1+11.1+11.1+11.1+11.1+11.1+11.1+11.1+11.1
PRINT (1.11+9.99)*9/2
END


PRINT 5.55*9 !平均は5.55
END


LET S=0
FOR A=1.11 TO 9.99 STEP 1.11
   LET S=S+A
NEXT A
PRINT S
END


類題
0.001+0.002+0.003+0.004+0.005+0.006+0.007+0.008+0.009を計算しなさい。


2進モード(浮動小数点による数値計算)
  LET S=0
  FOR A=0.001 TO 0.009 STEP 0.001
     LET S=S+A
  NEXT A
  PRINT S
  END
や
  LET S=0
  LET A=0.001
  DO WHILE A<=0.009
     LET S=S+A
     LET A=A+0.001
  LOOP
  PRINT S
  END

は、最後の0.009が加味されないので、正しく計算できません。



-------------------------------------------

問題 鴎友学園女子中学 2008年
友子さんは算数のテストを5回受けました。得点はすべて整数でした。
このとき、次の問に答えなさい。
(1) 次の①~⑥のうち、5回の平均点として考えられないものをすべて答えなさい。
    また、その理由を簡単に説明しなさい。
    ① 66.4 ② 68.7 ③ 75.3 ④ 78.5 ⑤ 87.4 ⑥ 88.2
(2) 最高点が95点、最低点が60点だったとき、(1)で残ったもののうち、
    5回の平均点として考えられないものをすべて答えなさい。
    また、その理由を簡単に説明しなさい。

答え

!(1)
DATA 66.4, 68.7, 75.3, 78.5, 87.4, 88.2
FOR i=1 TO 6
   READ A
   LET T=A*5
   IF T<>INT(T) THEN PRINT i; A !合計点が整数にならないので
NEXT i
END


!(2)
DATA 66.4, 68.7, 75.3, 78.5, 87.4, 88.2
FOR i=1 TO 6
   READ A
   LET T=A*5
   IF T=INT(T) THEN !合計点が整数になる
      LET W=(T-(95+60))/3 !最高点の95点と最低点の60点を除いたときの平均点
      IF W<60 OR W>95 THEN PRINT i; A !最低点より小さい、最高点より大きい
   END IF
NEXT i
END



-------------------------------------------

問題
3つの数113,266,385を1以外の整数Aで割ると、いずれも余りは同じBとなります。AとBはいくつですか。

答え

FOR A=2 TO CEIL(385/2)
   LET B=MOD(113,A)
   IF MOD(266,A)=B THEN
      IF MOD(385,A)=B THEN
         PRINT A;B
      END IF
   END IF
NEXT A
END


別解

OPTION ARITHMETIC RATIONAL
LET X=113
LET Y=266
LET Z=385
LET A=GCD(Y-X,Z-Y) !266-113と385-266はAの倍数なので、公約数である
LET B=MOD(X,A)
PRINT A;B
END



-------------------------------------------

問題 ヨセフスの問題、継子立ての問題
トランプ13枚が裏返しに束ねられている。
1回目は、一番上のカードを最下段に移して、次をめくり、机に置く。
2回目は、一番上のカードを最下段に移して、次をめくり、先ほど置かれたカードの右横に置く。
このような操作を順次繰り返して、次々に机に並べていく。
このとき、並べられたカードが、左側から順番に、A,2,3,…,10,J,Q,Kとなるためには、
最初に束ねられていたカードは上からどういう順番に並んでいたのだろうか?

答え

LET N=13 !枚数
DIM A(N) !並び
MAT A=ZER
LET P=0 !位置
FOR K=1 TO N !番号
   LET i=0
   DO WHILE i<2 !p番目の位置から2番目の位置を求める
      LET P=P+1 !p=[1,N]
      IF P>N THEN LET P=1
      IF A(P)=0 THEN LET i=i+1 !埋まっている場合、スキップする
   LOOP
   LET A(P)=K
NEXT K
MAT PRINT A; !結果を表示する
END

実行結果
7  1  12  2  8  3  11  4  9  5  13  6  10



類題 ねずみ取りゲーム、The Mousetrap
トランプ13枚が裏返しに束ねられている。
1回目は、一番上のカードをめくり、机に置く。
2回目は、一番上のカードを最下段に移して、次をめくり(2枚目に相当)、先ほど置かれたカードの右横に置く。
3回目は、上にある2枚のカードを順に最下段に移して、次をめくり(3枚目に相当)、先ほど置かれたカードの右横に置く。
このような操作を順次繰り返して、次々に机に並べていく。
このとき、並べられたカードが、左側から順番に、A,2,3,…,10,J,Q,Kとなるためには、
最初に束ねられていたカードは上からどういう順番に並んでいたのだろうか?


LET N=13 !枚数
DIM A(N) !並び
MAT A=ZER
LET P=0 !位置
FOR K=1 TO N !番号
   LET i=0
   DO WHILE i<K !p番目の位置から2番目の位置を求める
      LET P=P+1 !p=[1,N]
      IF P>N THEN LET P=1
      IF A(P)=0 THEN LET i=i+1 !埋まっている場合、スキップする
   LOOP
   LET A(P)=K
NEXT K
MAT PRINT A; !結果を表示する
END

実行結果
1  8  2  5  10  3  12  11  9  4  7  6  13

 

ねずみ取りゲーム、The Mousetrap

 投稿者:山中和義  投稿日:2014年 6月23日(月)13時19分8秒
  問題
トランプのカード4枚で1つの束をつくる。それぞれに、1,2,3,4の数字が記入されている。
カードの並びは、4!=24通りである。
「1」,「2」,「3」,「4」と数えながら、束の一番上から順にカードを確認する。
このとき、
 数字が一致する場合
 ・そのカードをテーブルの上に置く。2枚目以降は右隣りに置く。
 ・次に数える「数」は、「1」から始める。
 そうでない場合
 ・そのカードを束の一番下に移動させる。

次の場合、作業は終了する。
 ・すべてのカードがテーブルに並ぶ
 または
 ・「4」と数えたとき、数字が一致していない

例 束の並びが上から1,2,4,3の場合
 「数」  束(左側が上とする)           テーブル
  1     ①  2  4  3                     1
  1         2  4  3
  2            4  3  2
  3              ③  2  4               1  3
  1                  2  4
  2                     4  2
  3                        2  4
  4                          ④  2      1  3  4
  1                              2
  2                             ②      1  3  4  2
 なので、すべてテーブルに並ぶ。

すべてのカードがテーブルに並ぶものを見つけよ。


考察
 作業
  以下に注意しながら、
   表
    1 2 4 3
   --------
   ①②③④
   ⑤⑥ …
    :
    :
  に、1から4までの数字を順に記入していく。

 (1) 数字が一致する場合
  ・次に記入する数字は、1から始める。
  ・その列には、次の行からは数字を記入しない。

 (2) 次の場合は、作業を終了する。
  ・すべての列で数字が一致したとき
  ・4を記入したとき、一致していないとき


  1 2 4 3
 --------
 ①12③
 -12-
 -3④-
 -1--
 -②--
なので、1,3,4,2の順にすべてテーブルに並ぶ。
(終り)

参考サイト http://oeis.org/A007709



PUBLIC NUMERIC C !場合の数
LET C=0
LET N=4 !枚数
DIM A(N) !並び n!通り
FOR i=1 TO N !最初の並び 1,2,3,…,n
   LET A(i)=i
NEXT i
CALL perm(A,1)
END

EXTERNAL SUB perm(a(),n) !1からnまでの順列を辞書式順序で生成する
LET m=UBOUND(a)
IF n=m THEN
!!!MAT PRINT a; !debug
   CALL stub(m,a)
ELSE
   FOR i=n TO m
      LET t=a(i)
      FOR j=i-1 TO n STEP -1
         LET a(j+1)=a(j)
      NEXT j
      LET a(n)=t
      CALL perm(a,n+1)
      LET t=a(n)
      FOR j=n TO i-1
         LET a(j)=a(j+1)
      NEXT j
      LET a(i)=t
   NEXT i
END IF
END SUB

EXTERNAL SUB stub(N,A()) !シミュレーション
DIM B(N),Q(N)
MAT B=A !copy it
LET M=N
LET P=0
LET K=0
DO WHILE K<N !1からnまで
   DO !束の一番上
      LET P=P+1 !p=[1,N]
      IF P>N THEN LET P=1
   LOOP UNTIL B(P)>0
   LET K=K+1
   IF B(P)=K THEN !一致するカード
      LET Q(N-M+1)=K !場の並び
      LET B(P)=-1 !取り除く
      LET M=M-1
      IF M=0 THEN !カードがすべてなくなったなら
         LET C=C+1
         PRINT "No.";C
         MAT PRINT A; !元の束(左側が上とする)
         MAT PRINT Q; !場の並び
         PRINT
         EXIT DO
      END IF
      LET K=0
   END IF
LOOP
END SUB


実行結果

No. 1
1  2  4  3

1  3  4  2


No. 2
1  4  2  3

1  2  3  4


No. 3
1  4  3  2

1  4  2  3


No. 4
2  1  3  4

3  2  1  4


No. 5
2  4  3  1

3  1  4  2


No. 6
4  2  1  3

2  1  3  4



●連続性
テーブルに並んだものを、
 1番目のカードは束の一番上、
 2番目のカードは束の上から2番目、
  :
 4番目のカードは束の一番下
となるように束にして、
同じ作業を続けると、再びすべてのカードがテーブルに並ぶ。
 束              テーブル
  1  4  3  2  →  1  4  2  3
  1  4  2  3  →  1  2  3  4
なので、
  1  4  3  2  →  1  4  2  3  →  1  2  3  4

その他に、
  4  2  1  3  →  2  1  3  4  →  3  2  1  4


●任意の並びを生成する
テーブルの並びを、1,3,4,2にする場合
 ①
 1,2,③
 1,2,3,④
 1,②
と数字を埋めていけばよい。
したがって、
 ①12③
 -12-
 -3④-
 -1--
 -②--
なので、束の並びは1,2,4,3とすればよい。

テーブルの並びを、1,3,2,4にする場合
 ①
 1,2,③
 1,②
 1,2,3,④
なので、
 ①12③
 -1②-
と埋めていくが、3番目の数は、③を埋めるときに2以外となる。
だが、②を埋めるとき、2になるので矛盾する。
よって、この並びは存在しない。
すなわち、同じ列で、埋める数字(丸数字)と同じ数字がないことに注意する。

 

Re: ねずみ取りゲーム、The Mousetrap

 投稿者:GAI  投稿日:2014年 6月24日(火)10時54分52秒
  山中和義さんへのお返事です。


実は私的数学塾で問うていた問題なんですが
<ケース4>(難問です)
1~13までの数字の場合、成功してテーブルに積んだカードで再びチャレンジすること4回(連続5回成功ということ。)すべて成功に繋がるという最初のシャッフル状態がただ一通り存在する。それはどんな配列なのか?

についてなんですが、サイトの関連する文献にて ”ほう!一個あるんだ。”
<参考>
http://oeis.org/search?q=A127966&language=japanese&go=%E6%A4%9C%E7%B4%A2
http://www.dmmm.uniroma1.it/~alberto.bersani/mousetrap.html
(Reformed permutations in Mousetrap and its generalizationsに詳しい。)
という感慨だけで具体的にどんな配列であればいいのかが情報がなく、しかし調査しようにもその方法も作れず、でも知りたくて仕様がありません。
どうかこの配列を探し出して下さい。
 

Re: ねずみ取りゲーム、The Mousetrap

 投稿者:山中和義  投稿日:2014年 6月25日(水)10時10分10秒
  > No.3403[元記事へ]

GAIさんへのお返事です。

> どうかこの配列を探し出して下さい。

紹介された
数列のサイト や 添付された文書
 http://www.dmmm.uniroma1.it/~alberto.bersani/tables.pdf
 7ページ 表6
より、計4回では!?


n=13は困難(n=12が4時間なので、3日程度が予想される)のため、
DATA文を切り替えて、計13回実行します。
分担すると負担が軽減されるので、1,2,3,…を確認してください。
5,6,7にはありません。私は、8,9,…と確認してみます。


LET t0=TIME
DATA 1,2,3,4,5,6,7,8,9,10,11,12,13
!!DATA 2,1,3,4,5,6,7,8,9,10,11,12,13
!!DATA 3,1,2,4,5,6,7,8,9,10,11,12,13
!!DATA 4,1,2,3,5,6,7,8,9,10,11,12,13
!!DATA 5,1,2,3,4,6,7,8,9,10,11,12,13 !済み
!!DATA 6,1,2,3,4,5,7,8,9,10,11,12,13 !済み
!!DATA 7,1,2,3,4,5,6,8,9,10,11,12,13 !済み
!!DATA 8,1,2,3,4,5,6,7,9,10,11,12,13
!!DATA 9,1,2,3,4,5,6,7,8,10,11,12,13
!!DATA 10,1,2,3,4,5,6,7,8,9,11,12,13
!!DATA 11,1,2,3,4,5,6,7,8,9,10,12,13
!!DATA 12,1,2,3,4,5,6,7,8,9,10,11,13
!!DATA 13,1,2,3,4,5,6,7,8,9,10,11,12
DIM A(13)
MAT READ A
PUBLIC NUMERIC C !場合の数
LET C=0
CALL perm(A,2) !※先頭を固定する
PRINT C; "通り"
PRINT TIME-t0
END

EXTERNAL SUB perm(a(),n) !1からnまでの順列を生成する(辞書式でない)
LET m=UBOUND(a)
IF n=m THEN !すべて並んだなら
!!!MAT PRINT a; !debug
   LET X=0
   CALL stub2(1,m,a, X)
   IF X-1=4 THEN !回数 ※ ←←←←←←←←←←
      LET C=C+1
      PRINT "No.";C
      MAT PRINT A; !束の並び(左側が上とする)
   END IF
ELSE
   FOR i=n TO m !箇所を設定する
      LET t=a(n) !a[n]とa[i]を入れ替える
      LET a(n)=a(i)
      LET a(i)=t
      CALL perm(a,n+1) !次へ
      LET t=a(n) !元に戻す
      LET a(n)=a(i)
      LET a(i)=t
   NEXT i
END IF
END SUB

EXTERNAL SUB stub2(L,N,A(), X) !シミュレーション
DIM B(N),Q(N)
MAT B=A !copy it
LET M=N
LET P=0
LET K=0
DO WHILE K<N !1からnまで数える
   DO !束の一番上
      LET P=P+1 !p=[1,N]
      IF P>N THEN LET P=1
   LOOP UNTIL B(P)>0
   LET K=K+1
   IF B(P)=K THEN !一致するカード
      LET Q(N-M+1)=K !場の並び
      LET B(P)=-1 !取り除く
      LET M=M-1
      IF M=0 THEN !カードがすべてなくなったなら
         CALL stub2(L+1,N,Q, X) !連続で可能かどうか
         EXIT SUB
      END IF
      LET K=0
   END IF
LOOP
LET X=L !L回目がNG
END SUB



n=11までなら、n!通りを直接処理しても現実的なので、次のようになります。


LET N=11 !枚数 ※ ←←←←←←←←←←
DIM A(N) !並び n!通り
FOR i=1 TO N !最初の並び 1,2,3,…,n
   LET A(i)=i
NEXT i
PUBLIC NUMERIC C !場合の数
LET C=0
CALL perm(A,1)
PRINT C; "通り"
END

 :以下、同じなので省略する


 

Re: ねずみ取りゲーム、The Mousetrap

 投稿者:山中和義  投稿日:2014年 6月25日(水)18時52分33秒
  > No.3404[元記事へ]

GAIさんへのお返事です。

> 分担すると負担が軽減されるので、1,2,3,…を確認してください。
> 5,6,7にはありません。私は、8,9,…と確認してみます。

5,6,7,8,9にはありません。

続けて、10,11,…と確認してみます。
 

Re: ねずみ取りゲーム、The Mousetrap

 投稿者:GAI  投稿日:2014年 6月25日(水)19時21分13秒
  > No.3405[元記事へ]

山中和義さんへのお返事です。


> 5,6,7,8,9にはありません。
>
> 続けて、10,11,…と確認してみます。
>

1を動かしていますが、なかなか終わりません。(3時間位)
一つ当たりどれ位の時間で終わるものですか?
 

何か出たぞ!

 投稿者:GAI  投稿日:2014年 6月26日(木)06時27分50秒
  夜中中走らせて、朝起きて見てみたら
次のものが残っていました。


No. 1
1  12  3  2  13  5  8  4  11  10  9  6  7

1 通り
-46362.54

これが、喉から手が出るほど見つけたかった配列なんでしょうか?
早速今から確認してみます。
 

これです。これです。

 投稿者:GAI  投稿日:2014年 6月26日(木)07時08分23秒
  1,12,3,2,13,5,8,4,11,10,9,6,7
-->
1,5,6,3,4,8,12,10,7,11,2,13,9
-->
1,3,9,7,2,4,8,5,6,10,12,11,13
-->
1,11,10,3,4,7,12,5,6,8,13,2,9
-->
1,3,9,8,2,10,13,5,6,7,11,12,4

とまさに続けて4回(リフォームが4回と勘違いしていました。)
1~13をただ1回呼称する内に(何回も繰り返していいのはModular Mousetrapで区別されている。)
手持ちのカードが全て掃けていくのは爽快です。
イヤーまさにこの配列は
13!=6227020800 (62兆を越える)
の砂粒中の奇跡の現象を起こしてくれるキラリと光っているダイアモンドの一粒に相当します。
ぜひこれをトランプでのマジックに応用できる手順に組み入れる作品を作ってみます。
今日は朝から気分がいいです。
もしかして、私に発見の喜びを与えてくれるために1からの検索を譲って頂いたのではないかと推測しております。
重ね重ね適切なプログラムの提供を頂いていること感謝申し上げます。

 

稀なリフォーム構成の配列

 投稿者:GAI  投稿日:2014年 6月26日(木)11時56分49秒
  作って頂いたプログラムを利用して、他の超レアな繰り返し構成可能な配列を探し出してみました。

n=5 :2-reformed(1パターン)
{2,5,1,4,3}-->
{4,2,3,5,1}-->
{2,4,5,1,3}


n=6 :3-reformed(1パターン)
{1,6,5,3,4,2}-->
{1,3,2,5,6,4}-->
{1,2,5,3,4,6}-->
{1,3,6,5,2,4}


n=8 :3-reformed(1パターン)
{5,2,1,7,3,8,4,6}-->
{2,1,4,6,3,5,7,8}-->
{7,2,1,3,5,6,4,8}-->
{2,1,4,3,5,8,6,7}


n=11 :4-reformed(2パターン)
{1,2,6,4,11,7,10,5,8,3,9}-->
{1,8,7,3,2,5,10,6,4,11,10}-->
{1,3,8,2,4,6,10,7,9,5,11}-->
{1,4,5,7,3,2,6,8,10,9,11}-->
{1,6,7,2,8,4,9,3,10,11,5}

{8,3,10,9,2,6,7,5,4,1,11}-->
{6,9,4,1,3,2,10,8,5,11,7}-->
{8,10,11,4,1,2,7,3,9,5,6}-->
{4,1,3,9,7,10,2,5,8,6,11}-->
{3,5,4,1,6,10,9,2,11,7,8}


n=12 :4-reformed(1パターン)
{1,12,11,5,3,10,7,6,8,4,2,9}-->
{1,8,2,7,12,3,11,4,9,6,5,10}-->
{1,2,3,5,12,7,9,6,4,8,10,11}-->
{1,10,2,6,5,4,3,7,9,11,8,12}-->
{1,2,8,7,9,5,6,10,11,3,4,12}


n=13 :4-reformed(1パターン)
{1,12,3,2,13,5,8,4,11,10,9,6,7}-->
{1,5,6,3,4,8,12,10,7,11,2,13,9}-->
{1,3,9,7,2,4,8,5,6,10,12,11,13}-->
{1,11,10,3,4,7,12,5,6,8,13,2,9}-->
{1,3,9,8,2,10,13,5,6,7,11,12,4}

n=12の場合も挑戦していたら、結構早い段階で見つけることができました。

報告まで
 

Re: これです。これです。

 投稿者:山中和義  投稿日:2014年 6月26日(木)21時19分0秒
  > No.3408[元記事へ]

GAIさんへのお返事です。

> 1,12,3,2,13,5,8,4,11,10,9,6,7

2,3,4,…,13にはないことを確認しました。



追伸

> No. 1
> 1  12  3  2  13  5  8  4  11  10  9  6  7
>
> 1 通り
> -46362.54

0時を跨いだ場合、負になりますので、-46362.54 + 24*60*60 = 40037.46 ≒ 11.12 時間

たぶん、10進モードで実行しているのではないでしょうか。
2進モードに切り替えれば、3倍速くなります。(4時間程度)

 

2つの放物線の最短距離

 投稿者:山中和義  投稿日:2014年 7月 7日(月)10時58分55秒
  問題
2つの放物線 y=x^2 と y=-(x+8)^2-1 の最短距離を求めよ。

参考サイト 

答え
ラグランジュの未定乗数法より、
F=x^2-y=0、G=-(X+8)^2-1-Y=0、D=(x-X)^2+(y-Y)^2 として、H=D+αF+βG
偏微分して、
 Hx=Dx+αFx=0 ∴2(x-X)+α(2x)=0 ∴(α+1)x-X=0 ←①
 Hy=Dy+αFy=0 ∴2(y-Y)+α(-1)=0 ∴y-Y=α/2 ←②
 HX=DX+βGX=0 ∴-2(x-X)+β(-2(X+8))=0 ∴x+(β-1)X=-8β ←③
 HY=DY+βGY=0 ∴-2(y-Y)+β(-1)=0 ∴y-Y=-β/2 ←④
 Hα=F=0 ←⑤
 Hβ=G=0 ←⑥
となる。
②と④より、β=-α
これを③に代入して、 x-(α+1)X=8α ←③'
①と③'を連立させて、(行列で表記して、逆行列から)
 ┌ α+1  -1      ┐┌ x ┐=┌  0  ┐
 └ 1     -(α+1) ┘└ X ┘ └ 8α ┘
 ┌ x ┐= 1/{-(α+1)^2+1)} ┌ -(α+1)  1    ┐┌  0  ┐
 └ X ┘                   └ -1       α+1 ┘└ 8α ┘
x=-8/(α+2)、X=-8(α+1)/(α+2)
⑥-⑤より、-(X+8)^2-1-x^2+(y-Y)=0
これにx,X,y-Yを代入して、αで表すと、
α^3+2α^2-4α-264=(α-6)(α^2+8α+44)=(α-6){(α+4)^2+28}=0
を得る。これを満たす実数解αは、α=6
これより、x=-1、X=-7 ∴y=x^2=1、Y=-(X+8)^2-1=-2
したがって、点(-1,1)、点(-7,-2)を結ぶ線分が最短となる。
最短距離は、√D = 3√5
(終り)


ところで、

問題
点(p,q) と放物線 y=Ax^2+Bx+C の最短距離を求めよ。

答え
ラグランジュの未定乗数法より、
F=(Ax^2+Bx+C)-y=0、D=(x-p)^2+(y-q)^2 として、H=D+λF
Hx=Dx+λFx=0 ∴(2x-2p)+λ(2Ax+B)=0 ∴x=(-Bλ+2p)/(2Aλ+2) ←①
Hy=Dy+λFy=0 ∴(2y-2q)+λ(-1)=0 ∴y=(λ+2q)/2 ←②
Hλ=F=0 ←③
①と②を③に代入して、
 ( A{(-Bλ+2p)/(2Aλ+2)}^2 +B{(-Bλ+2p)/(2Aλ+2)} +C ) -(λ+2q)/2 = 0
∴( A(-Bλ+2p)^2 +2B(Aλ+1)(-Bλ+2p) +4C(Aλ+1)^2 ) -2(λ+2q)(Aλ+1)^2 = 0
整理すると、
(2A^2) λ^3
+ A(4 +4Aq +B^2 -4AC) λ^2
+ 2(1 +4Aq +B^2 -4AC) λ
+ 4(q -Ap^2 -Bp -C)
= 0
実数解λを求めて、x,yを求める。
(終り)

と、同様な流れで求めることができる。


先の問題に戻って、この解法を利用する。
すなわち、点(p,q)を相似の中心点とする。
そして、放物線がy=Ax^2なら、計算がかなり容易になる。

答え
相似の中心は、頂点(-8,-1)と頂点(0,0)を結ぶ線分を1:1に内分する点だから、(-4.-1/2)
ラグランジュの未定乗数法より、F=x^2-y=0、D=(x+4)^2+(y+1/2)^2として、H=D+λF
Hx=2(x+4)+2xλ=0 ∴x=-4/(λ+1)
Hy=2(y+1/2)-λ=0 ∴y=(λ-1)/2
これをx^2-y=0に代入して、{-4/(λ+1)}^2-(λ-1)/2=0
∴λ^3+λ^2-λ-33=(λ-3)(λ^2+4λ+11)=(λ-3){(λ+2)^2+7}=0
これを満たす実数解λは、λ=3
これより、x=-1, y=1
よって、最短距離は、2√D = 2 √{ ((-1)+4)^2 + (1+1/2)^2 } = 3√5
また、放物線 y=-(x+8)^2-1 上の点は、
点(-1,1)と点(-4,-1/2)を結ぶ線分を2:(-1)に外分する点なので、(-7,-2)となる。
(終り)



!図形と方程式
OPTION ARITHMETIC COMPLEX !複素数平面

SET WINDOW -11,5,-8,8 !表示領域を設定する ※調整が必要である
DRAW grid !XY座標

!放物線y=Ax^2+Bx+C=A(x+B/(2A))^2-(B^2-4AC)/(4A)

LET A=1 !放物線 y=x^2
LET B=0
LET C=0
CALL gcDRAWFNC2(A,B,C,-11,5)

CALL gcFNC2POINT(A,B,C, X1,Y1) !点P1
SUB gcFNC2POINT(A,B,C, PX,PY) !放物線の頂点を得る
   LET PX=-B/(2*A)
   LET PY=-(B^2-4*A*C)/(4*A)
   DRAW disk WITH SCALE(0.1)*SHIFT(PX,PY)
   PRINT "頂点=";PX;PY
END SUB


LET P=-1 !放物線 y=-(x+8)^2-1
LET Q=-16
LET R=-65
CALL gcDRAWFNC2(P,Q,R,-11,5)

CALL gcFNC2POINT(P,Q,R, X2,Y2) !点P2


!●放物線の相似

CALL gcDIVIDE(X1,Y1,X2,Y2,P,-A, xx,yy) !外分する点
DRAW disk WITH SCALE(0.1)*SHIFT(xx,yy)
PRINT xx;yy


!●相似の中心点と放物線との距離を考える。

LET S=2*A^2 !λ^3の係数
LET T=A*(4 +4*A*yy +B^2 -4*A*C) !λ^2の係数
LET U=2*(1 +4*A*yy +B^2 -4*A*C) !λ^1の係数
LET V=4*(yy -A*xx^2 -B*xx -C) !λ^0の係数
PRINT S;T;U;V !debug

CALL Solve3Equ(T/S,U/S,V/S, L1,L2,L3) !実数解を得る
PRINT "λ="; L1 !debug

LET QX1=(-B*L1+2*xx)/(2+2*A*L1)
LET QY1=(L1+2*yy)/2
DRAW disk WITH SCALE(0.1)*SHIFT(QX1,QY1)


CALL gcDIVIDE(QX1,QY1,xx,yy,ABS(P)+ABS(A),-ABS(A), QX2,QY2) !放物線2は相似性から
DRAW disk WITH SCALE(0.1)*SHIFT(QX2,QY2)

PRINT QX1;QY1; QX2;QY2

PRINT SQR((QX1-QX2)^2+(QY1-QY2)^2); 3*SQR(5) !距離
PLOT LINES: QX1,QY1; QX2,QY2

END


!FV.LIB より抜粋

EXTERNAL SUB gcDRAWFNC2(A,B,C,d1,d2) !2次関数y=Ax^2+Bx+C、x=[d1,d2]を描く
OPTION ARITHMETIC COMPLEX !複素数平面
IF A=0 THEN
   PRINT "A=0なので、2次関数ではありません。"; A;B;C
ELSE
   ASK WINDOW x1,x2,y1,y2
   LET x1=MAX(x1,d1)
   LET x2=MIN(x2,d2)
   FOR x=x1 TO x2 STEP (x2-x1)/2^8 !※折れ線による
      PLOT LINES: x,(A*x+B)*x+C;
   NEXT x
   PLOT LINES
END IF
END SUB

!点A(x1,y1),B(x2,y2)を結ぶ線分ABをm:nに分ける点(内分・外分する点)
EXTERNAL SUB gcDIVIDE(x1,y1,x2,y2,m,n, xx,yy)
OPTION ARITHMETIC COMPLEX !複素数平面
LET xx=(n*x1+m*x2)/(m+n) !※外分m:nは、m:(-n)となる
LET yy=(n*y1+m*y2)/(m+n)
END SUB


!複素数版 EQU.LIB より抜粋

EXTERNAL SUB Solve3Equ(P,Q,R, x1,x2,x3)!代数方程式 x^3+Px^2+Qx+R=0 の解
OPTION ARITHMETIC COMPLEX !複素数を扱う
!カルダノ(Cardano)の方法より
LET a=-P^2/3+Q !x=y-P/3として、2次の項のない3次方程式y^3+a*y+b=0に変形する
LET b=2*P^3/27-P*Q/3+R

LET t=b^2/4+a^3/27 !(b/2)^2+(a/3)^3(判別式D=27*b^2+4*a^3と同値)
LET z1=-b/2+SQR(t) !3乗根を求める
LET z2=-b/2-SQR(t)
IF t>=0 THEN !1実根と2虚根
   LET u=SGN(z1)*ABS(z1)^(1/3) !実数の範囲
   LET v=SGN(z2)*ABS(z2)^(1/3)
ELSE !3実根(不還元の場合)
   LET u=EXP(LOG(z1)/3) !複素数の範囲
   LET v=EXP(LOG(z2)/3)
END IF
!!!PRINT u*v; -a/3 !debug

LET w=(-1+SQR(-3))/2 !ω=(-1+√(-3))/2は1の原始3乗根の1つ
LET y1=u+v !y^3+a*y+b=0の解
LET y2=w*u+w^2*v
LET y3=w^2*u+w*v

LET x1=y1-P/3 !x=y-P/3
LET x2=y2-P/3
LET x3=y3-P/3
END SUB


 

Re: 2つの放物線の最短距離

 投稿者:山中和義  投稿日:2014年 7月 8日(火)19時25分22秒
  > No.3412[元記事へ]

> 答え
> 相似の中心は、頂点(-8,-1)と頂点(0,0)を結ぶ線分を1:1に内分する点だから、(-4.-1/2)
> ラグランジュの未定乗数法より、F=x^2-y=0、D=(x+4)^2+(y+1/2)^2として、H=D+λF
> Hx=2(x+4)+2xλ=0 ∴x=-4/(λ+1)
> Hy=2(y+1/2)-λ=0 ∴y=(λ-1)/2
> これをx^2-y=0に代入して、{-4/(λ+1)}^2-(λ-1)/2=0
> ∴λ^3+λ^2-λ-33=(λ-3)(λ^2+4λ+11)=(λ-3){(λ+2)^2+7}=0
> これを満たす実数解λは、λ=3
> これより、x=-1, y=1


考察
Hx=Dx+λFx=0
Hy=Dy+λFy=0
より、λを消去すると、
λ=-Dx/Fx=-Dy/Fy ∴FxDy-FyDx=0

行列式で表現すると、
| Fx  Fy | = 0
| Dx  Dy |
(終り)


F=x^2-y=0、D=(x+4)^2+(y+1/2)^2 として、

| 2x      -1       | = 0
| 2(x+4)  2(y+1/2) |

∴x(2y+1)+(x+4)=0 ∴xy+x+2=0

y=x^2を代入して、x^3+x+2=(x+1)(x^2-x+2)=0
実数解xは、x=-1 ∴y=x^2=1



一般的に、

問題
点(p,q) と放物線 y=Ax^2+Bx+C の最短距離を求めよ。

答え
F=Ax^2+Bx+C-y=0、D=(x-p)^2+(y-q)^2 として、関数行列式(ヤコビアン)を考える。

| ∂F/∂x  ∂F/∂y | = 0
| ∂D/∂x  ∂D/∂y |

| 2Ax+B   -1     | = 0
| 2(x-p)  2(y-q) |

∴(2Ax+B){2(y-q)}-(-1){2(x-p)}=0 ∴(2Ax+B)y-2Aqx-Bq+x-p=0

これより、(2A^2)x^3 +(3AB)x^2 +(2AC+B^2-2Aq+1)x +(BC-Bq-p) = 0

これを満たす実数解xを求める。
(終り)


この3次方程式は、次のものと同じである。

高校生向き
参考サイト http://www005.upp.so-net.ne.jp/mi_kana/story/distanceofgraphs.pdf

●その1
点(p,q)と放物線上の点(x,y)=(x,Ax^2+Bx+C)の距離を考える。
D
=(x-p)^2+(y-q)^2
=x^2-2px+p^2 +y^2-2qy+q^2
=x^2-2px+p^2 +(Ax^2+Bx+C)^2-2q(Ax^2+Bx+C)+q^2
=(A^2)x^4 +(2AB)x^3 +(1+B^2+2CA-2qA)x^2 +2(-p+BC-qB)x +(p^2+C^2-2qC+q^2)

ここで、D'を考える。
(終り)


●その2
点(p,q)と放物線上の点(x,y)=(x,Ax^2+Bx+C)の距離を考える。
点(x,y)における接線の方程式は、Y-y=(2Ax+B)(X-x) なので、
法線の方程式は、Y-y={-1/(2Ax+B)}(X-x)
これが点(p,q)を通るから、q-y={-1/(2Ax+B)}(p-x)
整理すると、(2A^2)x^3 +(3AB)x^2 +(-2Aq+2AC+B^2+1)x +(-Bq+BC-p)=0

上記のD'と同じ3次方程式が現れる。

 

球の衝突運動について

 投稿者:lark12_long  投稿日:2014年 7月10日(木)17時38分23秒
  球の衝突をシミュレートしようと思い、プログラミングしたのですが、
壁との衝突反射については、正常に動く様ですが、
球と球の衝突動作が、奇妙な動きをして、どうにもギブアップ状態です

どなたか、模範プログラム提供願えればと思います

lark12_long

'
'    反射.bas
'
'     各球の質量は1、接触摩擦はなし
'
'     H26-07-10
'
'

width=1260
height=640
SET BITMAP SIZE width, height

reft=0
right=width
bottom=0
top=height

'左端,右端,下端,上端
  set window  left,right,bottom,top

'描画エリアの背景色着色範囲設定
set area color 1 !'黒
plot area : left,bottom;left,top;right,top;right,bottom
'--------------------------------------------------------------
xbase=100       '画面表示x起点
ybase=100       '画面表示y起点

randomize

n=8                   '球の数
dim x(n),y(n)         '球のx、y座標
dim vx(n),vy(n)       '球のx、y成分速度

wb=400                '枠の幅
hb=400                '枠の高さ

r=30                  '球の半径
dt=0.2                'サンプリングタイム

'初期位置設定
for i=0 to n-1
   xi=rnd*wb*10
   yi=rnd*hb*10
   if xi>0+r and xi<wb-r and yi>0+r and yi<hb-r then
     x(i)=xi
     y(i)=yi
   else
     i=i-1
   end if
next i

'初期速度設定
  for i=0 to n-1
    vx(i)=(rnd-0.5)*20*2
    vy(i)=(rnd-0.5)*20*2
  next i

do
    '位置の更新
    for i=0 to n-1
      x(i)=x(i)+vx(i)*dt
      y(i)=y(i)+vy(i)*dt

      '枠との衝突処理
      if x(i)<0+r then        '左の枠に衝突
        vx(i)=-vx(i)
        x(i)=r
      end if
      if x(i)>wb-r then
        vx(i)=-vx(i)           '右の枠に衝突
        x(i)=wb-r
      end if
      if y(i)<0+r then         '下の枠に衝突
        vy(i)=-vy(i)
        y(i)=r
      end if
      if y(i)>hb-r then         '上の枠に衝突
        vy(i)=-vy(i)
        y(i)=hb-r
      end if

      '球同士の衝突
       call cal1        'これが、上手くいきませんです
    next i

    '球の表示
    set draw mode hidden
    line(0,0)-(width,height),1,bf

    for i=0 to n-1
      col=mod(i,6)+2
      circle(xbase+x(i),ybase+y(i)),r,col,,,,f
    next i

   '枠の表示
   set line width 4
   line(xbase,ybase)-(xbase+wb,ybase+hb),6,b
   set draw mode explicit


loop
'-----------------------------------------------------
sub cal1
'球同士の衝突

  if n>=2 then
     for j=0 to n-1
       if i<>j then
          l=sqr( (x(i)-x(j))^2+(y(i)-y(j))^2 )  '球ij間距離
          v=sqr( vx(i)^2+vy(i)^2 )              '球iの衝突前の速度
          if l<=2*r and  v>0 and l>0 then       '衝突判定と、v=0、l=0の回避
            cosa=(x(i)-x(j))/l                  '球ij衝突時の球ijの中心線とx軸の成す角度aのcos値
            sina=(y(i)-y(j))/l                  '球ij衝突時の球ijの中心線とx軸の成す角度aのsin値
            cosc=vx(i)/v                        '球iの衝突時の球i速度ベクトルがx軸の成す角度cのcos値
            sinc=vy(i)/v                        '球iの衝突時の球i速度ベクトルがx軸の成す角度cのcos値
            cosd=cosa*sinc+cosc*sina            '衝突時の球ijの接触点法線と球iの速度ベクトルと成す角度dのcos値
            cosac=cosa*cosc-sina*sinc           '角度a+cのcos値
            cosdc=cosc*cosd-sinc*sind           '角度d+cのcos値
            sindc=cosc*sind+cosd*sinc           '角度d+cのsin値

            va=v*cosd                           '衝突後の球iの速度ベクトル
            vb=v*cosac                          '衝突後の球jの速度ベクトル

            vx(i)=va*cosdc                      '衝突後の球iのx成分速度
            vy(i)=va*sindc                      '衝突後の球iのy成分速度

            vx(j)=vb*cosa                       '衝突後の球jのx成分速度
            vy(j)=vb*sina                       '衝突後の球jのy成分速度

          end if
        end if
      next j
  end if
end sub
'-----------------------------------------------------


 

Re: 球の衝突運動について

 投稿者:SECOND  投稿日:2014年 7月11日(金)04時45分9秒
  lark12_longさんへのお返事です。

!動くように補修しただけで、ごめんください。

!十進BASICの書式になっています。
!--------------------------------------------------------------
!lark12_long
!
!    反射.bas
!
!     各球の質量は1、接触摩擦はなし
!
!     H26-07-10
!
!
LET width=641  !1260
LET HEIGHT=641 !640
SET BITMAP SIZE width, HEIGHT
!
LET left=0
LET right=width
LET bottom=0
LET top=HEIGHT
!
!左端,右端,下端,上端
SET WINDOW  left,right, bottom,top
!
!描画エリアの背景色着色範囲設定
SET AREA COLOR 1   !黒
PLOT AREA : left,bottom; left,top; right,top; right,bottom
!--------------------------------------------------------------
LET xbase=100      !画面表示x起点
LET ybase=100      !画面表示y起点
!
RANDOMIZE
!
LET n=8                   !球の数
OPTION BASE 0
DIM x(n),y(n), en(6,6),xb(n),yb(n)    !球のx、y座標
DIM vx(n),vy(n)           !球のx、y成分速度
!
LET wb=400                !枠の幅
LET hb=400                !枠の高さ
!
LET r=30                  !球の半径
LET dt=0.2                !サンプリングタイム
!
!初期位置設定
LET i=0
DO
   LET u=INT(6*RND)
   LET v=INT(6*RND)
   IF en(u,v)=0 THEN
      LET x(i)=r*(1.15+2.2*u)
      LET y(i)=r*(1.15+2.2*v)
      LET en(u,v)=1
      LET i=i+1
   END IF
LOOP UNTIL n<=i
!
!初期速度設定
FOR i=0 TO n-1
   LET vx(i)=(RND-0.5)*20*2
   LET vy(i)=(RND-0.5)*20*2
NEXT i
!
!位置の更新
DO
   FOR i=0 TO n-1
      LET xb(i)=x(i)
      LET yb(i)=y(i)
      LET x(i)=x(i)+vx(i)*dt
      LET y(i)=y(i)+vy(i)*dt
      !
      !枠との衝突処理
      IF x(i)< 0+r THEN         !左の枠に衝突
         LET vx(i)=-vx(i)
         LET x(i)=r
      END IF
      IF x(i)> wb-r THEN
         LET vx(i)=-vx(i)       !右の枠に衝突
         LET x(i)=wb-r
      END IF
      IF y(i)< 0+r THEN         !下の枠に衝突
         LET vy(i)=-vy(i)
         LET y(i)=r
      END IF
      IF y(i)> hb-r THEN        !上の枠に衝突
         LET vy(i)=-vy(i)
         LET y(i)=hb-r
      END IF
      !
      !球同士の衝突
      CALL cal1
   NEXT i
   SET DRAW mode hidden
   !
   !画面消去
   !line(0,0)-(width,height),1,bf
   SET AREA COLOR 1
   PLOT AREA :0,0; width,0; width,HEIGHT; 0,HEIGHT
   !
   !球の表示
   FOR i=0 TO n-1
   !col=mod(i,6)+2
   !circle(xbase+x(i),ybase+y(i)),r,col,,,,f
      SET AREA COLOR MOD(i,6)+2
      DRAW disk WITH SCALE(r)*SHIFT(xbase+x(i),ybase+y(i))
   NEXT i
   !
   !枠の表示
   SET LINE width 4
   !line(xbase,ybase)-(xbase+wb,ybase+hb),6,b
   SET LINE COLOR 6
   PLOT LINES: xbase,ybase; xbase+wb,ybase; xbase+wb,ybase+hb; xbase,ybase+hb; xbase,ybase
   !
   SET DRAW mode explicit
   WAIT DELAY .01
   mouse poll mox,moy,mlb,mrb
LOOP UNTIL 0< mrb

!----------------------------------
! 球同士の衝突( 球表面の摩擦係数0)
!----------------------------------
SUB cal1
   IF n>=2 THEN
      FOR j=0 TO n-1
         IF i<>j THEN
            LET lb=SQR( (xb(i)-xb(j))^2+(yb(i)-yb(j))^2)   !過去の球(i)(j)間距離
            LET  l=SQR( ( x(i) -x(j))^2+( y(i) -y(j))^2)   !現在の球(i)(j)間距離
            IF l<=2*r AND l< lb THEN                       !距離と、その増減で、衝突判定
               LET vi=SQR( vx(i)^2+vy(i)^2 )          !球(i)の速度の絶対値
               LET vj=SQR( vx(j)^2+vy(j)^2 )          !球(j)の速度の絶対値
               LET cosnx=(x(j)-x(i))/l                !球(i)中心を始点とする接触点法線ベクトルの角度 nx のcos 値
               LET sinnx=(y(j)-y(i))/l                !球(i)中心を始点とする接触点法線ベクトルの角度 nx のsin 値
               !--
               LET cosix=vx(i)/vi                     !球(i)速度ベクトルの角度 ix の cos 値
               LET sinix=vy(i)/vi                     !球(i)速度ベクトルの角度 ix の sin 値
               LET cosjx=vx(j)/vj                     !球(j)速度ベクトルの角度 jx の cos 値
               LET sinjx=vy(j)/vj                     !球(j)速度ベクトルの角度 jx の sin 値
               LET cos_in=cosix*cosnx+sinix*sinnx     !cos(ix-nx)
               LET sin_in=sinix*cosnx-cosix*sinnx     !sin(ix-nx)
               LET cos_jn=cosjx*cosnx+sinjx*sinnx     !cos(jx-nx)
               LET sin_jn=sinjx*cosnx-cosjx*sinnx     !sin(jx-nx)
               !--
               LET v_in=vi*cos_in                     !vi*cos(ix-nx) 接触点法線方向の、球(i)速度ベクトル
               LET v_jn=vj*cos_jn                     !vj*cos(jx-nx) 接触点法線方向の、球(j)速度ベクトル
               swap v_in, v_jn                        !接触点法線方向の、球(i)(j)速度ベクトル入替り
               LET v_it=vi*sin_in                     !vi*sin(ix-nx) 接触点接線方向の、球(i)速度ベクトル
               LET v_jt=vj*sin_jn                     !vj*sin(jx-nx) 接触点接線方向の、球(j)速度ベクトル
               !--
               LET vx(i)= v_in*cosnx -v_it*sinnx      !球(i)速度ベクトルの x 成分速度
               LET vy(i)= v_in*sinnx +v_it*cosnx      !球(i)速度ベクトルの y 成分速度
               LET vx(j)= v_jn*cosnx -v_jt*sinnx      !球(j)速度ベクトルの x 成分速度
               LET vy(j)= v_jn*sinnx +v_jt*cosnx      !球(j)速度ベクトルの y 成分速度
            END IF
         END IF
      NEXT j
   END IF
END SUB

END
 

Re: 球の衝突運動について

 投稿者:SECOND  投稿日:2014年 7月11日(金)13時20分46秒
  > No.3415[元記事へ]

以下のパーツが、少し楽になりました。もっと整理できるかもしれません。

!----------------------------------
! 球同士の衝突( 球表面の摩擦係数0)
!----------------------------------
SUB cal1
   IF n>=2 THEN
      FOR j=0 TO n-1
         IF i<>j THEN
            LET lb=SQR( (xb(i)-xb(j))^2+(yb(i)-yb(j))^2)   !過去の球(i)(j)間距離
            LET  l=SQR( ( x(i) -x(j))^2+( y(i) -y(j))^2)   !現在の球(i)(j)間距離
            IF l<=2*r AND l< lb THEN                       !距離と、その増減で、衝突判定
               LET nx=(x(j)-x(i))/l             !球(i)中心を始点とする接触点法線ベクトル x 成分
               LET ny=(y(j)-y(i))/l             !           〃  〃     y 成分
               !--
               LET v_in=nx*vx(i)+ny*vy(i)       !接触点法線方向の、球(i)速度ベクトル内積
               LET v_jn=nx*vx(j)+ny*vy(j)       !    〃    球(j)速度ベクトル内積
               swap v_in, v_jn                  !    〃    球(i)(j)速度ベクトル入替り
               LET v_it=-ny*vx(i)+nx*vy(i)      ! 〃 接線方向の、球(i)速度ベクトル内積
               LET v_jt=-ny*vx(j)+nx*vy(j)      !    〃    球(j)速度ベクトル内積
               !--
               LET vx(i)= nx*v_in -ny*v_it      !球(i)速度ベクトルの x 成分
               LET vy(i)= ny*v_in +nx*v_it      !     〃    y 成分
               LET vx(j)= nx*v_jn -ny*v_jt      !球(j)速度ベクトルの x 成分
               LET vy(j)= ny*v_jn +nx*v_jt      !     〃    y 成分
            END IF
         END IF
      NEXT j
   END IF
END SUB
 

球の衝突運動の件

 投稿者:lark12_long  投稿日:2014年 7月11日(金)15時04分16秒
  SECOND様
早速のプログラム提供有難うございます
補修の形で提供頂き、大変助かります
早速、図を書いて勉強いたします

lark12_long
 

Re: 球の衝突運動の件

 投稿者:SECOND  投稿日:2014年 7月11日(金)15時20分18秒
  > No.3417[元記事へ]

lark12_longさんへのお返事です。

!こちらが、見やすいです。

!---------------------------------------------------------------
! 球同士の衝突( 球表面の摩擦係数0、同質量)
!
! ※法線単位ベクトルの内外向き、
!   接線単位ベクトルの回転向きは、(i)(j)が共用 する限り何れも可。
!---------------------------------------------------------------
SUB cal1
   IF n>=2 THEN
      FOR j=0 TO n-1
         IF i<>j THEN
            LET lb=SQR( (xb(i)-xb(j))^2+(yb(i)-yb(j))^2)   !過去の球(i)(j)間距離
            LET  l=SQR( ( x(i) -x(j))^2+( y(i) -y(j))^2)   !現在の球(i)(j)間距離
            IF l<=2*r AND l< lb THEN                       !距離と、その増減で、衝突判定
               LET nx=(x(i)-x(j))/l             !接触点 法線単位ベクトル x 成分
               LET ny=(y(i)-y(j))/l             !    〃       y 成分
               LET tx=-ny                       !    接線単位ベクトル x 成分
               LET ty= nx                       !    〃       y 成分
               !--
               LET v_in=nx*vx(i)+ny*vy(i)       !接触点 法線方向の 球(i)速度ベクトル内積
               LET v_jn=nx*vx(j)+ny*vy(j)       !    〃    球(j)速度ベクトル内積
               swap v_in, v_jn                  !    〃    球(i)(j)速度 入替り
               LET v_it=tx*vx(i)+ty*vy(i)       !    接線方向の 球(i)速度ベクトル内積
               LET v_jt=tx*vx(j)+ty*vy(j)       !    〃    球(j)速度ベクトル内積
               !--
               LET vx(i)= nx*v_in +tx*v_it      !球(i)速度ベクトルの x 成分
               LET vy(i)= ny*v_in +ty*v_it      !     〃    y 成分
               LET vx(j)= nx*v_jn +tx*v_jt      !球(j)速度ベクトルの x 成分
               LET vy(j)= ny*v_jn +ty*v_jt      !     〃    y 成分
            END IF
         END IF
      NEXT j
   END IF
END SUB
 

非線形連立式の解き方

 投稿者:島村1243  投稿日:2014年 7月13日(日)06時37分24秒
  Amとφを入力値とし、
 Am=0.1~1.0 step 0.1
 φ=PI/18(パラメータで、後でいろいろと変える)
とした場合に、下記の連立方程式を満足する出力値Edとθを求めるプログラムをご教示ください。

入力φとAmの範囲条件
 0<φ<PI/2 [rad]
 0<Am<=1
出力Edとθの範囲条件
 Ed>0
  -PI/2<θ<PI/2 [rad]
定数(値は変更できるようにする)
 R=100
 Xs=PI
 Vs=100
連立方程式
 Vs*Is*cos(θ)=Ed^2/R
 Vs*sin(θ)=Am/sqr(2)*Ed*sin(θ+φ)-Xs*Is
ただし、
 Is=sqr((Am/sqr(2)*Ed*sin(φ))^2+(Vs-Am/sqr(2)*Ed*cos(φ))^2)/Xs
 

Re: 非線形連立式の解き方

 投稿者:山中和義  投稿日:2014年 7月13日(日)09時52分42秒
  > No.3419[元記事へ]

島村1243さんへのお返事です。

> Amとφを入力値とし、
>  Am=0.1~1.0 step 0.1
>  φ=PI/18(パラメータで、後でいろいろと変える)
> 下記の連立方程式を満足する出力値Edとθを求めるプログラムをご教示ください。

これで解を求められると思います。


!2元非線形連立方程式の解

!ニュートン・ラフソン(Newton-Raphson)法
!  1変数の場合、Xi+1=Xi-f(Xi)/f'(Xi)  変形して、Xi+1=Xi+(-f(Xi)/f'(Xi))
!  ここで、漸化式の増分部分⊿x=-f(Xi)/f'(Xi)は、f'(Xi)*⊿x=-f(Xi)となる。
!  行列表記で解釈すると、Jx=bとなる。
!
!これを多変数に拡張する。

FUNCTION f(Ed,θ)
   LET IS=SQR((Am/SQR(2)*Ed*SIN(φ))^2+(Vs-Am/SQR(2)*Ed*COS(φ))^2)/Xs
   LET f=Ed^2/R -Vs*IS*COS(θ)
END FUNCTION
FUNCTION g(Ed,θ)
   LET IS=SQR((Am/SQR(2)*Ed*SIN(φ))^2+(Vs-Am/SQR(2)*Ed*COS(φ))^2)/Xs
   LET g=(Am/SQR(2)*Ed*SIN(θ+φ)-Xs*IS) -Vs*SIN(θ)
END FUNCTION

LET Am=0.5 !0<Am≦1
LET φ=PI/18 !0<φ<π/2

LET R=100
LET Xs=PI
LET Vs=100


LET d=0.01 !∂

LET xi=0 !初期値
LET yi=0

FOR i=1 TO 50 !漸化式を収束させる

   DIM x(2) !⊿x、⊿y

   !連立1次方程式Jx=bを得る
   DIM J(2,2)
   LET fxy=f(xi,yi) !前進差分で近似して求める(平均変化率)
   LET J(1,1)=(f(xi+d,yi)-fxy)/d !J=(∂f/∂x  ∂f/∂y)  ヤコビ(Jacobi)行列
   LET J(1,2)=(f(xi,yi+d)-fxy)/d !  (∂g/∂x  ∂g/∂y)
   LET gxy=g(xi,yi)
   LET J(2,1)=(g(xi+d,yi)-gxy)/d
   LET J(2,2)=(g(xi,yi+d)-gxy)/d

   DIM b(2)
   LET b(1)=-fxy !b=(-f)
   LET b(2)=-gxy !  (-g)

   !----------  ※ガウスの消去法などで2元連立1次方程式を解く
   DIM Ji(2,2) !逆行列を求める  Full BASIC版
   MAT Ji=INV(J) !正則なら
   MAT x=Ji*b
   !----------

   LET xi=xi+x(1) !Xi+1=Xi+⊿x
   LET yi=yi+x(2) !Yi+1=Yi+⊿y

   PRINT xi,yi !確認  ∥Xi+1 - Xi∥≦ε(1+∥Xi+1∥)

NEXT i

PRINT f(xi,yi),g(xi,yi) !確認  ∥f(xi)∥<δ

END


 

Re: 非線形連立式の解き方

 投稿者:島村1243  投稿日:2014年 7月13日(日)13時52分21秒
  > No.3420[元記事へ]

山中和義 様

島村1243です、早速のご教示有難う御座いました。
これからコードを読ませて頂きます。
解けずに弱っていたので大変助かりました。
 

ニュートンのゆりかご(Newton's cradle)

 投稿者:山中和義  投稿日:2014年 7月13日(日)15時55分37秒
  おはじきのような球状の物体の運動と衝突を考えます。
シミュレーションには、ベクトル方程式を記述することにしました。
ベクトルの計算は、複素数平面すなわち複素数モードで計算ができますが、
数値がFPUによる浮動小数点のみになるので、このモードに限定しません。
十進モード、1000桁モード、2進モードに切替えて、実行してみます。

●その1 1次元(直線)の衝突
移動が、p=p+⊿pなので、誤差の累積が影響します。
十進モード、1000桁モードでは、うまく動作します。


!ニュートンのゆりかご(Newton's cradle) ○○○→ ●●の場合

DIM WU(2),WD(2),WL(2),WR(2) !壁の表面の向き(法線ベクトル)
DATA 0,-1, 0,1, 1,0, -1,0
MAT READ WU !上
MAT READ WD !下
MAT READ WL !左
MAT READ WR !右

LET UP=10 !壁の位置(原点からの符号つき距離) ※
LET DW=-10
LET LF=-6
LET RT=14

SET WINDOW LF,RT,DW,UP !表示領域

PUBLIC NUMERIC E !跳ね返り係数
LET E=1 !弾性衝突のとき

!---------------------------------------

LET N=5 !ボールの個数 ※
LET R=0.5 !ボールの半径 ※

DIM X(N),Y(N) !位置(x,y)
DATA -4,0, -3,0, -2,0, 3,0, 4,0 ! ※
FOR i=1 TO N
   READ X(i),Y(i)
NEXT i

DIM VX(N),VY(N) !移動速度vのX,Y成分
DATA 2,0, 2,0, 2,0, 0,0, 0,0 ! ※
FOR i=1 TO N
   READ VX(i),VY(i)
NEXT i

!---------------------------------------

LET dt=0.1 !⊿t
DO
   SET DRAW mode hidden !ちらつき防止の開始
   CLEAR
   DRAW grid !座標

   FOR i=1 TO N !ボールを描く
      DRAW disk WITH SCALE(R)*SHIFT(X(i),Y(i))
   NEXT i

   SET DRAW mode explicit !ちらつき防止の終了

   !ボールの移動
   DO
      LET HIT=0

      FOR i=1 TO N !ボールiとボールjとの衝突を確認する
         DIM OA(2),AV(2), OB(2),BV(2)
         LET OA(1)=X(i) !copy it
         LET OA(2)=Y(i)
         LET AV(1)=VX(i)
         LET AV(2)=VY(i)

         IF DISTL(OA,WU,UP)<=R AND DOT(AV,WU)<0 THEN !表面から上壁に衝突するとき
            CALL HIT_WALL(AV,WU)
            LET HIT=-1
         END IF
         IF DISTL(OA,WD,-DW)<=R AND DOT(AV,WD)<0 THEN !下壁
            CALL HIT_WALL(AV,WD)
            LET HIT=-1
         END IF
         IF DISTL(OA,WL,-LF)<=R AND DOT(AV,WL)<0 THEN !左壁
            CALL HIT_WALL(AV,WL)
            LET HIT=-1
         END IF
         IF DISTL(OA,WR,RT)<=R AND DOT(AV,WR)<0 THEN !右壁
            CALL HIT_WALL(AV,WR)
            LET HIT=-1
         END IF

         FOR J=i+1 TO N !組み合わせによる
            DIM AB(2),Vd(2)
            LET OB(1)=X(J) !copy it
            LET OB(2)=Y(J)
            MAT AB=OB-OA !相対位置
            IF DOT(AB,AB)<=(2*R)^2 THEN !衝突するとき
               LET BV(1)=VX(J)
               LET BV(2)=VY(J)

               MAT Vd=AV-BV !ボールjを停止させた相対速度
               IF DOT(AB,Vd)>0 THEN !近づくとき(離れていくときは除く)

                  CALL HIT_BALL(OA,AV, OB,BV, R)

                  LET VX(J)=BV(1) !衝突後
                  LET VY(J)=BV(2)

                  LET HIT=-2
               END IF
            END IF
         NEXT J

         LET VX(i)=AV(1) !衝突後
         LET VY(i)=AV(2)
      NEXT i

      !!!PRINT HIT !debug
   LOOP UNTIL HIT=0 !衝突がなくなるまで

   FOR i=1 TO N
      LET X(i)=X(i)+dt*VX(i) !移動させる
      LET Y(i)=Y(i)+dt*VY(i)
   NEXT i

   WAIT DELAY 0.05 !アニメーションの速度  ※調整の必要性あり
LOOP
END

EXTERNAL SUB HIT_WALL(AV(), NW()) !ボールと壁との非弾性衝突による結果
DIM dV(2)
LET w=(1+E)*DOT(AV,NW) !壁の法線単位ベクトルnw
MAT dV=(w)*NW
MAT AV=AV-dV
END SUB

EXTERNAL SUB HIT_BALL(OA(),AV(), OB(),BV(), R) !同じ質量の2つのボールの非弾性衝突による結果
DIM OP(2),OC(2),V(2),dV(2)
MAT OP=OB-OA !衝突箇所の位置 ↑c
MAT OC=(1/2)*OP
MAT V=BV-AV !相対速度 v2-v1
LET w=(1+E)*DOT(OC,V)/(2*R*R) !w=(1+E)(↑c・(↑v2-↑v1))/(2r^2)
MAT dV=(w)*OC !ボールAの速度変化量
MAT AV=AV+dV !速度を変化させる
MAT BV=BV-dV
END SUB

EXTERNAL SUB VecNormalize(V()) !正規化する(長さが1の単位ベクトル)
LET L=SQR(DOT(V,V))
IF L<>0 THEN  MAT V=(1/L)*V
END SUB

EXTERNAL FUNCTION DISTL(P(),N(),D) !点pと直線↑n・↑P+d=0との距離
LET DISTL=ABS(DOT(N,P)+D)/SQR(DOT(N,N))
END FUNCTION



●その2 2次元(平面)の衝突

1000桁モード、2進モードでは、うまく動作します。

変更箇所

!---------------------------------------

LET N=2 !ボールの個数 ※
LET R=1 !ボールの半径 ※

DIM X(N),Y(N) !位置(x,y)
LET X(1)=-4
LET Y(1)=0
LET X(2)=SQR(3)
LET Y(2)=-1

DIM VX(N),VY(N) !移動速度vのX,Y成分
DATA 2,0, 0,0 ! ※
FOR i=1 TO N
   READ VX(i),VY(i)
NEXT i

DEF F(X)=-1/SQR(3)*X !軌跡
DEF G(X)=SQR(3)*X

!---------------------------------------

LET dt=0.1 !⊿t
DO
   SET DRAW mode hidden !ちらつき防止の開始
   CLEAR
   DRAW grid !座標
   PLOT LINES: LF,F(LF); RT,F(RT)
   PLOT LINES: LF,G(LF); RT,G(RT)

   FOR i=1 TO N !ボールを描く
      DRAW disk WITH SCALE(R)*SHIFT(X(i),Y(i))
   NEXT i

   SET DRAW mode explicit !ちらつき防止の終了

   !ボールの移動

   以下省略

 

希望

 投稿者:SECOND  投稿日:2014年 7月14日(月)03時56分38秒
  複素数の 随伴行列 作成 が、2段のfor~next になって不便です、
MAT 文でも、CONJ() が使えるとか、いずれか出来ないでしょうか。

一連なデーターをバラけない様に、表現したい場合もあり、
以下の様な書き方を、許容できると、たすかりますが・・

LET x=1,y=2,z=3
 

Re: 球の衝突に関して

 投稿者:SECOND  投稿日:2014年 7月14日(月)13時04分11秒
  > No.3424[元記事へ]

lark12_longさんへのお返事です。

!これ、以上の御説明は、私には出来ませんが、もう1つ、
!複素平面へ移した場合を、お送りします、何かのご参考にして下さい。

!
!------------------------------------------------------
OPTION ARITHMETIC COMPLEX         !複素数モード
LET wb=400                        !枠の幅
LET hb=400                        !枠の高さ
SET bitmap SIZE wb+101, hb+101
SET WINDOW  -50,wb+50, -50,hb+50  !左端,右端, 下端,上端
!------------------------------------------------------
RANDOMIZE
!
LET n=8                   !球の数
OPTION BASE 0
DIM p(n), pb(n)           !球の座標の 現在と、1つ手前
DIM vp(n)                 !球の速度
DIM en(10,10)             !初期位置設定の重複検査
!
SET COLOR MIX(0) 0,0,0    !CLEAR 文で黒にする。
LET dt=0.2                !サンプリングタイム
LET r=30                  !球の半径
!
!-----
LET i=0
LET wb1=INT((wb-4)/(2*r+2))
LET hb1=INT((hb-4)/(2*r+2))
DO
   LET u=INT(wb1*RND)
   LET v=INT(hb1*RND)
   IF en(u,v)=0 THEN
      LET p(i)=COMPLEX(r+3+(2*r+2)*u, r+3+(2*r+2)*v)    !初期位置設定
      LET en(u,v)=1
      LET i=i+1
   END IF
LOOP UNTIL n<=i
!-----
FOR i=0 TO n-1
   LET vp(i)=COMPLEX((RND-0.5)*40, (RND-0.5)*40)        !初期速度設定
NEXT i
!-----
DO
   FOR i=0 TO n-1
      LET pb(i)=p(i)
      LET p(i)=p(i)+vp(i)*dt
      !---
      IF re(p(i))< r AND re(vp(i))< 0 THEN              !左の枠に衝突
         LET vp(i)= -conj(vp(i))
         LET p(i)= COMPLEX(r,im(p(i)))
      ELSEIF wb-r< re(p(i)) AND 0< re(vp(i)) THEN       !右の枠に衝突
         LET vp(i)= -conj(vp(i))
         LET p(i)= COMPLEX(wb-r,im(p(i)))
      ELSEIF im(p(i))< r AND im(vp(i))< 0 THEN          !下の枠に衝突
         LET vp(i)= conj(vp(i))
         LET p(i)= COMPLEX(re(p(i)),r)
      ELSEIF hb-r< im(p(i)) AND 0< im(vp(i)) THEN       !上の枠に衝突
         LET vp(i)= conj(vp(i))
         LET p(i)= COMPLEX(re(p(i)),hb-r)
      END IF
      !---
      CALL cal1                                         !球同士の衝突
   NEXT i
   !
   SET DRAW mode hidden                                 !表示画、更新の一時停止。
   CLEAR                                                !全画面、黒で、塗りつぶす
   FOR i=0 TO n-1
      SET AREA COLOR MOD(i,6)+2
      DRAW disk WITH SCALE(r)*SHIFT(p(i))               !球の表示
   NEXT i
   SET LINE width 4
   SET LINE COLOR 6
   PLOT LINES: 0; wb; COMPLEX(wb,hb); COMPLEX(0,hb); 0  !枠の表示
   SET DRAW mode explicit                               !表示画、常時更新の再開。
   !
   WAIT DELAY .01                                       !節電。削除 → かなり速くなる
   mouse poll mox,moy,mlb,mrb
LOOP UNTIL 0< mrb

!-----------------------------------------------------------
! 球同士の衝突( 球表面の摩擦係数0、同質量)
!
! ※法線単位ベクトルの内外向き、
!   接線単位ベクトルの回転向きは、(i)(j)が共用 する限り任意。
!-----------------------------------------------------------
SUB cal1
   IF 2<=n THEN
      FOR j=0 TO n-1
         IF i<>j THEN
            LET lb=ABS( pb(i)-pb(j))            !過去の球(i)(j)間距離
            LET  l=ABS( p(i) -p(j) )            !現在の球(i)(j)間距離
            IF l<=2*r AND l< lb THEN            !距離と、その増減で、衝突判定
               LET np=(p(j)-p(i))/l             !接触点 法線単位ベクトル
               LET tp=np*COMPLEX(0,1)           ! 〃  接線単位ベクトル
               !--
               LET v_in=re(conj(np)*vp(i))      !接触点 法線方向の 球(i)速さ(+-)
               LET v_jn=re(conj(np)*vp(j))      !    〃    球(j)速さ(+-)
               swap v_in, v_jn                  !    〃    球(i)(j)速さ 入替り
               LET v_it=re(conj(tp)*vp(i))      !    接線方向の 球(i)速さ(+-)
               LET v_jt=re(conj(tp)*vp(j))      !    〃    球(j)速さ(+-)
               !--
               LET vp(i)= v_in*np +v_it*tp      !球(i)速度ベクトル
               LET vp(j)= v_jn*np +v_jt*tp      !球(j)速度ベクトル
            END IF
         END IF
      NEXT j
   END IF
END SUB

END
 

Re: 球の衝突に関して

 投稿者:山中和義  投稿日:2014年 7月14日(月)15時25分25秒
  > No.3424[元記事へ]

lark12_longさんへのお返事です。

> ベクトル方程式を使うプログラムが示されました

コンピュータゲームの物理 山北篤著 新紀元社
http://w3.shinkigensha.co.jp/books/978-4-7753-0358-0.html

第4,5章を参照しました。
導出の式の説明、そのプログラム(C言語)が載っています。


メイン部分(衝突の計算)の実装は、かなり試行錯誤を繰り返しました。

 

Re: 球の衝突に関して

 投稿者:山中和義  投稿日:2014年 7月14日(月)20時28分57秒
  > No.3424[元記事へ]

lark12_longさんへのお返事です。

> 先日、second様より、提供して頂いたプログラム、図を書いて吟味してるのですが、
> まだ理解できてません、作図間違ってるかもしれません
>
> できれば、図にて、各所角度等の図示を、願えればかと、思っています

こちらの場合

!----------------------------------
! 球同士の衝突( 球表面の摩擦係数0)
!----------------------------------
SUB cal1
   IF n>=2 THEN
      FOR j=0 TO n-1
         IF i<>j THEN
            LET lb=SQR( (xb(i)-xb(j))^2+(yb(i)-yb(j))^2)   !過去の球(i)(j)間距離
            LET  l=SQR( ( x(i) -x(j))^2+( y(i) -y(j))^2)   !現在の球(i)(j)間距離
            IF l<=2*r AND l< lb THEN                       !距離と、その増減で、衝突判定
               LET vi=SQR( vx(i)^2+vy(i)^2 )          !球(i)の速度の絶対値
               LET vj=SQR( vx(j)^2+vy(j)^2 )          !球(j)の速度の絶対値
               LET cosnx=(x(j)-x(i))/l                !球(i)中心を始点とする接触点法線ベクトルの角度 nx のcos 値
               LET sinnx=(y(j)-y(i))/l                !球(i)中心を始点とする接触点法線ベクトルの角度 nx のsin 値
               !--
               LET cosix=vx(i)/vi                     !球(i)速度ベクトルの角度 ix の cos 値
               LET sinix=vy(i)/vi                     !球(i)速度ベクトルの角度 ix の sin 値
               LET cosjx=vx(j)/vj                     !球(j)速度ベクトルの角度 jx の cos 値
               LET sinjx=vy(j)/vj                     !球(j)速度ベクトルの角度 jx の sin 値
               LET cos_in=cosix*cosnx+sinix*sinnx     !cos(ix-nx)
               LET sin_in=sinix*cosnx-cosix*sinnx     !sin(ix-nx)
               LET cos_jn=cosjx*cosnx+sinjx*sinnx     !cos(jx-nx)
               LET sin_jn=sinjx*cosnx-cosjx*sinnx     !sin(jx-nx)
               !--
               LET v_in=vi*cos_in                     !vi*cos(ix-nx) 接触点法線方向の、球(i)速度ベクトル
               LET v_jn=vj*cos_jn                     !vj*cos(jx-nx) 接触点法線方向の、球(j)速度ベクトル
               swap v_in, v_jn                        !接触点法線方向の、球(i)(j)速度ベクトル入替り
               LET v_it=vi*sin_in                     !vi*sin(ix-nx) 接触点接線方向の、球(i)速度ベクトル
               LET v_jt=vj*sin_jn                     !vj*sin(jx-nx) 接触点接線方向の、球(j)速度ベクトル
               !--
               LET vx(i)= v_in*cosnx -v_it*sinnx      !球(i)速度ベクトルの x 成分速度
               LET vy(i)= v_in*sinnx +v_it*cosnx      !球(i)速度ベクトルの y 成分速度
               LET vx(j)= v_jn*cosnx -v_jt*sinnx      !球(j)速度ベクトルの x 成分速度
               LET vy(j)= v_jn*sinnx +v_jt*cosnx      !球(j)速度ベクトルの y 成分速度
            END IF
         END IF
      NEXT j
   END IF
END SUB


 

Re: 希望

 投稿者:白石 和夫  投稿日:2014年 7月15日(火)16時15分19秒
  > No.3423[元記事へ]

随伴行列の計算など配列関数の追加は,文法上,可能です。
Full BASICには,配列関数を利用者が定義する手段がなくて,
すべてサプライヤが用意しないといけないのは欠点だといえます。

LET x=1,y=2,z=3
のように書くことは,技術的には可能と思いますが,
Full BASIC規格との整合性に難があります。
(規格外のプログラムの流通を避けたい)


> 複素数の 随伴行列 作成 が、2段のfor~next になって不便です、
> MAT 文でも、CONJ() が使えるとか、いずれか出来ないでしょうか。
>
> 一連なデーターをバラけない様に、表現したい場合もあり、
> 以下の様な書き方を、許容できると、たすかりますが・・
>
> LET x=1,y=2,z=3
>
 

C++トランスレーター(試作・テスト版)

 投稿者:しばっち  投稿日:2014年 7月16日(水)20時46分47秒
  このプログラムは、BASICファイルをC++ファイルに変換(補助?)します。
但し、このプログラムは「未完成」であり、試作テスト版です。

サポートが少なく、このプログラムのバグ(変換エラー)や未完成なため対応していないなど、コンパイル通すにはまだまだ「手直し」が必要です。
予めご了承ください。(私自身の勘違いや思い込み、知識不足などもあります)
そのため、テキストウィンドゥに書き出しています。(あ~ぁテストする度にエラー(変換ミス)が出てくる!!)

まだアクセレーション目的に使用できる段階ではありません。その際はBASIC Accを使用してください。

変数、関数等は基本的にdouble型に変換しています。
内部関数、内部サブルーチンには対応していません。外部関数、外部サブルーチンに定義しなおしてください。
グラフィック関係は全て未対応です。
行番号付きリストには対応しておりません。(GOTO,GOSUB-RETURN文にも対応していません)
書式設定、READ-DATA文、例外処理、Microsoft Basic互換モードや十進BASIC独自のもの等は未対応です。
(SUB COMMAND_???と記述されているコマンドのみです)

また、言語仕様の違いによるものなども対応していません。(●その他)

このプログラムでは構文解析などは行っておりません。
単純な置換処理を行っているだけです。

FOR I=1 TO 10   →   for (i=1;i<=10;i+=1)

このプログラムはC++変換のみです。コンパイル、実行(EXEファイル)は手動です。
全て自己責任でお願いします。(無限ループ等にご注意ください)

標準入出力を使用しています。表示数が多い時はリダイレクト「>」をしてください。
但し、入力メッセージも標準出力しています。

INPUT PROMPT "A,B=":A,B   →  cout << "A,B="; 標準出力
                              cin >> a >> b;  標準入力(スペースで区切る)
検証(●その他)、テスト(C++変換,コンパイル、EXE実行)がまだまだ不十分です。(ゴメンナサイ!! 検証とC++変換までで精一杯です)

● C/C++コンパイラー
フリーで使用できるC/C++コンパイラー(登録不要)に、GCC(「g++ --version」で4.8.1)を使用しました。
その他のC/C++コンパイラー(VC++等)でも使用できると思いますが、他のコンパイラーについては全く
検証・テストしておりませんので、ご了承ください。

○ MinGW(Minimalist GNU for Windows) GNUコンパイラコレクション
http://www.mingw.org/
http://sourceforge.jp/projects/mingw/

○ MinGw インストール
http://symfoware.blog68.fc2.com/blog-entry-797.html
http://rei-farms.jp/blog/webmaking/2565/

http://www.geocities.jp/penguinitis2002/computer/programming/MinGW-w64.html  (64bit)

○ コンパイル方法(sample.cppの場合)
「g++.exe」コマンドを使用します。

g++ -O2 sample.cpp -o sample.exe
「-O2」は最適化オプション 「-o」は出力ファイル名。(「g++ --help」「g++ --target-help」でヘルプ。「gcc --help」でも同じ)

又は
gcc -O2 sample.cpp -o sample.exe -l stdc++

○ gccオプション
http://www.asahi-net.or.jp/~wg5k-ickw/html/online/gcc-2.95.2/gcc_2.html
http://www.ysr.net.it-chiba.ac.jp/data/cc.html

● Boostライブラリー
1000桁モード、有理数モードはBoostライブラリーを使用します。
下記よりダウンロードして解凍するだけです。(ビルドは必要ありません)

http://www.boost.org/

○ 1000桁モードを浮動小数1000桁型で定義しています。(14368桁まで?)
https://sites.google.com/site/boostjp/tips/multiprec-float

○ 有理数モードを任意精度有理数型で定義しています。
http://www.boost.org/doc/libs/1_55_0/libs/multiprecision/doc/html/boost_multiprecision/tut/rational/cpp_rational.html

   任意精度整数型
https://sites.google.com/site/boostjp/tips/multiprec-int

   有理数型(多倍長ではない)
http://www.kmonos.net/alang/boost/classes/rational.html

(他にもgmp,mpfr,mpirライブラリーなどがあるのだが...浮動小数100000000桁!!!!)
https://gmplib.org/
http://www.mpfr.org/
http://www.mpir.org/

○ コンパイル方法
boost.png
index.html
LICENSE_1_0.txt
bootstrap.bat
boostフォルダ
docフォルダ
などが入っているフォルダを「-I」オプションで指定します。

g++ -I I:\MinGW\boost_1_55_0\boost_1_55_0 sample.cpp -o sample.exe

● その他(備考)
○long double型での計算がおかしい。原因不明。

#include <iostream>
using namespace std;
#include <cmath>
int main() {
long double x;
double y;
x=2.0;
y=2.0;
cout << sizeof(long double) << endl;
cout << sizeof(double) << endl;
cout << sqrt(x) << endl;
cout << sqrt(y) << endl;
}
実行結果
12
8
-2.7341e-053
1.41421

○ 想定外の書き方をしたプログラムは誤変換(誤動作)します。
DIM SQR(10)
PRINT """A"""
など
スペース「" "」1個の違いで誤変換したりします。

○ 変数宣言ルーチンで探索対象としているのは、LET文の左辺、FOR文の制御変数、DIM文、INPUT文で使用している変数、
CALL文での受け渡し、及びPUBLIC文でのグローバル変数宣言だけです。
それら以外で現れる変数は探索対象になっていません。

○ 配列の添字に使用する変数がint型とするため、このプログラムでは
for文で使用する変数をint型としていましたが、添え字へのアクセスを
強制的にint型へキャストさせることでdouble型で宣言することにしました。(仕様変更)

a[5]        → a[static_cast<int>(5)]                       定数をキャストしてもコンパイルエラーにならない。
a[sqrt(n)]  → a[static_cast<int>(sqrt(n))]                 関数でもキャストすればエラーにならない。
a[a[n]]     → a[static_cast<int>(a[static_cast<int>(n)])]  キャストしないとエラーになる。
a[z]        → a[static_cast<int>(abs(z))]                  変数zが複素数型の場合。(zがdouble型でも問題ない)

○ 配列の宣言においてC/C++では静的配列と動的配列は区別され、
C++では動的配列にnew演算子を使用して

double *b;
b = new double[n];

として確保し、delete[] 演算子で(確保時に失敗したときのエラー処理も必要です)

delete[] b;
として適切に開放する必要があります。これにはメモリーリークという問題と関連します。

このプログラムではそれらを区別していません。

DIM A(10),B(N)  →  double a[10+1]={},b[n+1];  (C99規格 可変長配列)

添字の下限指定は、定数かつ負数でない場合です。
DIM A(-10 TO 10)  未対応
DIM A(N TO M)     未対応
DIM A(5 TO 20) → DIM A(20)として変換処理する

なお、可変長配列の初期化はfor文によるループで行っています。

○ 割り算においてint型同士の場合、計算結果もint型になる
int型/int型        → int型        8  / 5  → 1
double型/int型     → double型    8.0 / 5  → 1.6
   int型/double型  → double型
このため、どちらも定数の場合、型変換(キャスト)しています。 8 / 5 →  8 /(double)5

○ SUB文では呼び出しが参照渡しで、実引数を書き換えることができる。
このため、仮引数に「&」をつけて参照渡しにしています。

SUB SAMPLE(A,B) → void sample(double &a,double &b)

ところが、実引数に定数や計算式を使って呼び出すようにしていると、
引数が戻り値を受け取ることができないため、コンパイルエラーになります。
このため、ダミー変数を用意した。
CALL SAMPLE(A+B,C) → double dummy1=a+b;
                       sample(dummy1,c);
○ SUBやFUNCTIONで配列引数に多次元配列での受け渡しができません。

  SUB A(N,M,ARRAY(,))
で2次元配列の受け渡しができますが、これを

void a(double &n,double &m,double array[][])
と変換できません。

○ 配列の値渡しができません。関数定義(FUNCTION 文)内で配列要素を書き換えても
実引数は影響を受けませんが、C/C++では配列引数は参照渡しになるため、
書き換えを行っていると実引数は影響を受けます。
(構造体にして渡す方法があるようだが...)

○ SUBやFUNCTION名、変数名がC/C++の予約語と重なっていた場合、"_"アンダーバーを付加しています。
http://www.wdic.org/w/TECH/予約語%20(C%2B%2B)

CALL TRY(A)  → _try(a);
LET SWITCH=1 → _switch=1;

○ 複素数モードでは変数を複素数型で宣言していますが、

IF A<B THEN
これを

if (a<b) {
のようにしても大小比較ができません。
これは

if (real(a)<real(b)) {

のように修正する必要があります。

但し、変数a,bが複素数型ではない時(double型の時)は、real関数は
使用できません。
○ ファイル入出力モード(ACCESS OUTIN,又は省略)

OPEN #1:NAME FILENAME$
PRINT #1:A
CLOSE #1
これを

fstream fs1(filename,ios::in | ios::out);
fs1 << a << endl;
fs1.close();
としてもファイルが生成されず

fstream fs1(filename,ios::out);
fs1 << a << endl;
fs1.close();
としないとファイルが生成されないようだ。

○「LET A=1,B=2,B=3」の書き方に対応しました。(仕様追加)

なお、これらの詳細については、ネット上で検索してください。
(大量書き込みにつきましては、ご容赦ください)
 

Re: C++トランスレーター(試作・テスト版)

 投稿者:しばっち  投稿日:2014年 7月16日(水)20時49分32秒
  > No.3430[元記事へ]

OPTION ARITHMETIC NATIVE
LET MAXLINE=1000
LET MAXSIZE=100
DIM VARIABLE_STRING$(MAXSIZE),VARIABLE_PUBLIC$(MAXSIZE)
DIM C$(MAXSIZE),C2$(4),A$(MAXLINE),VARIABLE_ARGUMENT$(MAXSIZE),VARIABLE_ARRAY$(MAXSIZE)
DIM EXPRESSION$(MAXSIZE,3),VA_DIM(MAXSIZE),VA_INIT$(MAXSIZE),VARIABLE_DIM$(MAXSIZE)
DIM VARIABLE_FOR$(MAXSIZE)
PUBLIC STRING FUNCNAME$(100),FUNCNAMENOARG$(100),VARIABLE$(100),TYPE$
PUBLIC NUMERIC FC,VA_COUNT
FILE GETOPENNAME F$,"BASファイル|*.BAS"
IF F$="" THEN STOP
OPEN #1:NAME F$
CALL CPRINT("// Converted file  "&F$)
CALL CPRINT("")
CALL CPRINT("#include <iostream>")
CALL CPRINT("using namespace std;")
LET SETPREC$=" setprecision(15) << "                                            !'マニピュレータ 15桁表示
LET TYPE$="double "                                                             !'10進、2進モード(double型)
FOR I=1 TO MAXLINE                                                              !'インクルードファイル設定
   LINE INPUT #1, IF MISSING THEN EXIT FOR:A$(I)
   CALL SETUP(A$(I))                                                            !'コマンド等を大文字化
   IF A$(I)(1:1)="&" THEN                                                       !'行継続
      LET A$(I)(1:1)=""
      FOR J=LEN(A$(I-1)) TO 1 STEP -1
         IF A$(I-1)(J:J)="&" THEN
            LET A$(I-1)(J:J)=TRIM$(A$(I))
            LET A$(I)=""
            EXIT FOR
         END IF
      NEXT J
   END IF
   IF POS(A$(I),"OPTION ARITHMETIC COMPLEX")>0 AND OPT=0 THEN
      CALL CPRINT("#include <complex>")
      LET TYPE$="complex <double> "                                             !'複素数型
      LET OPT=1
   END IF
   IF POS(A$(I),"OPTION ARITHMETIC DECIMAL_HIGH")>0 AND OPT=0 THEN
      CALL CPRINT("#include <boost/multiprecision/cpp_dec_float.hpp>")
      !'CALL CPRINT("#include <boost/math/constants/constants.hpp>")            !'PI値
      CALL CPRINT("using namespace boost::multiprecision;")
      CALL CPRINT("typedef number<cpp_dec_float<1000> > big_float;")            !'浮動小数1000桁型
      LET SETPREC$=" setprecision(1001) << "                                    !'マニピュレータ 1001桁表示
      LET TYPE$="big_float "
      LET OPT=1
   END IF
   IF POS(A$(I),"OPTION ARITHMETIC RATIONAL")>0 AND OPT=0 THEN
      CALL CPRINT("#include <boost/multiprecision/cpp_int.hpp>")
      CALL CPRINT("using namespace boost::multiprecision;")
      !'LET TYPE$="cpp_int "                                                    !'任意精度整数型
      LET TYPE$="cpp_rational "                                                 !'任意精度有理数型
      !' CALL CPRINT("#include <boost/rational.hpp>")
      !' LET TYPE$="rational <int> "                                            !'有理数型
      LET OPT=1
   END IF
   IF POS(A$(I),"OPEN")>0 AND LITERAL(A$(I),"OPEN")=0 AND INCLUDEOPEN=0 THEN
      LET INCLUDEOPEN=1
      CALL CPRINT("#include <fstream>")
   END IF
   RESTORE
   DO
      READ IF MISSING THEN EXIT DO:X$
      LET S$=X$(1:LEN(X$)-1)&" ("
      IF (POS(A$(I),X$)>0 AND LITERAL(A$(I),X$)=0 OR POS(A$(I),S$)>0 AND LITERAL(A$(I),S$)=0) AND INCLUDEMATH=0 THEN
         LET INCLUDEMATH=1
         CALL CPRINT("#include <cmath>")
         EXIT DO
      END IF
   LOOP
   DATA "ABS(","ACOS(","ASIN(","ATN(","ANGLE(","CSC(","COS(","COSH(","COT(","CEIL(","EXP(","FP(","IP(","INT("
   DATA "LOG(","LOG2(","LOG10(","MOD(","REMAINDER(","SIN(","SINH(","SEC(","SQR("
   DATA "TAN(","TANH(","TRUNCATE(","^"
   DATA "ACSC(","ASEC(","ACOT(","ATANH(","ASINH(","ACOSH(","ASECH(","ACSCH(","ACOTH(","CSCH(","COTH(","CBRT(","ERF(","ERFC("
   DATA "LGAMMA(","GAMMA(","HYPOT(","J0(","J1(","JN(","SECH(","Y0(","Y1(","YN("
   IF POS(A$(I),"$")>0 AND INCLUDESTR=0 THEN
      LET INCLUDESTR=1
      CALL CPRINT("#include <string>")
      CALL CPRINT("#include <sstream>")
      IF INCLUDERND=0 THEN CALL CPRINT("#include <cstdlib>")
   END IF
   IF ((POS(A$(I),"RANDOMIZE")>0 AND LITERAL(A$(I),"RANDOMIZE")=0) OR (POS(A$(I),"TIME$")=0 AND POS(A$(I),"TIME")>0 AND LITERAL(A$(I),"TIME")=0)) AND INCLUDERND=0 THEN
      LET INCLUDERND=1
      IF INCLUDESTR=0 THEN CALL CPRINT("#include <cstdlib>")
      CALL CPRINT("#include <ctime>")
   END IF
NEXT I
LET MAXLINE=I
CLOSE #1
IF TYPE$="double " OR TYPE$="complex <double> " THEN CALL CPRINT("#include <iomanip>")
IF OPT=1 OR INCLUDEOPEN=1 OR INCLUDEMATH=1 OR INCLUDESTR=1 OR INCLUDERND=1 THEN CALL CPRINT("")
LET PROTOTYPE=1
FOR I=1 TO MAXLINE                                                              !'プロトタイプ宣言
   LET X$=A$(I)
   IF POS(X$,"DECLARE")=0 AND POS(X$,"END")=0 AND POS(X$,"EXIT")=0 AND POS(X$,"(,)")=0 AND POS(X$,"(,,)")=0 AND POS(X$,"EXTERNAL")=1 THEN
      IF POS(X$,"FUNCTION ")>0 AND LITERAL(X$,"FUNCTION ")=0 THEN
         CALL COMMAND_FUNCTION(X$)
         LET FL=1
      END IF
      IF POS(X$,"SUB ")>0 AND LITERAL(X$,"SUB ")=0 THEN
         CALL COMMAND_SUB(X$)
         LET FL=1
      END IF
   END IF
NEXT I
IF FL=1 THEN CALL CPRINT("")
LET PROTOTYPE=0
FOR I=1 TO MAXLINE                                                              !'以下、関数定義(インライン関数)
   IF POS(A$(I),"ROUND(")>0 AND FL_ROUND=0 THEN
      CALL CPRINT("inline double round(double x,double n) {")                   !'関数オーバーロード
      CALL CPRINT("return floor(x*pow(10,n)+.5)/pow(10,n);")
      CALL CPRINT("}")
      CALL CPRINT("inline double round(double x) {")                            !'関数オーバーロード
      CALL CPRINT("return floor(x+.5);")
      CALL CPRINT("}")
      LET FL_ROUND=1
   END IF
   IF (POS(A$(I),"SGN(")>0 OR POS(A$(I),"IP(")>0 OR POS(A$(I),"FP(")>0 OR POS(A$(I),"TRUNCATE(")>0) AND FL_SGN=0 THEN
      CALL CPRINT("inline double sgn(double x) {")
      CALL CPRINT("if (x>0) return 1.0;")
      CALL CPRINT("if (x<0) return -1.0;")
      CALL CPRINT("return 0;")
      CALL CPRINT("}")
      CALL CPRINT("inline double ip(double x) {")
      CALL CPRINT("return sgn(x)*floor(abs(x));")
      CALL CPRINT("}")
      CALL CPRINT("inline double fp(double x) {")
      CALL CPRINT("return x-ip(x);")
      CALL CPRINT("}")
      CALL CPRINT("inline double truncate(double x,double n) {")
      CALL CPRINT("return ip(x*pow(10.0,(int)n))/pow(10.0,(int)n);")
      CALL CPRINT("}")
      !'CALL CPRINT("inline double remainder(double x,double y) {")
      !'CALL CPRINT("return x-y*ip(x/y);")
      !'CALL CPRINT("}")
      LET FL_SGN=1
   END IF
   IF POS(A$(I),"ANGLE(")>0 AND FL_ANGLE=0 THEN
      CALL CPRINT("inline double angle(double x,double y) {")
      CALL CPRINT("return atan2(y,x);")
      CALL CPRINT("}")
      LET FL_ANGLE=1
   END IF
   IF POS(A$(I),"ASECH(")>0 AND FL_ASECH=0 THEN
      CALL CPRINT("inline double asech(double x) {")
      CALL CPRINT("return log((sqrt(1.0-x*x)+1.0)/x);")
      CALL CPRINT("}")
      LET FL_ASECH=1
   END IF
   IF POS(A$(I),"ACSCH(")>0 AND FL_ACSCH=0 THEN
      CALL CPRINT("inline double acsch(double x) {")
      CALL CPRINT("return log((sgn(x)*sqrt(x*x+1.0)+1.0)/x);")
      CALL CPRINT("}")
      LET FL_ACSCH=1
   END IF
   IF POS(A$(I),"ACOTH(")>0 AND FL_ACOTH=0 THEN
      CALL CPRINT("inline double acoth(double x) {")
      CALL CPRINT("return log((x+1.0)/(x-1.0))/2.0;")
      CALL CPRINT("}")
      LET FL_ACOTH=1
   END IF
   IF POS(A$(I),"FACT(")>0 AND FL_FACT=0 THEN
      CALL CPRINT("inline double fact(double x) {")
      CALL CPRINT("if (x<=1.0) return 1.0;")
      CALL CPRINT("return fact(x-1)*x;")
      CALL CPRINT("}")
      LET FL_FACT=1
   END IF
   IF POS(A$(I),"PERM(")>0 AND FL_PERM=0 THEN
      CALL CPRINT("inline double perm(double n,double r) {")
      !'CALL CPRINT("return fact(n)/fact(n-r);")
      CALL CPRINT("double p=1.0;")
      CALL CPRINT("for (int i=1;i<=r;i++)")
      CALL CPRINT("p*=n-i+1.0;")
      CALL CPRINT("return p;")
      CALL CPRINT("}")
      LET FL_PERM=1
   END IF
   IF POS(A$(I),"COMB(")>0 AND FL_COMB=0 THEN
      CALL CPRINT("inline double comb(double n,double r) {")
      !' CALL CPRINT("return perm(n,r)/fact(r);")
      CALL CPRINT("double p=1.0;")
      CALL CPRINT("for(int i=1;i<=r;i++)")
      CALL CPRINT("p*=(n-i+1.0)/(double)i;")
      CALL CPRINT("return p;")
      CALL CPRINT("}")
      LET FL_COMB=1
   END IF
   IF (POS(A$(I),"GCD(")>0 OR POS(A$(I),"LCM(")>0) AND FL_GCD=0 THEN
      CALL CPRINT("inline double gcd(double m,double n) {")
      CALL CPRINT("if (n==0) return m;")
      CALL CPRINT("return gcd(n,fmod(m,n));")
      CALL CPRINT("}")
      CALL CPRINT("inline double lcm(double m,double n) {")
      CALL CPRINT("return m*n/gcd(m,n);")
      CALL CPRINT("}")
      LET FL_GCD=1
   END IF
   !'IF POS(A$(I),"MAX(")>0 AND FL_MAX=0 THEN
   !'   CALL CPRINT("template <typename T>")
   !'   CALL CPRINT("inline T tmax(T x , T y) {")
   !'   CALL CPRINT("if(x>y) return x;")
   !'   CALL CPRINT("return y;")
   !'   CALL CPRINT("}")
   !'   LET FL_MAX=1
   !'END IF
   !'IF POS(A$(I),"MIN(")>0 AND FL_MIN=0 THEN
   !'   CALL CPRINT("template <typename T>")
   !'   CALL CPRINT("inline T tmin(T x , T y) {")
   !'   CALL CPRINT("if(x<y) return x;")
   !'   CALL CPRINT("return y;")
   !'   CALL CPRINT("}")
   !'   LET FL_MIN=1
   !'END IF
   IF POS(A$(I),"BITOR(")>0 AND FL_BITOR=0 THEN
      CALL CPRINT("inline int bit_or(double x,double y) {")
      CALL CPRINT("return (int)x|(int)y;")
      CALL CPRINT("}")
      LET FL_BITOR=1
   END IF
   IF POS(A$(I),"BITAND(")>0 AND FL_BITAND=0 THEN
      CALL CPRINT("inline int bit_and(double x,double y) {")
      CALL CPRINT("return (int)x&(int)y;")
      CALL CPRINT("}")
      LET FL_BITAND=1
   END IF
   IF POS(A$(I),"BITXOR(")>0 AND FL_BITXOR=0 THEN
      CALL CPRINT("inline int bit_xor(double x,double y) {")
      CALL CPRINT("return (int)x^(int)y;")
      CALL CPRINT("}")
      LET FL_BITXOR=1
   END IF
   IF POS(A$(I),"BITNOT(")>0 AND FL_BITNOT=0 THEN
      CALL CPRINT("inline int bit_not(double x) {")
      CALL CPRINT("return ~(int)x;")
      CALL CPRINT("}")
      LET FL_BITNOT=1
   END IF
   IF POS(A$(I),"BITIMP(")>0 AND FL_BITIMP=0 THEN
      CALL CPRINT("inline int bit_imp(double x,double y) {")
      CALL CPRINT("return ~(int)x|(int)y;")
      CALL CPRINT("}")
      LET FL_BITIMP=1
   END IF
   IF POS(A$(I),"BVAL(")>0 AND FL_BVAL=0 THEN
   !'  CALL CPRINT("inline int bval(string x,int n) {")
   !'  CALL CPRINT("if (n==16) x="&CHR$(34)&"0x"&CHR$(34)&"+x;")
   !'  CALL CPRINT("if (n==8) x="&CHR$(34)&"0"&CHR$(34)&"+x;")
   !'  CALL CPRINT("return atoi(x.c_str());")
   !'  CALL CPRINT("}")
      CALL CPRINT("inline int bval(string x,int n) {")
      CALL CPRINT("int y=0,a;")
      CALL CPRINT("string s="&CHR$(34)&"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"&CHR$(34)&";")
      CALL CPRINT("for (int i=0;i<x.size();i++) {")
      CALL CPRINT("x[i]=toupper(x[i]);")
      CALL CPRINT("a=s.find(x[i],0);")
      CALL CPRINT("y=y*n+a;")
      CALL CPRINT("}")
      CALL CPRINT("return y;")
      CALL CPRINT("}")
      LET FL_BVAL=1
   END IF
   IF POS(A$(I),"VAL(")>0 AND POS(A$(I),"BVAL(")=0 AND FL_VAL=0 THEN
      CALL CPRINT("inline double val(string x) {")
      CALL CPRINT("return atof(x.c_str());")
      CALL CPRINT("}")
      LET FL_VAL=1
   END IF
   IF POS(A$(I),"UBOUND(")>0 AND FL_UBOUND=0 THEN
      CALL CPRINT("template <typename TYPE, size_t N>")
      CALL CPRINT("inline size_t ubound(const TYPE (&)[N]) {")
      CALL CPRINT("return N;")
      CALL CPRINT("}")
      LET FL_UBOUND=1
   END IF
   IF POS(A$(I),"SUBSTR$(")>0 AND FL_SUBSTR=0 THEN
      CALL CPRINT("inline string substr(string x,double m,double n) {")
      CALL CPRINT("return x.substr((int)m-1,(int)n);")
      CALL CPRINT("}")
      LET FL_SUBSTR=1
   END IF
   IF POS(A$(I),"BSTR$(")>0 AND POS(A$(I),"SUBSTR$(")=0 AND FL_BSTR=0 THEN
   !'  CALL CPRINT("inline string bstr(double x,int n) {")
   !'  CALL CPRINT("ostringstream stream;")
   !'  CALL CPRINT("if (n==16) stream << hex << (int)x;")
   !'  CALL CPRINT("else if (n==8) stream << oct << (int)x;")
   !'  CALL CPRINT("else  stream << dec << (int)x;")
   !'  CALL CPRINT("cout << dec;")                                              !'マニピュレータ設定を10進法に戻す
   !'  CALL CPRINT("return stream.str();")
   !'  CALL CPRINT("}")
      CALL CPRINT("inline string bstr(double x,int n) {")
      CALL CPRINT("string a="&CHR$(34)&"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"&CHR$(34)&",b;")
      CALL CPRINT("int i;")
      CALL CPRINT("while (x!=0) {")
      CALL CPRINT("i=fmod((int)x,n);")
      CALL CPRINT("b=a[i]+b;")
      CALL CPRINT("x=floor(x/n);")
      CALL CPRINT("}")
      CALL CPRINT("return b;")
      CALL CPRINT("}")
      LET FL_BSTR=1
   END IF
   IF POS(A$(I),"STR$(")>0 AND POS(A$(I),"SUBSTR$(")=0 AND POS(A$(I),"BSTR$(")=0 AND FL_STR=0 THEN
      CALL CPRINT("inline string str(double x) {")
      CALL CPRINT("ostringstream stream;")
      CALL CPRINT("stream << x;")
      CALL CPRINT("return stream.str();")
      CALL CPRINT("}")
      LET FL_STR=1
   END IF
   IF POS(A$(I),"POS(")>0 AND FL_POS=0 THEN
      CALL CPRINT("inline int pos(string x,string y) {")                        !'関数オーバーロード
      CALL CPRINT("return x.find(y,0)+1;")
      CALL CPRINT("}")
      CALL CPRINT("inline int pos(string x,string y,double n) {")               !'関数オーバーロード
      CALL CPRINT("return x.find(y,(int)n)+1;")
      CALL CPRINT("}")
      LET FL_POS=1
   END IF
   IF POS(A$(I),"REPEAT$(")>0 AND FL_REPEAT=0 THEN
      CALL CPRINT("inline string repeat(string a,double n) {")
      CALL CPRINT("string x;")
      CALL CPRINT("for(int i=0;i<n;i++)")
      CALL CPRINT("x+=a;")
      CALL CPRINT("return x;")
      CALL CPRINT("}")
      LET FL_REPEAT=1
   END IF
   IF POS(A$(I),"SPC(")>0 AND FL_SPC=0 THEN
      CALL CPRINT("inline string spc(int n) {")
      CALL CPRINT("string x;")
      CALL CPRINT("for (int i=0;i<n;i++)")
      CALL CPRINT("x+="&CHR$(34)&" "&CHR$(34)&";")
      CALL CPRINT("return x;")
      CALL CPRINT("}")
      LET FL_SPC=1
   END IF
   !'IF POS(A$(I),"TAB(")>0 AND FL_TAB=0 THEN
   !'   CALL CPRINT("inline string tab(int n) {")
   !'   CALL CPRINT("string x;")
   !'   CALL CPRINT("for (int i=0;i<n;i++)")
   !'   CALL CPRINT("x+="&CHR$(34)&" "&CHR$(34)&";")
   !'   CALL CPRINT("return x;")
   !'   CALL CPRINT("}")
   !'   LET FL_TAB=1
   !'END IF
   IF POS(A$(I),"LTRIM$(")>0 AND FL_LTRIM=0 THEN
      CALL CPRINT("inline string ltrim(string x) {")
      CALL CPRINT("int i;")
      CALL CPRINT("for (i=0;i<x.size();i++)")
      CALL CPRINT("if(x.substr(i,1)!="&CHR$(34)&" "&CHR$(34)&") break;")
      CALL CPRINT("return x.substr(i);")
      CALL CPRINT("}")
      LET FL_LTRIM=1
   END IF
   IF POS(A$(I),"RTRIM$(")>0 AND FL_RTRIM=0 THEN
      CALL CPRINT("inline string rtrim(string x) {")
      CALL CPRINT("int i;")
      CALL CPRINT("for (i=x.size();i>0;i--)")
      CALL CPRINT("if(x.substr(i,1)!="&CHR$(34)&" "&CHR$(34)&") break;")
      CALL CPRINT("return x.substr(0,i);")
      CALL CPRINT("}")
      LET FL_RTRIM=1
   END IF
   IF POS(A$(I),"ORD(")>0 AND FL_ORD=0 THEN
      CALL CPRINT("inline int ord(string x) {")
      CALL CPRINT("return (int)x[0];")
      CALL CPRINT("}")
      LET FL_ORD=1
   END IF
   IF POS(A$(I),"CHR$(")>0 AND FL_CHR=0 THEN
      CALL CPRINT("inline string chr(char x) {")
      CALL CPRINT("return string(1,x);")
      CALL CPRINT("}")
      LET FL_CHR=1
   END IF
   IF POS(A$(I),"UCASE$(")>0 AND FL_UCASE=0 THEN
      CALL CPRINT("inlne string ucase(string x) {")
      CALL CPRINT("string s;")
      CALL CPRINT("for(int i=0;i<x.size();i++)")
      CALL CPRINT("s+=toupper(x[i]);")
      CALL CPRINT("return s;")
      CALL CPRINT("}")
      LET FL_UCASE=1
   END IF
   IF POS(A$(I),"LCASE$(")>0 AND FL_LCASE=0 THEN
      CALL CPRINT("inline string lcase(string x) {")
      CALL CPRINT("string s;")
      CALL CPRINT("for(int i=0;i<x.size();i++)")
      CALL CPRINT("s+=tolower(x[i]);")
      CALL CPRINT("return s;")
      CALL CPRINT("}")
      LET FL_LCASE=1
   END IF
   IF POS(A$(I),"LEFT$(")>0 AND FL_LEFT=0 THEN
      CALL CPRINT("inline string left(string x,double n) {")
      CALL CPRINT("return x.substr(x.size()-(int)n,(int)n);")
      CALL CPRINT("}")
      LET FL_LEFT=1
   END IF
   IF POS(A$(I),"RIGHT$(")>0 AND FL_RIGHT=0 THEN
      CALL CPRINT("inline string right(string x,double n) {")
      CALL CPRINT("return x.substr(0,(int)n);")
      CALL CPRINT("}")
      LET FL_RIGHT=1
   END IF
   IF POS(A$(I),"MID$(")>0 AND FL_MID=0 THEN
      CALL CPRINT("inline string mid(string x,double m,double n) {")
      CALL CPRINT("return x.substr((int)m-1,(int)m+(int)n-1);")
      CALL CPRINT("}")
      LET FL_MID=1
   END IF
   !'IF POS(A$(I),"SWAP ")>0 AND FL_SWAP=0 THEN
   !'   CALL CPRINT("template <typename T>")
   !'   CALL CPRINT("inline void cswap(T &x,T &y) {")
   !'   CALL CPRINT("T z;")
   !'   CALL CPRINT("z=x;x=y;y=z;")
   !'   CALL CPRINT("}")
   !'   LET FL_SWAP=1
   !'END IF
   IF POS(A$(I),"EPS(")>0 AND FL_EPS=0 THEN
      CALL CPRINT("inline double eps(x) {")
      CALL CPRINT("if (x==0) return 1e-99;")
      CALL CPRINT("if (x>0 && x<10) return 1e-14;")
      CALL CPRINT("return fmax(pow(10,floor(log10(abs(x))-14)),1e-99);")
      CALL CPRINT("}")
      LET FL_EPS=1
   END IF
   IF POS(A$(I),"DEF ")>0 AND LITERAL(A$(I),"DEF ")=0 THEN
      LET X$=A$(I)
      IF POS(X$,"!")>0 AND LITERAL(X$,"!")=0 THEN LET X$=TRIM$(FRONTSTRING$(X$,"!"))
      IF POS(X$,"REM ")>0 AND LITERAL(X$,"REM ")=0 THEN LET X$=TRIM$(FRONTSTRING$(X$,"REM "))
      IF X$<>"" THEN
         IF POS(X$,"(")=0 THEN
            LET FNAME$=TRIM$(BETWEENSTRING$(X$,"DEF ","="))
         ELSE
            LET FNAME$=TRIM$(BETWEENSTRING$(X$,"DEF ","("))
         END IF
         LET FNAME$=LCASE$(TRANSRESERVED$(FNAME$))
         IF POS(FNAME$,"$")>0 THEN LET FNAME$=TRANSFORM$(FNAME$,"$","")
         LET FC=FC+1
         LET FUNCNAME$(FC)=FNAME$
         IF POS(X$,"(")>0 THEN
            LET BETWEEN$=BETWEENSTRING$(X$,"(",")")
            LET BETWEEN$=TRIM$(LCASE$(TRANSRESERVED$(BETWEEN$)))
         ELSE
            LET BETWEEN$=""
            LET FUNCNAMENOARG$(FC)=FNAME$&"()"
         END IF
         LET BEHIND$=BEHINDSTRING$(X$,"=")
         LET BEHIND$=TRANSRESERVED$(BEHIND$)
         LET BEHIND$=TRIM$(LCASE$(TRANSFUNC$(BEHIND$)))
         IF POS(BETWEEN$,",")=0 THEN
            IF BETWEEN$="" THEN
               CALL CPRINT("inline "&TYPE$&FNAME$&"(void) {")
            ELSE
               CALL CPRINT("inline "&TYPE$&FNAME$&"("&TYPE$&BETWEEN$&") {")
            END IF
         ELSE
            LET AA$=""
            CALL TOKUN(BETWEEN$,C$,N)
            FOR J=1 TO N
               LET AA$=AA$&TYPE$&C$(J)&","
            NEXT J
            CALL CPRINT("inline "&TYPE$&FNAME$&"("&AA$(1:LEN(AA$)-1)&") {")
         END IF
         CALL CPRINT("return "&BEHIND$&";")
         CALL CPRINT("}")
      END IF
   END IF
NEXT I
LET CTAB=0
FOR I=1 TO MAXLINE
!' IF POS(A$(I),"EPS")>0 AND FL_EPS=0 THEN
!'    IF TYPE$="bigfloat " THEN
!'       CALL CPRINT("bigfloat eps;")
!'       CALL CPRINT("eps.assign("&CHR$(34)&"1e-1000"&CHR$(34)&");")
!'    ELSE
!'       CALL CPRINT("const double eps=1e-14;")
!'    END IF
!'    LET FL_EPS=1
!' END IF
   IF POS(A$(I),"PI")>0 AND LITERAL(A$(I),"PI")=0 AND FL_PI=0 THEN
   !'IF TYPE$="big_float " THEN CALL CPRINT("const big_float pi=boost::math::constants::pi<big_float>();")
      IF TYPE$="double " OR TYPE$="complex <double> " THEN
      !'CALL CPRINT("const double pi=M_PI;")
         CALL CPRINT("const double pi=3.1415926535897932384626;")
      END IF
      LET FL_PI=1
   END IF
   IF (POS(A$(I),"PUBLIC NUMERIC")>0 OR POS(A$(I),"PUBLIC STRING")>0) AND LITERAL(A$(I),"PUBLIC")=0 THEN   !'グローバル変数宣言
      LET X$=A$(I)
      CALL COMMAND_PUBLIC(X$)
      LET FL_PUBLIC=1
   END IF
NEXT I
 

Re: C++トランスレーター(試作・テスト版)

 投稿者:しばっち  投稿日:2014年 7月16日(水)20時50分46秒
  続き 2

IF FL_EPS=1 OR FL_PI=1 OR FL_PUBLIC=1 THEN CALL CPRINT("")
CALL CPRINT("int main(int argc, char* argv[]) {")
MAT VARIABLE_ARGUMENT$=NUL$
LET VA_ARGUMENT_COUNT=0
CALL SCAN$(A$,1)                                                                !'ローカル変数宣言
!'CALL CPRINT("cout <<"&SETPREC$(1:POS(SETPREC$,"<<")-1)&";")                   !'マニピュレータ設定
!'CALL CPRINT("cout << uppercase << dec << right << fixed;")
FOR II=1 TO MAXLINE                                                             !'メイン処理
   CALL MAIN(A$(II))
NEXT II
STOP

SUB MAIN(X$)                                                                    !'分岐処理ルーチン
   LET X$=TRIM$(X$)
   IF X$="" THEN EXIT SUB
   IF POS(X$,"!")>0 OR POS(X$,"REM ")>0 THEN                                    !'「REM・AINDER」
      IF LITERAL(X$,"!")=0 AND LITERAL(X$,"REM")=0 THEN
         CALL COMMAND_REM(X$)                                                   !'「IF A$="!" THEN 」
         EXIT SUB
      END IF
   END IF
   CALL CPRINT("// "&X$)
   IF POS(X$,"IF ")=1 OR POS(X$,"IF(")=1 OR POS(X$,"ELSEIF")=1 THEN
      IF (POS(X$,"END")=0 OR LITERAL(X$,"END")<>0) AND (POS(X$,"READ")=0 OR LITERAL(X$,"READ")<>0) AND (POS(X$,"INPUT")=0 OR LITERAL(X$,"INPUT")<>0) THEN
         CALL COMMAND_IF(X$)
         EXIT SUB                                                               !'「READ IF MISSING THEN」「INPUT #1,IF MISSING THEN」「END IF」
      END IF
   END IF
   IF POS(X$,"LET ")=1 THEN
      CALL COMMAND_LET(X$)
      EXIT SUB
   END IF
   IF POS(X$,"PRINT")=1 AND (POS(X$,"USING")=0 OR LITERAL(X$,"USING")<>0) THEN
      CALL COMMAND_PRINT(X$)                                                    !'「PRINT "USING"」
      EXIT SUB
   END IF
   IF POS(X$,"CASE ")>0 AND LITERAL(X$,"CASE")=0 THEN
      CALL COMMAND_CASE(X$)                                                     !'「SELECT CASE」「CASE ELSE」
      EXIT SUB
   END IF
   IF POS(X$,"CALL ")=1 THEN
      CALL COMMAND_CALL(X$)
      EXIT SUB
   END IF
   IF POS(X$,"ELSE")=1 AND POS(X$,"CASE")=0 AND POS(X$,"ELSEIF")=0 AND LITERAL(X$,"ELSE")=0 AND LITERAL(X$,"CASE")=0 THEN
      CALL COMMAND_ELSE(X$)
      EXIT SUB
   END IF
   IF POS(X$,"DIM ")=1 THEN
      CALL COMMAND_DIM(X$)
      EXIT SUB
   END IF
   IF POS(X$,"FUNCTION ")>0 AND POS(X$,"DECLARE")=0 AND POS(X$,"(,)")=0 AND POS(X$,"(,,)")=0 AND LITERAL(X$,"FUNCTION ")=0 AND POS(X$,"EXTERNAL")=1 THEN
      CALL COMMAND_FUNCTION(X$)
      EXIT SUB
   END IF
   IF POS(X$,"SUB ")>0 AND POS(X$,"DECLARE")=0 AND POS(X$,"(,)")=0 AND POS(X$,"(,,)")=0 AND LITERAL(X$,"SUB ")=0 AND POS(X$,"EXTERNAL")=1 THEN
      CALL COMMAND_SUB(X$)
      EXIT SUB
   END IF
   IF POS(X$,"FOR ")=1 THEN
      CALL COMMAND_FOR(X$)
      EXIT SUB
   END IF
   IF POS(X$,"NEXT ")=1 THEN
      CALL COMMAND_NEXT(X$)
      EXIT SUB
   END IF
   IF POS(X$,"DO")=1 THEN
      CALL COMMAND_DO(X$)
      EXIT SUB
   END IF
   IF POS(X$,"LOOP")=1 THEN
      CALL COMMAND_LOOP(X$)
      EXIT SUB
   END IF
   IF POS(X$,"INPUT ")=1 AND POS(X$,"IF")=0 AND POS(X$,"CHARACTER")=0 AND POS(X$,"ELAPSED")=0 AND POS(X$,"TIMEOUT")=0 OR POS(X$,"LINE INPUT")=1 THEN
      CALL COMMAND_INPUT(X$)                                                    !'「CHARACTER INPUT」「INPUT ELAPSED」「INPUT TIMEOUT」「INPUT #1,IF MISSING THEN 」
      EXIT SUB
   END IF
   IF POS(X$,"END")=1 AND POS(X$,"PICTURE")=0 THEN
      CALL COMMAND_END(X$)                                                      !'「END」「END IF」「END SUB」「END FUNCTION」「END SELECT」
      EXIT SUB
   END IF
   IF POS(X$,"EXIT")=1 AND POS(X$,"PICTURE")=0 THEN
      CALL COMMAND_EXIT(X$)
      EXIT SUB
   END IF
   IF POS(X$,"RANDOMIZE")=1 THEN
      CALL COMMAND_RANDOMIZE(X$)
      EXIT SUB
   END IF
   IF POS(X$,"STOP")=1 THEN
      CALL COMMAND_STOP(X$)
      EXIT SUB
   END IF
   IF POS(X$,"OPEN ")=1 THEN
      CALL COMMAND_OPEN(X$)
      EXIT SUB
   END IF
   IF POS(X$,"CLOSE")=1 THEN
      CALL COMMAND_CLOSE(X$)
      EXIT SUB
   END IF
   IF POS(X$,"SWAP ")=1 THEN
      CALL COMMAND_SWAP(X$)
      EXIT SUB
   END IF
   IF POS(X$,"OPTION ARITHMETIC")>0 THEN EXIT SUB
   IF POS(X$,"OPTION ANGLE RADIANS")>0 THEN EXIT SUB
   IF POS(X$,"OPTION BASE")>0 THEN EXIT SUB
   IF POS(X$,"OPTION CHARACTER BYTE")>0 THEN EXIT SUB
   IF POS(X$,"PUBLIC")>0 THEN EXIT SUB
   IF POS(X$,"DEF ")>0 THEN EXIT SUB
   IF POS(X$,"DECLARE EXTERNAL")>0 THEN EXIT SUB
   IF POS(X$,"SET ECHO")>0 THEN EXIT SUB
   CALL CPRINT(X$&" // ******* 未対応です *******")
END SUB

SUB COMMAND_PUBLIC(XX$)                                                         !'以下、各コマンド処理ルーチン
   LOCAL I,K,J,N,L
   LET X$=XX$
   IF POS(X$,"!")>0 THEN LET X$=TRIM$(FRONTSTRING$(X$,"!"))
   IF POS(X$,"REM ")>0 THEN LET X$=TRIM$(FRONTSTRING$(X$,"REM "))
   LET X$=TRANSRESERVED$(X$)                                                    !'変数名がC/C++予約語なら変換
   LET X$=TRANSFORM$(X$,"(","[")                                                !'配列変数なら変換
   LET X$=TRANSFORM$(X$,")","+1]")
   LET I=1
   DO
      IF X$(I:I)="[" THEN
         LET J=I+1
         DO
            IF X$(J:J)="," THEN                                                 !'多次元配列時の処理
               LET X$(J:J)="+1]["
               LET J=J+4
            END IF
            LET J=J+1
         LOOP UNTIL X$(J:J)="]"
      END IF
      LET I=I+1
   LOOP UNTIL LEN(X$)<=I
   IF POS(X$,"NUMERIC")>0 THEN
      LET BEHIND$=BEHINDSTRING$(X$,"NUMERIC ")
   ELSEIF POS(X$,"STRING")>0 THEN
      LET BEHIND$=BEHINDSTRING$(X$,"STRING ")
   END IF
   CALL TOKUN(BEHIND$,C$,K)
   FOR I=1 TO K
      IF POS(C$(I),"TO")>0 THEN                                                 !'下限指定 TO句の処理
         IF POS(C$(I),"][")=0 THEN                                              !'1次元配列
            LET AA$=TRIM$(BETWEENSTRING$(C$(I),"[","TO"))
            LET BB$=TRIM$(BETWEENSTRING$(C$(I),"TO","+1]"))
            IF POS("0123456789",AA$(1:1))=0 OR POS("0123456789",BB$(1:1))=0 THEN   !'定数でないなら
               CALL CPRINT(XX$&" // ******* 未対応です *******")
               EXIT SUB
            ELSE
               LET C$(I)=C$(I)(1:POS(C$(I),"["))&BB$&"+1]"
            END IF
         ELSE                                                                   !'多次元配列時の処理
            LET CC$=""
            LET J=0
            LET L=0
            LET N=0
            DO
               LET J=POS(C$(I),"[",J+1)
               LET L=POS(C$(I),"+1]",L+1)
               LET N=N+1
               LET C2$(N)=C$(I)(J+1:L-1)
            LOOP UNTIL L+2>=LEN(C$(I))
            FOR J=1 TO N
               LET AA$=TRIM$(FRONTSTRING$(C2$(J),"TO"))
               LET BB$=TRIM$(BEHINDSTRING$(C2$(J),"TO"))
               IF POS("0123456789",AA$(1:1))=0 OR POS("0123456789",BB$(1:1))=0 THEN
                  CALL CPRINT(XX$&" // ******* 未対応です *******")
                  EXIT SUB
               ELSE
                  LET CC$=CC$&BB$&"+1]["
               END IF
            NEXT J
            LET C$(I)=C$(I)(1:POS(C$(I),"["))&CC$(1:LEN(CC$)-1)
         END IF
      END IF
      IF POS(C$(I),"[")=0 THEN
         LET VA_PUBLIC_COUNT=VA_PUBLIC_COUNT+1
         LET VARIABLE_PUBLIC$(VA_PUBLIC_COUNT)=LCASE$(TRIM$(C$(I)))             !'配列変数名登録
      END IF
   NEXT I
   IF POS(X$,"NUMERIC")>0 THEN
      IF POS(BEHIND$,"]")>0 THEN
         LET BEHIND$=""
         FOR I=1 TO K
            LET BEHIND$=BEHIND$&C$(I)
            IF POS(C$(I),"]")>0 THEN LET BEHIND$=BEHIND$&"={}," ELSE LET BEHIND$=BEHIND$&","   !'配列初期化設定
         NEXT I
         LET BEHIND$=BEHIND$(1:LEN(BEHIND$)-1)
      ELSE
         LET I=1
         DO
            IF BEHIND$(I:I)="," AND BEHIND$(I-3:I)<>"={}," THEN                 !'配列でないなら初期値0
               LET BEHIND$(I:I)="=0,"
               LET I=I+2
            END IF
            LET I=I+1
         LOOP UNTIL LEN(X$)<=I
         IF BEHIND$(LEN(BEHIND$)-2:LEN(BEHIND$))<>"={}" THEN
            LET BEHIND$=BEHIND$&"=0"
         END IF
      END IF
      CALL CPRINT(TYPE$&LCASE$(BEHIND$)&";")
   ELSE
      LET BEHIND$=TRANSFORM$(BEHIND$,"$","_string")
      IF POS(BEHIND$,"]")>0 THEN
         LET BEHIND$=TRANSFORM$(BEHIND$,"]",")={"&CHR$(34)&CHR$(34)&"}")        !'string配列 NULL初期化
         LET BEHIND$=TRANSFORM$(BEHIND$,")","]")
      END IF
      CALL CPRINT("string "&LCASE$(BEHIND$)&";")
   END IF
END SUB

SUB COMMAND_DIM(XX$)
   LOCAL I,N,J,K
   LET X$=XX$
   LET X$=TRANSRESERVED$(X$)
   LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"DIM "))
   LET INI$=""
   CALL SPLIT2(BEHIND$,C$,N)
   LET CC$=""
   LET SS$=""
   MAT EXPRESSION$=NUL$
   MAT VA_DIM=ZER
   MAT VA_INIT$=NUL$
   MAT VARIABLE_DIM$=NUL$
   FOR I=1 TO N
      LET FL=0
      LET C$(I)=TRIM$(C$(I))
      IF POS(C$(I),"TO")>0 THEN                                                 !'下限指定時の処理
         IF POS(C$(I),",")=0 THEN                                               !'1次元配列時
            LET AA$=TRIM$(BETWEENSTRING$(C$(I),"(","TO"))
            LET BB$=TRIM$(BETWEENSTRING$(C$(I),"TO",")"))
            IF POS("0123456789",AA$(1:1))=0 OR POS("0123456789",BB$(1:1))=0 THEN
               CALL CPRINT(XX$&" // ******* 未対応です *******")
               EXIT SUB
            ELSE
               LET C$(I)=C$(I)(1:POS(C$(I),"("))&BB$&")"
            END IF
         ELSE                                                                   !'多次元配列時の処理
            LET J=POS(C$(I),"(")
            LET K=POS(C$(I),")")
            LET AA$=C$(I)(J+1:K-1)
            CALL TOKUN(AA$,C2$,K)
            FOR J=1 TO K
               LET AA$=TRIM$(FRONTSTRING$(C2$(J),"TO"))
               LET BB$=TRIM$(BEHINDSTRING$(C2$(J),"TO"))
               IF POS("0123456789",AA$(1:1))=0 OR POS("0123456789",BB$(1:1))=0 THEN
                  CALL CPRINT(XX$&" // ******* 未対応です *******")
                  EXIT SUB
               ELSE
                  LET CC$=CC$&BB$&","
               END IF
            NEXT J
            LET C$(I)=C$(I)(1:POS(C$(I),"("))&CC$(1:LEN(CC$)-1)&")"
            LET CC$=""
         END IF
      END IF
      LET AA$=""
      LET BB$=""
      IF POS(C$(I),"$")>0 THEN LET C$(I)=TRANSFORM$(C$(I),"$","_string")
      LET B$=TRANSARRAYNAME$(C$(I))
      IF TYPE$="complex <double> " THEN                                         !'強制キャストとりあえず解除
         LET INI$="static_cast<int>(abs("
         LET B$=TRANSFORM$(B$,INI$,"")
         LET B$=TRANSFORM$(B$,"))","")
         LET AA$="abs("
         LET BB$=")"
      ELSE
         LET INI$="static_cast<int>("
         LET B$=TRANSFORM$(B$,INI$,"")
         LET B$=TRANSFORM$(B$,")","")
      END IF
      LET C$(I)=TRANSFUNC$(B$)
      IF B$=C$(I) THEN
         LET K=POS(B$,"[")
         FOR J=K+1 TO LEN(B$)
            IF POS("abcdefghijklmnopqrstuvwxyz",LCASE$(B$(J:J)))>0 THEN LET FL=1   !'変数指定なら
         NEXT J
      ELSE
         LET FL=1
      END IF
      IF FL=1 THEN
         FOR J=1 TO LEN(C$(I))
            IF C$(I)(J:J)="[" THEN EXIT FOR
         NEXT J
         LET VARIABLE_DIM$(I)=TRIM$(LCASE$(C$(I)(1:J-1)))
      END IF
      LET K=POS(C$(I),"[")
      LET J=K
      LET SP=0
      DO
         LET J=J+1
         IF C$(I)(J:J)="(" THEN LET SP=SP+1
         IF C$(I)(J:J)=")" THEN LET SP=SP-1
         IF SP=0 AND C$(I)(J:J+1)="][" THEN
            LET VA_DIM(I)=VA_DIM(I)+1
            LET EXPRESSION$(I,VA_DIM(I))=LCASE$(C$(I)(K+1:J-1))
            LET C$(I)(J:J+1)="+1]["
            LET J=J+3
            LET K=J
         END IF
      LOOP UNTIL C$(I)(J:J)="]" OR LEN(C$(I))=J
      LET VA_DIM(I)=VA_DIM(I)+1
      LET EXPRESSION$(I,VA_DIM(I))=LCASE$(C$(I)(K+1:J-1))
      LET C$(I)(J:J)="+1]"
      IF FL=1 THEN
         LET C$(I)=TRANSFORM$(C$(I),"[","\"&INI$)
         LET C$(I)=TRANSFORM$(C$(I),"\","[")
         IF TYPE$="complex <double> " THEN
            LET C$(I)=TRANSFORM$(C$(I),"]","))\")
            LET C$(I)=TRANSFORM$(C$(I),"\","]")
         ELSE
            LET C$(I)=TRANSFORM$(C$(I),"]",")\")
            LET C$(I)=TRANSFORM$(C$(I),"\","]")
         END IF
      END IF
      IF POS(C$(I),"_string")>0 THEN
         IF FL=0 THEN
            LET CC$=CC$&C$(I)&"={"&CHR$(34)&CHR$(34)&"},"
         ELSE
            LET CC$=CC$&C$(I)&","
            LET VA_INIT$(I)=CHR$(34)&CHR$(34)&";"                               !'初期値"" NULL
         END IF
      ELSE
         IF FL=0 THEN
            LET SS$=SS$&C$(I)&"={},"
         ELSE
            LET SS$=SS$&C$(I)&","
            LET VA_INIT$(I)="0;"                                                !'初期値0
         END IF
      END IF
   NEXT I
   IF CC$<>"" THEN
      CALL CPRINT("string "&LCASE$(LEFT$(CC$,LEN(CC$)-1))&";")
   END IF
   IF SS$<>"" THEN
      CALL CPRINT(TYPE$&LCASE$(LEFT$(SS$,LEN(SS$)-1))&";")
   END IF
   FOR I=1 TO N                                                                 !'可変長配列の初期化
      IF VARIABLE_DIM$(I)<>"" THEN
         SELECT CASE VA_DIM(I)
         CASE 1
            CALL CPRINT("for (int i=0;i<="&AA$&EXPRESSION$(I,1)&BB$&";i++)")
            CALL CPRINT(VARIABLE_DIM$(I)&"[i]="&VA_INIT$(I))
         CASE 2
            CALL CPRINT("for (int i=0;i<="&AA$&EXPRESSION$(I,1)&BB$&";i++)")
            CALL CPRINT("for (int j=0;j<="&AA$&EXPRESSION$(I,2)&BB$&";j++)")
            CALL CPRINT(VARIABLE_DIM$(I)&"[i][j]="&VA_INIT$(I))
         CASE 3
            CALL CPRINT("for (int i=0;i<="&AA$&EXPRESSION$(I,1)&BB$&";i++)")
            CALL CPRINT("for (int j=0;j<="&AA$&EXPRESSION$(I,2)&BB$&";j++)")
            CALL CPRINT("for (int k=0;k<="&AA$&EXPRESSION$(I,3)&BB$&";k++)")
            CALL CPRINT(VARIABLE_DIM$(I)&"[i][j][k]="&VA_INIT$(I))
         CASE ELSE
         END SELECT
      END IF
   NEXT I
END SUB

SUB COMMAND_FOR(X$)
   LOCAL I
   LET X$=TRANSRESERVED$(X$)
   LET P$=TRIM$(LCASE$(BETWEENSTRING$(X$,"FOR","=")))                           !'制御変数名
   LET NUM$=TRIM$(BETWEENSTRING$(X$,"=","TO"))                                  !'初期値
   IF POS(X$,"STEP")>0 THEN
      LET ST$=BEHINDSTRING$(X$,"STEP")                                          !'増分
      LET ST$=TRANSARRAYNAME$(ST$)
      LET ST$=TRANSFUNC$(ST$)
      LET I=POS(ST$,"-")
      IF I>0 THEN
         LET SI$=">="
         LET SIGN$="-"
         LET ST$(I:I)=""
      ELSE
         LET SI$="<="
         LET SIGN$="+"
      END IF
      LET T$=TRIM$(BETWEENSTRING$(X$,"TO","STEP"))                              !'終了値
   ELSE
      LET T$=TRIM$(BEHINDSTRING$(X$,"TO"))
      LET ST$="1"
      LET SI$="<="
      LET SIGN$="+"
   END IF
   LET T$=TRANSARRAYNAME$(T$)                                                   !'配列変数名変換
   LET T$=TRANSFUNC$(T$)                                                        !'関数名変換
   LET NUM$=TRANSARRAYNAME$(NUM$)
   LET NUM$=TRANSFUNC$(NUM$)
   !!!CALL CPRINT("#pragma omp parallel for")                                   !!! openMP マルチスレッド (#include<omp.h>)
   CALL CPRINT("for("&P$&"="&LCASE$(NUM$)&";"&P$&SI$&LCASE$(T$)&";"&P$&SIGN$&"="&LCASE$(TRIM$(ST$))&") {")
END SUB

SUB COMMAND_NEXT(X$)
   CALL CPRINT("}")
END SUB

SUB COMMAND_FUNCTION(XX$)
   LOCAL N,K
   LET X$=XX$
   IF POS(X$,"!")>0 THEN LET X$=TRIM$(FRONTSTRING$(X$,"!"))
   IF POS(X$,"REM ")>0 THEN LET X$=TRIM$(FRONTSTRING$(X$,"REM "))
   LET X$=TRANSRESERVED$(X$)
   IF POS(X$,"(")=0 THEN                                                        !'仮引数なしの場合
      LET FNAME$=LCASE$(TRIM$(BEHINDSTRING$(X$,"FUNCTION")))                    !'関数名
      IF POS(FNAME$,"$")>0 THEN LET FNAME$=TRANSFORM$(FNAME$,"$","")
      IF PROTOTYPE<>0 THEN                                                      !'プロトタイプ宣言
         CALL CPRINT(TYPE$&FNAME$&"(void);")
         LET FC=FC+1
         LET FUNCNAME$(FC)=FNAME$                                               !'関数名登録
         EXIT SUB
      ELSE
         CALL CPRINT(TYPE$&FNAME$&"(void)")
         CALL CPRINT("{")
         EXIT SUB
      END IF
   END IF
   IF POS(X$,"()")>0 THEN LET X$=TRANSFORM$(X$,"()","[]")                       !'1次元配列 A() → A[]
   LET BEHIND$=BEHINDSTRING$(X$,"(")
   LET BEHIND$=BEHIND$(1:LEN(BEHIND$)-1)                                        !'仮引数列
   LET FNAME$=LCASE$(TRIM$(BETWEENSTRING$(X$,"FUNCTION","(")))
   IF PROTOTYPE<>0 THEN
      LET FC=FC+1
      LET FUNCNAME$(FC)=FNAME$
   END IF
   CALL TOKUN(BEHIND$,C$,K)
   LET AA$=""
   MAT VARIABLE_ARGUMENT$=NUL$
   LET VA_ARGUMENT_COUNT=0
   FOR N=1 TO K
      LET C$(N)=LCASE$(TRIM$(C$(N)))
      LET B$=C$(N)
      LET B$=TRANSFORM$(B$,"[]","")
      LET VA_ARGUMENT_COUNT=VA_ARGUMENT_COUNT+1
      LET VARIABLE_ARGUMENT$(VA_ARGUMENT_COUNT)=B$                              !'仮引数変数名登録
      IF POS(C$(N),"$")>0 THEN
         LET C$(N)="string "&TRANSFORM$(C$(N),"$","_string")
      ELSE
         LET C$(N)=TYPE$&C$(N)
      END IF
      LET AA$=AA$&C$(N)&","
   NEXT N
   LET AA$=AA$(1:LEN(AA$)-1)
   IF PROTOTYPE<>0 THEN LET AA$=AA$&");" ELSE LET AA$=AA$&")"
   CALL CPRINT(TYPE$&LCASE$(FNAME$&"("&AA$))
   IF PROTOTYPE=0 THEN                                                          !'プロトタイプ宣言でないなら使用変数名のスキャン、変数宣言
      CALL CPRINT("{")
      CALL SCAN$(A$,II)
   END IF
END SUB
 

Re: C++トランスレーター(試作・テスト版)

 投稿者:しばっち  投稿日:2014年 7月16日(水)20時52分15秒
  続き 3

SUB COMMAND_SUB(XX$)
   LOCAL N,K
   LET X$=XX$
   LET VA_CALL_COUNT=0
   IF POS(X$,"!")>0 THEN LET X$=TRIM$(FRONTSTRING$(X$,"!"))
   IF POS(X$,"REM ")>0 THEN LET X$=TRIM$(FRONTSTRING$(X$,"REM "))
   LET X$=TRANSRESERVED$(X$)
   IF POS(X$,"(")=0 THEN                                                        !'仮引数なしの場合
      LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"SUB "))
      IF PROTOTYPE<>0 THEN
         CALL CPRINT("void "&LCASE$(BEHIND$)&"(void);")
         EXIT SUB
      ELSE
         CALL CPRINT("void "&LCASE$(BEHIND$)&"(void)")
         CALL CPRINT("{")
         EXIT SUB
      END IF
   END IF
   IF POS(X$,"()")>0 THEN LET X$=TRANSFORM$(X$,"()","[]")
   LET BEHIND$=BEHINDSTRING$(X$,"(")
   LET BEHIND$=BEHIND$(1:LEN(BEHIND$)-1)
   LET SNAME$=TRIM$(LCASE$(BETWEENSTRING$(X$,"SUB","(")))                       !'サブルーチン名
   CALL TOKUN(BEHIND$,C$,K)
   LET AA$=""
   MAT VARIABLE_ARGUMENT$=NUL$
   LET VA_ARGUMENT_COUNT=0
   FOR N=1 TO K
      LET C$(N)=LCASE$(TRIM$(C$(N)))
      LET B$=C$(N)
      LET B$=TRANSFORM$(B$,"[]","")
      LET VA_ARGUMENT_COUNT=VA_ARGUMENT_COUNT+1
      LET VARIABLE_ARGUMENT$(VA_ARGUMENT_COUNT)=B$
      IF POS(C$(N),"[")=0 THEN
         LET B$="&"
      ELSE
         LET B$=""
      END IF
      IF POS(C$(N),"$")>0 THEN
         LET C$(N)="string "&B$&TRANSFORM$(C$(N),"$","_string")
      ELSE
         LET C$(N)=TYPE$&B$&C$(N)
      END IF
      LET AA$=AA$&C$(N)&","
   NEXT N
   LET AA$=AA$(1:LEN(AA$)-1)
   IF PROTOTYPE<>0 THEN LET AA$=AA$&");" ELSE LET AA$=AA$&")"
   CALL CPRINT("void "&SNAME$&"("&AA$)
   IF PROTOTYPE=0 THEN
      CALL CPRINT("{")
      CALL SCAN$(A$,II)
   END IF
END SUB

SUB COMMAND_CASE(X$)
   LOCAL I,N
   LET X$=TRANSRESERVED$(X$)
   IF POS(X$,"SELECT CASE")>0 THEN
      LET SWITCH$=BEHINDSTRING$(X$,"SELECT CASE")                               !'SELECT CASE区の変数名
      LET SWITCH$=TRANSARRAYNAME$(SWITCH$)
      LET SWITCH$=LCASE$(TRANSFUNC$(SWITCH$))
      IF POS(SWITCH$,"$")>0 AND LITERAL(SWITCH$,"$")=0 THEN  LET SWITCH$=TRANSFORM$(SWITCH$,"$","_string")
      LET NUMCASE=0
      EXIT SUB
   END IF
   IF POS(X$,"CASE ELSE")>0 THEN
      CALL CPRINT("}")
      CALL CPRINT("else")
      CALL CPRINT("{")
   ELSEIF POS(X$,"CASE")>0 THEN                                                 !'CASE区の処理
      LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"CASE"))
      LET AA$=""
      CALL TOKUN(BEHIND$,C$,N)
      FOR I=1 TO N
         IF POS(C$(I),"TO")>0 THEN                                              !'範囲指定時「CASE 1 TO 5」
            LET FRONT$=FRONTSTRING$(C$(I),"TO")
            LET BEHIND$=BEHINDSTRING$(C$(I),"TO")
            LET AA$=AA$&TRIM$(FRONT$)&"<="&SWITCH$&" && "&SWITCH$&" <= "&TRIM$(BEHIND$)&" || "
         ELSEIF POS(C$(I),"IS")>0 THEN                                          !' IS区指定時「CASE IS>5,IS<0」
            LET AA$=AA$&SWITCH$&TRIM$(BEHINDSTRING$(C$(I),"IS"))&" || "
         ELSE
            LET AA$=AA$&SWITCH$&"=="&C$(I)&" || "                               !'「CASE 1,3,5」
         END IF
      NEXT I
      LET AA$=AA$(1:LEN(AA$)-4)
      LET NUMCASE=NUMCASE+1
      IF NUMCASE=1 THEN                                                         !'最初のCASE区
         CALL CPRINT("if("&AA$&") { ")
      ELSE                                                                      !'2番目以降のCASE区
         CALL CPRINT("}")
         CALL CPRINT("else if("&AA$&") { ")
      END IF
   END IF
END SUB

SUB COMMAND_DO(XX$)
   LET X$=XX$
   LET X$=TRANSRESERVED$(X$)
   LET X$=TRANSCO$(X$)
   LET X$=TRANSARRAYNAME$(X$)
   LET X$=TRANSFUNC$(X$)
   IF POS(X$,"DO WHILE")>0 THEN                                                 !'DO WHILE処理
      LET BEHIND$=BEHINDSTRING$(X$,"WHILE")
      CALL CPRINT("while ("&LLCASE$(TRIM$(BEHIND$))&") {")
      EXIT SUB
   END IF
   IF POS(X$,"DO UNTIL")>0 THEN
      LET BEHIND$=BEHINDSTRING$(X$,"UNTIL")
      CALL CPRINT("do {")                                                       !'DO UNTIL処理
      CALL CPRINT( "if ("&LLCASE$(TRIM$(BEHIND$))&") break;")
      EXIT SUB
   END IF
   CALL CPRINT("do {")
END SUB

SUB COMMAND_LOOP(XX$)
   LET X$=XX$
   LET X$=TRANSRESERVED$(X$)
   LET X$=TRANSCO$(X$)
   LET X$=TRANSARRAYNAME$(X$)
   LET X$=TRANSFUNC$(X$)
   IF POS(X$,"LOOP UNTIL")>0 THEN                                               !'LOOP UNTIL処理
      LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"UNTIL"))
      CALL CPRINT("if ("&LLCASE$(BEHIND$)&") break;")
   END IF
   IF POS(X$,"LOOP WHILE")>0 THEN                                               !'LOOP WHILE処理
      LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"WHILE"))
      CALL CPRINT("} while ("&LLCASE$(BEHIND$)&");")
      EXIT SUB
   END IF
   CALL CPRINT("}")
END SUB

SUB COMMAND_LET(XX$)
   LOCAL I,N,K
   LET N=0
   LET K=0
   LET X$=XX$
   LET X$=TRANSRESERVED$(X$)
   FOR I=1 TO LEN(X$)
      IF X$(I:I)="=" THEN LET K=K+1
   NEXT I
   IF K=1 THEN LET BETWEEN$=LCASE$(TRIM$(BETWEENSTRING$(X$,"LET","=")))
   LET AA$=""
   IF K=1 AND BETWEEN$=FNAME$ THEN                                              !'FUNCTION内で関数名と同じ場合
      LET AA$="return "
      LET X$=BEHINDSTRING$(X$,"=")
   END IF
   LET X$=TRANSFORM$(X$,"LET ","")
   IF K=1 AND POS(BETWEEN$,",")=0 THEN
      LET X$=TRANSARRAYNAME$(X$)
      LET X$=LLCASE$(TRANSFUNC$(X$))
      CALL CPRINT(AA$&X$&";")
      EXIT SUB
   END IF
   IF K=1 THEN                                                                  !'複数、多次元配列指定「LET A,B,C(1,1)=5」
      LET X$=BEHINDSTRING$(X$,"=")
      CALL SPLIT2(BETWEEN$,C$,N)
      FOR I=1 TO N
         IF POS(C$(I),"(")>0 THEN LET C$(I)=TRANSARRAYNAME$(C$(I))
         LET X$=TRANSARRAYNAME$(X$)
         LET X$=LLCASE$(TRANSFUNC$(X$))
         CALL CPRINT(C$(I)&"="&X$&";")
      NEXT I
   ELSE                                                                         !'「LET A=1,B=2,C=3」
      CALL SPLIT2(X$,C$,N)
      FOR I=1 TO N
         LET BEHIND$=BEHINDSTRING$(C$(I),"=")
         LET BEHIND$=TRANSARRAYNAME$(BEHIND$)
         LET BEHIND$=LLCASE$(TRANSFUNC$(BEHIND$))
         LET FRONT$=FRONTSTRING$(C$(I),"=")
         IF POS(FRONT$,"(")>0 THEN LET FRONT$=TRANSARRAYNAME$(FRONT$)
         LET FRONT$=TRANSFORM$(FRONT$,"$","_string")
         CALL CPRINT(LCASE$(FRONT$)&"="&BEHIND$&";")
      NEXT I
   END IF
END SUB

SUB COMMAND_INPUT(XX$)
   LOCAL I,J,K
   LET X$=XX$
   LET X$=TRANSRESERVED$(X$)
   LET NUM$=""
   LET X$=TRANSFORM$(X$,"$","_string")
   IF POS(X$,"#")>0 THEN                                                        !'ファイル読込指定時
      LET NUM$=TRIM$(BETWEENSTRING$(X$,"#",":"))                                !'経路番号
      LET X$=TRANSFORM$(X$,"#"&NUM$&":","")
   END IF
   LET K=POS(X$,"PROMPT")
   IF K>0 THEN                                                                  !'INPUT PROMPT文「INPUT PROMPT "男:1 女:2":N」
      IF POS(X$,CHR$(34))>0 THEN                                                !'文字定数取出
         FOR I=K+6 TO LEN(X$)
            IF X$(I:I)=CHR$(34) THEN
               FOR J=I+1 TO LEN(X$)
                  IF X$(J:J)=CHR$(34) THEN
                     LET S$=TRIM$(X$(I:J))
                     LET I=J+1
                     EXIT FOR
                  END IF
               NEXT J
            END IF
         NEXT I
         FOR I=J+1 TO LEN(X$)
            IF X$(I:I)=":" THEN EXIT FOR
         NEXT I
         LET ST$=TRIM$(X$(I+1:LEN(X$)))
      ELSE
         LET S$=TRIM$(BETWEENSTRING$(X$,"PROMPT",":"))                          !'出力文(文字定数取出)
         LET ST$=TRIM$(BEHINDSTRING$(X$,":"))                                   !'変数列取出
      END IF
      LET ST$=TRANSFORM$(ST$,","," >> ")
      LET ST$=LCASE$(TRANSARRAYNAME$(ST$))
      CALL CPRINT("cout << "&S$&";")
      !' CALL CPRINT("cerr << "&S$&";")
      IF POS(X$,"LINE INPUT")>0 THEN
         CALL CPRINT("getline(cin,"&ST$&");")                                   !'「LINE INPUT PROMPT "A=":A$」
      ELSE
         CALL CPRINT("cin >> "&ST$&";")                                         !'「INPUT PROMPT "A,B,C=":A$,B$,C$」
      END IF
   ELSE
      IF POS(X$,"LINE INPUT")>0 THEN
         IF NUM$<>"" THEN
            LET X$=TRANSARRAYNAME$(X$)
            LET X$=TRANSFORM$(X$,"LINE INPUT","getline(fs"&NUM$&",")            !'「LINE INPUT #1:A$」
            CALL CPRINT(LCASE$(X$)&");")
         ELSE
            LET X$=TRANSFORM$(X$,"LINE INPUT","getline(cin,")                   !'「LINE INPUT A$」
            CALL CPRINT(LCASE$(X$)&");")
         END IF
      ELSE
         IF NUM$<>"" THEN
            LET X$=TRANSFORM$(X$,"INPUT","fs"&NUM$&" >> ")                      !'「INPUT #1:A,B,C」
         ELSE
            LET X$=TRANSFORM$(X$,"INPUT","cin >> ")                             !'「INPUT A,B,C」
            LET X$=TRANSFORM$(X$,","," >> ")
            CALL CPRINT(LCASE$(X$)&";")
         END IF
      END IF
   END IF
END SUB

SUB COMMAND_PRINT(XX$)
   LET X$=XX$
   LET X$=TRANSRESERVED$(X$)
   LOCAL I,J,N
   LET NUM$=""
   IF TRIM$(BEHINDSTRING$(X$,"PRINT"))="" THEN                                  !'改行指定
      CALL CPRINT("cout << endl;")
      !'CALL CPRINT("cout << '\n';")
      EXIT SUB
   END IF
   LET ST$=""
   IF RIGHT$(X$,1)<>";" AND RIGHT$(X$,1)<>"," THEN                              !'文末に";"又は","がないなら改行指定
      LET ST$=" << endl"
      !'LET ST$=" << '\n'"
   ELSE
      IF RIGHT$(X$,1)=";" THEN LET X$(LEN(X$):LEN(X$))=" <<"&CHR$(39)&" "&CHR$(39)   !'スペース文字に置き換え
      IF RIGHT$(X$,1)="," THEN LET X$(LEN(X$):LEN(X$))=" <<"&CHR$(39)&REPEAT$(CHR$(32),20)&CHR$(39)
   END IF
   LET SP=0
   LET I=0
   DO
      LET I=I+1
      IF X$(I:I)=CHR$(34) THEN                                                  !'文字定数内の「,」「;」を除く「"A,B=";A,B」
         FOR J=I+1 TO LEN(X$)
            IF X$(J:J)=CHR$(34) THEN EXIT FOR
         NEXT J
         LET I=J
      END IF
      IF X$(I:I)="(" OR X$(I:I)="[" THEN                                        !'多次元配列変数内の「,」を除く「A,B;C(1,1),D」
         LET SP=SP+1
         FOR J=I+1 TO LEN(X$)
            IF X$(J:J)="(" OR X$(J:J)="[" THEN LET SP=SP+1
            IF X$(J:J)=")" OR X$(J:J)="]" THEN LET SP=SP-1
            IF SP=0 THEN EXIT FOR
         NEXT J
         LET I=J
      END IF
      IF X$(I:I)="," THEN LET X$(I:I)=" <<"&CHR$(39)&REPEAT$(CHR$(32),20)&CHR$(39)&"<< "   !'「,」「;」を" "スペースに置換
      IF X$(I:I)=";" THEN LET X$(I:I)=" <<"&CHR$(39)&" "&CHR$(39)&"<< "
   LOOP UNTIL LEN(X$)<=I
   IF POS(X$,"#")>0 THEN
      LET NUM$=TRIM$(BETWEENSTRING$(X$,"#",":"))                                !'経路番号
      LET X$=TRANSFORM$(X$,"#"&NUM$&":","")
      IF TRIM$(X$)="PRINT" THEN
         CALL CPRINT("fs"&NUM$&" << endl;")
         EXIT SUB
      END IF
   END IF
   IF POS(X$,CHR$(34))>0 THEN                                                   !'文字定数があるなら
      LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"PRINT"))
      CALL SPLIT(BEHIND$,C$,N)                                                  !'PRINT文以降を分割
      FOR I=1 TO N STEP 2
         IF C$(I)<>"" THEN
            LET C$(I)=TRANSARRAYNAME$(C$(I))
            LET C$(I)=LCASE$(TRANSFUNC$(C$(I)))
         END IF
      NEXT I
      IF NUM$<>"" THEN LET B$="fs"&NUM$&" << "&SETPREC$ ELSE LET B$="cout << "&SETPREC$
      FOR I=1 TO N
         LET B$=B$&TRIM$(C$(I))
      NEXT I
      LET B$=TRANSFORM$(B$,CHR$(39),CHR$(34))
      CALL CPRINT(B$&ST$&";")
   ELSE
      LET X$=TRANSARRAYNAME$(X$)
      LET X$=TRANSFUNC$(X$)
      IF NUM$<>"" THEN
         LET X$=TRANSFORM$(X$,"PRINT","fs"&NUM$&" <<"&SETPREC$)
      ELSE
         LET X$=TRANSFORM$(X$,"PRINT","cout <<"&SETPREC$)
      END IF
      LET X$=TRANSFORM$(X$,CHR$(39),CHR$(34))
      CALL CPRINT(LCASE$(TRIM$(X$))&ST$&";")
   END IF
END SUB

SUB COMMAND_IF(XX$)
   LOCAL FRONT$,BEHIND$,I
   LET SW=0
   LET X$=XX$
   LET X$=TRANSRESERVED$(X$)
   IF POS(X$,CHR$(34))>0 THEN                                                   !'「IF A$="THEN" THEN」
      FOR I=1 TO LEN(X$)
         IF X$(I:I)=CHR$(34) THEN LET SW=1-SW
         IF SW=0 AND X$(I:I+3)="THEN" THEN
            LET FRONT$=TRIM$(X$(1:I-1))
            LET BEHIND$=TRIM$(X$(I+4:LEN(X$)))
            EXIT FOR
         END IF
      NEXT I
   ELSE
      LET FRONT$=TRIM$(FRONTSTRING$(X$,"THEN"))
      LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"THEN"))
   END IF
   LET FRONT$=TRANSCO$(FRONT$)
   LET FRONT$=TRANSARRAYNAME$(FRONT$)
   LET FRONT$=TRANSFUNC$(FRONT$)
   IF POS(FRONT$,"ELSEIF")>0 THEN
      CALL CPRINT("}")
      LET FRONT$=TRANSFORM$(FRONT$,"ELSEIF ","else if (")
      LET FRONT$=TRANSFORM$(FRONT$,"ELSEIF(","else if ((")
   ELSE
      LET FRONT$=TRANSFORM$(FRONT$,"IF ","if (")
      LET FRONT$=TRANSFORM$(FRONT$,"IF(","if ((")
   END IF
   CALL CPRINT(LLCASE$(FRONT$)&")")
   CALL CPRINT("{")
   IF BEHIND$<>"" THEN                                                          !'THEN区以降
      IF POS(BEHIND$,"ELSE")>0 THEN                                             !'ELSE区があるなら
         LET FRONT$=BETWEENSTRING$(X$,"THEN","ELSE")                            !'THEN区とELSE区の間
         LET BEHIND$=BEHINDSTRING$(X$,"ELSE")                                   !'ELSE区以降
         CALL MAIN(FRONT$)                                                      !'再帰処理
         CALL CPRINT("}")
         CALL CPRINT("else")
         CALL CPRINT("{")
         CALL MAIN(BEHIND$)
         CALL CPRINT("}")
      ELSE
         CALL MAIN(BEHIND$)
         CALL CPRINT("}")
      END IF
   END IF
END SUB

SUB COMMAND_ELSE(X$)
   IF POS(X$,"ELSE")>0 THEN
      CALL CPRINT("}")
      CALL CPRINT("else")
      CALL CPRINT("{")
   END IF
END SUB

SUB COMMAND_OPEN(X$)
   LET X$=TRANSRESERVED$(X$)
   LET NAME$=TRIM$(BEHINDSTRING$(X$,"NAME"))
   IF POS(X$,",ACCESS")>0 THEN
      LET NAME$=TRIM$(BETWEENSTRING$(X$,"NAME",",ACCESS"))
      IF POS(X$,"INPUT")>0 THEN
         LET IO$="if"                                                           !'読み込みストリーム
         !' OPENMODE$=",ios::in"
      END IF
      IF POS(X$,"OUTPUT")>0 THEN
         LET IO$="of"                                                           !'書き込みストリーム
         !' OPENMODE$=",ios::out"
      END IF
      IF POS(X$,"OUTIN")>0 THEN
         LET IO$="f"                                                            !'読み書きストリーム
         LET OPENMODE$=",ios::in | ios::out"                                    !'●その他
      END IF
   ELSE
      LET IO$="f"
      LET OPENMODE$=",ios::in | ios::out"                                       !'●その他
   END IF
   LET NUM$=TRIM$(BETWEENSTRING$(X$,"#",":"))                                   !'経路番号
   IF POS(NAME$,"$")>0 THEN LET NAME$=TRANSFORM$(NAME$,"$","_string.c_str()")
   CALL CPRINT(IO$&"stream fs"&NUM$&"("&LLCASE$(NAME$)&OPENMODE$&");")
   !' CALL CPRINT(IO$&"stream fs"&NUM$&";")
   !' CALL CPRINT("fs&NUM$&".open("&LLCASE$(NAME$)&OPENMODE$&");")
   CALL CPRINT("if (fs"&NUM$&".fail()){")                                       !'エラー処理
   CALL CPRINT("cout << "&CHR$(34)&"ファイルをオープンできません"&CHR$(34)&" << endl;")
   CALL CPRINT("exit(1);")
   CALL CPRINT("}")
END SUB

SUB COMMAND_CLOSE(X$)
   CALL CPRINT("fs"&NUM$&".close();")
   LET NUM$=""
END SUB

SUB COMMAND_EXIT(X$)
   IF POS(X$,"EXIT SUB")>0 THEN
      CALL CPRINT("return;")
      EXIT SUB
   END IF
   IF POS(X$,"EXIT FUNCTION")>0 THEN
   !' CALL CPRINT("return;")
      EXIT SUB
   END IF
   IF POS(X$,"EXIT DO")>0 OR POS(X$,"EXIT FOR")>0 THEN
      CALL CPRINT("break;")
      EXIT SUB
   END IF
END SUB

SUB COMMAND_END(X$)
!' IF X$="END" THEN
!'    CALL CPRINT("cout << "&CHR$(34)&"Hit Enter Key"&CHR$(34)&" << endl;")
!'    CALL CPRINT("cin.get();")                                                 !'エンターキー入力待ち(ウィンドゥが閉じてしまうのを防ぐ)
!' END IF
   CALL CPRINT("}")
END SUB

SUB COMMAND_RANDOMIZE(X$)
   CALL CPRINT("srand((unsigned)time(NULL));")
END SUB

SUB COMMAND_CALL(XX$)
   LET X$=XX$
   LET X$=TRANSRESERVED$(X$)
   LOCAL I,N,J,K
   LET AA$=""
   LET X$=TRIM$(TRANSFORM$(X$,"CALL",""))
   IF LITERAL(X$,"$")=0 THEN LET X$=TRANSFORM$(X$,"$","_string")
   IF POS(X$,"(")=0 THEN                                                        !'引数なし
      CALL CPRINT(LCASE$(X$)&"();")
      EXIT SUB
   END IF
   LET FRONT$=TRIM$(FRONTSTRING$(X$,"("))
   LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"("))
   CALL SPLIT2(BEHIND$(1:LEN(BEHIND$)-1),C$,N)
   FOR I=1 TO N
      IF C$(I)<>"" THEN
         LET FL=0
         FOR J=1 TO LEN(C$(I))
            IF POS("+-*/^",C$(I)(J:J))>0 OR POS("0123456789",C$(I)(1:1))>0 THEN LET FL=1   !'引数が数式、定数なら
         NEXT J
         LET C$(I)=TRANSARRAYNAME$(C$(I))
         IF POS(C$(I),CHR$(34))=0 AND POS(C$(I),"&")=0 THEN
            LET BB$=C$(I)
            LET C$(I)=TRANSFUNC$(C$(I))                                         !'関数名変換で変換されたか
            IF BB$<>C$(I) OR FL=1 THEN                                          !'引数が関数なら
               LET VA_CALL_COUNT=VA_CALL_COUNT+1
               LET BB$=LCASE$(C$(I))
               LET C$(I)="dummy"&STR$(VA_CALL_COUNT)                            !'ダミー変数宣言
               CALL CPRINT(TYPE$&C$(I)&"="&BB$&";")
            END IF
         ELSE                                                                   !'文字定数指定なら
            LET BB$=C$(I)
            LET VA_CALL_COUNT=VA_CALL_COUNT+1
            LET C$(I)="dummy"&STR$(VA_CALL_COUNT)                               !'ダミー変数宣言
            CALL CPRINT("string "&C$(I)&"="&LLCASE$(BB$)&";")
         END IF
      END IF
      LET AA$=AA$&C$(I)&","
   NEXT I
   CALL CPRINT(LLCASE$(FRONT$&"("&AA$(1:LEN(AA$)-1)&");"))
END SUB

SUB COMMAND_REM(XX$)
   LOCAL I,FRONT$,BEHIND$
   LET X$=XX$
   LET I=POS(X$,"!")
   LET X$=TRANSFORM$(X$,"!","//")
   IF I=0 THEN
      LET I=POS(X$,"REM ")
      LET X$=TRANSFORM$(X$,"REM ","//")
   END IF
   IF I>1 THEN
      LET FRONT$=TRIM$(X$(1:I-1))                                               !'注釈文字以前
      !'  LET BEHIND$=TRIM$(X$(I:LEN(X$)))                                      !'注釈文字以降
      CALL MAIN(FRONT$)                                                         !'再帰処理
      !'  CALL CPRINT(BEHIND$)
   END IF
END SUB
 

Re: C++トランスレーター(試作・テスト版)

 投稿者:しばっち  投稿日:2014年 7月16日(水)20時52分56秒
  > No.3433[元記事へ]

続き 4

SUB COMMAND_STOP(X$)
   CALL CPRINT("exit(0);")
   !'CALL CPRINT("exit(1);")
END SUB

SUB COMMAND_SWAP(X$)
   LET X$=TRANSRESERVED$(X$)
   LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"SWAP "))
   LET BEHIND$=TRANSARRAYNAME$(BEHIND$)
   LET BEHIND$=TRANSFORM$(BEHIND$,"$","_string")
   CALL CPRINT("swap("&LCASE$(BEHIND$)&");")
   !'CALL CPRINT("cswap("&LCASE$(BEHIND$)&");")
END SUB

SUB SCAN$(A$(),NN)                                                              !'使用変数名の探索、宣言
   LOCAL I,J,K,N
   LET J=NN
   LET AA$=""
   LET BB$=""
   LET B$=""
   MAT VARIABLE$=NUL$
   MAT VARIABLE_FOR$=NUL$
   MAT VARIABLE_STRING$=NUL$
   MAT VARIABLE_ARRAY$=NUL$
   LET VA_COUNT=0
   LET VA_FOR_COUNT=0
   LET VA_STRING_COUNT=0
   LET VA_ARRAY_COUNT=0
   DO
      LET X$=A$(J)
      IF POS(X$,"!")>0 AND LITERAL(X$,"!")=0 THEN LET X$=FRONTSTRING$(X$,"!")
      IF POS(X$,"REM ")>0 AND LITERAL(X$,"REM ")=0 THEN LET X$=FRONTSTRING$(X$,"REM ")
      IF POS(X$,"DIM ")>0 AND LITERAL(X$,"DIM ")=0 THEN                         !'DIM文より探索
         LET X$=TRANSRESERVED$(X$)
         LET BEHIND$=TRIM$(BEHINDSTRING$(X$,"DIM "))
         CALL SPLIT2(BEHIND$,C$,N)
         FOR K=1 TO N
            LET AA$=TRIM$(LCASE$(FRONTSTRING$(C$(K),"(")))
            LET SAME=0
            FOR I=1 TO VA_ARRAY_COUNT
               IF AA$=VARIABLE_ARRAY$(I) THEN LET SAME=1
            NEXT I
            IF SAME=0 THEN
               LET VA_ARRAY_COUNT=VA_ARRAY_COUNT+1
               LET VARIABLE_ARRAY$(VA_ARRAY_COUNT)=AA$
            END IF
         NEXT K
      END IF
      LET X$=A$(J)
      LET SAME=0
      IF POS(X$,"!")>0 AND LITERAL(X$,"!")=0 THEN LET X$=FRONTSTRING$(X$,"!")
      IF POS(X$,"REM ")>0 AND LITERAL(X$,"REM ")=0 THEN LET X$=FRONTSTRING$(X$,"REM ")
      IF POS(X$,"LET ")>0 AND LITERAL(X$,"LET ")=0 THEN                         !'LET文より探索
         LET K=0
         FOR I=1 TO LEN(X$)
            IF X$(I:I)="=" THEN LET K=K+1
         NEXT I
         IF K=1 THEN
            LET X$=TRIM$(BETWEENSTRING$(X$,"LET ","="))
         ELSE
            LET X$=TRANSFORM$(X$,"LET ","")
         END IF
         IF POS(X$,",")=0 THEN                                                  !'単指定「LET A=5」
            LET X$=LCASE$(TRANSRESERVED$(X$))
            IF POS(X$,"(")=0 THEN
               FOR I=1 TO MAXSIZE
                  IF VARIABLE_STRING$(I)=X$ OR VARIABLE$(I)=X$ OR VARIABLE_FOR$(I)=X$ OR FUNCNAME$(I)=X$ OR VARIABLE_PUBLIC$(I)=X$ OR VARIABLE_ARGUMENT$(I)=X$ OR VARIABLE_ARRAY$(I)=X$ THEN
                     LET SAME=1
                     EXIT FOR
                  END IF
               NEXT  I
               IF SAME=0 THEN
                  IF POS(X$,"$")>0 THEN
                     LET VA_STRING_COUNT=VA_STRING_COUNT+1
                     LET VARIABLE_STRING$(VA_STRING_COUNT)=X$
                  ELSE
                     LET VA_COUNT=VA_COUNT+1
                     LET VARIABLE$(VA_COUNT)=X$
                  END IF
               END IF
            ELSE
               LET X$=FRONTSTRING$(X$,"(")
               FOR I=1 TO VA_ARRAY_COUNT
                  IF VARIABLE_ARRAY$(I)=X$ THEN
                     LET SAME=1
                     EXIT FOR
                  END IF
               NEXT I
               IF SAME=0 THEN
                  LET VA_ARRAY_COUNT=VA_ARRAY_COUNT+1
                  LET VARIABLE_ARRAY$(VA_ARRAY_COUNT)=X$                        !'配列変数名登録
               END IF
            END IF
         ELSE                                                                   !'複数指定「LET A(1,1),B,C=5」
            CALL SPLIT2(X$,C$,N)
            FOR K=1 TO N
               IF POS(C$(K),"=")>0 THEN LET C$(K)=TRIM$(FRONTSTRING$(C$(K),"="))!'複数指定「LET A=1,B=2,C=3」
               IF POS(C$(K),"(")=0 THEN
                  FOR I=1 TO MAXSIZE
                     IF VARIABLE_STRING$(I)=C$(K) OR VARIABLE$(I)=C$(K) OR VARIABLE_FOR$(I)=C$(K) OR FUNCNAME$(I)=C$(K) OR VARIABLE_PUBLIC$(I)=C$(K) OR VARIABLE_ARGUMENT$(I)=C$(K) OR VARIABLE_ARRAY$(I)=X$ THEN
                        LET SAME=1
                        EXIT FOR
                     END IF
                  NEXT  I
                  IF SAME=0 THEN
                     IF POS(C$(K),"$")>0 THEN
                        LET VA_STRING_COUNT=VA_STRING_COUNT+1
                        LET VARIABLE_STRING$(VA_STRING_COUNT)=C$(K)
                     ELSE
                        LET VA_COUNT=VA_COUNT+1
                        LET VARIABLE$(VA_COUNT)=C$(K)
                     END IF
                  END IF
               ELSE
                  LET C$(K)=FRONTSTRING$(C$(K),"(")
                  FOR I=1 TO VA_ARRAY_COUNT
                     IF VARIABLE_ARRAY$(I)=C$(K) THEN
                        LET SAME=1
                        EXIT FOR
                     END IF
                  NEXT I
                  IF SAME=0 THEN
                     LET VA_ARRAY_COUNT=VA_ARRAY_COUNT+1
                     LET VARIABLE_ARRAY$(VA_ARRAY_COUNT)=C$(K)                  !'配列変数名登録
                  END IF
               END IF
            NEXT K
         END IF
      END IF
      LET SAME=0
      LET X$=A$(J)
      IF POS(X$,"!")>0 AND LITERAL(X$,"!")=0 THEN LET X$=FRONTSTRING$(X$,"!")
      IF POS(X$,"REM ")>0 AND LITERAL(X$,"REM ")=0 THEN LET X$=FRONTSTRING$(X$,"REM ")
      IF POS(X$,"FOR ")>0 AND LITERAL(X$,"FOR ")=0 THEN                         !'FOR文より探索
         LET X$=TRIM$(BETWEENSTRING$(X$,"FOR ","="))
         LET X$=LCASE$(TRANSRESERVED$(X$))
         FOR I=1 TO MAXSIZE
            IF VARIABLE_FOR$(I)=X$ OR VARIABLE_STRING$(I)=X$ OR VARIABLE$(I)=X$ OR VARIABLE_PUBLIC$(I)=X$ OR VARIABLE_ARGUMENT$(I)=X$ THEN
               LET SAME=1
               EXIT FOR
            END IF
         NEXT I
         IF SAME=0 THEN
            LET VA_FOR_COUNT=VA_FOR_COUNT+1
            LET VARIABLE_FOR$(VA_FOR_COUNT)=X$
         END IF
      END IF
      LET X$=A$(J)
      IF POS(X$,"!")>0 AND LITERAL(X$,"!")=0 THEN LET X$=FRONTSTRING$(X$,"!")
      IF POS(X$,"REM ")>0 AND LITERAL(X$,"REM ")=0 THEN LET X$=FRONTSTRING$(X$,"REM ")
      IF POS(X$,"INPUT ")>0 AND LITERAL(X$,"INPUT ")=0 THEN                     !'INPUT文より探索
         IF POS(X$,":")>0 THEN
            LET SW=0
            FOR I=1 TO LEN(X$)
               IF X$(I:I)=CHR$(34) THEN LET SW=1-SW
               IF SW=0 AND X$(I:I)=":" THEN EXIT FOR
            NEXT I
            LET X$=X$(I+1:LEN(X$))
         ELSE
            LET X$=TRIM$(BEHINDSTRING$(X$,"INPUT"))
         END IF
         LET X$=LCASE$(TRANSRESERVED$(X$))
         LET SP=0
         FOR I=1 TO LEN(X$)
            IF X$(I:I)="(" THEN
               LET SP=SP+1
               FOR K=I+1 TO LEN(X$)
                  IF X$(K:K)="(" THEN LET SP=SP+1
                  IF SP>0 AND X$(K:K)="," THEN LET X$(K:K)="\"                  !'多次元配列内の「,」置換
                  IF X$(K:K)=")" THEN LET SP=SP-1
                  IF SP=0 THEN EXIT FOR
               NEXT K
            END IF
         NEXT I
         CALL TOKUN(X$,C$,N)                                                    !'区切り「,」で分割
         FOR K=1 TO N
            IF C$(K)<>"" THEN
               LET SAME=0
               IF POS(C$(K),"(")=0 THEN
                  FOR I=1 TO MAXSIZE
                     IF VARIABLE_FOR$(I)=C$(K) OR VARIABLE_STRING$(I)=C$(K) OR VARIABLE$(I)=C$(K) OR VARIABLE_PUBLIC$(I)=C$(K) OR VARIABLE_ARGUMENT$(I)=C$(K) OR VARIABLE_ARRAY$(I)=C$(K) THEN
                        LET SAME=1
                        EXIT FOR
                     END IF
                  NEXT  I
                  IF SAME=0 THEN
                     IF POS(C$(K),"$")>0 THEN
                        LET VA_STRING_COUNT=VA_STRING_COUNT+1
                        LET VARIABLE_STRING$(VA_STRING_COUNT)=C$(K)
                     ELSE
                        LET VA_COUNT=VA_COUNT+1
                        LET VARIABLE$(VA_COUNT)=C$(K)
                     END IF
                  END IF
               END IF
            END IF
         NEXT K
      END IF
      LET X$=A$(J)
      IF POS(X$,"!")>0 AND LITERAL(X$,"!")=0 THEN LET X$=FRONTSTRING$(X$,"!")
      IF POS(X$,"REM ")>0 AND LITERAL(X$,"REM ")=0 THEN LET X$=FRONTSTRING$(X$,"REM ")
      IF POS(X$,"CALL ")>0 AND POS(X$,"(")>0 AND LITERAL(X$,"CALL ")=0 THEN     !'CALL文より探索
         LET SP=0
         FOR I=1 TO LEN(X$)
            IF X$(I:I)="(" THEN
               LET K=I
               FOR N=K+1 TO LEN(X$)
                  IF X$(N:N)="(" THEN LET SP=SP+1
                  IF X$(N:N)=")" THEN LET SP=SP-1
                  IF SP>0 AND X$(N:N)="," THEN LET X$(N:N)="\"
                  IF SP=0 THEN EXIT FOR
               NEXT N
               LET BETWEEN$=X$(K+1:N-1)
               EXIT FOR
            END IF
         NEXT I
         CALL TOKUN(BETWEEN$,C$,N)
         FOR K=1 TO N
            IF C$(K)<>"" THEN
               IF POS(C$(K),"(")>0 THEN LET C$(K)=TRIM$(FRONTSTRING$(C$(K),"("))
               LET SAME=0
               LET FL=0
               IF C$(K)<>"" AND POS("0123456789",C$(K)(1:1))=0 THEN
                  FOR I=1 TO LEN(C$(K))
                     IF POS("+-*/^&"&CHR$(34),C$(K)(I:I))>0 THEN  LET FL=1
                  NEXT I
                  IF FL=0 THEN
                     LET B$=TRANSFUNC$(C$(K))
                     IF B$<>C$(K) THEN LET FL=1
                  END IF
                  IF FL=0 THEN
                     LET C$(K)=LCASE$(TRANSRESERVED$(C$(K)))
                     FOR I=1 TO MAXSIZE
                        IF VARIABLE_FOR$(I)=C$(K) OR VARIABLE_STRING$(I)=C$(K) OR VARIABLE$(I)=C$(K) OR VARIABLE_PUBLIC$(I)=C$(K) OR VARIABLE_ARRAY$(I)=C$(K) OR VARIABLE_ARGUMENT$(I)=C$(K) THEN
                           LET SAME=1
                           EXIT FOR
                        END IF
                     NEXT  I
                     IF SAME=0 THEN
                        IF POS(C$(K),"$")>0 THEN
                           LET VA_STRING_COUNT=VA_STRING_COUNT+1
                           LET VARIABLE_STRING$(VA_STRING_COUNT)=C$(K)
                        ELSE
                           LET VA_COUNT=VA_COUNT+1
                           LET VARIABLE$(VA_COUNT)=C$(K)
                        END IF
                     END IF
                  END IF
               END IF
            END IF
         NEXT K
      END IF
      LET J=J+1
   LOOP UNTIL POS(X$,"END")>0 AND POS(X$,"END IF")=0 AND POS(X$,"END SELECT")=0 AND POS(X$,"END WHEN")=0 AND LITERAL(X$,"END")=0
   LET B$=""
   LET AA$=""
   LET BB$=""
   IF VA_COUNT>0 THEN                                                           !'変数名宣言、初期化
      LET B$=TYPE$
      FOR I=1 TO VA_COUNT-1
         IF VARIABLE$(I)<>"" THEN  LET B$=B$&LCASE$(VARIABLE$(I))&"=0,"
      NEXT I
      IF VARIABLE$(VA_COUNT)<>"" THEN LET B$=B$&LCASE$(VARIABLE$(VA_COUNT))&"=0;" ELSE LET B$=B$(1:LEN(B$)-1)&";"
   END IF
   IF VA_FOR_COUNT>0 THEN                                                       !'FOR文での使用変数名宣言、初期化
      LET BB$="double "                                                         !'仕様変更
      !'  LET BB$="int "
      FOR I=1 TO VA_FOR_COUNT-1
         IF VARIABLE_FOR$(I)<>"" THEN LET BB$=BB$&LCASE$(VARIABLE_FOR$(I))&"=0,"
      NEXT I
      IF VARIABLE_FOR$(VA_FOR_COUNT)<>"" THEN LET BB$=BB$&LCASE$(VARIABLE_FOR$(VA_FOR_COUNT))&"=0;" ELSE LET BB$=BB$(1:LEN(BB$)-1)&";"
   END IF
   IF VA_STRING_COUNT>0 THEN                                                    !'文字列変数名宣言、初期化
      LET AA$="string "
      FOR I=1 TO VA_STRING_COUNT-1
         LET AA$=AA$&LCASE$(VARIABLE_STRING$(I))&"="&CHR$(34)&CHR$(34)&","
      NEXT I
      LET AA$=AA$&LCASE$(VARIABLE_STRING$(VA_STRING_COUNT))&"="&CHR$(34)&CHR$(34)&";"
   END IF
   IF B$<>"" THEN CALL CPRINT(B$)
   IF BB$<>"" THEN CALL CPRINT(BB$)
   IF AA$<>"" THEN
      LET AA$=TRANSFORM$(AA$,"$","_string")
      CALL CPRINT(AA$)
   END IF
   IF B$<>"" OR BB$<>"" OR AA$<>"" THEN CALL CPRINT("")
END SUB

SUB CPRINT(X$)                                                                  !'簡易整形&表示
   IF POS(X$,"{")>0 AND POS(X$,"{}")=0 AND POS(X$,"{"&CHR$(34)&CHR$(34)&"}")=0 AND LITERAL(X$,"{")=0 THEN
      PRINT REPEAT$(" ",CTAB*4);
      LET CTAB=CTAB+1
   ELSEIF POS(X$,"}")>0 AND POS(X$,"{}")=0 AND POS(X$,"{"&CHR$(34)&CHR$(34)&"}")=0 AND LITERAL(X$,"}")=0 THEN
      LET CTAB=CTAB-1
      IF CTAB<0 THEN LET CTAB=0
      PRINT REPEAT$(" ",CTAB*4);
   ELSE
      PRINT REPEAT$(" ",CTAB*4);
   END IF
   IF POS(X$,"null")>0 AND LITERAL(X$,"null")=0 THEN LET X$=TRANSFORM$(X$,"null","NULL")
   PRINT TRIM$(X$)
END SUB
END

EXTERNAL  SUB SPLIT(X$,C$(),N)                                                  !'PRINT文抽出ルーチン(偶数番目が文字定数)
OPTION ARITHMETIC NATIVE                                                        !'A;"ABC";B;"DEF" → C$(1)=A; C$(2)="ABC" C$(3)=;B;  C$(4)="DEF"
MAT C$=NUL$                                                                     !'"ABC";B;C;"DEF" → C$(1)="" C$(2)="ABC" C$(3)=;B;C; C$(4)="DEF"
LET N=1
FOR I=1 TO LEN(X$)
   IF X$(I:I)=CHR$(34) THEN
      IF MOD(N,2)=0 THEN
         LET C$(N)=C$(N)&X$(I:I)
         LET N=N+1
      ELSE
         LET N=N+1
         LET C$(N)=C$(N)&X$(I:I)
      END IF
   ELSE
      LET C$(N)=C$(N)&X$(I:I)
   END IF
NEXT I
END SUB

EXTERNAL  SUB SPLIT2(X$,C$(),N)                                                 !'抽出ルーチン「,」区切り
OPTION ARITHMETIC NATIVE                                                        !'A,B(1,1),"A,B" → A
LET SP=0                                                                        !'                  B(1,1)
MAT C$=NUL$                                                                     !'                  "A,B"
LET N=0
LET SW=0
FOR I=1 TO LEN(X$)
   IF I=1 OR X$(I:I)="," THEN
      IF I=1 THEN LET K=1 ELSE LET K=I+1
      FOR J=I+1 TO LEN(X$)
         IF X$(J:J)="(" THEN LET SP=SP+1
         IF X$(J:J)=")" THEN LET SP=SP-1
         IF X$(J:J)=CHR$(34) THEN LET SW=1-SW
         IF SW=0 AND SP=0 AND X$(J:J)="," OR J=LEN(X$) THEN EXIT FOR
      NEXT  J
      LET N=N+1
      IF J=LEN(X$) THEN LET J=J+1
      LET C$(N)=TRIM$(X$(K:J-1))
      LET I=J-1
   END IF
NEXT I
END SUB

EXTERNAL FUNCTION TRANSFORM$(A$,B$,C$)                                          !'置換ルーチン TRANSFORM$("AAABAB","A","a")="aaaBaB"
OPTION ARITHMETIC NATIVE
DO                                                                              !'複数個に対応するためループ
   LET N=POS(A$,B$)
   IF N>0 THEN
      LET L$=LEFT$(A$,N-1)
      LET R$=RIGHT$(A$,LEN(A$)-LEN(B$)-N+1)
      LET A$=L$&C$&R$
   END IF
LOOP UNTIL N=0
LET TRANSFORM$=A$
END FUNCTION

EXTERNAL FUNCTION TRANSFORM2$(A$,B$,C$)                                         !'置換ルーチン
OPTION ARITHMETIC NATIVE
LET I=0
DO
   LET I=I+1
   IF A$(I:I)=CHR$(34) THEN LET SW=1-SW
   IF SW=0 AND A$(I:I+LEN(B$)-1)=B$ THEN
      LET A$(I:I+LEN(B$)-1)=""
      LET A$(I:I-1)=C$
   END IF
LOOP UNTIL LEN(A$)<=I
LET TRANSFORM2$=A$
END FUNCTION

EXTERNAL FUNCTION FRONTSTRING$(A$,B$)                                           !'前方取り出し FRONTSTRING$("ABCDEFG","DE")="ABC"
OPTION ARITHMETIC NATIVE
LET N=POS(A$,B$)
IF N=0 THEN
   LET FRONTSTRING$=A$
ELSE
   LET FRONTSTRING$=A$(1:N-1)
END IF
END FUNCTION

EXTERNAL FUNCTION BEHINDSTRING$(A$,B$)                                          !'後方取り出し BEHINDSTRING$("ABCDEFG","DE")="FG"
OPTION ARITHMETIC NATIVE
LET N=POS(A$,B$)
IF N=0 THEN
   LET BEHINDSTRING$=A$
ELSE
   LET BEHINDSTRING$=A$(N+LEN(B$):LEN(A$))
END IF
END FUNCTION

EXTERNAL  FUNCTION BETWEENSTRING$(X$,B$,A$)                                     !'指定間取り出し BETWEENSTRING$("ABCDEFG","B","F")="CDE"
OPTION ARITHMETIC NATIVE
LET K$=BEHINDSTRING$(X$,B$)
LET BETWEENSTRING$=FRONTSTRING$(K$,A$)
END FUNCTION

EXTERNAL SUB TOKUN(A$,X$(),K)                                                   !'抽出ルーチン「,」区切り
OPTION ARITHMETIC NATIVE
LET B$=A$
MAT X$=NUL$
LET K=0
DO
   LET N=POS(B$,",")
   IF N>0 THEN
      LET K=K+1
      LET X$(K)=TRIM$(FRONTSTRING$(B$,","))
      LET B$=BEHINDSTRING$(B$,",")
   END IF
LOOP UNTIL N=0
LET K=K+1
IF RIGHT$(B$,1)="," THEN
   LET X$(K)=TRIM$(LEFT$(B$,LEN(B$)-1))
ELSE
   LET X$(K)=TRIM$(B$)
END IF
END SUB
 

Re: C++トランスレーター(試作・テスト版)

 投稿者:しばっち  投稿日:2014年 7月16日(水)20時53分25秒
  > No.3434[元記事へ]

続き 5

EXTERNAL  FUNCTION TRANSFUNC$(X$)                                               !'関数名変換ルーチン SQR(X) → sqrt(x)
OPTION ARITHMETIC NATIVE
RESTORE
DO
   READ IF MISSING THEN EXIT DO:S$,T$
   LET FL=0
   FOR I=1 TO FC
      IF POS(LCASE$(X$),FUNCNAME$(I))>0 THEN                                    !'FUNCTION定義で同一関数名ではない
         LET FL=1
         IF FUNCNAMENOARG$(I)<>"" THEN                                          !'DEF文定義の引数なしの場合「()」をつける DEF F=X^2 , LET Y=Y+F → =y=y+f();
            LET X$=TRANSFORM$(X$,UCASE$(FUNCNAMENOARG$(I)(1:LEN(FUNCNAMENOARG$(I))-2)),"#")
            LET X$=TRANSFORM$(X$,"#",FUNCNAMENOARG$(I))
         END IF
      END IF
   NEXT I
   IF FL=0 THEN
      DO WHILE POS(X$,S$)>0 AND LITERAL(X$,S$)=0
         LET X$=TRANSFORM$(X$,S$,T$)
      LOOP
      LET SS$=S$(1:LEN(S$)-1)&" ("
      DO WHILE POS(X$,SS$)>0 AND LITERAL(X$,SS$)=0
         LET X$=TRANSFORM$(X$,SS$,T$)
      LOOP
   END IF
LOOP
DO
   LET FL=0
   !'IF POS(X$,"POS(")>0 THEN
   !'   LET I=POS(X$,"POS(")
   !'   LET X$=TRANSFORM$(X$,"POS(","")
   !'   LET X$=TRANSFORM$(X$,",",".find(")
   !'   LET I=POS(X$,")",I)
   !'   LET X$(I:I)=",0)"
   !'   LET FL=1
   !'END IF
   !' IF POS(X$,"VAL(")>0 AND POS(X$,"BVAL(")=0 THEN
   !'    LET X$=TRANSFORM$(X$,"VAL(","atod(")
   !'    LET X$=TRANSFORM$(X$,")",".c_str(}}")
   !'    LET X$=TRANSFORM$(X$,"}",")")
   !'    LET FL=1
   !' END IF
   IF POS(X$,"^")>0 AND LITERAL(X$,"^")=0 THEN
      DO WHILE POS(X$,"^")>0
         LET N=POS(X$,"^")
         LET SP=0
         FOR I=N-1 TO 1 STEP -1
            IF X$(I:I)=")" OR X$(I:I)="]" THEN LET SP=SP+1
            IF SP>0 AND (X$(I:I)="(" OR X$(I:I)="[") THEN LET SP=SP-1
            IF POS("=,+-*/(<>[ ",X$(I:I))>0 AND SP=0 AND (I<>N-1 OR X$(I:I)<>" ") THEN
               IF POS("(",X$(I:I))>0 AND POS("+-*/=,",X$(I-1:I-1))>0 OR POS("<>=,+-*/ ",X$(I:I))>0 OR POS("abcdefghijklmnopqrstuvwxyz",LCASE$(X$(I-1:I-1)))=0 OR POS("([",X$(I:I))>0 AND POS("abcdefghijklmnopqrstuvwxyz",LCASE$(X$(I-1:I-1)))>0 AND (X$(N-1:N)<>")^" AND X$(N-1:N)<>"]^") THEN
                  IF X$(N-1:N)=")^" OR X$(N-1:N)="]^" THEN
                     IF (POS("+-*/ ",X$(I-1:I-1))>0 OR X$(I-1:I)="((") AND POS("abcdefghijklmnopqrstuvwxyz",LCASE$(X$(I-1:I-1)))=0 THEN
                        LET X$(I:I-1)="pow("
                     ELSE
                        LET X$(I+1:I)="pow("
                     END IF
                  ELSE
                     LET X$(I+1:I)="pow("
                  END IF
                  EXIT FOR
               END IF
            ELSEIF SP=0 AND I=1 AND POS(",(=+-*/[ ",X$(I:I))=0 THEN
               LET X$="pow("&X$
               EXIT FOR
            END IF
         NEXT I
         LET N=POS(X$,"^")
         LET SP=0
         FOR I=N+1 TO LEN(X$)
            IF X$(I:I)="(" OR X$(I:I)="[" THEN LET SP=SP+1
            IF SP>0 AND (X$(I:I)=")" OR X$(I:I)="]") THEN LET SP=SP-1
            IF POS(",)+-*/]<> ",X$(I:I))>0 AND SP=0 AND (I<>N+1 OR X$(I:I)<>" ") THEN
               LET X$(I:I-1)=")"
               EXIT FOR
            ELSEIF SP=0 AND I=LEN(X$) AND POS(",)+-*/] ",X$(I:I))=0 THEN
               LET X$=X$&")"
            END IF
         NEXT I
         LET X$(N:N)=","
      LOOP
      LET FL=1
   END IF
   IF POS(X$,"LEN(")>0 THEN
      LET I=POS(X$,"LEN(")
      LET X$=TRANSFORM$(X$,"BLEN(","")
      LET X$=TRANSFORM$(X$,"LEN(","")
      LET I=POS(X$,")",I)
      LET X$(I:I)=""
      LET X$(I:I)=".size()"
      LET FL=1
   END IF
   !' IF POS(X$,"ANGLE(")>0 THEN
   !'    LET I=POS(X$,"ANGLE(")
   !'    LET J=POS(X$,",",I)
   !'    LET AA$=X$(I+6:J-1)
   !'    LET K=POS(X$,")",J)
   !'    LET BB$=X$(J+1:K-1)
   !'    LET X$=TRANSFORM$(X$,"ANGLE(","atan2(")
   !'    LET X$=TRANSFORM$(X$,AA$,REPEAT$("#",LEN(AA$)))
   !'    LET X$=TRANSFORM$(X$,BB$,REPEAT$("&",LEN(BB$)))
   !'    LET X$=TRANSFORM$(X$,REPEAT$("#",LEN(AA$)),BB$)
   !'    LET X$=TRANSFORM$(X$,REPEAT$("&",LEN(BB$)),AA$)
   !'    LET FL=1
   !' END IF
   !' IF POS(X$,"LEFT$(")>0 THEN
   !'    LET I=POS(X$,"LEFT$(")
   !'    LET X$=TRANSFORM$(X$,"LEFT$(","")
   !'    LET I=POS(X$,",",I)
   !'    LET X$(I:I)=".substr(0,"
   !'    LET FL=1
   !' END IF
   !' IF POS(X$,"RIGHT$(")>0 THEN
   !'    LET I=POS(X$,"RIGHT$(")
   !'    LET BETWEEN$=BETWEENSTRING$(X$,"RIGHT$(",",")
   !'    LET NUM$=BETWEENSTRING$(X$,",",")")
   !'    LET X$=TRANSFORM$(X$,"RIGHT$(","")
   !'    LET I=POS(X$,",",I)
   !'    LET X$(I:I)=".substr("&BETWEEN$&".size()-"&NUM$&","
   !'    LET FL=1
   !' END IF
   !' IF POS(X$,"MID$(")>0 THEN
   !'    DIM C$(3)
   !'    LET J=POS(X$,"MID$(")
   !'    LET SP=0
   !'    FOR I=J+5 TO LEN(X$)
   !'       IF X$(I:I)="," THEN LET SP=SP+1
   !'       IF SP=2 AND X$(I:I)=")" THEN EXIT FOR
   !'    NEXT I
   !'    CALL TOKUN(X$(J:I),C$)
   !'    LET X$=TRANSFORM$(X$,"MID$("&C$(1),C$(1)&".subst("&C$(2)&"-1,"&C$(3)&")")
   !'    LET FL=1
   !' END IF
   !' IF POS(X$,"BITAND(")>0 THEN
   !'    LET I=POS(X$,"BITAND(")
   !'    LET I=POS(X$,",",I)
   !'    LET X$(I:I)="&"
   !'    LET X$=TRANSFORM$(X$,"BITAND","")
   !'    LET FL=1
   !' END IF
   !' IF POS(X$,"BITOR(")>0 THEN
   !'    LET I=POS(X$,"BITOR(")
   !'    LET I=POS(X$,",",I)
   !'    LET X$(I:I)="|"
   !'    LET X$=TRANSFORM$(X$,"BITOR","")
   !'    LET FL=1
   !' END IF
   !' IF POS(X$,"BITXOR(")>0 THEN
   !'    LET I=POS(X$,"BITXOR(")
   !'    LET I=POS(X$,",",I)
   !'    LET X$(I:I)="^"
   !'    LET X$=TRANSFORM$(X$,"BITXOR","")
   !'    LET FL=1
   !' END IF
   !' IF POS(X$,"BITNOT(")>0 THEN
   !'    LET X$=TRANSFORM$(X$,"BITNOT","~")
   !'    LET FL=1
   !' END IF
   IF POS(X$,"&&")=0 AND POS(X$,"&")>0 AND LITERAL(X$,"&")=0 THEN
      LET X$=TRANSFORM$(X$,"&","+")
      LET FL=1
   END IF
   LET I=POS(X$,"/")
   IF I>0 THEN
      LET SW=0
      LET I=0
      DO
         LET I=I+1
         IF X$(I:I)=CHR$(34) THEN LET SW=1-SW
         IF SW=0 AND X$(I:I)="/" AND X$(I:I+8)<>"/(double)" THEN
            LET K=0
            LET L=0
            FOR J=I-1 TO 1 STEP -1                                              !'被除数
               IF POS("0123456789",X$(J:J))>0 THEN                              !'定数か
                  LET K=1
               END IF
               IF POS("abcdefghijklmnopqrstuvwxyz",LCASE$(X$(J:J)))>0 THEN      !'変数、関数なら
                  LET K=0                                                       !'変数名 A123など
                  EXIT FOR
               END IF
               IF POS("= ;,+-*/<>()[]",X$(J:J))>0 AND (J<>I-1 OR X$(J:J)<>" ") THEN EXIT FOR
            NEXT J
            FOR J=I+1 TO LEN(X$)                                                !'除数
               IF POS("0123456789",X$(J:J))>0 THEN
                  LET L=1
               END IF
               IF POS("abcdefghijklmnopqrstuvwxyz",LCASE$(X$(J:J)))>0 THEN      !'変数、関数なら
                  LET L=0
                  EXIT FOR
               END IF
               IF POS(" ;,+-*/<>()[]",X$(J:J))>0 AND (J<>I+1 OR X$(J:J)<>" ") THEN EXIT FOR
            NEXT J
            IF K=1 AND L=1 THEN                                                 !'共に定数なら
               LET X$(I:I)="/(double)"                                          !'double型へキャスト
               LET I=I+8
               LET FL=1
            END IF
         END IF
      LOOP UNTIL I>=LEN(X$)
   END IF
   IF POS(X$,"TIME")>0 AND LITERAL(X$,"TIME")=0 AND POS(X$,"TIME$")=0 THEN
      LET X$=TRANSFORM$(X$,"TIME","(unsigned)time(NULL)")
      LET FL=1
   END IF
   IF POS(X$,CHR$(34)&CHR$(34)&CHR$(34)&CHR$(34))>0 THEN                        !'「PRINT """";A$;""""」
      LET X$=TRANSFORM$(X$,CHR$(34)&CHR$(34)&CHR$(34)&CHR$(34),CHR$(39)&CHR$(34)&CHR$(39))
      LET FL=1
   END IF
LOOP UNTIL FL=0
IF LITERAL(X$,"$")=0 THEN LET X$=TRANSFORM$(X$,"$","_string")
LET TRANSFUNC$=X$
DATA "ABS(","abs("                                                              !'関数名置換リスト BASIC → C/C++
DATA "ARG(","arg("
DATA "ANGLE(","angle("
DATA "ASIN(","asin("
DATA "ATN(","atan("
DATA "ACOS(","acos("
DATA "ACSC(","asin(1.0/"                                                        !'「"A・CSC("」
DATA "ASEC(","acos(1.0/"
DATA "ACOT(","atan(1.0/"
DATA "ATANH(","atanh("
DATA "ASINH(","asinh("
DATA "ACOSH(","acosh("
DATA "ASECH(","asech("
DATA "ACSCH(","acsch("
DATA "ACOTH(","acoth("
DATA "SUBSTR$(","substr("                                                       !'「"SUB・STR$("」「"SU・BSTR$("」
DATA "BSTR$(","bstr("
DATA "BVAL(","bval("
DATA "BITAND(","bit_and("
DATA "BITOR(","bit_or("
DATA "BITXOR(","bit_xor("
DATA "BITNOT(","bit_not("                                                       !'「"BIT・NOT("」
DATA "BITIMP(","bit_imp("
DATA "CEIL(","ceil("
DATA "CHR$(","chr("
DATA "COMB(","comb("
DATA "CONJ(","conj("
DATA "COMPLEX(","complex<double>("
DATA "COS(","cos("
DATA "COT(","1.0/tan("
DATA "CSC(","1.0/sin("
DATA "CSCH(","1.0/sinh("
DATA "COSH(","cosh("
DATA "COTH(","1.0/tanh("
DATA "CBRT(","cbrt("                                                            !'立方根 X^(1/3)
DATA "DEG(","(180.0/pi*"
DATA "DENOM(","denominator("
DATA "EXP(","exp("
DATA "ERF(","erf("                                                              !'誤差関数
DATA "ERFC(","erfc("                                                            !'1-erf(x)
DATA "EPS(","eps("
DATA "FACT(","fact("
DATA "FP(","fp("
DATA "LGAMMA(","lgamma("                                                        !'対数ガンマ関数「"L・GAMMA("」
DATA "GAMMA(","tgamma("                                                         !'ガンマ関数
DATA "GCD(","gcd("
DATA "HYPOT(","hypot("                                                          !'HYPOT(X,Y)=SQR(X*X+Y*Y)
DATA "IP(","ip("
DATA "INT(","floor("
DATA "IM(","imag("
DATA "J0(","j0("                                                                !'ベッセル関数 J0(X)
DATA "J1(","j1("                                                                !'ベッセル関数 J1(X)
DATA "JN(","jn("                                                                !'ベッセル関数 JN(N,X)
DATA "LCM(","lcm("
DATA "LOG(","log("
DATA "LOG2(","log2("
DATA "LOG10(","log10("
DATA "LTRIM$(","ltrim("
DATA "LCASE$(","lcase("
DATA "LEFT$(","left("
DATA "MOD(","fmod("
DATA "MID$(","mid("
DATA "MAX(","fmax("
DATA "MIN(","fmin("
!'DATA "MAX(","tmax("
!'DATA "MIN(","tmin("
DATA "NOT(","(! "
DATA "NUMER(","numerator("
DATA "ORD(","ord("
DATA "PERM(","perm("
DATA "POS(","pos("
DATA "RND","rand()/32768.0"
DATA "ROUND(","round("
DATA "REMAINDER(","fmod("
DATA "RAD(","(pi/180.0*"
DATA "RE(","real("
DATA "RTRIM$(","rtrim("
DATA "RIGHT$(","right("
DATA "REPEAT$(","repeat("
DATA "SPC(","spc("
DATA "SGN(","sgn("
DATA "SQR(","sqrt("
DATA "SIN(","sin("
DATA "SEC(","1.0/cos("
DATA "SINH(","sinh("
DATA "SECH(","1.0/cosh("
!'DATA "STR$(","toString<double>("
DATA "STR$(","str("
DATA "UBOUND(","ubound("
DATA "TRUNCATE(","truncate("
DATA "TAN(","tan("
DATA "TANH(","tanh("
DATA "TAB(","tab("
DATA "UCASE$(","ucase("
DATA "VAL(","val("
DATA "Y0(","y0("                                                                !'ベッセル関数 Y0(X)
DATA "Y1(","y1("                                                                !'ベッセル関数 Y1(X)
DATA "YN(","yn("                                                                !'ベッセル関数 YN(N,X)
END FUNCTION

EXTERNAL  FUNCTION TRANSCO$(A$)                                                 !'条件式変換
OPTION ARITHMETIC NATIVE
LET S$="_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
LET I=POS(A$,"AND")
IF I>0 AND POS(S$,A$(I-1:I-1))=0 AND POS(S$,A$(I+3:I+3))=0 THEN LET A$=TRANSFORM2$(A$,"AND"," && ")
LET I=POS(A$,"OR")
IF I>0 AND POS(S$,A$(I-1:I-1))=0 AND POS(S$,A$(I+2:I+2))=0 THEN LET A$=TRANSFORM2$(A$,"OR"," || ")
IF POS(A$,"<=")>0 THEN LET A$=TRANSFORM2$(A$,"=<","<=")
IF POS(A$,"=>")>0 THEN LET A$=TRANSFORM2$(A$,"=>",">=")
IF POS(A$,"<=")=0 AND POS(A$,">=")=0 AND POS(A$,"=")>0 THEN
   LET A$=TRANSFORM2$(A$,"=","\")                                               !'無限ループ抑制
   LET A$=TRANSFORM2$(A$,"\","==")
END IF
IF POS(A$,"<>")>0 THEN LET A$=TRANSFORM2$(A$,"<>","!=")
IF POS(A$,"><")>0 THEN LET A$=TRANSFORM2$(A$,"><","!=")
LET TRANSCO$=A$
END FUNCTION

EXTERNAL  FUNCTION TRANSRESERVED$(X$)                                           !'C/C++予約語名変換("_"アンダーバー付加)
OPTION ARITHMETIC NATIVE
RESTORE
DO
   READ IF MISSING THEN EXIT DO:A$
   LET I=POS(X$,A$)
   IF LITERAL(X$,A$)=0 AND (I>0 AND POS(" (),+-*/=<>",X$(I-1:I-1))>0) OR I=1 THEN
      LET X$=TRANSFORM2$(X$,A$,"_"&LCASE$(A$))
   END IF
LOOP
LET TRANSRESERVED$=X$
DATA ALIGNOF,ALIGNAS,ASM,AUTO,BOOL,BREAK,CATCH,CHAR,CLASS,CONST,CONSTEXPR,CONTINUE,DECLTYPE,DEFAULT,DELETE,DOUBLE
DATA ENUM,EXPLICIT,EXPORT,FALSE,FINAL,FLOAT,FRIEND,INLINE,LONG,MUTABLE,NAMESPACE,NEW,OPERATOR,OVERRIDE
DATA PRIVATE,PROTECTED,REGISTER,SHORT,SIGNED,SIZEOF,STATIC,STRUCT,SWITCH
DATA TEMPLATE,THIS,THROW,TRUE,TRY,TYPEDEF,TYPEID,TYPENAME,NOEXCEPT,NULLPTR,USING,UNION,UNSIGNED,VIRTUAL,VOID,VOLATILE
DATA XOR,RESTRICT
!'DATA COMPL,EXTERN
END FUNCTION

EXTERNAL  FUNCTION TRANSARRAYNAME$(X$)                                          !'配列変数名変換 SQR(A(10)) → SQR(a[10])
OPTION ARITHMETIC NATIVE
LET X$=TRIM$(X$)
LET I=0
DO
   LET I=POS(X$,"(",I+1)
   IF I=0 THEN EXIT DO
   RESTORE
   LET FL=0
   DO
      READ IF MISSING THEN EXIT DO:FUNC$
      IF LEN(FUNC$)<=I AND X$(I-LEN(FUNC$)+1:I)=FUNC$ THEN
         LET FL=1
         IF FUNC$=" (" AND POS("abcdefghijklmnopqrstuvwxyz",LCASE$(X$(I-2:I-2)))>0 THEN   !' A (N) → a[n]
            LET X$(I-1:I-1)=""
            LET FL=0
         ELSE
            EXIT DO
         END IF
      END IF
      IF FUNC$(LEN(FUNC$):LEN(FUNC$))="(" THEN
         LET S$=FUNC$(1:LEN(FUNC$)-1)&" ("
         IF LEN(S$)<=I AND X$(I-LEN(S$)+1:I)=S$ THEN
            LET FL=1
            EXIT DO
         END IF
      END IF
   LOOP
   IF FL=0 THEN
      FOR J=1 TO FC
         IF LEN(FUNCNAME$(J))<=I AND LCASE$(X$(I-LEN(FUNCNAME$(J)):I))=FUNCNAME$(J)&"(" THEN
            LET FL=1
            EXIT FOR
         END IF
      NEXT J
   END IF
   IF I>1 AND (X$(I-1:I)="=("  OR X$(I-1:I)="^(") OR X$(1:1)="(" THEN LET FL=1
   LET SP=0
   IF FL=0 THEN
      IF X$(I:I)="(" THEN LET SP=SP+1
      LET X$(I:I)="["
      LET J=I
      DO
         LET J=J+1
         IF X$(J:J)="(" THEN LET SP=SP+1
         IF X$(J:J)=")" THEN  LET SP=SP-1
         IF SP=0 THEN
            LET X$(J:J)="]"
            EXIT DO
         END IF
         IF SP=1 AND X$(J:J)="," THEN LET X$(J:J)="]["
      LOOP UNTIL LEN(X$)<=J
   END IF
LOOP
IF TYPE$="complex <double> " THEN
   LET X$=TRANSFORM$(X$,"[","\static_cast<int>(abs(")                           !'int型へ強制キャスト(複素数型)
   LET X$=TRANSFORM$(X$,"\","[")
   LET X$=TRANSFORM$(X$,"]","))\")
   LET X$=TRANSFORM$(X$,"\","]")
ELSE
   LET X$=TRANSFORM$(X$,"[","\static_cast<int>(")                               !'int型へ強制キャスト
   LET X$=TRANSFORM$(X$,"\","[")
   LET X$=TRANSFORM$(X$,"]",")\")
   LET X$=TRANSFORM$(X$,"\","]")
END IF
LET TRANSARRAYNAME$=X$
DATA "ABS(","ACOS(","ANGLE(","ARG(","ASIN(","ATN(","ACSC(","ASEC(","ACOT(","ASECH(","ACSCH(","ACOTH("
DATA "BITAND(","BITNOT(","BITOR(","BITXOR(","BLEN(","SUBSTR$(","BSTR$(","BVAL("
DATA "CEIL(","CHR$(","CONJ(","COS(","COSH(","COT(","COTH(","CON(","CSC(","CSCH(","COMPLEX(","COMB("
DATA "DEG(","DENOM(","DET(","DWORD$(","DOT("
DATA "EXP(","EPS(","FACT(","FP(","GCD("
DATA "IM(","INT(","IP(","LBOUND(","LCASE$(","LEFT$(","LEN(","LOG(","LOG10(","LOG2(","LTRIM$("
DATA "MAX(","MID$(","MIN(","MOD(","NOT(","NUMER(","ORD("
DATA "PACKDBL$(","PERM(","POS(","PIXLX(","PIXELY(","RAD(","RE(","REMAINDER(","REPEAT$(","RIGHT$(","RTRIM$(","ROUND("
DATA "SEC(","SECH(","SGN(","SIN(","SINH(","SQR(","STR$(","SIZE(","SPC("
DATA "TAB(","TAN(","TANH(","TRUNCATE("
DATA "UBOUND(","UCASE$(","USING$(","UNPACKDBL(","VAL(","WORD$(","WORLDX(","WORLDY("
DATA "LGAMMA(","GAMMA(","ERF(","ERFC(","HYPOT(","CBRT(","J0(","J1(","JN(","Y0(","Y1(","YN("
DATA "+(","-(","*(","/("," (","((","IF(","OR(","AND(","||(","&&(","pow("
END FUNCTION

EXTERNAL  FUNCTION TRIM$(X$)                                                    !'空白削除
OPTION ARITHMETIC NATIVE
LET TRIM$=RTRIM$(LTRIM$(X$))
END FUNCTION

EXTERNAL  FUNCTION LITERAL(X$,Y$)                                               !'文字定数か
OPTION ARITHMETIC NATIVE
LET K=POS(X$,Y$)
LET S=0
IF K>0 THEN
   FOR I=K+1 TO LEN(X$)
      IF X$(I:I)=CHR$(34) THEN
         LET S=S+1
         EXIT FOR
      END IF
   NEXT I
   FOR I=K-1 TO 1 STEP -1
      IF X$(I:I)=CHR$(34) THEN
         LET S=S+1
         EXIT FOR
      END IF
   NEXT I
END IF
IF S=2 THEN LET LITERAL=1 ELSE LET LITERAL=0
END FUNCTION

EXTERNAL  FUNCTION LLCASE$(X$)                                                  !'文字定数でないなら小文字化
OPTION ARITHMETIC NATIVE
LET S$=""
LET SW=0
FOR I=1 TO LEN(X$)
   IF X$(I:I)=CHR$(34) THEN LET SW=1-SW
   IF SW=0 THEN
      LET S$=S$&LCASE$(X$(I:I))
   ELSE
      LET S$=S$&X$(I:I)
   END IF
NEXT I
LET LLCASE$=S$
END FUNCTION

EXTERNAL  FUNCTION UUCASE$(X$)
OPTION ARITHMETIC NATIVE
LET S$=""
LET SW=0
FOR I=1 TO LEN(X$)
   IF X$(I:I)=CHR$(34) THEN LET SW=1-SW
   IF SW=0 THEN
      LET S$=S$&UCASE$(X$(I:I))
   ELSE
      LET S$=S$&X$(I:I)
   END IF
NEXT I
LET UUCASE$=S$
END FUNCTION

EXTERNAL  SUB SETUP(X$)                                                         !'手始めに大文字にする 大文字→小文字化(無限ループを抑える)
OPTION ARITHMETIC NATIVE
LET X$=TRIM$(X$)
LET I=POS(X$,"!")
IF I=0 THEN LET I=POS(X$,"REM ")
IF I>0 AND LITERAL(X$,"!")=0 AND LITERAL(X$,"REM ")=0 THEN
   LET BEHIND$=X$(I:LEN(X$))
   LET X$=X$(1:I-1)
END IF
LET X$=UUCASE$(X$)&BEHIND$
END SUB
 

素数生成

 投稿者:GAI  投稿日:2014年 7月17日(木)22時20分0秒
  以下のアルゴリズムで素数を全て見つけることができるという。

1.赤コインを2枚と青コイン1枚をすべて裏向きに置く
2.赤青どちらかが全部表になるまで任意の赤と青を1枚ずつ(計2枚)を同時にひっくり返す
3A.青が先に全部表を向いたときには青を全て裏返して2に戻る
3B.赤が先に全部表になったときには青コインを1枚減らし全て裏返して2に戻る
3C.青赤同時に全部表になったときには各コインの枚数を何らかの方法で出力し、赤コインを1枚増やし、青コインをそれより1枚少ない枚数にして全て裏返し2に戻る
4.必要なだけ繰り返した後、出力から青コインの枚数が1枚となっているときの赤コインの枚数を抽出する

この動きをモニターすることができるプログラムを作って頂きたい。
 

Re: 素数生成

 投稿者:山中和義  投稿日:2014年 7月18日(金)06時41分57秒
  > No.3437[元記事へ]

GAIさんへのお返事です。

> 以下のアルゴリズムで素数を全て見つけることができるという。
>
> 1.赤コインを2枚と青コイン1枚をすべて裏向きに置く
> 2.赤青どちらかが全部表になるまで任意の赤と青を1枚ずつ(計2枚)を同時にひっくり返す
> 3A.青が先に全部表を向いたときには青を全て裏返して2に戻る
> 3B.赤が先に全部表になったときには青コインを1枚減らし全て裏返して2に戻る
> 3C.青赤同時に全部表になったときには各コインの枚数を何らかの方法で出力し、赤コインを1枚増やし、青コインをそれより1枚少ない枚数にして全て裏返し2に戻る
> 4.必要なだけ繰り返した後、出力から青コインの枚数が1枚となっているときの赤コインの枚数を抽出する
>
> この動きをモニターすることができるプログラムを作って頂きたい。

自分自身を除く最大の約数を求めるものですね。1の場合、素数が現れます。(赤色の部分)


LET RR=2 !赤の枚数 ※自然数n≧2
LET BB=1 !青の枚数 ※約数d=n-1
LET R=RR !赤の裏向きの枚数 step.1
LET B=BB !青の裏向きの枚数
DO
   LET M=MIN(R,B) !表にする枚数 step.2
   LET R=R-M !※dをひく
   LET B=B-M
   IF R=0 AND B=0 THEN !step.3C ※dで割り切れる
      PRINT RR;BB !step.4
      !!IF BB=1 THEN PRINT RR;BB !step.4
      LET RR=RR+1 !次へ
      LET BB=RR-1
      LET R=RR
      LET B=BB
   ELSEIF B=0 THEN !step.3A
      LET B=BB
   ELSEIF R=0 THEN !step.3B
      LET BB=BB-1 !※d=n-1,n-2,…,3,2,1
      LET R=RR
      LET B=BB
   END IF
LOOP
END


実行結果

2  1
3  1
4  2
5  1
6  3
7  1
8  4
9  3
10  5
11  1
12  6
13  1
14  7
15  5
16  8
17  1
18  9
19  1
20  10
21  7
22  11
23  1
24  12
25  5
26  13
27  9
28  14
29  1
30  15
31  1
32  16
33  11
34  17
35  7
36  18
37  1
38  19
39  13
40  20
41  1
42  21
43  1
44  22
45  15
46  23
47  1
48  24
49  7
50  25
 :
 :

 

不定方程式の解

 投稿者:山中和義  投稿日:2014年 7月19日(土)09時44分57秒
  問題
水を入れる3つの容器があります。
それぞれ6リットル、10リットル、15リットルずつ入ります。途中に目盛りはありません。
この容器を使って、23リットルの水をはかりなさい。

考察
不定方程式±Ax±By±Cz=Nを考える。

たとえば、10x+15y-6z=23のとき、(x,y,z)=(2,1,2)なので、10,10,15,-6,-6
これより、
  6 10 15   P
 -------------
  0  0  0   0
  0 10  0   0
  0  0  0  10
  0 10  0  10
  0  0  0  20
  0  0 15  20
  0  0  0  35
  6  0  0  29
  0  6  0  29
  6  6  0  23
のような単純な操作で実現できる。操作を式で表すと、10+10+15-6-6=23となる。
この場合、10+10+15=35リットルをサーバーからくみ出しているが、
   S   6 10 15   P
 -------------------
    0   0  0  0   0
  -10   0 ⑩  0   0
    0   6  4  0   0
    0   6  0  0   4
    0   0  6  0   4
   -4   0 ⑩  0   4
    0   6  4  0   4
    0   6  0  0   8
    0   0  0  6   8
   -9   0  0 ⑮   8
    0   0  0  0  23
 -------------------
  -23
とすると、ちょうど23リットルのくみ出しになる。

Ax+By-Cz=N≧max(A,B,C)の非負整数解(x,y,z)が、x+y-z>0なら可能となる。(予想)

その他に、
6x+10y-15z=23のとき、(x,y,z)=(3,2,1)なので、6,6,6,10,10,-15
15x+6y-10z=23のとき、(x,y,z)=(1,3,1)なので、15,6,6,6,-10
6x-10y-15z=23のとき、(x,y,z)=(8,1,1)なので、6,6,6,6,6,6,6,6,-10,-15
10x-15y-6z=23のとき、(x,y,z)=(5,1,2)なので、10,10,10,10,10,-15,-6,-6
15x-6y-10z=23のとき、(x,y,z)=(3,2,1)なので、15,15,15,-6,-6,-10
(終り)


LET A=6
LET B=10
LET C=15
LET N=23
CALL Solve(A,B,C,N)
PRINT
CALL Solve2(A,B,C,N)
CALL Solve2(B,C,A,N)
CALL Solve2(C,A,B,N)
PRINT
CALL Solve3(A,B,C,N)
CALL Solve3(B,C,A,N)
CALL Solve3(C,A,B,N)
END

!A,B,C,Nは非負整数とする。不定方程式Ax+By+Cz=Nの非負整数解は、
!By+Cz=N-Ax≧0なので、A=0,1,2,3,…,[N/A]として、By+Cz=Mに帰着させる。
EXTERNAL SUB Solve(A,B,C,N) !Ax+By+Cz=N
FOR X=0 TO N/A
   CALL SolveEQU(B,C,N-A*X, Y,Z,K)
   IF K=-1 THEN EXIT FOR
NEXT X
PRINT STR$(A);"x+";STR$(B);"y+";STR$(C);"z=";STR$(N)
IF K=-1 THEN PRINT X;Y;Z ELSE PRINT "解なし"
END SUB


!A,B,C,Nは非負整数とする。不定方程式Ax+By-Cz=Nの非負整数解は、
!Ax+By=N+Cz≧0なので、Z=0,1,2,3,…として、Ax+By=Mに帰着させる。
EXTERNAL SUB Solve2(A,B,C,N) !Ax+By-Cz=N
LET Z=0
DO
   CALL SolveEQU(A,B,N+C*Z, X,Y,K)
   IF K=-1 THEN EXIT DO
   LET Z=Z+1
LOOP
PRINT STR$(A);"x+";STR$(B);"y-";STR$(C);"z=";STR$(N)
IF K=-1 THEN PRINT X;Y;Z ELSE PRINT "解なし"
END SUB


!A,B,C,Nは非負整数とする。不定方程式Ax-By-Cz=Nの非負整数解は、
!Ax-N=By+Cz≧0なので、X=0,1,2,3,…として、By+Cz=Mに帰着させる。
EXTERNAL SUB Solve3(A,B,C,N) !Ax-By-Cz=N
LET X=CEIL(N/A) !Ax-N≧0より
DO
   CALL SolveEQU(B,C,A*X-N, Y,Z,K)
   IF K=-1 THEN EXIT DO
   LET X=X+1
LOOP
PRINT STR$(A);"x-";STR$(B);"y-";STR$(C);"z=";STR$(N)
IF K=-1 THEN PRINT X;Y;Z ELSE PRINT "解なし"
END SUB


EXTERNAL SUB SolveEQU(A,B,N, X,Y,K) !Ax+By=Nの非負整数解
LET K=-1
FOR X=0 TO N/A !Ax+By=N
   LET Y=(N-A*X)/B
   IF Y=INT(Y) THEN EXIT SUB !解
NEXT X
LET K=0 !解なし
END SUB

 

!修正プログラム

 投稿者:SECOND  投稿日:2014年 7月19日(土)11時15分9秒
  > No.3425[元記事へ]

!修正プログラム

! 異なる質量の、球と球の衝突( 表面摩擦は0)で 試行した結果、約半数くらいは、
! 互にもぐりこみ、正常な衝突検知が、出来ていませんでした。 その修正です。
!
! 衝突距離 以内に入った2球で、接近中か、直後離散中か、の判断をしていた部分が、
! 球の座標配列 p() 変化を元にしていたのが、応答の遅い点で、まずかったようです。

! 速度配列 vp() と法線ベクトル np から 速さの極性を、遅滞無く検出するよう改め、
! 「1つ前の座標」配列 pb() は、取去りました。

!
!------------------------------------------------------
OPTION ARITHMETIC COMPLEX         !複素数モード
LET wb=400                        !枠の幅
LET hb=400                        !枠の高さ
SET bitmap SIZE wb+101, hb+101
SET WINDOW  -50,wb+50, -50,hb+50  !左端,右端, 下端,上端
!------------------------------------------------------
RANDOMIZE 5               !引数を取ると、再現しない。
!
LET n=8                   !球の数
DIM p(n)                  !球の座標
DIM vp(n)                 !球の速度
DIM m(n), r(n)            !球の重量、半径
DATA 1,2,3,4,5,6,7,8,9,10 !球の重量データー
MAT READ m
FOR i=1 TO n
   LET r(i)=20*m(i)^(1/3) !半径 r ∝ 重量の3乗根。4 で 半径≒31.7
NEXT i
!
SET COLOR MIX(0) 0,0,0    !CLEAR 文で黒にする。
SET COLOR MIX(1) 1,1,1    !text,line, 初期カラーを白にする。
LET dt=0.2                !サンプリングタイム
!
!----- 重ならない初期位置のランダム設定
LET j=1
DO
   LET p(j)=COMPLEX( r(j)+2+(wb-2*r(j)-4)*RND, r(j)+2+(hb-2*r(j)-4)*RND)
   FOR i=1 TO j-1
      IF ABS(p(i)-p(j))< r(i)+r(j)+3 THEN EXIT FOR      !オーバーラップ: 再試行
   NEXT i
   IF j<=i THEN LET j=j+1                               !Ok: j+1
LOOP UNTIL n< j
!-----
DO
   LET j=0
   FOR i=1 TO n
      LET vp(i)=COMPLEX((RND-0.5)*40, (RND-0.5)*40)     !初期速度設定
      LET j=j+ABS(vp(i))
   NEXT i
LOOP UNTIL SQR(n)*20< j
!-----
DO
   FOR i=1 TO n
      LET p(i)=p(i)+vp(i)*dt
      !---
      IF re(p(i))< r(i) AND re(vp(i))< 0 THEN           !左の枠に衝突
         LET vp(i)= -conj(vp(i))
         LET p(i)= COMPLEX(r(i),im(p(i)))
      ELSEIF wb-r(i)< re(p(i)) AND 0< re(vp(i)) THEN    !右の枠に衝突
         LET vp(i)= -conj(vp(i))
         LET p(i)= COMPLEX(wb-r(i),im(p(i)))
      ELSEIF im(p(i))< r(i) AND im(vp(i))< 0 THEN       !下の枠に衝突
         LET vp(i)= conj(vp(i))
         LET p(i)= COMPLEX(re(p(i)),r(i))
      ELSEIF hb-r(i)< im(p(i)) AND 0< im(vp(i)) THEN    !上の枠に衝突
         LET vp(i)= conj(vp(i))
         LET p(i)= COMPLEX(re(p(i)),hb-r(i))
      END IF
      !---
      CALL collide                                      !球同士の衝突
   NEXT i
   !
   SET DRAW mode hidden                                 !表示画、更新の一時停止。
   CLEAR                                                !全画面、黒で、塗りつぶす
   PLOT TEXT,AT wb*.8,hb+20:"右クリック終了"
   SET LINE COLOR 0
   FOR i=1 TO n
      SET AREA COLOR i
      DRAW disk WITH SCALE(r(i))*SHIFT(p(i))            !球の表示
   NEXT i
   SET LINE width 4
   SET LINE COLOR 6
   PLOT LINES: 0; wb; COMPLEX(wb,hb); COMPLEX(0,hb); 0  !枠の表示
   SET DRAW mode explicit                               !表示画、常時更新の再開。
   !
   WAIT DELAY .01                                       !節電。削除 → かなり速くなる
   mouse poll mox,moy,mlb,mrb
LOOP UNTIL 0< mrb

!-----------------------------------------------------------
! 球同士の衝突( 表面摩擦0、異なる質量)
!
! ※反射速度は、法線ベクトルの内外向き、接線ベクトルの回転向き、
!  などの影響を受けないが、法線上の 相対的速さ は、極性に反映。
!-----------------------------------------------------------
SUB collide
   FOR j=1 TO n
      IF i<>j THEN
         LET  l=ABS( p(i) -p(j) )               !球(i)(j)間距離
         IF l<=r(i)+r(j) THEN                   !距離が範囲内、衝突の前 後?
            LET np=(p(j)-p(i))/l                !接触点 法線単位ベクトル
            LET vni=re(conj(np)*vp(i))          !接触点 法線方向の 球(i)速さ(+-)
            LET vnj=re(conj(np)*vp(j))          !    〃    球(j)速さ(+-)
            IF vnj-vni< 0 THEN                  !法線上、相対的速さ(+-)、衝突の前、確定。
               LET   w=((m(i)-m(j))*vni+2*m(j)*vnj)/(m(i)+m(j))  !球(i)
               LET vnj=((m(j)-m(i))*vnj+2*m(i)*vni)/(m(i)+m(j))  !球(j) 反射後の速さ
               LET vni=w
               LET tp=np*COMPLEX(0,1)           ! 〃  接線単位ベクトル
               LET vti=re(conj(tp)*vp(i))       !    接線方向の 球(i)速さ(+-)
               LET vtj=re(conj(tp)*vp(j))       !    〃    球(j)速さ(+-)
               !--
               LET vp(i)= vni*np +vti*tp        !球(i)速度ベクトル
               LET vp(j)= vnj*np +vtj*tp        !球(j)速度ベクトル
            END IF
         END IF
      END IF
   NEXT j
END SUB

END
 

Re: 不定方程式の解

 投稿者:山中和義  投稿日:2014年 7月24日(木)20時26分59秒
  > No.3439[元記事へ]

問題
下図のような8×8の格子状の経路を考える。
地点Aから地点Bへ進むとき、交差点を5回曲がる場合の経路は何通りあるか。

 A─・─・─・─・─・─・─・
 │ │ │ │ │ │ │ │
 ・─・─・─・─・─・─・─・
 │ │ │ │ │ │ │ │
 ・─・─・─・─・─・─・─・
 │ │ │ │ │ │ │ │
 ・─・─・─・─・─・─・─・
 │ │ │ │ │ │ │ │
 ・─・─・─・─・─・─・─・
 │ │ │ │ │ │ │ │
 ・─・─・─・─・─・─・─・
 │ │ │ │ │ │ │ │
 ・─・─・─・─・─・─・─・
 │ │ │ │ │ │ │ │
 ・─・─・─・─・─・─・─B

答え
a,b,c,d,e,fは自然数とする。
右にa,下にb,右にc,下にd,右にe,下にf または 下にa,右にb,下にc,右にd,下にe,右にf
と進むと、曲がる回数は題意を満たす。
これに、a+c+e=7 かつ b+d+f=7
と制限すれば、距離も題意を満たす。
いま、a,c,eを右方向とすると、
(a-1)+(c-1)+(e-1)=4すなわちx+y+z=4の非負整数解を求めると、重複組合せより、H(4+1,2)=15通りである。
下方向b,d,fも同様なので、15×15=225通りとなる。
また、a,c,eを下方向としても、225通りとなる。
よって、225+225=450通り
(終り)


LET S=0 !場合の数
FOR X=0 TO 4 !x+y+z=4より
   FOR Y=0 TO 4-X !y+z=4-xより
      LET Z=4-(X+Y)
      LET S=S+1
      PRINT S; X+1;Y+1;Z+1 !a,c,e
   NEXT Y
NEXT X
END


別解
地点Aから右方向に進むとする。交差点を5回曲がる場合の経路は、
   1 2 3 4 5 6
 A→①─・─・─・─・─・─・
 │ ↓
1・ ② → ③
 │
2・     ↓
 │
3・     ④   →   ⑤
 │
4・
 │
5・             ↓
 │
6・
 │
 ・─・─・─・─・─・─・─B
となる。
上の図の偶数番目の位置を決めれば経路は確定する。
その位置は、横方向と縦方向とも、6箇所から2つ選べばよい。
これより、C(6,2)×C(6,2)=15×15=225通りとなる。
また、地点Aから下方向に進んでも、225通りとなる。
よって、225+225=450通り



---------------------------------------------------

問題
500円、100円、50円、10円、5円、1円の硬貨があります。
この6種類の硬貨をそれぞれ1枚以上使って、あわせて15枚で980円をつくるとき、
何通りつくることができますか。

答え
500円、100円、50円、10円、5円、1円の硬貨の枚数を、a,b,c,d,e,fとする。
500a+100b+50c+10d+5e+f=980から、500(a-1)+100(b-1)+50(c-1)+10(d-1)+5(e-1)+(f-1)=314
a+b+c+d+e+f=15から、(a-1)+(b-1)+(c-1)+(d-1)+(e-1)+(f-1)=9
すなわち、
 500A+100B+50C+10D+5E+F=314、A+B+C+D+E+F=9 の非負整数解を求める
となる。
314の百の位と一の位に注意して、、A=0,F=4 ∴a=1,f=5
よって、100B+50C+10D+5E=310より、20B+10C+2D+E=62、B+C+D+E=5
62の一の位に注意して、
E=2,e=3のとき、20B+10C+2D=60、B+C+D=3 ∴10B+5C+D=30、B+C+D=3
D=1,d=2のとき、20B+10C+E=60、B+C+E=4
これを解いて、(a,b,c,d,e,f)=(1,4,1,1,3,5)、(1,3,3,2,1,5)
(終り)


FOR B=0 TO 30/10
   FOR C=0 TO (30-10*B)/5
      LET D=30-(10*B+5*C)
      IF B+C+D=3 THEN PRINT B;C;D
   NEXT C
NEXT B
PRINT

FOR B=0 TO 60/20
   FOR C=0 TO (60-20*B)/10
      LET E=60-(20*B+10*C)
      IF B+C+E=4 THEN PRINT B;C;E
   NEXT C
NEXT B

PRINT 500*1 +100*4 +50*1 +10*1 +5*3 +1*5 !検算
PRINT 500*1 +100*3 +50*3 +10*2 +5*1 +1*5

END


別解
  :
  :
よって、100B+50C+10D+5E=310より、20B+10C+2D+E=62、B+C+D+E=5
62の一の位の2に注意して、
E=2,e=3のとき、20B+10C+2D=60、B+C+D=3 ∴10B+5C+D=30、B+C+D=3
 D=0,1,2,3に注意して、D=0、9B+4C=27、B+C=3
 連立させて、B=3, C=0 ∴b=4, c=1, d=1
D=1,d=2のとき、20B+10C+E=60、B+C+E=4
 E=0,1,2,3,4に注意して、E=0、19B+9C=56、B+C=4
 連立させて、B=2, C=2 ∴b=3, c=3, e=1

 

シーケンスシミュレータ削除の件

 投稿者:lark12_long  投稿日:2014年 7月25日(金)08時21分47秒
  一部不具合の発見及び修正の実施しました
最近発見した不具合の未修正等あります

それと、あまりにも説明不足で、ずさんな状況で、アップしてしまいましたので、
一旦削除させて頂きます

再度吟味して、アップしようと思います

ご迷惑を、おかけしました

lark12_long
 

席に座る順序(長いす)

 投稿者:山中和義  投稿日:2014年 8月 1日(金)05時39分54秒
  問題
7人がけの長いすが全て空いていて、そこへ7人の客が1人ずつ座っていくとする。
最初の客は、任意の位置に座る。
2番目の客は、最初の客と隣り合わないように離れた位置に座る。
以降同様に、なるべく隣り合わないような位置を選んで座っていく。
ある程度座るとそのような位置が選べなくなり、仕方なく任意の客の隣に座ることになる。
さて、この席が7人で埋め尽くされる順序は、全部で何通りあるか。

例 3人の場合
 123 番目の席
 132 番目の客

 123
 231

 123
 213

 123
 312

以上、4通り

考察
k人目で、これ以上隣り合わないようにすることができなくなったとする。
そのときの空き席は、(n-k)個である。
その内の(k-1)個を用いて間を埋めて、k人が隣り合わないようにする。
残りは、(n-k)-(k-1)=n-2k+1個なので、これを(k+1)箇所に1つずつ埋めればよい。
(∵それぞれの左側のk個 と 右端の1個 との 計(k+1)個 より)
よって、C(k+1,n-2k+1)通りのパターンを得る。

例 n=7、k=3のとき、
 │×●│×●│×│  残りは、2個   ∴C(4,2)=6
例 n=7、k=4のとき、
 │×●│×●│×●│×│  残りは、なし   ∴C(5,0)=1

また、kの範囲は、
最小値は、2個ずつ空けて座る場合である。
最大値は、1個ずつ空けて座る場合である。
よって、[(n+2)/3]≦k≦[(n+1)/2]となる。
(終り)


OPTION ARITHMETIC RATIONAL !多桁の整数
LET N=7 !席の数 ※2以上
DIM A(N) !これ以上隣り合わないように座れるパターン
MAT A=ZER
PUBLIC NUMERIC C !パターンの場合の数
LET C=0
PUBLIC NUMERIC X !場合の数
LET X=0
LET A(1)=1 !1番目の席に座る
CALL try(2,N,A)
PRINT
LET A(1)=0 !1番目の席を空ける
CALL try(2,N,A)
PRINT C; "通り"
PRINT X; "通り"

LET S=0
FOR K=INT((N+2)/3) TO INT((N+1)/2)
   LET S=S+COMB(K+1,N-2*K+1)
   PRINT K; COMB(K+1,N-2*K+1) !debug
NEXT K
PRINT S; "通り"
END

EXTERNAL SUB try(P,N,A()) !バックトラック法で埋めていく
OPTION ARITHMETIC RATIONAL !多桁の整数
IF P=N THEN !右端(最後の席)の場合
   IF A(P-1)=0 THEN LET A(P)=1 !補正する

   LET T=0 !座る順序を考える
   FOR i=1 TO N
      IF A(i)=0 THEN LET T=T+1
   NEXT i
   LET X=X+FACT(N-T)*FACT(T)

   LET C=C+1
   MAT PRINT A; !パターン

   LET A(P)=0 !元に戻す
ELSE
   IF A(P-1)=1 THEN !1つ前に座っている
      LET A(P)=0 !空き席にする
      CALL try(P+1,N,A) !左端から埋めていく
      LET A(P)=0 !元に戻す

      IF P+1<N THEN !空き席は連続2つまで可能である
         LET A(P)=0
         LET A(P+1)=0
         CALL try(P+2,N,A)
         LET A(P)=0
         LET A(P+1)=0
      END IF
   ELSE !1つ前が空き席なら
      LET A(P)=1 !座らせる
      CALL try(P+1,N,A)
      LET A(P)=0
   END IF
END IF
END SUB


実行結果

1  0  1  0  1  0  1

1  0  1  0  0  1  0

1  0  0  1  0  1  0

1  0  0  1  0  0  1


0  1  0  1  0  1  0

0  1  0  1  0  0  1

0  1  0  0  1  0  1

7 通り
1008 通り
3  6
4  1
7 通り


 

Re: 不定方程式の解

 投稿者:山中和義  投稿日:2014年 8月 3日(日)06時58分5秒
  > No.3446[元記事へ]

両替問題 http://izumi-math.jp/T_Ogasawara/ryougae/ryougae.pdf

2004年度 高知大理学部 推薦入試
10000円を100円玉、50円玉、10円玉に両替する方法は、何通りあるか。


OPTION ARITHMETIC RATIONAL !多桁の整数
PRINT G100(10000)
END

EXTERNAL FUNCTION G10(N) !不定方程式10a=Nの解の個数
OPTION ARITHMETIC RATIONAL !多桁の整数
IF MOD(N,10)<>0 THEN
   PRINT "10円未満の金額があります。"
   STOP
END IF
LET G10=1 !すべて10円の1通り
END FUNCTION

EXTERNAL FUNCTION G50(N) !10a+50b=N ∴a=N-50bに帰着させる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/50) !50円の枚数
   LET S=S+G10(N-50*K) !残りは、10円でつくる
NEXT K
LET G50=S
END FUNCTION

EXTERNAL FUNCTION G100(N) !10a+50b+100c=N ∴10a+50b=N-100cに帰着させる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/100) !100円の枚数
   LET S=S+G50(N-100*K) !残りは、50円,10円でつくる
NEXT K
LET G100=S
END FUNCTION



多重FOR文による


OPTION ARITHMETIC RATIONAL !多桁の整数
LET N=10000
LET S=0
FOR C100=0 TO N/100 !100円玉の枚数
   FOR C50=0 TO (N-100*C100)/50 !50円玉の枚数
      LET S=S+1 !10円玉は1通り
   NEXT C50
NEXT C100
PRINT S; "通り"
END



-------------------------------------------------------------------

500円の100円玉、50円玉、10円玉、5円玉、1円玉への両替方法は、19161通りである。


OPTION ARITHMETIC RATIONAL !多桁の整数
PRINT F100(500)
END

!不定方程式 a+5b+10c+50d+100e+500f+1000g+5000h+10000i=N の解の個数

EXTERNAL FUNCTION F1(N) !1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET F1=1 !すべて1円の1通り
END FUNCTION

EXTERNAL FUNCTION F5(N) !5円,1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/5) !5円の枚数
   LET S=S+F1(N-5*K) !残りは、1円でつくる
NEXT K
LET F5=S
END FUNCTION

EXTERNAL FUNCTION F10(N) !10円,5円,1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/10) !10円の枚数
   LET S=S+F5(N-10*K) !残りは、5円,1円でつくる
NEXT K
LET F10=S
END FUNCTION

EXTERNAL FUNCTION F50(N) !50円,10円,5円,1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/50) !50円の枚数
   LET S=S+F10(N-50*K) !残りは、10円,5円,1円でつくる
NEXT K
LET F50=S
END FUNCTION

EXTERNAL FUNCTION F100(N) !100円,50円,10円,5円,1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/100)
   LET S=S+F50(N-100*K)
NEXT K
LET F100=S
END FUNCTION

EXTERNAL FUNCTION F500(N) !500円,100円,50円,10円,5円,1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/500)
   LET S=S+F100(N-500*K)
NEXT K
LET F500=S
END FUNCTION

EXTERNAL FUNCTION F1000(N) !1000円,500円,100円,50円,10円,5円,1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/1000)
   LET S=S+F500(N-1000*K)
NEXT K
LET F1000=S
END FUNCTION

EXTERNAL FUNCTION F5000(N) !5000円,1000円,500円,100円,50円,10円,5円,1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/5000)
   LET S=S+F1000(N-5000*K)
NEXT K
LET F5000=S
END FUNCTION

EXTERNAL FUNCTION F10000(N) !10000円,5000円,1000円,500円,100円,50円,10円,5円,1円の硬貨で、n円をつくる
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=0
FOR K=0 TO INT(N/10000)
   LET S=S+F5000(N-10000*K)
NEXT K
LET F10000=S
END FUNCTION



多重FOR文による


OPTION ARITHMETIC RATIONAL !多桁の整数
LET N=500
LET S=0
FOR C100=0 TO N/100 !100円玉の枚数
   LET R50=N-100*C100 !残り
   FOR C50=0 TO R50/50 !50円玉
      LET R10=R50-50*C50
      FOR C10=0 TO R10/10 !10円玉
         LET R5=R10-10*C10
         !!FOR C5=0 TO R5/5 !5円玉
         !!   LET S=S+1 !1円玉は1通り
         !!NEXT C5
         LET S=S+(R5/5+1) !5円玉
      NEXT C10
   NEXT C50
NEXT C100
PRINT S; "通り"
END


 

Re: 不定方程式の解

 投稿者:山中和義  投稿日:2014年 8月 4日(月)10時14分29秒
  > No.3449[元記事へ]

> 両替問題 http://izumi-math.jp/T_Ogasawara/ryougae/ryougae.pdf

つづき

10000円の5000札、1000円札、500円玉、100円玉、50円玉、10円玉、5円玉、1円玉への両替方法は、
18155171408通りある。

関数の呼出し、かけ算・割り算の負荷を避けて、次のように記述しました。


OPTION ARITHMETIC RATIONAL !多桁の整数
LET M=10000 !金額
LET S=0
FOR C5000=0 TO M STEP 5000 !0,5000,10000,15000,…
   LET T5000=M-C5000 !残りの金額に対して
   FOR C1000=0 TO T5000 STEP 1000
      LET T1000=T5000-C1000
      FOR C500=0 TO T1000 STEP 500
         LET T500=T1000-C500
         FOR C100=0 TO T500 STEP 100
            LET T100=T500-C100
            FOR C50=0 TO T100 STEP 50
               LET T50=T100-C50
               FOR C10=0 TO T50 STEP 10
                  LET T10=T50-C10
                  LET S=S+INT(T10/5)+1 ! !0,5,10,15,… ※5n円を5,1円で両替する n+1通り
               NEXT C10
            NEXT C50
         NEXT C100
      NEXT C500
   NEXT C1000
NEXT C5000
PRINT S;"通り" !18155171408 通り
END



参考サイト
Weekend Mathematics http://www.junko-k.com/ 内
 コロキウム室 http://www2.ocn.ne.jp/~mizuryu/renzoku.html 第196回数学的な応募問題

 

塗り分け

 投稿者:山中和義  投稿日:2014年 8月 5日(火)18時55分31秒
  問題
3×3の各マス目に、赤か青の何れかの色を無作為に塗るとする。
(1) 何通りの塗り分け方ができるか。
(2) この中で、どこかの2×2の正方形には同色で塗られるものが存在する。それは何通りあるか。
例
 ■■□  □□□  ■■■ など
 ■■□  ■■□  ■■■
 □□□  ■■□  □□□

答え  (1) 2^9=512通り  (2) 190通り

考察
n種類の色を塗るとする。色を0,1,2,3,…,n-1と番号付ける。
中央は0とする。順にA,B,C,Dと塗っていく。
その過程で、E,F,G,Hの箇所で同色になる場合の数を求める。
  EAH
  B0D
  FCG
他の色1,2,3,…,n-1も同数である。
(終り)


!その1 シミュレーション

LET N=2 !色数

LET S=0 !場合の数

FOR A=0 TO N-1
   FOR B=0 TO N-1
      FOR E=0 TO N-1
         IF A+B+E=0 THEN !この箇所で同色になる場合
            LET S=S+N^3*N^2 !残りF,G,Hは、何色でもよい。また、C,Dも何色でもよい。
         ELSE

            FOR C=0 TO N-1
               FOR F=0 TO N-1
                  IF B+C+F=0 THEN
                     LET S=S+N^2*N^1 !残りG,Hは、何色でもよい。また、Dも何色でもよい。
                  ELSE

                     FOR D=0 TO N-1
                        FOR G=0 TO N-1
                           IF C+D+G=0 THEN
                              LET S=S+N^1 !残りHは、何色でもよい。
                           ELSE
                              IF D+A=0 THEN LET S=S+1 !D+A+H=0の1通り
                              !!FOR H=0 TO N-1
                              !!   IF D+A+H=0 THEN
                              !!      LET S=S+N^0
                              !!   ELSE
                              !!   END IF
                              !!NEXT H
                           END IF
                        NEXT G
                     NEXT D

                  END IF
               NEXT F
            NEXT C

         END IF
      NEXT E
   NEXT B
NEXT A

PRINT S; N*S; "通り"


!その2

!中央でも角でもない4マスについて、
!中央マスとの色の関係であり得るパターンは、次の6通りである。
!これより、中央の色を固定して、2×2の同色がないものは、
LET T=0
!(1) 4マスすべてが中央マスと異なる色
LET T=T+(N-1)^4*N^4 !  1*( (N-1)^4 * N^4 )
!(2) 4マスのうち1マスだけ中央マスと同じ色
LET T=T+4*(N-1)^3*N^4 !  4*( 1*(N-1)^3 * N^4 )
!(3) 4マスのうち向い合う2マスだけ中央マスと同じ色
LET T=T+2*(N-1)^2*N^4 !  2*( 1^2*(N-1)^2 * N^4 )
!(4) 4マスのうち隣接する2マスだけ中央マスと同じ色
LET T=T+4*(N-1)^3*N^3 !  4*( 1^2*(N-1)^2 * (N-1)*N^3 )
!(5) 4マスのうち3マスが中央マスと同じ色
LET T=T+4*(N-1)^3*N^2 !  4*( 1^3*(N-1) * (N-1)^2*N^2 )
!(6) 4マス全部が中央マスと同じ色
LET T=T+(N-1)^4 !  1*( 1^4 * (N-1)^4 )
!他の色でも同数となる。
!よって、求める場合の数は、余事象なので、
LET S=N^9-N*T

PRINT S; "通り"

END

 

Re: 中学生プログラミングコンテスト

 投稿者:山中和義  投稿日:2014年 8月 7日(木)10時42分56秒
  > No.3401[元記事へ]

>  福島工業高等専門学校 情報処理教育センター
>  http://www.fukushima-nct.ac.jp/information/htdocs/index.php?page_id=25
>
> 予想問題


問題
nを3けたの自然数とします。
n^2を5で割ると1余るとき、nはどのような数ですか。
また、それらをすべて足し合わせると、いくつになりますか。

答え
一の位が、1,4,6,9となる。

百十の位の個数は、10,11,12,…,89,99の(99-10+1)=90個である。
それぞれに、101,104,106,109のように4個ずつあるので、計90×4=360個となる。
したがって、和は、(101+999)×360÷2=198000


LET C=0
LET S=0
FOR N=100 TO 999
   IF MOD(N*N,5)=1 THEN
      LET C=C+1
      PRINT C; N
      LET S=S+N
   END IF
NEXT N
PRINT C; "個"
PRINT "和="; S

PRINT (101+999)*((99-10+1)*4)/2 !計算式
END



-------------------------------------------

問題
15,21,25,26,31,34,46の数が1つずつ書かれた7枚のカードがある。
3枚ずつ組み合わせて、その総和を求めたところ同じになった。
このとき使われなかったカードに書かれている数字は何か?

答え
26, 34

考察
15を除いた場合、21,25,26,31,34,46の和は、183
奇数なので、不適である。

21を除いた場合、15,25,26,31,34,46の和は、177
奇数なので、不適である。

25を除いた場合、15,21,26,31,34,46の和は、173
奇数なので、不適である。

26を除いた場合、15,21,25,31,34,46の和は、172
3枚の和は、86
偶数なので、偶数+偶数+偶数、偶数+奇数+奇数 の組み合わせになる。
15+25+46、21+31+34 とすればよい。

31を除いた場合、15,21,25,26,34,46の和は、167
奇数なので、不適である。

34を除いた場合、15,21,25,26,31,46の和は、164
3枚の和は、82
15+21+46、25+26+31 とすればよい。

46を除いた場合、15,21,25,26,31,34の和は、152
3枚の和は、76
解なし
(終り)


DATA 15,21,25,26,31,34,46
DIM A(7)
MAT READ A
FOR X=1 TO 7
   LET W=A(1) !swap it
   LET A(1)=A(X)
   LET A(X)=W

   LET T=0 !1番目を除く6つの和
   FOR i=2 TO 7
      LET T=T+A(i)
   NEXT i
   LET S=T/2
   IF S=INT(S) THEN !偶数なら

      FOR i=2 TO 7-2 !組み合わせ
         FOR J=i+1 TO 7-1
            FOR K=J+1 TO 7
               IF A(i)+A(J)+A(K)=S THEN !題意を満たす

                  PRINT A(1); S; A(i);A(J);A(K);
                  FOR P=2 TO 7
                     IF NOT(P=i OR P=J OR P=K) THEN PRINT A(P);
                  NEXT P
                  PRINT

               END IF
            NEXT K
         NEXT J
      NEXT i

   END IF
NEXT X
END



-------------------------------------------

問題
1桁の数a,bを用いて、10進法表記で26ab26と表される6桁の数がある。
13と17のいずれでも割り切れるとき、a+bの和はいくつか。

答え
13の倍数判定より、-(260+a)+(100b+26)≡0 mod 13 ∴-a+9b≡0 mod 13
17の倍数判定より、26-2*(10a+b)+4*26≡0 mod 17 ∴-3a-2b+11≡0 mod 17


FOR a=0 TO 9
   FOR b=0 TO 9
      IF MOD(-a+9*b,13)=0 THEN
      !!!PRINT a;b
         IF MOD(-3*a-2*b+11,17)=0 THEN PRINT a;b
      END IF
   NEXT b
NEXT a
END


別解
260026は13の倍数なので、100(10a+b)も13の倍数である。


FOR x=0 TO 99 STEP 13
   IF MOD(x*100+260026,13*17)=0 THEN PRINT x
NEXT x
END



-------------------------------------------

問題
10×10の表の対角方向に同じ数字が並んでいる。
暗算で、この表の数字の和を求めよ。

  1  2  3  4  5  6  7  8  9 10
  2  3  4  5  6  7  8  9 10 11
  3  4  5  6  7  8  9 10 11 12
  4  5  6  7  8  9 10 11 12 13
  5  6  7  8  9 10 11 12 13 14
  6  7  8  9 10 11 12 13 14 15
  7  8  9 10 11 12 13 14 15 16
  8  9 10 11 12 13 14 15 16 17
  9 10 11 12 13 14 15 16 17 18
10 11 12 13 14 15 16 17 18 19

答え
10×(10×10)、(1+19)×(10×10)÷2
より、1000


LET S=0
FOR Y=1 TO 10 !行
   FOR X=Y TO Y+10-1 !列
      LET S=S+X
   NEXT X
NEXT Y
PRINT S
END


別解

LET S=0
FOR Y=1 TO 10 !行
   LET S=S+(Y+(Y+10-1))*10/2 !1行目の場合、1+10,2+9,3+8,…,10+1 すなわち、11が10個
NEXT Y
PRINT S
END



-------------------------------------------

問題
1から1億までの数の各桁の和を考える。
1+2+3+4+5+6+7+8+9+(1+0)+(1+1)+(1+2)+ … +(9+9+9+9+9+9+9+9)+(1+0+0+0+0+0+0+0+0)

答え
0から99999999までの1億個の数について、
  99999999
+ 00000000
-----------
  99999999
より、9×8=72

  99999998
+ 00000001
-----------
  99999999
より、9×8=72

  99999997
+ 00000002
-----------
  99999999
より、9×8=72

 :
 :

また、1億は、1+0+0+0+0+0+0+0+0=1
よって、72×1億÷2+1=36億1


LET S=0
FOR N=1 TO 100000000
   LET A=N
   DO WHILE A>0
      LET S=S+MOD(A,10)
      LET A=INT(A/10)
   LOOP
NEXT N
PRINT S
END


別解 度数
1から1000までの場合、
0から999までの数において、下2けた(百の位を除く)では、
 00 01 02 03 04 05 06 07 08 09
 10 11 12 13 14 15 16 17 18 19
 20 21 22 23 24 25 26 27 28 29
   :
 90 91 92 93 94 95 96 97 98 99
と並べて、たとえば、数字1の個数を数えると、縦に10個、横に10個ある。
百の位を加味すると、これが10個ある。
また、百の位では、100から199なので、10×10個ある。
すなわち、0+1+2+3+ … +9=45が、10×10 + (2×10)×10個となる。

残りの1000は、1+0+0+0=1である。


LET K=8 !10^k ※kは自然数
PRINT 45*F(K)+1 !(0+1+2+3+… +9)*F(k) + 1
END

EXTERNAL FUNCTION F(K) !0から10^k-1まで数に現れる数字0,1,2,3,…,9のそれぞれの個数
IF K=1 THEN
   LET F=1 !0から9までは、1個ずつ
ELSE
   LET F=10^(K-1)+F(K-1)*10 !10^(k-1)の位がnのもの + 10^(k-1)の位未満がnのもの
END IF
END FUNCTION

 

不思議な、RND

 投稿者:SECOND  投稿日:2014年 8月 8日(金)12時58分45秒
  !不思議な、RND
!------------------------
!http://www.fukushima-nct.ac.jp/information/htdocs/?action=common_download_main&upload_id=24

!正三角形のある頂点の上に、カエルが一匹乗っています。
!カエルは正三角形の頂点のうち一つを適当に選び、そこに
!ジャンプを試みますが、半分までしか飛べず、途中で着地
!してしまいます。その後も、頂点を適当に選んではジャン
!プを試みる・・・
!
!・・カエルが着地した地点に点を打つとすれば、最終的には
!どんな図形が描かれるでしょうか?( 上のサイトからの引用)

! カエルの軌跡
!------------------------
OPTION ARITHMETIC COMPLEX
SET POINT STYLE 1
SET WINDOW -1.05, 1.05,  -1, 1.1
DRAW grid(.2,.2)
RANDOMIZE
!
LET N=3                               !角数
!---
DIM p(N)
LET w=2*PI/N                          !頂点ステップ角
LET s=-(PI+w)/2                       !スタート角オフセット
FOR i=1 TO N
   LET p(i)=EXP( COMPLEX(0, s+w*i) )  !底辺を揃えた N角形頂点の座標
NEXT i
!---
FOR i=1 TO N
   PLOT LINES: p(i);                  !N角形 輪郭
NEXT i
PLOT LINES: p(1)
!---
LET w=p(1)
FOR i=1 TO 50000
   LET s=IP(RND*N)+1       !LET s=MOD(i,N)+1 ←× (sの同配分だけでは、図が出来ない)
   LET w=( w +p(s))/2
   PLOT POINTS: w
NEXT i

END
 

Re: 不思議な、RND

 投稿者:GAI  投稿日:2014年 8月10日(日)07時43分45秒
  > No.3453[元記事へ]

SECONDさんへのお返事です。


>
> ! カエルの軌跡
> !------------------------
> OPTION ARITHMETIC COMPLEX
> SET POINT STYLE 1
> SET WINDOW -1.05, 1.05,  -1, 1.1
> DRAW grid(.2,.2)
> RANDOMIZE
> !
> LET N=3                               !角数
> !---
> DIM p(N)
> LET w=2*PI/N                          !頂点ステップ角
> LET s=-(PI+w)/2                       !スタート角オフセット
> FOR i=1 TO N
>    LET p(i)=EXP( COMPLEX(0, s+w*i) )  !底辺を揃えた N角形頂点の座標
> NEXT i
> !---
> FOR i=1 TO N
>    PLOT LINES: p(i);                  !N角形 輪郭
> NEXT i
> PLOT LINES: p(1)
> !---
> LET w=p(1)
> FOR i=1 TO 50000
>    LET s=IP(RND*N)+1       !LET s=MOD(i,N)+1 ←× (sの同配分だけでは、図が出来ない)
>    LET w=( w +p(s))/2
>    PLOT POINTS: w
> NEXT i
>
> END


たったこれだけのアルゴリズムでこんなに面白い図形が浮かび上がることに驚きました。
これをいじってたら
LET N=5
LET w=(2*w+3*p(s))/5
の場合に感動しました。

 

和と差から復元する

 投稿者:山中和義  投稿日:2014年 8月12日(火)09時58分36秒
  問題
3つの数a,b,cがあります。
そのうちの2つを取って和をつくると、3通りの和x,y,zができます。
(3通りの中に同じものがある可能性はあます)
このとき、3つの数をもとめなさい。

答え
連立方程式
 a+b  =x
 a  +c=y
   b+c=z
を解けばよい。
辺々をたすと、2(a+b+c)=x+y+z ∴a+b+c=(x+y+z)/2
よって、
 a=(x+y+z)/2-z
 b=(x+y+z)/2-y
 c=(x+y+z)/2-x
(終り)



問題
2けたの整数が3つあります。
この中の2つの数の和と差を、大きい順にすべて書き出したところ、
 94,72,50,44,28,22
となりました。
3つの整数をもとめなさい。

答え
3つの数を大きい順に、a[1],a[2],a[3]とする。
和と差を大きい順に、s[1],s[2],s[3],s[4],s[5],s[6]とする。
和と差は、
 a[1]+a[2]
 a[1]     +a[3]
      a[2]+a[3]
 a[1]-a[2]
 a[1]     -a[3]
      a[2]-a[3]
なので、
a[1]+a[2]≧a[1]+a[3]≧a[2]+a[3]に注意して、6つから3つを選んで、
 a[1]+a[2]     =s[i]
 a[1]     +a[3]=s[j]
      a[2]+a[3]=s[k]
となる連立方程式に帰着させる。
C(6,3)=20通りを検証する。


DATA 94,72,50,44,28,22
DIM S(6)
MAT READ S
FOR i=1 TO 4 !a[1]+a[2]
   FOR J=i+1 TO 5 !a[1]+a[3]
      FOR K=J+1 TO 6 !a[2]+a[3]
         LET T=S(i)+S(J)+S(K) !総和
         PRINT T
         LET A=T/2-S(K)
         LET B=T/2-S(J)
         LET C=T/2-S(i)
         IF C>=10 THEN PRINT A;B;C
      NEXT K
   NEXT J
NEXT i
END



答え
3つの数を大きい順に、a[1],a[2],a[3]とする。
和と差を大きい順に、s[1],s[2],s[3],s[4],s[5],s[6]とする。
和と差は、
 a[1]+a[2]         ←
 a[1]     +a[3]
      a[2]+a[3]
 a[1]-a[2]
 a[1]     -a[3]
      a[2]-a[3]
である。
総和は、4a[1]+2a[2]=Σs[k]
いま、a[1]+a[2]=s[i]を選んだとすると、2a[1]+2s[i]=Σs[k]
よって、a[1]=(Σs[k]-2s[i])/2、a[2]=s[i]-a[1]
続いて、a[1]+a[3]=s[j]を選んだとすると、a[3]=a[j]-a[1]
ただし、a[1]+a[2]≧a[1]+a[3]に注意する。
C(6,2)=15通りを検証する。


DATA 94,72,50,44,28,22
DIM S(6)
MAT READ S
LET T=0 !総和
FOR i=1 TO 6
   LET T=T+S(i)
NEXT i
PRINT T
FOR i=1 TO 5 !a[1]+a[2]=s[i]
   LET A=(T-2*S(i))/2
   LET B=S(i)-A
   IF B>=10 THEN
      PRINT S(i); A;B !debug

      FOR J=i+1 TO 6 !a[1]+a[3]=s[j]
         LET C=S(J)-A
         IF C>=10 THEN PRINT A;B;C
      NEXT J

   END IF
NEXT i
END



出題を算数の範囲とすると、すなわち、負の数を扱わない場合、

 a[1]≧a[2]≧a[3]≧0とする。
 a[1]+a[2]≧a[1]+a[3]≧a[2]+a[3]
 a[1]+a[3] -(a[1]-a[2])=a[2]+a[3]≧0
 a[1]+a[3] -(a[1]-a[3])=2a[3]≧0
 a[1]+a[3] -(a[2]-a[3])=(a[1]-a[2])+2a[3]≧0
 より、a[1]+a[2]=s[1]、a[1]+a[3]=s[2]

なので、


DATA 94,72,50,44,28,22
DIM S(6)
MAT READ S
LET T=0 !総和
FOR i=1 TO 6
   LET T=T+S(i)
NEXT i
PRINT T
LET A1=(T-2*S(1))/2
LET A2=S(1)-A1
LET A3=S(2)-A1
PRINT A1;A2;A3
END


 

最大文字列数

 投稿者:金子  投稿日:2014年 8月12日(火)16時49分47秒
  Macを使って、アスキーデータのファイルを読み込んで、データ処理を行うつもりなのですが、途中の行の文字列が大きする為に、添付エラーが出てしまいます。
すみませんが、回避する方法を教えてください。
よろしくお願いします。
 

Re: 最大文字列数

 投稿者:白石和夫  投稿日:2014年 8月12日(火)17時02分24秒
  > No.3456[元記事へ]

多分,1行中のコンマの個数が変数の個数と対応していないのだと思います。
LINE INPUT #n: s$
のようにして読めるか調べてみてください。
なお,本当に長すぎる文字列があるときは,
OPTION CHARACTER BYTE
を宣言して,
CHARACTER INPUT #n: s$
で1バイトずつ読んでみてください。

 

Re: 最大文字列数

 投稿者:金子  投稿日:2014年 8月12日(火)18時00分42秒
  > No.3457[元記事へ]

白石和夫さんへのお返事です。

> 多分,1行中のコンマの個数が変数の個数と対応していないのだと思います。
> LINE INPUT #n: s$
> のようにして読めるか調べてみてください。
> なお,本当に長すぎる文字列があるときは,
> OPTION CHARACTER BYTE
> を宣言して,
> CHARACTER INPUT #n: s$
> で1バイトずつ読んでみてください。
>
>

白石様
ありがとうございます。
LINE INPUTの処理で、動作しました。
 

Re: 和と差から復元する

 投稿者:山中和義  投稿日:2014年 8月14日(木)06時29分58秒
  > No.3455[元記事へ]

2014年度 女子学院中学 入学試験問題(算数1)
第1問の(4)
異なる4つの整数があり、それらの2つずつの数の和をすべてもとめると、30,37,38,41,42,49です。
4つの数のうち、一番小さい数と一番大きい数の和は □ で、
4つの数は小さい順に、□,□,□,□ です。

答え 連立方程式
4つの整数をa<b<c<dとする。
C(4,2)=6通りの和の大小関係は、
 a+b<a+c<a+d<b+d<c+d
      a+c<b+c<b+d
となる。
これより、
 1番目に小さい和(a+b)、2番目に小さい和(a+c)
 2番目に大きい和(b+d)、1番目に大きい和(c+d)
は確定されるが、a+dとb+cの大小は不明である。


DATA 30,37,38,41,42,49 !和 ※小さい順
DIM S(6)
MAT READ S

DIM A(4,4),x(4),b(4) !連立方程式 Ax=b
DATA 1,1,0,0 !1番目に小さい和a+b
DATA 1,0,1,0 !2番目に小さい和a+c
DATA 1,0,0,1 !1番小さい数と1番大きい数との和a+d
DATA 0,0,1,1 !1番目に大きい和c+d
MAT READ A

LET b(1)=S(1)
LET b(2)=S(2)
LET b(3)=S(3)
LET b(4)=S(6)

DIM iA(4,4) !解く
MAT iA=INV(A)
MAT x=iA*b
MAT PRINT x; !4つの数


!もう1つの候補について

LET b(3)=S(4)
MAT x=iA*b
MAT PRINT x; !4つの数

END



答え
4つの整数をa<b<c<dとする。
6つの和は、a+b,a+c,a+d,b+c,b+d,c+dである。
6つの和をすべて足すと、3×(a+b+c+d)なので、4つの整数の和は、(30+37+38+41+42+49)/3=79
また、a+b<a+c<a+d<b+d<c+d、a+c<b+c<b+dより、a+b=30,a+c=37,b+d=42,c+d=49である。

a+d=41と仮定すると、(a+b)+(a+c)+(a+d)=2a+(a+b+c+d)=2a+79=30+37+41=108 ∴a=18.5
整数の和は整数なので、これは不適である。

a+d=38と仮定すると、(a+b)+(a+c)+(a+d)=2a+(a+b+c+d)=2a+79=30+37+38=105 ∴a=13
このとき、
a+b=30より、b=17
a+c=37より、c=24
a+d=38より、d=25
(終り)



-------------------------------------------------

問題
2けたの整数が4つあります。
この中の2つの数の和と差を、大きい順にすべて書き出したところ、
 93,83,81,49,47,46,44,37,34,12,10,2
となりました。
4つの整数をもとめなさい。

答え
3つの数を大きい順に、a[1],a[2],a[3],a[4]とする。
和と差を大きい順に、s[1],s[2],s[3],s[4],…,s[12]とする。
和と差は、
 a[1]+a[2]            ←
 a[1]     +a[3]       ←
 a[1]          +a[4]
      a[2]+a[3]
      a[2]     +a[4]
           a[3]+a[4]
 a[1]-a[2]
 a[1]     -a[3]
 a[1]          -a[4]
      a[2]-a[3]       ←
      a[2]     -a[4]
           a[3]-a[4]
である。
総和は、6a[1]+4a[2]+2a[3]=Σs[k]
いま、a[1]+a[2]=s[i]とa[1]+a[3]=s[j]を選んだとすると、
総和は、4s[i]+2s[j]=Σs[k]と表される。
また、a[2]-a[3]=s[i]-s[j]
そこで、a[2]+a[3]=s[k]を選んだとすると、
a[2]=(s[k]+(s[i]-s[j]))/2、a[3]=(s[k]-(s[i]-s[j]))/2
よって、a[1]=s[i]-a[2]
a[1]-a[2]とa[1]-a[3]が存在することを確認して、a[1],a[2],a[3]を確定する。
続いて、a[1]+a[4]=s[p]を選んだとすると、a[4]=a[p]-a[1]
a[1]+a[2]≧a[1]+a[3]≧a[2]+a[3]、a[1]+a[3]≧a[1]+a[4]に注意する。


DATA 93,83,81,49,47,46,44,37,34,12,10,2
DIM S(12)
MAT READ S
LET T=0 !総和
FOR i=1 TO 12
   LET T=T+S(i)
NEXT i
PRINT T
FOR i=1 TO 10 !a[1]+a[2]
   FOR J=i+1 TO 11 !a[1]+a[3]
      IF 4*S(i)+2*S(J)=T THEN
         PRINT S(i);S(J) !debug

         FOR K=J+1 TO 12 !a[2]+a[3]
            LET W=S(i)-S(J)
            IF MOD(S(K)+W,2)=0 THEN !a[2]とa[3]の偶奇は一致する

               LET B=(S(K)+W)/2
               LET C=(S(K)-W)/2
               LET A=S(i)-B

               IF C>=10 THEN

                  FOR X=1 TO 12 !a[1]-a[2]を確認する
                     IF NOT(X=i OR X=J) THEN
                        IF A-B=S(X) THEN EXIT FOR
                     END IF
                  NEXT X
                  IF X<=12 THEN
                     FOR Y=1 TO 12 !a[1]-a[3]を確認する
                        IF NOT(Y=i OR Y=J OR Y=X) THEN
                           IF A-C=S(Y) THEN EXIT FOR
                        END IF
                     NEXT Y
                     IF Y<=12 THEN
                        PRINT S(K) !debug

                        FOR P=J+1 TO 12 !a[1]+a[4]
                           IF NOT(P=K OR P=X OR P=Y) THEN
                              LET D=S(P)-A
                              IF D>=10 THEN PRINT A;B;C;D
                           END IF
                        NEXT P

                     END IF
                  END IF

               END IF

            END IF
         NEXT K

      END IF
   NEXT J
NEXT i
END



出題を算数の範囲とすると、すなわち、負の数を扱わない場合、

a[1]≧a[2]≧a[3]≧a[4]≧0とすると、
a[1]+a[2]≧a[1]+a[3]≧a[1]+a[4]≧a[2]+a[4]≧a[3]+a[4]
a[1]+a[3]≧a[2]+a[3]≧a[2]+a[4]
a[1]+a[3] -(a[1]-a[2])=a[2]+a[3]≧0
a[1]+a[3] -(a[1]-a[3])=2a[3]≧0
a[1]+a[3] -(a[1]-a[4])=a[3]+a[4]≧0
a[1]+a[3] -(a[2]-a[3])=(a[1]-a[2])+2a[3]≧0
a[1]+a[3] -(a[2]-a[4])=(a[1]-a[2])+a[3]+a[4]≧0
a[1]+a[3] -(a[3]-a[4])=a[1]+a[4]≧0
より、
a[1]+a[2]=s[1]、a[1]+a[3]=s[2]

 

Re: 和と差から復元する

 投稿者:山中和義  投稿日:2014年 8月14日(木)10時15分32秒
  > No.3459[元記事へ]

問題
5つの数があります。
この中の2つを選んで和をつくると、小さい順に、
 7,10,11,11,12,14,15,15,18,19
となりました。
5つの数をもとめなさい。


「3つの数」と同様に、鮮やかに解けます。


DATA 7,10,11,11,12,14,15,15,18,19
DIM S(10)
MAT READ S
LET T=0 !総和
FOR i=1 TO 10
   LET T=T+S(i)
NEXT i
PRINT T
DATA 1,1,0,0,0
DATA 1,0,1,0,0
DATA 0,0,1,0,1
DATA 0,0,0,1,1
DATA 1,1,1,1,1
DIM A(5,5),x(5),b(5) !Ax=b
MAT READ A
LET b(1)=S(1) !1番目に小さい
LET b(2)=S(2) !2番目に小さい
LET b(3)=S(9) !2番目に大きい
LET b(4)=S(10) !1番目に大きい
LET b(5)=T/4 !和
DIM iA(5,5)
MAT iA=INV(A)
MAT x=iA*b
MAT PRINT x;
END



そのうちの3つを選んで和をつくる。


DATA 35,46,47,48,49,49,51,60,62,63
DIM S(10)
MAT READ S
LET T=0 !総和
FOR i=1 TO 10
   LET T=T+S(i)
NEXT i
PRINT T
DATA 1,1,1,0,0
DATA 1,1,0,1,0
DATA 0,1,0,1,1
DATA 0,0,1,1,1
DATA 1,1,1,1,1
DIM A(5,5),x(5),b(5) !Ax=b
MAT READ A
LET b(1)=S(1) !1番目に小さい
LET b(2)=S(2) !2番目に小さい
LET b(3)=S(9) !2番目に大きい
LET b(4)=S(10) !1番目に大きい
LET b(5)=T/6 !和
DIM iA(5,5) !連立方程式を解く
MAT iA=INV(A)
MAT x=iA*b
MAT PRINT x; !解
END

 

とんち問題 40-32÷2=4!

 投稿者:山中和義  投稿日:2014年 8月17日(日)15時33分40秒
  とんち問題 40-32÷2=4!

答案
小さい人が想像の翼を広げてみました。

 良い子
 40-(32÷2)=40-16=24=4!  階乗の記号

 悪い子
 40-32は8、8÷2は4 てっ  感嘆符、びっくりマーク

 普通の子
 ! って

 電卓好きの子
 4 ピカッ  強調を表す

 パズル好きの子
 40-32÷2 != 4  不等演算子


大きい方は、他にないか探してみました。

連立方程式
 a-kb÷k=n!
 (a-kb)÷k=n
より、
a-b=n! ∴a=(b+n)+(n!-n)
a-kb=kn ∴k=a/(b+n)=(b+n!)/(b+n)=1+(n!-n)/(b+n)
b+n>0、n!-n≧0なので、k=1+(n!-n)/(b+n)≧1
n=1,2のとき、n!-n=0なので、k=1 ∴(b+1)-b÷1=1!、(b+2)-b÷1=2!
n≧3のとき、n!-n>0なので、(n!-n)/(b+n)>0
(b+n)が(n!-n)の約数のとき、すなわち、n!-n≧b+n≧1+nのとき、k≧2となる。
(終り)

ごきげんよう。さようなら (不連続テレビ小説「花◎と答アン」より)



OPTION ARITHMETIC RATIONAL !多桁の整数
FOR N=3 TO 10
   LET P=FACT(N)-N !n!-n
   FOR B=N+1 TO P !b+n
      IF MOD(P,B)=0 THEN !約数なら
         LET K=1+P/B
         PRINT STR$(B+P); "-"; STR$(K*(B-N)); "÷"; STR$(K); "="; STR$(N); "!"
      END IF
   NEXT B
NEXT N
END


実行結果

25-5÷5=4!
30-18÷3=4!
40-32÷2=4!
138-108÷6=5!
230-220÷2=5!
721-103÷103=6!
728-416÷52=6!
731-473÷43=6!
735-525÷35=6!
748-616÷22=6!
756-648÷18=6!
765-675÷15=6!
816-768÷8=6!
833-791÷7=6!
952-928÷4=6!
1071-1053÷3=6!
1428-1416÷2=6!
5752-5696÷8=7!
10066-10052÷2=7!
45351-45279÷9=8!
50390-50350÷5=8!
60468-60444÷3=8!
80624-80608÷2=8!
  :
  :


 

Re: とんち問題 40-32÷2=4!

 投稿者:山中和義  投稿日:2014年 8月18日(月)09時56分46秒
  > No.3461[元記事へ]

> とんち問題 40-32÷2=4!

つづき

(k+1)!-0÷k!=(k+1)! は自明でしょう。

40-32÷2=4! は、akb-ak(b-1)÷a=k! ですね。

akb-k(b-1)=k! ∴(a-1)kb=k!-k ∴(a-1)b=(k-1)!-1 より、


OPTION ARITHMETIC RATIONAL !多桁の整数
FOR K=2 TO 10
   LET P=FACT(K-1)-1
   FOR B=1 TO P
      IF MOD(P,B)=0 THEN
         LET A=P/B+1
         PRINT STR$(A*K*B); "-"; STR$(A*K*(B-1)); "÷"; STR$(A); "="; STR$(K); "!"
      END IF
   NEXT B
NEXT K
END


実行結果

6-0÷2=3!
24-0÷6=4!
40-32÷2=4!
120-0÷24=5!
230-220÷2=5!
720-0÷120=6!
756-648÷18=6!
816-768÷8=6!
1428-1416÷2=6!
5040-0÷720=7!
10066-10052÷2=7!
40320-0÷5040=8!
80624-80608÷2=8!
362880-0÷40320=9!
363078-347292÷1754=9!
378648-378432÷24=9!
725742-725724÷2=9!
3628800-0÷362880=10!
3628900-3299000÷32990=10!
3630000-3600000÷3000=10!
3658780-3657560÷122=10!
3958680-3958560÷12=10!
7257580-7257560÷2=10!


 

Re: 中学生プログラミングコンテスト

 投稿者:山中和義  投稿日:2014年 8月21日(木)07時00分46秒
  > No.3452[元記事へ]

>  福島工業高等専門学校 情報処理教育センター
>  http://www.fukushima-nct.ac.jp/information/htdocs/index.php?page_id=25
>
> 予想問題


問題
1から100までの整数の和を表わす式S=1+2+3+ …+100がある。
この式にある99個の+のうち1つを×に変えて計算したら、Sの値より239だけ大きい値になった。
記号×の直前の数を求めよ。

答え
S-{n+(n+1)}+n(n+1)=S+239より、n^2+n-240=0 ∴(n+15)(n-16)=0 ∴n=16


FOR N=1 TO 100-1
   IF N*(N+1)-(N+(N+1))=239 THEN PRINT N
NEXT N
END



-------------------------------------------

問題
2桁以上の自然数で、その各桁の数の総和が10になるものを小さいほうから順に並べたとき、
2008は何番目か。

答え
千の位が0のとき、
百、十、一の位の数は、次のような数字の組を並べ替えたものである。
0,1,9で、3!=6通り
0,2,8で、3!=6通り
0,3,7で、3!=6通り
0,4,6で、3!=6通り
0,5,5で、3!/(1!2!)=3通り

1,1,8で、3!/(2!1!)=3通り
1,2,7で、3!=6通り
1,3,6で、3!=6通り
1,4,5で、3!=6通り

2,2,6で、3!/(2!1!)=3通り
2,3,5で、3!=6通り
2,4,4で、3!/(1!2!)=3通り

3,3,4で、3!/(1!2!)=3通り
計 6+6+6+6+3 +3+6+6+6 +3+6+3 +3=63通り
別解
10個の○と2個の仕切りを並べる( ○○│○○○│○○○○○ )より、H(10+1,2)=66通り
そのうち、0,0,10の3通りを除いた、63通り
(終り)

千の位が1のとき、
0,0,9で、3!/(2!1!)=3通り
0,1,8で、3!=6通り
0,2,7で、3!=6通り
0,3,6で、3!=6通り
0,4,5で、3!=6通り

1,1,7で、3!/(2!1!)=3通り
1,2,6で、3!=6通り
1,3,5で、3!=6通り
1,4,4で、3!/(1!2!)=3通り

2,2,5で、3!/(2!1!)=3通り
2,3,4で、3!=6通り

3,3,3で、1通り
計 3+6+6+6+6 +3+6+6+3+ 3+6 +1=55通り ※H(9+1,2)=55通り

千の位が2のとき、2008は1番目

よって、63+55+1=119通り


LET C=0
FOR N=10 TO 2008
   LET T=N
   LET S=0 !各位の数の和
   DO WHILE T>0
      LET S=S+MOD(T,10)
      LET T=INT(T/10)
   LOOP
   IF S=10 THEN LET C=C+1 !題意を満たす
NEXT N
PRINT C
END



-------------------------------------------

問題
0,1,2,3,4,5から異なる3つの数字を選んで3桁の整数をつくるとき、
異なる整数の和はいくつになるか。

答え 32640


LET S=0
FOR A=1 TO 5 !百の位
   FOR B=0 TO 5 !十の位
      IF NOT(B=A) THEN
         FOR C=0 TO 5 !一の位
            IF NOT(C=A OR C=B) THEN
               PRINT A;B;C
               LET S=S+(100*A+10*B+C)
            END IF
         NEXT C
      END IF
   NEXT B
NEXT A
PRINT S
END


別解
0,1,2,3,4,5から異なる3つの数字を選ぶ場合
「3つの数字の組を選んで、それらを並べ替える」と考えると、C(6,3)×3!=P(6,3)通り
和は、組(a,b,c)とすると、並べ替えて、
 a,b,c
 a,c,b
 b,a,c
 b,c,a
 c,a,b
 c,b,a
より、各位とも(a+b+c)×2=xなので、100x+10x+x=111x

その中で2桁の整数になる場合
すなわち、百の位を0、十一の位を1,2,3,4,5から選ぶ場合は、C(5,2)×2!=P(5,2)通り
 b,c
 c,b
より、和は、各位ともb+c=xなので、10x+x=11x


LET S=0
FOR A=0 TO 5
   FOR B=A+1 TO 5
      FOR C=B+1 TO 5
         PRINT A;B;C
         LET X=(A+B+C)*2
         LET S=S+111*X
      NEXT C
   NEXT B
NEXT A
PRINT S

LET T=0
FOR B=1 TO 5
   FOR C=B+1 TO 5
      PRINT B;C
      LET X=B+C
      LET T=T+11*X
   NEXT C
NEXT B
PRINT T

PRINT S-T

END



-------------------------------------------

問題
2,2,2,2,3,3,3,4,4のうち4個を使って4桁の整数をつくるとき、全部で何通りできるか。

答え 71通り

3,3,4,4と選んで、4!/(2!2!)=6通り
3,3,3,4と選んで、4!/(3!1!)=4通り
2,3,4,4と選んで、4!/(1!1!2!)=12通り
2,3,3,4と選んで、12通り
2,3,3,3と選んで、4通り
2,2,4,4と選んで、6通り
2,2,3,4と選んで、12通り
2,2,3,3と選んで、6通り
2,2,2,4と選んで、4通り
2,2,2,3と選んで、4通り
2,2,2,2と選んで、4!/4!=1通り
以上の71通り


DATA 4,3,2 !数字2,3,4の個数
DIM X(3)
MAT READ X
LET K=4 !桁数
LET S=0
FOR A=0 TO MIN(K,X(1)) !数字2をa個選ぶ
   FOR B=0 TO MIN(K-A,X(2)) !数字3をb個選ぶ
      LET C=K-(A+B) !数字4をc個選ぶ
      IF C>=0 AND C<=X(3) THEN
         PRINT A;B;C
         LET S=S+FACT(A+B+C)/(FACT(A)*FACT(B)*FACT(C)) !同じものを含むときの順列
      END IF
   NEXT B
NEXT A
PRINT S; "通り"
END


別解
2,2,2,2,3,3,3,3,4,4,4,4の場合、3^4=81通り
この中で、次のような4個の数字を選んで並べる整数はつくれない。
3,3,3,3と選ぶときの1通り
4,4,4,4と選ぶときの1通り
2,4,4,4と選ぶときの4!/(1!3!)=4通り
3,4,4,4と選ぶときの4通り
計1+1+4+4=10通り
よって、81-10=71通り

 

Re: 不定方程式の解

 投稿者:山中和義  投稿日:2014年 8月22日(金)19時24分8秒
  > No.3450[元記事へ]

問題
4つの正の整数a,b,c,dを
 a b
 c d
と並べて、たすきに掛けた数が、ad+1=bcを満たすとする。
a=d=1のとき、b,cを求めよ。

答え
ad+1=bcより、2=bc ∴(b,c)=(2,1),(1,2)
(終り)


問題
6つの正の整数a,b,c,d,e,fを
 a b c
 d e f
と並べて、たすきに掛けた数が、ae+1=bd、bf+1=ceを満たすとする。
a=f=1のとき、b,c,d,eを求めよ。

答え
 1        k  (k+1)/A
 (A+1)/k  A  1
と、kを(A+1)の約数とすると、1つの変数Aで表せる。
A=1のとき、
  1    k  k+1
  2/k  1  1
 なので、k=1,2
 並びは、
  1  1  2   1  2  3
  2  1  1   1  1  1
A=2のとき、
  1    k  (k+1)/2
  3/k  2  1
 なので、k=1,3
 並びは、
  1  1  1   1  3  2
  3  2  1   1  2  1
A=3のとき、
  1    k  (k+1)/3
  4/k  3  1
 なので、k=2
 並びは、
  1  2  1
  2  3  1
A=4のとき、
  :
  :


FOR A=1 TO 50
   FOR K=1 TO A+1
      IF MOD(A+1,K)=0 THEN

         IF MOD(K+1,A)=0 THEN
            PRINT 1;K;(K+1)/A
            PRINT (A+1)/K;A;1
            PRINT
         END IF

      END IF
   NEXT K
NEXT A
END


ところで、A≧3のとき、
kは(A+1)の約数なので、1≦k≦A+1 ∴2≦k+1≦A+2
右端上(k+1)/A≦(A+2)/A=1+2/A A≧3から、正の整数になるのは、1のみである。
よって、(k+1)/A=1 ∴k=A-1
左端下(A+1)/k=(A+1)/(A-1)=1+2/(A-1)
これが正の整数になるには、A=3のみである。
したがって、
 1  2  1
 2  3  1
のみとなる。
(終り)


対称性
 a b c … d
 e f g … h
が題意を満たすなら、
 h … g f e
 d … c b a
も題意を満たす。



問題
8つの正の整数a,b,c,d,e,f,g,hを
 a b c d
 e f g h
と並べて、たすきに掛けた数が、af+1=be、bg+1=cf、ch+1=dgを満たすとする。
a=h=1のとき、b,c,d,e,f,gを求めよ。

答え
2つの変数A,Bで
 1        k  B  (B+1)/m
 (A+1)/k  A  m  1
として、


FOR A=1 TO 50
   FOR B=1 TO A !対称性

      FOR K=1 TO A+1
         IF MOD(A+1,K)=0 THEN
            FOR M=1 TO B+1
               IF MOD(B+1,M)=0 THEN

                  IF K*M+1=A*B THEN
                     PRINT 1;K;B;(B+1)/M
                     PRINT (A+1)/K;A;M;1
                     PRINT
                  END IF

               END IF
            NEXT M
         END IF
      NEXT K

   NEXT B
NEXT A
END

実行結果

1  1  1  2
3  2  1  1

1  1  2  1  ※1
3  2  3  1

1  3  2  3  ※1
1  2  1  1

1  1  1  1
4  3  2  1

1  2  1  2
2  3  1  1

1  2  3  1  ※2
2  3  4  1

1  4  3  2  ※2
1  3  2  1

1  2  1  1
3  5  2  1

1  3  2  1
2  5  3  1


※は対称となるので、14通り



問題
2n個の正の整数a[1],a[2],…,a[n],b[1],b[2],…,b[n]を
 a[1],a[2],…,a[n]
 b[1],b[2],…,b[n]
と並べて、たすきに掛けた数が、
a[1]b[2]+1=a[2]b[1]、a[2]b[3]+1=a[3]b[2]、…、a[n-1]b[n]+1=a[n]b[n-1]を満たすとする。
a[1]=b[n]=1のとき、a[2],a[3],…,a[n],b[1],b[2],…,b[n-1]を求めよ。

予想
●個数
C(2n,n)/(n+1)、すなわち、カタラン数

●並びの生成方法
n=2のとき
並び
 1 2   1 1
 1 1   2 1
なので、
 1/1 2/1   1/2 1/1
のように、上段を分子、下段を分母とする分数で表すと、
分数列 1/2  1/1  2/1
    └─┘└─┘
から、1/1を含んで連続する2項を選んだと解釈できる。


n=3のとき
 1  1  2    1  2  3
 2  1  1    1  1  1
なので、
 1/2 1/1 2/1   1/1 2/1 3/1

 1  1  1    1  3  2
 3  2  1    1  2  1
なので、
 1/3 1/2 1/1   1/1 3/2 2/1

 1  2  1
 2  3  1
なので、
 1/2 2/3 1/1

    ┌───┐ ┌───┐
分数列 1/3  1/2  1/1  2/1  3/1
      └─┘ └─┘
      └─────┘
から、1/1を含んで連続する2項または3項を選んだと解釈できる。
2項の場合は、中間分数を考える。

補足 1:1の中間分数(隣り合う分数)
並び
 a  c
 b  d
が、ad+1=bcを満たすとする。
このとき、
 a  a+c  c
 b  b+d  d
を考える。
ad+1=bcの両辺にabをたして、ab+ad+1=ab+bc ∴a(b+d)+1=b(a+c)
ad+1=bcの両辺にcdをたして、ad+1+cd=bc+cd ∴(a+c)d+1=(b+d)c
これより、題意を満たして列を増やすことができる。
(終り)

参考サイト
 私的数学塾 http://www004.upp.so-net.ne.jp/s_honma/index.htm 内
  私の備忘録
   数学・・・代数学分野
    隣り合う分数 http://www004.upp.so-net.ne.jp/s_honma/fraction/fraction.htm

 

Re: 不定方程式の解

 投稿者:山中和義  投稿日:2014年 8月24日(日)19時14分13秒
  > No.3464[元記事へ]

> 問題
> 2n個の正の整数a[1],a[2],…,a[n],b[1],b[2],…,b[n]を
>  a[1],a[2],…,a[n]
>  b[1],b[2],…,b[n]
> と並べて、たすきに掛けた数が、
> a[1]b[2]+1=a[2]b[1]、a[2]b[3]+1=a[3]b[2]、…、a[n-1]b[n]+1=a[n]b[n-1]を満たすとする。
> a[1]=b[n]=1のとき、a[2],a[3],…,a[n],b[1],b[2],…,b[n-1]を求めよ。

自明な解
その1
1 2 3 … n-1 n
1 1 1 … 1   1

その2
フィボナッチ数列 1,1,2,3,5,8,13,21,34,55,… を、

           n :  ①   ③   ⑤   ⑦     ⑨              ⑧     ⑥    ④   ②
 a[n+1]/a[n] :  1/1, 3/2, 8/5, 21/13, 55/34, …,φ, …, 34/21, 13/8, 5/3, 2/1

のように、φを中心として左右交互に並べる。

 

トランプ遊びでの数理

 投稿者:GAI  投稿日:2014年 8月25日(月)17時06分22秒
  10枚のトランプを裏向きに
□□□□
□  □
□□□□
の形に並べる。
何処の位置からスタートしてもいいから
左回り、もしくは右回りに
スタートを"1”として4つ目のカードを表向きにする。
引き続いて、どこの位置の裏向きカードでもかまわずそこをスタートとして
4つ目にあたるカード(表向きになったカードもカウントする。)
をやはり表向きにする。
これを可能な限り繰り返したとき、最後まで裏向きのままの状態のカード
の数(多分1,2,3,4,5のいずれかになる。)の確率分布が知りたいのですが、式で表せないときはモンテカルロなどの手法による実験数値を知りたいので願いします。
 

Re: トランプ遊びでの数理

 投稿者:しばっち  投稿日:2014年 8月25日(月)21時37分25秒
  > No.3466[元記事へ]

GAIさんへのお返事です。

確率分布の出し方というのがよくわかりませんが
とりあえず作ってみました。
また、裏向きのままの状態でなく、表向きになった状態を表しています。あしからず

RANDOMIZE
DIM A(10),B(10),M(1024)
FOR L=1 TO 1000 !'試行回数
   MAT A=ZER !'カード全てを裏の状態とする
   MAT B=ZER
   LET S=0
   DO
      DO
         LET I=INT(RND*10)+1 !'任意の位置のカード
      LOOP UNTIL A(I)=0 !'裏向きのカードなら
      IF RND<.5 THEN LET I=I+3 ELSE LET I=I-3 !'右回り、左回りに相当
      IF I>10 THEN LET I=I-10
      IF I<1 THEN LET I=I+10
      LET A(I)=1 !'表向きにする
      LET FL=0
      FOR J=1 TO 10
         IF A(J)<>B(J) THEN
            LET FL=1 !'前回と違うなら
            LET S=0
         END IF
      NEXT J
      IF FL=0 THEN LET S=S+1 !'前回と同じ状態ならカウント
      IF S>10 THEN !'同じ状態が10回続くなら
         LET Z=0
         FOR J=1 TO 10
            LET Z=Z*2+A(J) !'各状態を2進法とみなす
         NEXT J
         LET M(Z)=M(Z)+1 !'カウントする
         EXIT DO
      END IF
      MAT B=A !'状態をコピー
   LOOP
NEXT L
MAT B=ZER
FOR I=1 TO 1024 !'各状態の表示
   IF M(I)>0 THEN
      PRINT RIGHT$("000000000"&BSTR$(I,2),10);" ";M(I)
      LET N=BITCOUNT32(I) !'bitの数
      LET B(N)=B(N)+M(I)
   END IF
NEXT I
PRINT
FOR I=1 TO 10
   PRINT I;B(I)
NEXT I
END

EXTERNAL FUNCTION BITCOUNT32(X) !'32bitの中の"1"の数
LET X=BITAND(X,BVAL("55555555",16))+BITAND(INT(X/2),BVAL("55555555",16))
LET X=BITAND(X,BVAL("33333333",16))+BITAND(INT(X/4),BVAL("33333333",16))
LET X=BITAND(X,BVAL("0F0F0F0F",16))+BITAND(INT(X/16),BVAL("0F0F0F0F",16))
LET X=BITAND(X,BVAL("00FF00FF",16))+BITAND(INT(X/256),BVAL("00FF00FF",16))
LET X=BITAND(X,BVAL("0000FFFF",16))+BITAND(INT(X/65536),BVAL("0000FFFF",16))
LET BITCOUNT32=X
END FUNCTION
 

Re: トランプ遊びでの数理

 投稿者:GAI  投稿日:2014年 8月26日(火)07時54分29秒
  > No.3467[元記事へ]

しばっちさんへのお返事です。


プログラムの提供ありがとうございます。
自分でもある程度作ってみようと挑戦していたんですが、こんなにいろいろなテクニックを駆使しなければならないなんてとてもできません。
表にできる枚数は何回も実行してみて、4~9枚(裏のままでは1~6枚)であることがわかりました。
(表4枚でストップすることに気付かなかった。でもそのパターンを探そうとしても見つけられなかった。できたらこの状態になるパターンを教えて下さい。)
中でも9枚を表にすることはランダムにやっていたらなかなか起こらない現象ですが、戦略的に前の試行で表にしたカードに対する"1"番の裏向きカード(カウントをはじめたであろう裏向きカード)を表にできるように次の試行を起こす。
という戦略を続けていくと9枚のカードを表にすることができます。

 

Re: トランプ遊びでの数理

 投稿者:しばっち  投稿日:2014年 8月26日(火)18時42分45秒
  > No.3468[元記事へ]

GAIさんへのお返事です。

> (表4枚でストップすることに気付かなかった。でもそのパターンを探そうとしても見つけられなかった。できたらこの状態になるパターンを教えて下さい。)

FOR I=1 TO 1024 !'各状態の表示
   IF M(I)>0 THEN
      PRINT RIGHT$("000000000"&BSTR$(I,2),10);" ";M(I)
      LET N=BITCOUNT32(I) !'bitの数
      IF N=4 THEN INPUT D$ !'←このように一旦止めて見て下さい。
      LET B(N)=B(N)+M(I)
   END IF
NEXT I

BITCOUNT32関数は32bitの中で"1"の数を表していて、
その数が、このプログラムでは表向きの数となっています。
矢印のようにしてしてみると分かると思います。

但し、プログラムのチェックの甘さからきたバグの可能性もあります。
同じ状態が10回以上続くならを100回以上続くならに変更してみてください。


      IF FL=0 THEN LET S=S+1 !'前回と同じ状態ならカウント
      IF S>100 THEN !'← 同じ状態が100回続くなら
         LET Z=0
         FOR J=1 TO 10
            LET Z=Z*2+A(J) !'各状態を2進法とみなす
         NEXT J
         LET M(Z)=M(Z)+1 !'カウントする
         EXIT DO
      END IF
 

Re: トランプ遊びでの数理

 投稿者:GAI  投稿日:2014年 8月26日(火)20時07分23秒
  しばっちさんへのお返事です。



> 同じ状態が10回以上続くならを100回以上続くならに変更してみてください。
>
>
>       IF FL=0 THEN LET S=S+1 !'前回と同じ状態ならカウント
>       IF S>100 THEN !'← 同じ状態が100回続くなら

の指示で走らせますと4での集計はいつも0の結果になりました。
表4枚になることはないと解釈していいんでしょうか?
9での集計はたまに1になります。
 

Re: トランプ遊びでの数理

 投稿者:山中和義  投稿日:2014年 8月27日(水)10時12分38秒
  > No.3466[元記事へ]

GAIさんへのお返事です。

> 10枚のトランプを裏向きに
> □□□□
> □  □
> □□□□
> の形に並べる。


シミュレーションで場合の数を求めてみました。 2進モードで実行してください。


LET N=10 !カードの枚数

!⑤④③②
!⑥  ①
!⑦⑧⑨0
DIM A(0 TO N-1) !並び
MAT A=ZER !すべて裏にする

DIM B(0 TO 2^N-1) !(ビット)パターンごとの場合の数
MAT B=ZER
CALL try(A,N,B)

!!MAT PRINT B; !debug
DIM C(0 TO N) !裏の個数ごとの場合の数
MAT C=ZER
LET T=0 !総数
FOR i=0 TO 2^N-1
   LET X$=right$("000000000"&BSTR$(i,2),N) !パターン
   LET S=0 !裏の個数
   FOR J=1 TO N
      IF X$(J:J)="0" THEN LET S=S+1
   NEXT J
   PRINT X$; S; B(i)

   LET C(S)=C(S)+B(i)
   LET T=T+B(i)
NEXT i

PRINT T
FOR i=0 TO 10
   PRINT i; C(i)/T
NEXT i
END

EXTERNAL SUB try(A(),N,B()) !バックトラック法で検証する
LET FLG=0
FOR i=0 TO N-1 !基準のカードが裏なら
   IF A(i)=0 THEN
      LET X=MOD(i-3,N) !右回りの4枚目の位置
      IF A(X)=0 THEN !4枚目を表にする
         LET A(X)=1
         CALL try(A,N,B) !次へ
         LET A(X)=0
         LET FLG=-1 !ひっくり返した
      END IF
      LET Y=MOD(i+3,N) !左回り
      IF A(Y)=0 THEN !4枚目を表にする
         LET A(Y)=1
         CALL try(A,N,B)
         LET A(Y)=0
         LET FLG=-1
      END IF
   END IF
NEXT i

IF FLG=0 THEN !これ以上ひっくり返せない
!!MAT PRINT A; !debug
   LET S=0 !ビットパターンで並びを記録する
   FOR i=0 TO N-1
      LET S=S*2+A(i)
   NEXT i
   LET B(S)=B(S)+1
END IF
END SUB


0  0
1  3.77002827521206E-3
2  .239396795475966
3  .567389255419416
4  .183788878416588
5  5.6550424128181E-3
6  0
7  0
8  0
9  0
10  0

 

Re: トランプ遊びでの数理

 投稿者:GAI  投稿日:2014年 8月27日(水)19時39分21秒
  > No.3471[元記事へ]

山中和義さんへのお返事です。

しばっちさんに作って頂いたプログラムで100万回試行したら
裏向きのまま残るカードの枚数が
1枚  :    24回
2枚  : 18985回
3枚  :345183回
4枚  :572847回
5枚  : 62961回
なる結果をえていました。

一方山中さんのプログラムでは
下記の結果ですので随分開きがあるように感じます。
これはどの様に解釈しておけば良いのでしょうか?
また確率値の前に1358080が出力されていますが
これはなにを表す数字ですか。
またカードの枚数を13枚で調べるときは
プログラムの
LET X$=right$("000000000"&BSTR$(i,2),N) !パターン
の部分は
LET X$=right$("000000000000"&BSTR$(i,2),N) !パターン
にしておけばいいのでしょうか?

  1358080
>  0  0
>  1  3.77002827521206E-3
>  2  .239396795475966
>  3  .567389255419416
>  4  .183788878416588
>  5  5.6550424128181E-3
>  6  0
>  7  0
>  8  0
>  9  0
>  10  0
>
>  
 

Re: トランプ遊びでの数理

 投稿者:山中和義  投稿日:2014年 8月27日(水)22時44分10秒
  > No.3472[元記事へ]

GAIさんへのお返事です。

> 下記の結果ですので随分開きがあるように感じます。
> これはどの様に解釈しておけば良いのでしょうか?

まだひっくり返せるのに、途中で中断しているのではないでしょうか。


> また確率値の前に1358080が出力されていますが
> これはなにを表す数字ですか。

「場合の数」の総数です。
真の値は、円順列なので、1番目の位置を固定しないといけないと思います。


> またカードの枚数を13枚で調べるときは
> プログラムの
> LET X$=right$("000000000"&BSTR$(i,2),N) !パターン
> の部分は
> LET X$=right$("000000000000"&BSTR$(i,2),N) !パターン
> にしておけばいいのでしょうか?

LET X$=right$(REPEAT$("0",N-1)&BSTR$(i,2),N) !パターン

 

Re: 不定方程式の解

 投稿者:山中和義  投稿日:2014年 8月28日(木)06時30分31秒
  > No.3465[元記事へ]

問題
n個のさいころを投げて、出たn個の目の積が6の倍数である確率を求めよ。

答え
少なくとも1つが偶数 かつ 少なくとも1つが3の倍数 であればよい。
その確率は、余事象から、(1-(1/2)^n)(1-(2/3)^n)
(終り)


その他の解法

●漸化式による
3個のさいころを大,中,小とする。
まず、大,中の積が、
 2の倍数になるのは、27通り
 3の倍数になるのは、20通り
 6の倍数になるのは、15通り
である。
残りの小の目が、
1,5の場合、大,中の積が6の倍数のとき、15×2通り
2,4の場合、大,中の積が3の倍数のとき、20×2通り
3の場合、大,中の積が2の倍数のとき、27通り
6の場合、大,中の積は何でもよいので、6^2=36通り
よって、15×2+20×2+27+36=133通り


FOR N=1 TO 10
   PRINT N; f6(N); f6(N)/6^N; (1-(1/2)^N)*(1-(2/3)^N)
NEXT N
END

EXTERNAL FUNCTION f2(n) !2の倍数
IF N=1 THEN
   LET f2=3 !2,4,6
ELSE
!n番目について、
!1,3,5のとき、(n-1)番までが2の倍数なら、2の倍数になる。
!2,4,6のとき、(n-1)番までは何でも良い。
   LET f2=3*f2(n-1)+3*6^(n-1)
END IF
END FUNCTION

EXTERNAL FUNCTION f3(n) !3の倍数
IF N=1 THEN
   LET f3=2 !3,6
ELSE
!1,2,4,5のとき、(n-1)番までが3の倍数
!3,6のとき、(n-1)番までは何でも良い
   LET f3=4*f3(n-1)+2*6^(n-1)
END IF
END FUNCTION

EXTERNAL FUNCTION f6(n) !6の倍数
IF N=1 THEN
   LET f6=1 !6
ELSE
!1,5のとき、(n-1)番までが6の倍数
!2,4のとき、(n-1)番までが3の倍数
!3のとき、(n-1)番までが2の倍数
!6のとき、(n-1)番までは何でも良い
   LET f6=2*f6(n-1)+2*f3(n-1)+1*f2(n-1)+1*6^(n-1)
END IF
END FUNCTION


●不定方程式 x[1]x[2]x[3]…x[n]=m、1≦x[1]≦x[2]≦x[3]≦…≦x[n]≦6 の解
例 n=3のとき、xyz=6k

LET N=3 !n個の変数
DIM X(0 TO N) !※0番目は番兵
LET X(0)=1
PUBLIC NUMERIC C,S
LET C=0
LET S=0
LET K=1
DO WHILE 6*K<=6^N
   CALL try(1, N,X,6*K)
   LET K=K+1
LOOP
PRINT C;"通り"
PRINT S;"通り" !場合の数
END

EXTERNAL SUB try(P, N,X(),M) !x[1]x[2]x[3]…x[n]=m の解
IF P=N THEN !最後の変数のとき
   IF X(P-1)<=M AND M<=6 THEN
      LET X(P)=M
      LET C=C+1
      MAT PRINT X;

      DIM B(6) !n!/(p!q!…r!)通りに並べる
      MAT B=ZER
      FOR i=1 TO N
         LET B(X(i))=B(X(i))+1
      NEXT i
      LET S=S+PermFactorialM(B,6)
   END IF
ELSE
   FOR K=X(P-1) TO 6 !昇順
      IF MOD(M,K)=0 THEN !約数なら
         LET X(P)=K
         CALL try(P+1, N,X,M/K) !次へ
      END IF
   NEXT K
END IF
END SUB


!COMB.LIB 抜粋

EXTERNAL FUNCTION PermFactorialM(B(),M) !同じものを含む順列の「場合の数」
LET s=B(M) !総数 r, … ,q+ … +r,p+q+ … +r
LET t=1 !組合せ comb(r,r), … ,comb(q+ … +r,q),comb(p+q+ … +r,p)
FOR i=M-1 TO 1 STEP -1
   LET s=s+B(i)
   LET t=t*COMB(s,B(i)) !組合せ順列
NEXT i
LET PermFactorialM=t
END FUNCTION



-----------------------------------------

発展問題
n個のさいころを投げて、出たn個の目の積が立方数となる場合の数を求めよ。

答え
不定方程式版のプログラムを

 :
LET S=0
LET K=1
DO WHILE K^3<=6^N
   CALL try(1, N,X,K^3)
   LET K=K+1
LOOP
PRINT C;"通り"
 :

と変更して、実行する。


類題
大中小3個のさいころを投げるとき、目の積が60になるのは何通りあるか。
答え
 :
LET S=0
CALL try(1, N,X,60)
PRINT C;"通り"
 :
(終り)


別解
(1+x+y+x^2+z+xy)^n を展開したとき、
 x^(3a) y^(3b) z^(3c)
という形にかける項の係数をすべて足し合わせたものになる。
(終り)


OPTION ARITHMETIC COMPLEX !複素数を扱う
LET N=2 !さいころの個数
LET K=3 !k乗
LET w=EXP(2*PI*COMPLEX(0,1)/K) !w^k-1=0
LET S=0
FOR A=0 TO K-1
   FOR B=0 TO K-1
      FOR C=0 TO K-1
         LET S=S+(1+w^A+w^B+w^(2*A)+w^C+w^(A+B))^N
      NEXT C
   NEXT B
NEXT A
S=S/K^3 !場合の数
PRINT S
END


 

こんな実験して見ました

 投稿者:lark12_long  投稿日:2014年 8月29日(金)14時34分34秒
  '
'   汎用シミュレータ.bas
'
'     マウス左クリック保持で一時停止
'     マウス右クリックで打ち切り終了
'
'     H26-08-29 lark12
'
'
width= 1100
height=660
SET BITMAP SIZE width, height

gx=width
gy=2

'左端,右端,下端,上端
set window  -gx/20-50,gx,-gy,gy

'描画エリアの背景色着色範囲設定
set area color 1 !'黒
plot area : -gx,-gy;-gx,gy;gx,gy;gx,-gy

'座標描画
  draw axes (50,0.1)
  draw grid(50,0.1)
'------------------------------------------------------------

n=20                              '出力信号数
dim p(n)                          '出力信号
dim po(n)                         '前回出力信号
dim p$(n)                         '出力信号名

dt=0.01                           '計算ピッチ
dtx=dt*100                        '表示ピッチ:1/100単位
'---------------------------------------------
do
  '計算式記述subコール
   call cal1                       '一時遅れ
  'call cal2                       '連立方程式
  'call cal3                       'sin^2+cos^2=1に成る様子

'---------------------------------------------
   call draw
   t=t+dt
   mouse poll xm,ym,left,right
   if right=1 then stop             '終了

   do while left=1                  'ポーズ
     mouse poll xm,ym,left,right
   loop

loop
'-----------------------------------------------
'計算式記述

sub cal1
  '1次遅れ
  ta=1                   '時定数
  k=1                    'ゲイン
  x=1                    '入力信号
  y=y+( k*x-y)/ta*dt     '一時遅れ出力
  z=0.63                 '63%値

  p(0)=x    :p$(0)="x"
  p(1)=y    :p$(1)="y"
  p(2)=z    :p$(2)="z"

end sub
'----------------------------------------------------
sub cal2
'連立方程式
'解は a=0.1:b=0.2:c=0.3:d=0.4
'5*a+3*b-4*c+2*d=0.7
'4*a-3*b+4*c-2*d=0.2
'5*a+4*b+5*c-5*d=0.8
'2*a+10*b+10*c+9*d=8.8

'原始式を、下記の様に一時遅れの形に変形し、
'繰り返し計算し収束した値が解となる
  a=a+( (0.7-(3*b-4*c+2*d) )/5  -a)*dt
  b=b+( (0.2-(4*a+4*c-2*d) )/(-3) -b)*dt
  c=c+( (0.8-(5*a+4*b-5*d) )/5-c)*dt
  d=d+( (8.8-(2*a+10*b+10*c) )/9-d)*dt

  p(0)=a      :p$(0)="a"
  p(1)=b      :p$(1)="b"
  p(2)=c      :p$(2)="c"
  p(3)=d      :p$(3)="d"

end sub
'----------------------------------------------------
sub cal3
  a=sin(t*2)
  b=cos(t*2)
  c=a^2+b^2   'が1になる様子

  p(0)=a      :p$(0)="a"
  p(1)=b      :p$(1)="b"
  p(2)=c      :p$(2)="c"

end sub
'----------------------------------------------------
sub draw
   '出力信号グラフ、信号名の表示
   local xd1,yd1,xd2,yd2
  '表示記述
   set draw mode hidden
   set line width 2

   '変数名表示エリアクリア
   xd1=-100:yd1=-2
   xd2=xd1+60:yd2=2
   line(xd1,yd1)-(xd2,yd2),1,bf

   '左端に出力信号名を、その値の大きさ位置に表示
   for i=0 to n-1
     col=mod(i,6)+3
     line( tx-dtx,po(i))-(tx,p(i)),col
     po(i)=p(i)

     xd1=-100:yd1=p(i)
     set text color col
     set text font "MS 明朝",20
     plot text,at xd1,yd1:p$(i)
   next i
   set text font "MS 明朝",11

   tx=tx+dtx

   'グラフが画面右端まで到達したら、画面更新
   if tx>1100 then
     '描画エリアの背景色着色範囲設定
      set area color 1 !'黒
      plot area : -gx,-gy;-gx,gy;gx,gy;gx,-gy

     '座標軸描画
      draw axes (50,0.1)
      draw grid(50,0.1)
      tx=0
   end if

   set text color 5
   set text font "MS 明朝",20
   plot text,at 850,-1.7:"横軸=         sec"
   plot text,at 850+80,-1.7,using"##.###":0.1

   set draw mode explicit

end sub
'-------------------------------------------
 

TSP 問題

 投稿者:SECOND  投稿日:2014年 8月31日(日)01時25分23秒
  DEBUG ON
!---------------------------------------------------------------------
! TSP 問題 (Traveling Salesman Problem)

!---------------------------------------------------------------------
! 先日の、lark12_long さんの投稿で、紹介されていた「論文」の結果が、
! どんな物か 見る目的で、できる限り、忠実に実行してみた。
!
! 都市配置が、等辺の格子状の場合は 特別で、
! 最短コースが、目視で直視でき、それを、100% の距離として比較すると、
!
! 平均して 105% 前後の距離になるコースが、比較的 安定して得られる。
! 条件を探すと、101~102% の結果も、まれにあるが、困難。

!---------------------------------------------------------------------
! 自己組織化マップ法 (Self Organizing Maps)
! SOM による巡回セールスマン問題の解法Ⅱ (アンジェニオールのアルゴリズム)
! http://www.lib.fit.ac.jp/pub/ronsyu/42_1/011.pdf

!---------------------------------------------------------------------
! 左クリックで、中間結果の重ね書き 一時停止。 再 左クリックで継続。
! 右クリックで、強制終了。(100 都市では、500M.P3 でも 75 秒程度)
!
!2次元座標を、xy で扱うと煩雑なため、1変数の複素数で操作している。
!
!   x(i)= 都市(i)の座標          |   c(j)= node(j)の座標
!cind(i)= 都市(i)の対応node番号  |xind(j)= node(j)の対応都市番号
!                                | nac(j)= node(j)の対応都市無しの回数
!---------------------------------------------------------------------
OPTION ARITHMETIC COMPLEX
LET hw=460
LET vw=460
SET BITMAP SIZE hw+41, vw+41
SET WINDOW -20, hw+20, -20, vw+20      !左,右, 下,上
!---
SET COLOR MIX(0) 0,0,0                 !CLEAR 文で黒にする。
SET COLOR MIX(1) 1,1,1                 !text,line, 初期カラーを白にする。
SET POINT STYLE 7
SET TEXT font "",12
SET TEXT COLOR 1
LET tx0=COMPLEX(0,vw-8)                !文字列 左下端
RANDOMIZE 1
!
!------------調整項目( 定数)
LET M_=100                             !都市数
LET C_=100                             !初期 node 数 1~M_
LET G_=50                              !node 移動パラメーター
LET a_= 0.95                           !α= G_ の更新係数。G_(t+1)=α*G_(t)
LET r_=-0.2                            !γ= α の更新係数。α(t+1)=α(t)+γ/M_*(C_(t)-C_(t-1))
!
!--------------
OPTION BASE 0
LET w=M_*5                             !node 数の上限
DIM    x(M_-1)                         !都市 座標
DIM cind(M_-1)                         !都市 番号 に対する node番号
DIM xind(w)                            !node 番号 に対する 都市番号
DIM    c(w)                            !node 座標
DIM  nac(w)                            !no access counter
CALL set_grid_ini                      !都市配置が、格子状の場合の準備(hn,vn,ss1)
!
!------------調整項目( 都市 の並べ方)
CALL set_grid(x)                       !格子状 配置( 都市 )
!CALL set_circle(x)                     !サークル 配置( 都市 )
CALL shuffle(x)                        !番号シャッフル( 都市 )
!CALL set_random(x)                     !ランダム 配置( 都市 )
!
!------------調整項目( 初期 node の並べ方)
!CALL set_grid(c)                       !格子状 配置( node )
CALL set_circle(c)                     !サークル 配置( node )
!CALL shuffle(c)                        !番号シャッフル( node )
!CALL set_random(c)                     !ランダム 配置( node )
!
!----------------------------------------
! メイン
!----------------------------------------
CLEAR
CALL pl_node_run                       !都市 node 位置と、その連結線
IF 1< C_ THEN pause 1
!
MAT cind=(-1)*CON                      !都市番号 に対応する node番号 クリア
MAT xind=(-1)*CON                      !node番号 に対応する 都市番号 クリア
MAT nac=ZER                            !no access counter
LET Mcyc=0                             !都市一巡の回数
DO
   LET Cb=C_
   FOR i=0 TO C_-1
      LET nac(i)=nac(i)+1              !各 node 毎の、no access counter
   NEXT i
   FOR ss_=0 TO M_-1
      CALL Get_node                    !都市番号ss_に 最近傍node 取得
      !--
      SET DRAW mode hidden
      CLEAR
      CALL pl_node_run                 !都市位置表示と、全node の連結線
      SET DRAW mode explicit
      !--
      mouse poll mox,moy,mlb,mrb       !マウス状態取得
      IF mlbk< mlb OR 0< mrb THEN
         CALL pl_node_z                !都市位置表示と、node の対応都市+孤立node の連結線
         DO
            LET mlbk=mlb
            mouse poll mox,moy,mlb,mrb
            WAIT DELAY .03
            IF 0< mrb THEN STOP        !右クリック停止
         LOOP UNTIL mlbk< mlb          !左クリック続行
      END IF
      LET mlbk=mlb
      !--
      CALL move                        !都市番号ss_対応の 全node 移動
   NEXT ss_
   CALL Remove                         !連続3巡回、選ばれなかった node の除去
   LET G_=G_*a_                        !node 移動パラメーター G_ の更新
   LET a_=a_+r_/M_*(C_-Cb)             !更新係数 a_
   LET Mcyc=Mcyc+1                     !都市一巡の回数
   !--
   IF M_=C_ THEN LET cm_eq=cm_eq+1 ELSE LET cm_eq=0
LOOP UNTIL 1< cm_eq
CLEAR
CALL pl_node_z                         !都市位置表示と、node の対応都市+孤立node の連結線

!----------------------------------------
! 連続3巡回、選ばれなかった node の除去
!----------------------------------------
SUB Remove
   LET j=0
   FOR i=0 TO C_-1
      IF nac(i)< 3 THEN                !no access 3回未満の node を前に詰める
         LET c(j)=c(i)                 !node 座標
         LET xind(j)=xind(i)                       !対応 都市番号
         IF 0<=xind(j) THEN LET cind( xind(j))=j   !対応 都市の 対応 node番号
         LET nac(j)=nac(i)                         !no access node counter
         LET j=j+1
      END IF
   NEXT i
   LET C_=j
END SUB

!----------------------------------------
! 都市 ss_ の最近傍 node 取得
!----------------------------------------
SUB Get_node
   IF 0<=cind(ss_) THEN LET xind( cind(ss_))=-1
   LET lmin=1e9
   FOR j=0 TO C_-1
      LET l=ABS( x(ss_)-c(j) )         !都市ss_ と、各 node 間距離
      IF l< lmin THEN
         LET jc=j                      !最近傍の node 番号
         LET loc=c(j)                  !  〃     node 座標
         LET lmin=l                    !  〃     その距離
      END IF
   NEXT j
   IF 0<=xind(jc) THEN CALL add        !使用中 node の生成(複製)
   LET xind(jc)=ss_                    !node jc → 対応都市 xi
   LET nac(jc)=0                       !node jc:リセット no access node counter
   LET cind(ss_)=jc                    !都市 xi → 対応node jc
END SUB

!----------------------------------------
! node の生成
!----------------------------------------
SUB add
   LET jc=jc+1                         !複製node番号jc を後続。
   FOR i=C_-1 TO jc STEP -1            !既存node jc ~C_ を後へシフト
      LET j=i+1                        !転送元i → 転送先j
      !--
      LET c(j)=c(i)                            !node i の座標
      LET xind(j)=xind(i)                      !node i 対応都市番号
      LET nac(j)=nac(i)                        !node i:no access node counter
      IF 0<=xind(i) THEN LET cind( xind(i))=j  !node i の対応都市xind(i) → 対応node j
   NEXT i
   LET C_=C_+1
   LET c(jc)=loc                       !複製node 座標
END SUB

!----------------------------------------
! 最近傍 node と周辺の移動 更新
!
! 座標移動node(j)= node(j)+ EXP[-{node番号間数(I~j)/G_}^2] * 座標差{都市(I)-node(j)}/√2
!----------------------------------------
SUB move                                     !都市番号ss_の対応node jc と 周辺node 移動
   LET jc=cind(ss_)
   FOR j=0 TO C_-1
      LET n=MIN( MOD(jc-j,C_), MOD(j-jc,C_))
      LET fgn=EXP(-(n/G_)^2)/SQR(2)          !更新率
      LET c(j)=c(j)+fgn*( x(ss_)-c(j))
   NEXT j
END SUB

!----------------------------------------
! 描画パーツ
!----------------------------------------
! 都市位置
SUB pl_city
   FOR i=0 TO M_-1
      IF 0<=cind(i) THEN SET POINT COLOR 6 ELSE SET POINT COLOR 5
      PLOT POINTS: x(i)                !黄: 都市 with node  シアン: 都市 off node
   NEXT i
END SUB

!----都市位置表示と、node の対応都市+孤立node の連結線
SUB pl_node_z
   CALL pl_city                        !都市位置
   SET POINT COLOR 5
   FOR i=0 TO C_-1
      IF xind(i)< 0 THEN PLOT POINTS: c(i)   !対応都市の無い node のみ 位置を加える
   NEXT i
   SET LINE COLOR 5
   LET TL=0
   IF 0<=xind(0) THEN LET wb=x( xind(0)) ELSE LET wb=c(0)
   FOR i=C_-1 TO 0 STEP -1
      IF 0<=xind(i) THEN LET w=x( xind(i)) ELSE LET w=c(i)
      LET TL=TL+ABS(w-wb)
      PLOT LINES: wb;w                 !連結線
      LET wb=w
   NEXT i
   !----都市数 node数 一巡回数 距離
   PLOT label,AT tx0 ,USING "都市数=#### node数=#### 都市一巡の回数=### 距離=###.##": M_,C_,Mcyc,TL/ss1
END SUB

!----都市位置表示と、全node の連結線
SUB pl_node_run
   CALL pl_city                        !都市位置
   FOR i=0 TO C_-1
      IF 0<=xind(i) THEN SET POINT COLOR 4 ELSE SET POINT COLOR 5
      PLOT POINTS: c(i)                !赤: node with 都市  シアン: node off 都市
   NEXT i
   SET LINE COLOR 4
   FOR i=0 TO C_-1
      PLOT LINES: c(i);                !赤: 連結線 of node
   NEXT i
   PLOT LINES: c(0)
   !----都市数 node数 一巡回数
   PLOT label,AT tx0 ,USING "都市数=#### node数=#### 都市一巡の回数=###": M_,C_,Mcyc
END SUB

!---------------------------------------------------
! 都市、node の初期 配置
!---------------------------------------------------
SUB set_grid_ini                       !都市配置が、格子状の場合の準備。
   LET vn=INT( SQR(M_))                !他の配置になっても、距離の単位長 ss1 を共用。
   LET hn=vn
   IF vn*hn< M_ THEN LET hn=vn+1       !hn: 横列数 (端数列込み)
   IF vn*hn< M_ THEN LET vn=vn+1       !vn: 縦行数
   LET ss1=vw/vn                       !距離の単位長 (格子の一辺の長さ)
END SUB

SUB set_grid(a())                                !格子状配置
   IF M_< UBOUND(a) THEN LET w=C_ ELSE LET w=M_  !都市・node の識別
   LET mi=0
   FOR i=0 TO hn-1
      FOR j=0 TO vn-1
         LET a(mi)=ss1*COMPLEX(i,j)
         LET mi=mi+1
         IF w<=mi THEN EXIT SUB
      NEXT j
   NEXT i
END SUB

SUB set_circle(a())                              !サークル配置
   IF M_< UBOUND(a) THEN LET w=C_ ELSE LET w=M_  !都市・node の識別
   LET x1=x(1)
   IF x1=0 THEN                                  !都市座標が 未設定の場合は、
      LET x2=ss1*COMPLEX(hn-1,vn-1)              !広がりを、M_ の格子状とし、
   ELSE                                          !都市座標が 設定済みの場合は、
      LET x2=x1                                  !広がりの、最大最小をさがす
      FOR i=0 TO M_-1
         LET x1=COMPLEX( MIN(re(x1),re(x(i))), MIN(im(x1),im(x(i))) )
         LET x2=COMPLEX( MAX(re(x2),re(x(i))), MAX(im(x2),im(x(i))) )
      NEXT i
   END IF
   LET xc=(x1+x2)/2                              !サークル中心点
   LET ds=2*PI/w
   FOR i=0 TO w-1
      LET a(i)=xc+COMPLEX( re(x2-xc)*COS(i*ds), im(x2-xc)*SIN(i*ds) )
   NEXT i
END SUB

SUB shuffle(a())                                 !番号シャッフル
   IF M_< UBOUND(a) THEN LET w=C_ ELSE LET w=M_  !都市・node の識別
   FOR i=0 TO w-1
      LET j=INT(RND*w)
      swap a(i),a(j)
   NEXT i
END SUB

SUB set_random(a())                              !ランダム配置
   IF M_< UBOUND(a) THEN LET w=C_ ELSE LET w=M_  !都市・node の識別
   LET j=0
   DO
      LET a(j)=COMPLEX( hw*(.8*RND+.1), vw*(.8*RND+.1))
      FOR i=0 TO j-1
         IF ABS(a(i)-a(j))< 7 THEN EXIT FOR      !隣接間隔不足、再試行
      NEXT i
      IF j<=i THEN LET j=j+1
   LOOP UNTIL w<=j
END SUB

END
 

RE:TSP問題

 投稿者:lark12_long  投稿日:2014年 8月31日(日)10時37分6秒
  SECOND様

プログラム提示有難うございます
勉強させて頂きます
 

Re: TSP 問題

 投稿者:SECOND  投稿日:2014年 9月 1日(月)00時32分58秒
  > No.3476[元記事へ]

DEBUG ON
!---------------------------------------------------------------------
! TSP 問題 (Traveling Salesman Problem) の付録
!---------------------------------------------------------------------
! 先の投稿で、
! ・・都市配置が、等辺の格子状の場合は 特別で、
!   最短コースが、目視で直視でき、それを、100% の距離として・・・
! としたが、
! それを、任意な都市数 M_ で、順に表示してみるプログラム。
!
! 左クリック押し下げの間、一時停止。 右クリック終了。

!---------------------------------------------------------------------
! これを、初期 node とすれば、先のプログラムは、100% の最短距離へ
! 引き込めるけれども、node 移動パラメーター G_=1~1.4 くらいの時だけで、
! 吸引と言えるか否か、G_=40~50 では、形を失い、あまり意味はないようです。

! この実験をするには、先の投稿プログラムを以下のようにします。
!
!1)----------調整項目( 定数 )
!      LET C_=M_
!      LET G_=1~1.4
!2)----------調整項目( 都市 の並べ方)
!      CALL set_grid(x)      ← 投稿時の格子状のまま
!      CALL shuffle(x)       ←シャッフルの有無は、どちらでもよい
!3)----------調整項目( 初期 node の並べ方)
!      CALL set_grid_order(c)   ←このcall追加、他のcall停止。
!
!4)末尾に、今回の、SUB set_grid_order(x()) ~ END SUB を追加。

!---------------------------------------------------------------------
OPTION ARITHMETIC COMPLEX
LET hw=460
LET vw=460
SET BITMAP SIZE hw+41, vw+41
SET WINDOW -20, hw+20, -20, vw+20   !左,右, 下,上
!---
SET COLOR MIX(0) 0,0,0              !CLEAR 文で黒にする。
SET COLOR MIX(1) 1,1,1              !text,line, 初期カラーを白にする。
SET POINT STYLE 7
SET TEXT font "",14
SET TEXT COLOR 1
LET tx0=COMPLEX(0,vw-8)             !文字列 左下端
!
OPTION BASE 0
DIM x(600)                          !都市 座標
!
!----------------------------------------
! メイン
!----------------------------------------
FOR M_=100 TO 1 STEP -1               !M_= 都市数
   LET vn=INT( SQR(M_) )
   LET hn=vn
   IF vn*hn< M_ THEN LET hn=vn+1      !hn: 横列数 (端数列込み)
   IF vn*hn< M_ THEN LET vn=vn+1      !vn: 縦行数
   ! LET ss1=vw/vn                      !距離の単位長 (格子の一辺の長さ) ※M_ が昇順の時。
   IF ss1=0 THEN LET ss1=vw/vn        !距離の単位長 (格子の一辺の長さ) ※最初の幅を固定
   !--
   CALL set_grid_order(x)             !格子状配置 最短距離コース
   !--
   SET DRAW mode hidden
   CLEAR
   CALL pl_city_sts                   !表示
   SET DRAW mode explicit
   LET i=0
   DO
      mouse poll mox,moy,mlb,mrb
      IF mrb=1 THEN EXIT FOR
      LET i=i+1-mlb
      WAIT DELAY .05
   LOOP UNTIL 18<=i
NEXT M_

!----------------------------------------
! 描画
!----------------------------------------
SUB pl_city_sts             !都市と、その連結線
   SET POINT COLOR 6
   SET LINE COLOR 5
   LET TL=0
   LET wb=x(0)
   FOR i=M_-1 TO 0 STEP -1
      LET w=x(i)
      PLOT POINTS: w
      PLOT LINES: wb;w
      LET TL=TL+ABS(w-wb)
      LET wb=w
   NEXT i
   !----都市数 距離
   PLOT label,AT tx0 ,USING "都市数=#### 距離=###.##": M_,TL/ss1
END SUB

!-------------------------------
! 都市 格子状配置 最短距離コース
!-------------------------------

!--+----------------------------+------------------------
! ! 横:偶数         ! 横:奇数
!--+----------------------------+------------------------
! !・・・・・・ ┌┐┌┐┌┐ !・・・・・ ┌┐┌→┐
! !・・・・・・ ↑↓↑↓↑↓ !・・・・・ ↑↓↑┌┘
! !・・・・・・ ↑└┘└┘↓ !・・・・・ ↑└┘└┐
! !・・・・・・ └←←←←┘ !・・・・・ └←←←┘
! !              !
!縦!・・・・・  ┌┐┌┐ <  !・・・・  ┌┐┌ <
! !・・・・・・ ↑↓↑↓↑>  !・・・・・ ↑↓↑┌>
!偶!・・・・・・ ↑└┘└┘↓ !・・・・・ ↑└┘└┐
!数!・・・・・・ └←←←←┘ !・・・・・ └←←←┘
! !              !
! !・・・・・  ┌┐┌→┐  !・・・・  ┌┐┌┐
! !・・・・・  ↑↓↑┌┘  !・・・・  ↑↓↑↓
! !・・・・・・ ↑└┘└→┐ !・・・・・ ↑└┘└┐
! !・・・・・・ └←←←←┘ !・・・・・ └←←←┘
! !              !
! !・・・・・  ┌┐┌→┐  !・・・・  ┌┐┌┐  !・・・・ ┌┐┌┐
! !・・・・・  ↑↓↑┌┘  !・・・・  ↑↓↑↓  !・・・・ ↑↓↑↓
! !・・・・・  ↑└┘└ <  !・・・・  ↑└┘ <  !・・・・ ↑└┘↓
! !・・・・・・ └←←←←>  !・・・・・ └←←←>  !・・・・ └←←┘
!--+----------------------------+------------------------
! ! 横:偶数         ! 横:奇数
!--+----------------------------+------------------------
! !・・・・・・ ┌┐┌┐┌┐ !・・・・・ ┌┐┌→>
! !・・・・・・ ↑↓↑↓↑↓ !・・・・・ ↑↓↑ <┐
! !・・・・・・ ↑↓↑↓↑↓ !・・・・・ ↑↓↑┌┘
! !・・・・・・ ↑└┘└┘↓ !・・・・・ ↑└┘└┐
! !・・・・・・ └←←←←┘ !・・・・・ └←←←┘
! !              !
!縦!・・・・・  ┌┐┌┐ <  !・・・・  ┌┐┌┐
! !・・・・・・ ↑↓↑↓↑>  !・・・・・ ↑↓↑└┐
!奇!・・・・・・ ↑↓↑↓↑↓ !・・・・・ ↑↓↑┌┘
!数!・・・・・・ ↑└┘└┘↓ !・・・・・ ↑└┘└┐
! !・・・・・・ └←←←←┘ !・・・・・ └←←←┘
! !              !
! !・・・・・  ┌┐┌→┐  !・・・・  ┌┐┌┐
! !・・・・・  ↑↓↑┌┘  !・・・・  ↑↓↑ <
! !・・・・・・ ↑↓↑↓┌┐ !・・・・・ ↑↓↑┌>
! !・・・・・・ ↑└┘└┘↓ !・・・・・ ↑└┘└┐
! !・・・・・・ └←←←←┘ !・・・・・ └←←←┘
! !              !
! !・・・・・  ┌┐┌→┐  !・・・・  ┌┐┌┐
! !・・・・・  ↑↓↑┌┘  !・・・・  ↑↓↑↓
! !・・・・・  ↑↓↑↓ <  !・・・・  ↑↓↑↓
! !・・・・・・ ↑└┘└┘>  !・・・・・ ↑└┘└┐
! !・・・・・・ └←←←←┘ !・・・・・ └←←←┘
! !--------- 特2/------------!
! !・・・・・  ┌┐┌→>   !・・・・  ┌┐┌┐  !・・・・ ┌┐┌┐
! !・・・・・  ↑↓↑ <┐  !・・・・  ↑↓↑↓  !・・・・ ↑↓↑↓
! !・・・・・  ↑↓↑┌┘  !・・・・  ↑↓↑↓  !・・・・ ↑↓↑↓
! !・・・・・  ↑└┘└ <  !・・・・  ↑└┘ <  !・・・・ ↑└┘↓
! !・・・・・・ └←←←←>  !・・・・・ └←←←>  !・・・・ └←←┘
!--+----------------------------+------------------------

SUB set_grid_order(x())
   LET rn=MOD(M_,vn)                  !rn: 右端列 の端数
   IF rn=0 THEN LET rn=vn             !    (端数0不可)
   !--
   LET mi=0
   LET i=0
   FOR j=0 TO vn-1                    !・
      LET x(mi)=ss1*COMPLEX(i,j)      !↑
      LET mi=mi+1                     !・
   NEXT j
   LET i=i+1
   !--
   IF MOD(hn,2)=0 THEN
   !--------------------------------------------横:even
      DO WHILE i< hn-2
         LET j=vn-1                             !→・
         IF i=hn-3 THEN
         !--
            IF MOD(vn,2)=0 THEN
            !-----------------------------------横:even 縦:even
               LET w=CEIL(rn/2)*2   !2,2,4,4,6,6
            ELSE
            !-----------------------------------横:even 縦:odd
               LET w=INT(rn/2)*2+1  !1,3,3,5,5,7,7
               !--
               IF rn=1 THEN
                  LET x(mi)=ss1*COMPLEX(i,j)    !・
                  LET mi=mi+1
                  LET x(mi)=ss1*COMPLEX(i+1,j)  !→
                  LET mi=mi+1
                  LET j=j-1
               END IF
            END IF
            !--
            LET d=1
            FOR j=j TO w STEP -1
               LET x(mi)=ss1*COMPLEX(i,j)       !・
               LET mi=mi+1
               LET i=i+d
               LET x(mi)=ss1*COMPLEX(i,j)       !←→
               LET mi=mi+1
               LET d=-d
            NEXT j
         END IF
         !--
         LET w=j
         FOR j=j TO 1 STEP -1                   !→・
            LET x(mi)=ss1*COMPLEX(i,j)          ! ↓
            LET mi=mi+1                         ! ・
         NEXT j
         LET i=i+1
         !--
         IF i< hn-2 AND 0< w THEN LET w=vn-1    ! ・
         FOR j=1 TO w                           ! ↑
            LET x(mi)=ss1*COMPLEX(i,j)          !→・
            LET mi=mi+1
         NEXT j
         LET i=i+1
      LOOP
      !--
      FOR j=rn-1 TO 1 STEP -1                   !→・
         LET x(mi)=ss1*COMPLEX(i,j)             ! ↓
         LET mi=mi+1                            ! ・
      NEXT j
   ELSE
   !--------------------------------------------横:odd
      DO WHILE i< hn-3
         FOR j=vn-1 TO 1 STEP -1                !→・
            LET x(mi)=ss1*COMPLEX(i,j)          ! ↓
            LET mi=mi+1                         !
         NEXT j
         LET i=i+1
         FOR j=1 TO vn-1                        ! ・
            LET x(mi)=ss1*COMPLEX(i,j)          !→↑
            LET mi=mi+1                         !
         NEXT j
         LET i=i+1
      LOOP
      !--
      FOR j=vn-1 TO rn STEP -1                  !→・
         LET x(mi)=ss1*COMPLEX(i,j)             ! ↓
         LET mi=mi+1                            !
      NEXT j
      !--
      LET d=1
      FOR j=j TO 1 STEP -1
         LET x(mi)=ss1*COMPLEX(i,j)             !・
         LET mi=mi+1
         LET i=i+d
         LET x(mi)=ss1*COMPLEX(i,j)             !←→
         LET mi=mi+1
         LET d=-d
      NEXT j
   END IF
   FOR i=hn-1 TO 1 STEP -1            !
      LET x(mi)=ss1*COMPLEX(i,j)      !
      LET mi=mi+1                     !←・
   NEXT i
END SUB

END
 

RE1:TSP問題

 投稿者:lark12_long  投稿日:2014年 9月 1日(月)07時43分24秒
  SECOND様

TSP問題RUNさせて、観察いたしました

自分が半製品状態で作ったものは、収束過程で交差が発生し、途中で交差が解消されない場合がありましたが、提供頂いたプログラムでは、途中経過に於いて交差が発生することな無いですね

提供頂いたプログラム、複素数を使っているので、私に取っては難解で勉強中です

提供頂いたプログラム、アンジェニオール法を、完全にシミュレートしてると思います

しかし プログラミング技術 すごいでんな....  ボソ
 

Re: RE1:TSP問題

 投稿者:SECOND  投稿日:2014年 9月 1日(月)13時35分8秒
  lark12_long 様

G_ が小さい場合、交差ができる可能性は、残っています。
「論文」掲載のデーターの中にも、交差が残っている部分が、ありました、、
都市位置のシャッフル状態、node 移動処理、移動パラメ-タG の組合せで発生するのは、
分っているのですが・・、何度、試行錯誤、書き直したことか、、仕方ないです。
 

カレンダー

 投稿者:しばっち  投稿日:2014年 9月 2日(火)19時16分5秒
  PUBLIC STRING SEKKI24$(0 TO 23, 0 TO 1),QROKUYOU$,QJUKKAN$,Z$
PUBLIC NUMERIC QYEAR,QURUU,QMONTH,QDAY,QMAGE,QMAGENOON,QILLUMI,QMPHASE,RM_SUN0
LET A4=297/210
!'LET B5=257/182
!'LET B4=364/257
LET XSIZE=800
LET YSIZE=INT(XSIZE*A4)
LET XS=XSIZE*75/800
LET YS=YSIZE*250/800
CALL GINIT(XSIZE,YSIZE)
LET HEIGHT=XSIZE*50/800
SET TEXT HEIGHT HEIGHT
DIM DD(12),MON$(12)
MAT READ DD
DATA 31,28,31,30,31,30,31,31,30,31,30,31
MAT READ MON$
DATA 睦月,如月,弥生,卯月,皐月,水無月,文月,葉月,長月,神無月,霜月,師走
LET YEAR = INT(VAL(DATE$)/10000)
LET MONTH = MOD(INT(VAL(DATE$)/100),100)
INPUT  PROMPT "西暦  年=":YEAR$
IF YEAR$<>"" THEN LET YEAR=VAL(YEAR$)
INPUT  PROMPT "月=":MONTH$
IF MONTH$<>"" THEN LET MONTH=VAL(MONTH$)
LET TM = YMDT2JD(YEAR, MONTH, 1, 0, 0, 0)
LET R=MOD(TM+2,7)
SET LINE COLOR "BLACK"
LET XX=R*XSIZE/8
IF YEAR>=1989 THEN LET M$=" 平成"&STR$(YEAR-1988)&"年"
IF YEAR<1989 AND YEAR>=1926 THEN LET M$=" 昭和"&STR$(YEAR-1925)&"年"
IF YEAR<1926 AND YEAR>=1912 THEN LET M$=" 大正"&STR$(YEAR-1911)&"年"
IF YEAR<1912 AND YEAR>=1868 THEN LET M$=" 明治"&STR$(YEAR-1867)&"年"
CALL SYMBOL(XSIZE/2-HEIGHT*3,YSIZE/8,"BLACK",STR$(YEAR)&"年"&" "&STR$(MONTH)&"月")
SET TEXT HEIGHT HEIGHT/2
CALL SYMBOL(XSIZE/2+HEIGHT*4,YSIZE/9,"BLACK",M$)
CALL SYMBOL(XSIZE/2+HEIGHT*5,YSIZE/7,"BLACK",MON$(MONTH))
SET TEXT HEIGHT HEIGHT
FOR I=0 TO 6
   READ A$,COL$
   DATA 日,RED,月,BLACK,火,BLACK,水,BLACK,木,BLACK,金,BLACK,土,BLUE
   CALL SYMBOL(XS+I*XSIZE/8,YSIZE/4,COL$,A$)
NEXT I
CALL CALC_SEKKI24(YEAR)
FOR I=1 TO DD(MONTH)
   LET FL=0
   SET TEXT HEIGHT HEIGHT
   LET COL$=DAYCOLOR$(YEAR,MONTH,I,R)
   CALL SYMBOL(XS+XX,YS+YY,COL$,USING$("##",I))
   CALL CALC_KYUREKI(YEAR,MONTH,I)
   IF QURUU<>0 THEN LET N$="閏" ELSE LET N$=""
   LET TM = YMDT2JD(YEAR, MONTH, I, 0, 0, 0)
   LET A$=CALC_JUKKAN$(TM)
   LET B$=QSEI$(TM)
   SET TEXT HEIGHT HEIGHT*.25
   CALL MOON(XS+XX+HEIGHT*.6,YS+YY+HEIGHT*.5,HEIGHT*.5,QMAGENOON-.5,QILLUMI/100)
   CALL SYMBOL(XS+XX,YS+YY+HEIGHT*.3,COL$,QROKUYOU$&" "&N$&STR$(QMONTH)&"/"&STR$(QDAY))
   CALL SYMBOL(XS+XX,YS+YY+HEIGHT*.6,COL$,A$)
   CALL SYMBOL(XS+XX,YS+YY+HEIGHT*.9,COL$,B$)
   IF Z$<>"" THEN CALL SYMBOL(XS+XX,YS+YY+HEIGHT*1.2,"GREEN",Z$)
   FOR K=0 TO 23
      IF VAL(SEKKI24$(K, 0)(6:7))=MONTH AND VAL(SEKKI24$(K, 0)(9:10))=I THEN
         IF Z$<>"" THEN
            CALL SYMBOL(XS+XX,YS+YY+HEIGHT*1.5,"MAGENTA",SEKKI24$(K, 1))
            LET FL=1
         ELSE
            CALL SYMBOL(XS+XX,YS+YY+HEIGHT*1.2,"MAGENTA",SEKKI24$(K, 1))
            LET FL=2
         END IF
         EXIT FOR
      END IF
   NEXT K
   IF QMPHASE=14 THEN
      LET S$="満月"
   ELSEIF QMPHASE=0 THEN
      LET S$="新月"
   ELSE
   !'LET S$=USING$("##.#",QILLUMI)&"%"
      LET S$=""
   END IF
   IF S$<>"" THEN
      IF Z$="" AND FL<>2 THEN
         CALL SYMBOL(XS+XX,YS+YY+HEIGHT*1.2,"BLUE",S$)
      ELSEIF FL<>1 THEN
         CALL SYMBOL(XS+XX,YS+YY+HEIGHT*1.5,"BLUE",S$)
      ELSE
         CALL SYMBOL(XS+XX,YS+YY+HEIGHT*1.8,"BLUE",S$)
      END IF
   END IF
   LET XX=XX+XSIZE/8
   IF MOD(R+I,7)=0 THEN
      LET XX=0
      LET YY=YY+YSIZE/8
   END IF
NEXT I
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"
CLEAR
END SUB

EXTERNAL SUB SYMBOL(X,Y,COL$,A$)
SET TEXT COLOR COL$
PLOT TEXT,AT X,Y:A$
END SUB

EXTERNAL  FUNCTION DAYCOLOR$(Y,M,N,R)
LET DAYCOLOR$="BLACK"
LET Z$=""
IF MOD(N+R,7)=1 THEN LET DAYCOLOR$="RED"
IF MOD(N+R,7)=0 THEN LET DAYCOLOR$="BLUE"
IF M=1 AND N=1 THEN
   LET DAYCOLOR$="RED"
   LET Z$="元日"
END IF
IF Y>=1973 AND M=1 AND N=2 AND MOD(N+R-1,7)=1 THEN
   LET DAYCOLOR$="RED"
   LET Z$="振替休日"
END IF
IF Y>=2000 THEN
   IF M=1 AND ((R<=1 AND R+N=9) OR (R>1 AND R+N=16)) THEN
      LET DAYCOLOR$="RED"
      LET Z$="成人の日"
   END IF
ELSE
   IF M=1 AND N=15 THEN
      LET DAYCOLOR$="RED"
      LET Z$="成人の日"
   END IF
   IF Y>=1973 AND M=1 AND N=16 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
END IF
IF M=2 AND N=11 THEN
   LET DAYCOLOR$="RED"
   LET Z$="建国記念の日"
END IF
IF Y>=1973 AND M=2 AND N=12 AND MOD(N+R-1,7)=1 THEN
   LET DAYCOLOR$="RED"
   LET Z$="振替休日"
END IF
IF Y>=1900 AND Y<1980 THEN
   IF M=3 AND N=INT(20.8357+0.242194*(Y-1980)-INT((Y-1983)/4)) THEN
      LET DAYCOLOR$="RED"
      LET Z$="春分の日"
   END IF
   IF Y>=1973 AND M=3 AND N=INT(20.8357+0.242194*(Y-1980)-INT((Y-1983)/4))+1 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
   IF M=9 AND N=INT(23.2588+0.242194*(Y-1980)-INT((Y-1983)/4)) THEN
      LET DAYCOLOR$="RED"
      LET Z$="秋分の日"
   END IF
   IF Y>=1973 AND M=9 AND N=INT(23.2588+0.242194*(Y-1980)-INT((Y-1983)/4))+1 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
ELSEIF Y>=1980 AND Y<2100 THEN
   IF M=3 AND N=INT(20.8431 + 0.242194 * (Y - 1980)) - INT((Y - 1980)/4) THEN
      LET DAYCOLOR$="RED"
      LET Z$="春分の日"
   END IF
   IF M=3 AND N=INT(20.8431 + 0.242194 * (Y - 1980)) - INT((Y - 1980)/4)+1 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
   IF M=9 AND N=INT(23.2488 + 0.242194 * (Y - 1980)) - INT((Y - 1980)/4) THEN
      LET DAYCOLOR$="RED"
      LET Z$="秋分の日"
   END IF
   IF M=9 AND N=INT(23.2488 + 0.242194 * (Y - 1980)) - INT((Y - 1980)/4)+1 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
ELSEIF Y>=2100 AND Y<2150 THEN
   IF M=3 AND N=INT(21.8510+0.242194*(Y-1980)-INT((Y-1980)/4)) THEN
      LET DAYCOLOR$="RED"
      LET Z$="春分の日"
   END IF
   IF M=3 AND N=INT(21.8510+0.242194*(Y-1980)-INT((Y-1980)/4))+1 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
   IF M=9 AND N=INT(24.2488+0.242194*(Y-1980)-INT((Y-1980)/4)) THEN
      LET DAYCOLOR$="RED"
      LET Z$="秋分の日"
   END IF
   IF M=9 AND N=INT(24.2488+0.242194*(Y-1980)-INT((Y-1980)/4))+1 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
END IF
IF M=4 AND N=29 THEN
   LET DAYCOLOR$="RED"
   IF Y>=2007 THEN
      LET Z$="昭和の日"
   ELSEIF Y>=1989 AND Y<2007 THEN
      LET Z$="みどりの日"
   ELSEIF Y>1948 THEN
      LET Z$="天皇誕生日"
   END IF
END IF
IF Y>=1973 AND M=4 AND N=30 AND MOD(N+R-1,7)=1 THEN
   LET DAYCOLOR$="RED"
   LET Z$="振替休日"
END IF
IF M=5 AND N=3 THEN
   LET DAYCOLOR$="RED"
   LET Z$="憲法記念日"
END IF
IF Y>=2007 THEN
   IF M=5 AND N=4 THEN
      LET DAYCOLOR$="RED"
      LET Z$="みどりの日"
   END IF
ELSEIF Y>=1988 AND Y<2007 THEN
   IF M=5 AND N=4 THEN
      LET DAYCOLOR$="RED"
      LET Z$="国民の休日"
   END IF
END IF
IF M=5 AND N=5 THEN
   LET DAYCOLOR$="RED"
   LET Z$="こどもの日"
END IF
IF Y>=1973 AND M=5 AND N=6 AND MOD(N+R-1,7)=1 THEN
   LET DAYCOLOR$="RED"
   LET Z$="振替休日"
END IF
IF Y>=2003 THEN
   IF M=7 AND ((R<=1 AND R+N=16) OR (R>1 AND R+N=23)) THEN
      LET DAYCOLOR$="RED"
      LET Z$="海の日"
   END IF
ELSEIF Y>=1996 AND Y<2003 THEN
   IF M=7 AND N=20 THEN
      LET DAYCOLOR$="RED"
      LET Z$="海の日"
   END IF
   IF M=7 AND N=21 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
END IF
IF Y>=2016 THEN
   IF M=8 AND N=11 THEN
      LET DAYCOLOR$="RED"
      LET Z$="山の日"
   END IF
   IF M=8 AND N=12 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
END IF
IF Y>=2003 THEN
   IF M=9 AND ((R<=1 AND R+N=16) OR (R>1 AND R+N=23)) THEN
      LET DAYCOLOR$="RED"
      LET Z$="敬老の日"
   END IF
ELSEIF Y>=1966 AND Y<2003 THEN
   IF M=9 AND N=15 THEN
      LET DAYCOLOR$="RED"
      LET Z$="敬老の日"
   END IF
   IF Y>=1973 AND M=9 AND N=16 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
END IF
IF Y>=2000 THEN
   IF M=10 AND ((R<=1 AND R+N=9) OR (R>1 AND R+N=16)) THEN
      LET DAYCOLOR$="RED"
      LET Z$="体育の日"
   END IF
ELSEIF Y>=1966 AND Y<2000 THEN
   IF M=10 AND N=10 THEN
      LET DAYCOLOR$="RED"
      LET Z$="体育の日"
   END IF
   IF Y>=1973 AND M=10 AND N=11 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
END IF
IF M=11 AND N=3 THEN
   LET DAYCOLOR$="RED"
   LET Z$="文化の日"
END IF
IF M=11 AND N=23 THEN
   LET DAYCOLOR$="RED"
   LET Z$="敬老感謝の日"
END IF
IF Y>=1973 AND M=11 AND (N=4 OR N=24) AND MOD(N+R-1,7)=1 THEN
   LET DAYCOLOR$="RED"
   LET Z$="振替休日"
END IF
IF Y>=1989 THEN
   IF M=12 AND N=23 THEN
      LET DAYCOLOR$="RED"
      LET Z$="天皇誕生日"
   END IF
   IF M=12 AND N=24 AND MOD(N+R-1,7)=1 THEN
      LET DAYCOLOR$="RED"
      LET Z$="振替休日"
   END IF
END IF
LET D$=DATE$
IF Y=VAL(D$(1:4)) AND M=VAL(D$(5:6)) AND N=VAL(D$(7:8)) THEN LET DAYCOLOR$="CYAN"
END FUNCTION

EXTERNAL  FUNCTION QSEI$(TM)
DIM A$(9)
MAT READ A$
LET QSEI$=A$(MOD(TM-1,9)+1)
DATA 九紫火星
DATA 八白土星
DATA 七赤金星
DATA 六白金星
DATA 五黄土星
DATA 四緑木星
DATA 三碧木星
DATA 二黒土星
DATA 一白水星
END FUNCTION

EXTERNAL  SUB MOON(X,Y,R,H,N)
DIM XX(73),YY(73)
SET COLOR "GRAY"
DRAW DISK WITH SCALE(R)*SHIFT(X,Y)
SET AREA COLOR "YELLOW"
IF H>15 THEN LET SW=-1 ELSE LET SW=1
LET RR=2*(N-.5)
IF RR>0 THEN
   FOR T=0 TO 360 STEP 5
      LET B=R
      IF T>=90 AND T<=270 THEN LET B=R*RR
      LET I=I+1
      LET YY(I)=R*SIN(RAD(T))+Y
      LET XX(I)=SW*B*COS(RAD(T))+X
   NEXT T
ELSE
   FOR T=-90 TO 90 STEP 5
      LET I=I+1
      LET YY(I)=R*SIN(RAD(T))+Y
      LET XX(I)=SW*R*COS(RAD(T))+X
   NEXT T
   LET B=R*ABS(RR)
   FOR T=85 TO -90 STEP -5
      LET I=I+1
      LET YY(I)=R*SIN(RAD(T))+Y
      LET XX(I)=SW*B*COS(RAD(T))+X
   NEXT T
END IF
IF RR>-1 THEN MAT PLOT AREA :XX,YY
END SUB

!'これより以下は、「旧暦 for VB」から「旧暦.bas」を(仮称)十進BASICに移植したものです。
!' http://www.vector.co.jp/soft/win95/personal/se243537.html?_ga=1.114790919.1276112294.1407498580

!' 旧暦計算 標準モジュール「旧暦.bas」Version 1.0
!'     Arranged for Visual Basic 6.0 or 5.0 & Excel97 VBA & Access97 VBA
!'                       by Masayuki Kanari (C)2002
!'
!'   原典 「旧暦計算サンプルプログラム」
!'     Copyright (C) 1993,1994 by H.Takano
!'     http://www.vector.co.jp/soft/dos/personal/se016093.html
!'
!'   原典  旧暦計算 JavaScript(ECMAScript) Library "qreki.js" Version 1.5
!'     Arranged for ECMAScript(ECMA-262) by Nagano Yutaka (C)1999-2001
!'     http://www.ai.wakwak.com/~y-nagano/Programs/koyomi/
!'
!'     この標準モジュールの計算結果は無保証です。
!'     この標準モジュールはフリーソフトであり、自由に再利用・改良を行ってかまいませんが、
!'     著作権は原典のjgAWK版を開発された高野英明氏、およびJavaScript版を開発された長野隆氏に
!'     帰属しています。上記のリンクより高野氏の「QRSAMP」、長野氏の「qreki.js」を取得し、
!'     そのドキュメント内に書かれている再配布規定に従ってください。
!'
!' 使用法
!'   1.旧暦は下記コードをFormモジュールで実行すると、Kyurekiに旧暦が入っています。
!'       Kyureki.QYear に旧暦年   Kyureki.QMonth に旧暦月  下記コードの Type Q_Rekiを参照
!'         Calc_Kyureki "2002","5","26"   "2002"などは当然ですが、変数でも可
!'
!'   2.二十四節季は下記コードをFormモジュールで実行すると、Sekki24に二十四節季が入っています。
!'       Sekki24(i,0) に節季の日時 Sekki24(i,1) に節季の名称が入ります。
!'         Calc_Sekki24 "2002"       "2002"は当然ですが、変数でも可
!'Type Q_Reki         ' ユーザー定義型を作成
!'   QYear     As Integer     ' 旧暦年
!'   QUruu     As Boolean     ' 平月:False 閏月:True
!'   QMonth    As Integer     ' 旧暦月
!'   QDay      As Integer     ' 旧暦日
!'   QRokuyou  As String      ' 六曜名
!'   QJukkan   As String      ' 十干十二支
!'   QMage          ' リアルタイム月齢
!'   QMagenoon      ' 正午月齢
!'   QIllumi        ' 輝面比 %
!'   QMphase   As Integer     ' 月相 0~27
!'End Type
!' 十干十二支 甲(きのえ) 乙(きのと) 丙(ひのえ) 丁(ひのと) 戊(つちのえ) 己(つちのと) 庚(かのえ) 辛(かのと) 壬(みずのえ) 癸(みずのと)
EXTERNAL  FUNCTION CALC_JUKKAN$(TM)
DIM A$(10),B$(12)
MAT READ A$,B$
LET N$ = A$(MOD(INT(TM / 2), 5) * 2 + MOD(TM ,2) + 1)
DATA "甲", "乙", "丙", "丁", "戊"
DATA "己", "庚", "辛", "壬", "癸"
LET CALC_JUKKAN$ = N$ & " " & B$(MOD(TM - 10,12) + 1)
DATA "子", "丑", "寅", "卯", "辰", "巳"
DATA "午", "未", "申", "酉", "戌", "亥"
END FUNCTION

!' 二分二至の時刻または中気の時刻を求める二分二至の時刻
!' 引数 tm .... 計算対象となる時刻(ユリウス日)
!'      logitudeas ....  二分二至の時90 中気の時30
!' 戻り値  .... 二分二至の時刻または中気の時刻(ユリウス日)
!' グローバル変数rm_sun0にその時の太陽黄経をセットする
EXTERNAL  FUNCTION CALC_CHU(TM, LOGITUDEAS)
LET TM1 = INT(TM)                                       !' 時刻引数を分解する
LET TM2 = TM - TM1 - 9 / 24                             !' JST ==> DT
!' 二分二至の時刻または中気の黄経λsun0を求める
LET T = (TM2 + 0.5 + TM1 - 2451545) / 36525
LET RM_SUN = LONGITUDE_SUN(T)
LET RM_SUN0 = LOGITUDEAS * INT(RM_SUN / LOGITUDEAS)
!' 繰り返し計算によって中気の時刻を計算する(誤差が±1.0 sec以内になったら打ち切る)
DO
   LET T = (TM2 + 0.5 + TM1 - 2451545) / 36525
   LET RM_SUN = LONGITUDE_SUN(T)                       !' 太陽の黄経λsunを計算
   LET DELTA_RM = RM_SUN - RM_SUN0                     !' 黄経差Δλ
   !' Δλの引き込み範囲(±180°)を逸脱した場合には、補正を行う
   IF DELTA_RM > 180 THEN
      LET DELTA_RM = DELTA_RM - 360
   ELSEIF DELTA_RM < -180 THEN
      LET DELTA_RM = DELTA_RM + 360
   END IF
   LET DELTA_T1 = INT(DELTA_RM * 365.24219878 / 360)   !' 時刻引数の補正値 Δt
   LET DELTA_T2 = DELTA_RM * 365.24219878 / 360
   LET DELTA_T2 = DELTA_T2 - DELTA_T1
   LET TM1 = TM1 - DELTA_T1                            !' 時刻引数の補正
   LET TM2 = TM2 - DELTA_T2
   IF TM2 < 0 THEN
      LET TM2 = TM2 + 1
      LET TM1 = TM1 - 1
   END IF
LOOP UNTIL ABS(DELTA_T1 + DELTA_T2) < (1 / 86400)
LET CALC_CHU = TM1 + TM2 + 9 / 24
END FUNCTION

!' 朔の計算
!' 与えられた時刻の直近の朔の時刻(JST)を求める
!' 引数 tm ........ 計算対象となる時刻(ユリウス日)
!' 戻り値  ........ 朔の時刻      引数、戻り値ともユリウス日で表し、時分秒は日の小数で表す
EXTERNAL  FUNCTION CALC_SAKU(TM)
LET LC = 1                                              !' ループカウンタのセット
LET TM1 = INT(TM)                                       !' 時刻引数を分解する
LET TM2 = TM - TM1 - 9 / 24                             !' JST ==> DT
!' 繰り返し計算によって朔の時刻を計算する(誤差が±1.0 sec以内になったら打ち切る)
DO
   LET T = (TM2 + 0.5 + TM1 - 2451545) / 36525
   LET RM_SUN = LONGITUDE_SUN(T)                       !' 太陽の黄経λsunを計算
   LET RM_MOON = LONGITUDE_MOON(T)                     !' 月の黄経λmoonを計算
   LET DELTA_RM = RM_MOON - RM_SUN                     !' 月と太陽の黄経差Δλ
   !' ループの1回目(Lc=1)で delta_rm < 0 の場合には引き込み範囲に入るように補正する
   IF LC = 1 AND DELTA_RM < 0 THEN
      LET DELTA_RM = NORMALIZATION_ANGLE(DELTA_RM)
      !'   春分の近くで朔がある場合(0 ≦λsun≦ 20)で、月の黄経λmoon≧300 の
      !'   場合には、Δλ= 360 - Δλ と計算して補正する
   ELSEIF RM_SUN >= 0 AND RM_SUN <= 20 AND RM_MOON >= 300 THEN
      LET DELTA_RM = NORMALIZATION_ANGLE(DELTA_RM)
      LET DELTA_RM = 360 - DELTA_RM
      !' Δλの引き込み範囲(±40°)を逸脱した場合には、補正を行う
   ELSEIF ABS(DELTA_RM) > 40 THEN
      LET DELTA_RM = NORMALIZATION_ANGLE(DELTA_RM)
   END IF
   LET DELTA_T1 = INT(DELTA_RM * 29.530589 / 360)      !' 時刻引数の補正値 Δt
   LET DELTA_T2 = DELTA_RM * 29.530589 / 360
   LET DELTA_T2 = DELTA_T2 - DELTA_T1
   LET TM1 = TM1 - DELTA_T1                            !' 時刻引数の補正
   LET TM2 = TM2 - DELTA_T2
   IF TM2 < 0 THEN
      LET TM2 = TM2 + 1
      LET TM1 = TM1 - 1
   END IF
   !' ループ回数が15回になったら、初期値 tm を tm-26 とする
   IF LC = 15 AND ABS(DELTA_T1 + DELTA_T2) > (1 / 86400) THEN
      LET TM1 = INT(TM - 26)
      LET TM2 = 0
      !' 初期値を補正したにも関わらず、振動を続ける場合には初期値を答えとして返して強制的にループを抜け出して異常終了させる
   ELSEIF LC > 30 AND ABS(DELTA_T1 + DELTA_T2) > (1 / 86400) THEN
      LET TM1 = TM
      LET TM2 = 0
      EXIT DO
   END IF
   LET LC = LC + 1
LOOP UNTIL ABS(DELTA_T1 + DELTA_T2) < (1 / 86400)
!' 時刻引数を合成するのと、DT ==> JST 変換を行い、戻り値とする
LET CALC_SAKU = TM2 + TM1 + 9 / 24
END FUNCTION
 

Re: カレンダー

 投稿者:しばっち  投稿日:2014年 9月 2日(火)19時16分41秒
  > No.3481[元記事へ]

続き

!' 角度の正規化を行う。すなわち引数の範囲を0≦θ<360にする
EXTERNAL  FUNCTION NORMALIZATION_ANGLE(ANGLE)
LET NORMALIZATION_ANGLE = MOD(ANGLE+360,360)
END FUNCTION

EXTERNAL  FUNCTION LONGITUDE_SUN(T) !' 太陽の黄経λsunを計算する
!' 摂動項の計算
LET ANG = NORMALIZATION_ANGLE(31557 * T + 161)
LET TH = 0.0004 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(29930 * T + 48)
LET TH = TH + 0.0004 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(2281 * T + 221)
LET TH = TH + 0.0005 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(155 * T + 118)
LET TH = TH + 0.0005 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(33718 * T + 316)
LET TH = TH + 0.0006 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(9038 * T + 64)
LET TH = TH + 0.0007 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(3035 * T + 110)
LET TH = TH + 0.0007 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(65929 * T + 45)
LET TH = TH + 0.0007 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(22519 * T + 352)
LET TH = TH + 0.0013 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(45038 * T + 254)
LET TH = TH + 0.0015 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(445267 * T + 208)
LET TH = TH + 0.0018 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(19 * T + 159)
LET TH = TH + 0.0018 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(32964 * T + 158)
LET TH = TH + 0.002 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(71998.1 * T + 265.1)
LET TH = TH + 0.02 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(35999.05 * T + 267.52)
LET TH = TH - 0.0048 * T * COS(PI * ANG / 180)
LET TH = TH + 1.9147 * COS(PI * ANG / 180)
!' 比例項の計算
LET ANG = NORMALIZATION_ANGLE(36000.7695 * T)
LET ANG = NORMALIZATION_ANGLE(ANG + 280.4659)
LET LONGITUDE_SUN = NORMALIZATION_ANGLE(TH + ANG)
END FUNCTION

EXTERNAL  FUNCTION LONGITUDE_MOON(T) !' 月の黄経λmoonを計算する
!' 摂動項の計算
LET ANG = NORMALIZATION_ANGLE(2322131 * T + 191)
LET TH = 0.0003 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(4067 * T + 70)
LET TH = TH + 0.0003 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(549197 * T + 220)
LET TH = TH + 0.0003 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1808933 * T + 58)
LET TH = TH + 0.0003 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(349472 * T + 337)
LET TH = TH + 0.0003 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(381404 * T + 354)
LET TH = TH + 0.0003 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(958465 * T + 340)
LET TH = TH + 0.0003 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(12006 * T + 187)
LET TH = TH + 0.0004 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(39871 * T + 223)
LET TH = TH + 0.0004 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(509131 * T + 242)
LET TH = TH + 0.0005 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1745069 * T + 24)
LET TH = TH + 0.0005 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1908795 * T + 90)
LET TH = TH + 0.0005 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(2258267 * T + 156)
LET TH = TH + 0.0006 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(111869 * T + 38)
LET TH = TH + 0.0006 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(27864 * T + 127)
LET TH = TH + 0.0007 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(485333 * T + 186)
LET TH = TH + 0.0007 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(405201 * T + 50)
LET TH = TH + 0.0007 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(790672 * T + 114)
LET TH = TH + 0.0007 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1403732 * T + 98)
LET TH = TH + 0.0008 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(858602 * T + 129)
LET TH = TH + 0.0009 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1920802 * T + 186)
LET TH = TH + 0.0011 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1267871 * T + 249)
LET TH = TH + 0.0012 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1856938 * T + 152)
LET TH = TH + 0.0016 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(401329 * T + 274)
LET TH = TH + 0.0018 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(341337 * T + 16)
LET TH = TH + 0.0021 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(71998 * T + 85)
LET TH = TH + 0.0021 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(990397 * T + 357)
LET TH = TH + 0.0021 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(818536 * T + 151)
LET TH = TH + 0.0022 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(922466 * T + 163)
LET TH = TH + 0.0023 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(99863 * T + 122)
LET TH = TH + 0.0024 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1379739 * T + 17)
LET TH = TH + 0.0026 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(918399 * T + 182)
LET TH = TH + 0.0027 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1934 * T + 145)
LET TH = TH + 0.0028 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(541062 * T + 259)
LET TH = TH + 0.0037 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1781068 * T + 21)
LET TH = TH + 0.0038 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(133 * T + 29)
LET TH = TH + 0.004 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1844932 * T + 56)
LET TH = TH + 0.004 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1331734 * T + 283)
LET TH = TH + 0.004 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(481266 * T + 205)
LET TH = TH + 0.005 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(31932 * T + 107)
LET TH = TH + 0.0052 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(926533 * T + 323)
LET TH = TH + 0.0068 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(449334 * T + 188)
LET TH = TH + 0.0079 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(826671 * T + 111)
LET TH = TH + 0.0085 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1431597 * T + 315)
LET TH = TH + 0.01 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1303870 * T + 246)
LET TH = TH + 0.0107 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(489205 * T + 142)
LET TH = TH + 0.011 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1443603 * T + 52)
LET TH = TH + 0.0125 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(75870 * T + 41)
LET TH = TH + 0.0154 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(513197.9 * T + 222.5)
LET TH = TH + 0.0304 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(445267.1 * T + 27.9)
LET TH = TH + 0.0347 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(441199.8 * T + 47.4)
LET TH = TH + 0.0409 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(854535.2 * T + 148.2)
LET TH = TH + 0.0458 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(1367733.1 * T + 280.7)
LET TH = TH + 0.0533 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(377336.3 * T + 13.2)
LET TH = TH + 0.0571 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(63863.5 * T + 124.2)
LET TH = TH + 0.0588 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(966404 * T + 276.5)
LET TH = TH + 0.1144 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(35999.05 * T + 87.53)
LET TH = TH + 0.1851 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(954397.74 * T + 179.93)
LET TH = TH + 0.2136 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(890534.22 * T + 145.7)
LET TH = TH + 0.6583 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(413335.35 * T + 10.74)
LET TH = TH + 1.274 * COS(PI * ANG / 180)
LET ANG = NORMALIZATION_ANGLE(477198.868 * T + 44.963)
LET TH = TH + 6.2888 * COS(PI * ANG / 180)
!' 比例項の計算
LET ANG = NORMALIZATION_ANGLE(481267.8809 * T)
LET ANG = NORMALIZATION_ANGLE(ANG + 218.3162)
LET LONGITUDE_MOON = NORMALIZATION_ANGLE(TH + ANG)
END FUNCTION

!' ユリウス日(JD)から年月日、時分秒(世界時)を計算する
!' この関数で求めた年月日は、グレゴリオ暦法によって表されている
EXTERNAL  FUNCTION JD2YMDT$(JD)
LET X0 = INT(JD + 68570)
LET X1 = INT(X0 / 36524.25)
LET X2 = X0 - INT(36524.25 * X1 + 0.75)
LET X3 = INT((X2 + 1) / 365.2425)
LET X4 = X2 - INT(365.25 * X3) + 31
LET X5 = INT(INT(X4) / 30.59)
LET X6 = INT(INT(X5) / 11)
LET GDAY = X4 - INT(30.59 * X5)
LET GMONTH = X5 - 12 * X6 + 2
LET GYEAR = 100 * (X1 - 49) + X3 + X6
!' 2月30日の補正
IF GMONTH = 2 AND GDAY > 28 THEN
   IF MOD(GYEAR,100) = 0 AND MOD(GYEAR,400) = 0 THEN
      LET GDAY = 29
   ELSEIF MOD(GYEAR,4) = 0 AND MOD(GYEAR,100) > 0 THEN
      LET GDAY = 29
   ELSE
      LET GDAY = 28
   END IF
END IF
LET X0 = 24 * (JD - INT(JD))
LET GHOUR = INT(X0)
LET GMINUTE = INT((X0 - GHOUR) * 60)
LET GSECOND = INT((X0 - GHOUR - GMINUTE / 60) * 3600 + 0.05)
LET JD2YMDT$ = STR$(GYEAR) & "/" & RIGHT$("0"&STR$(GMONTH),2) & "/" & RIGHT$("0"&STR$(GDAY),2) & " " & RIGHT$("0"&STR$(GHOUR),2) & ":" & RIGHT$("0"&STR$(GMINUTE),2) & ":" & RIGHT$("0"&STR$(GSECOND),2)
END FUNCTION

!' 年月日、時分秒(世界時)からユリウス日(JD)を計算する
EXTERNAL  FUNCTION YMDT2JD(GYEAR, GMONTH, GDAY, GHOUR, GMINUTE, GSECOND)
IF GMONTH < 3 THEN
   LET CALC_GYEAR = GYEAR - 1
   LET CALC_GMONTH = GMONTH + 12
ELSE
   LET CALC_GYEAR = GYEAR
   LET CALC_GMONTH = GMONTH
END IF
LET Y = INT(365.25 * CALC_GYEAR) + INT(CALC_GYEAR / 400) - INT(CALC_GYEAR / 100)
LET Y = Y + INT(30.59 * (CALC_GMONTH - 2)) + 1721088 + GDAY
LET YMDT2JD = Y + (GHOUR + GMINUTE / 60 + GSECOND / 3600) / 24
END FUNCTION

!' 二十四節季
!' Sekki(x,0)  .... 節季日
!' Sekki(x,1)  .... 節季
EXTERNAL  SUB CALC_SEKKI24(GYEAR)
DIM A$(24)
MAT READ A$
LET YMD = YMDT2JD(GYEAR, 1, 1, 0, 0, 0)
LET J = 0
FOR I = 0 TO 400 STEP 15
   LET SEKKI$ = JD2YMDT$(CALC_CHU(YMD + I, 15))
   IF VAL(LEFT$(SEKKI$, 4)) = GYEAR THEN
      LET SEKKI24$(J, 0) = SEKKI$
      LET SEKKI24$(J, 1) = A$(RM_SUN0 / 15+1)
      DATA "春分", "清明", "穀雨", "立夏", "小満", "芒種"
      DATA "夏至", "小暑", "大暑", "立秋", "処暑", "白露"
      DATA "秋分", "寒露", "霜降", "立冬", "小雪", "大雪"
      DATA "冬至", "小寒", "大寒", "立春", "雨水", "啓蟄"
      LET J = J + 1
   END IF
NEXT I
END SUB

!' 新暦に対応する、旧暦を求める
!' 引数 tm .... 計算する日付(ユリウス日)
!' 戻り値  .... kyureki
EXTERNAL  SUB CALC_KYUREKI(GYEAR, GMONTH, GDAY)
DIM CHU(0 TO 4), SAKU(0 TO 5), M(0 TO 5, 0 TO 2),ROKU$(6)
LET TM = YMDT2JD(GYEAR, GMONTH, GDAY, 0, 0, 0)
LET CHU(0) = CALC_CHU(TM, 90)                       !' 計算対象の直前にあたる二分二至の時刻を求める
LET M(0, 0) = INT(RM_SUN0 / 30) + 2                 !' 上で求めた二分二至の時の太陽黄経をもとに朔日行列の先頭に月名をセット
FOR I = 1 TO 4
   LET CHU(I) = CALC_CHU(CHU(I - 1) + 32, 30)
NEXT I
!' 計算対象の直前にあたる二分二至の直前の朔の時刻を求める
LET SAKU(0) = CALC_SAKU(CHU(0))
!' 朔の時刻を求める
FOR I = 1 TO 5
   LET SAKU(I) = CALC_SAKU(SAKU(I - 1) + 30)
   !'  前と同じ時刻を計算した場合(両者の差が26日以内)には、初期値を+33日にして再実行させる
   IF ABS(INT(SAKU(I - 1)) - INT(SAKU(I))) <= 26 THEN
      LET SAKU(I) = CALC_SAKU(SAKU(I - 1) + 35)
   END IF
NEXT I
!' saku(1)が二分二至の時刻以前になってしまった場合には、朔をさかのぼり過ぎたと考えて、
!' 朔の時刻を繰り下げて修正する
!' その際、計算もれsaku(4)になっている部分を補うため、朔の時刻を計算する
!' 近日点通過の近辺で朔があると起こる事があるようだ...?
IF INT(SAKU(1)) <= INT(CHU(0)) THEN
   FOR I = 0 TO 4
      LET SAKU(I) = SAKU(I + 1)
   NEXT I
   LET SAKU(4) = CALC_SAKU(SAKU(3) + 35)
   !' saku(0)が二分二至の時刻以後になってしまった場合には、朔をさかのぼり足りないと見て、
   !' 朔の時刻を繰り上げて修正する
   !' その際、計算もれsaku(0)になっている部分を補うため、朔の時刻を計算する
   !' 春分点の近辺で朔があると起こる事があるようだ...?
ELSEIF INT(SAKU(0)) > INT(CHU(0)) THEN
   FOR I = 4 TO 1 STEP -1
      LET SAKU(I) = SAKU(I - 1)
   NEXT I
   LET SAKU(0) = CALC_SAKU(SAKU(0) - 27)
END IF
!' 閏月検索Flagセット   節月で4ヶ月の間に朔が5回あると、閏月がある可能性がある
!' lap=false:平月  lap=true:閏月
IF INT(SAKU(4)) <= INT(CHU(3)) THEN LET LAP=1 ELSE LET LAP=0
!' 朔日行列の作成
!' m(i,0) ... 月名(1:正月 2:2月 3:3月 ....)
!' m(i,1) ... 閏フラグ(false:平月 true:閏月)
!' m(i,2) ... 朔日のjd
!' m(0, 0)はこの関数の始めの方ですでに代入済み
LET M(0, 1) = 0
LET M(0, 2) = INT(SAKU(0))
FOR I = 1 TO 5
   IF LAP=1 AND I > 1 THEN
      IF CHU(I - 1) <= INT(SAKU(I - 1)) OR CHU(I - 1) >= INT(SAKU(I)) THEN
         LET M(I - 1, 0) = M(I - 2, 0)
         LET M(I - 1, 1) = 1
         LET M(I - 1, 2) = INT(SAKU(I - 1))
         LET LAP = 0
      END IF
   END IF
   LET M(I, 0) = M(I - 1, 0) + 1
   IF M(I, 0) > 12 THEN
      LET M(I, 0) = M(I, 0) - 12
   END IF
   LET M(I, 2) = INT(SAKU(I))
   LET M(I, 1) = 0
NEXT I
!' 朔日行列から旧暦を求める
LET STATE = 0
FOR I = 0 TO 5
   IF INT(TM) < INT(M(I, 2)) THEN
      LET STATE = 1
      EXIT FOR
   ELSEIF INT(TM) = INT(M(I, 2)) THEN
      LET STATE = 2
      EXIT FOR
   END IF
NEXT I
IF STATE = 0 OR STATE = 1 THEN
   LET I = I - 1
END IF
LET QURUU = M(I, 1)
LET QMONTH = M(I, 0)
LET QDAY = INT(TM) - INT(M(I, 2)) + 1
!'旧暦年の計算    旧暦月が10以上でかつ新暦月より大きい場合には、まだ年を越していないはず...
!'YMD$ = JD2YMDT$(tm)
!'QYear = Val(Left$(YMD$, 4))
!'If QMonth > 9 And QMonth > Val(Mid$(YMD$, 6, 2)) Then
LET QYEAR = GYEAR
IF QMONTH > 9 AND QMONTH > GMONTH THEN
   LET QYEAR = QYEAR - 1
END IF
!' 六曜を求める
MAT READ ROKU$
DATA "大安", "赤口", "先勝", "友引", "先負", "仏滅"
LET QROKUYOU$ = ROKU$(MOD((QMONTH + QDAY) ,6) + 1)
!' 十干十二支を求める
LET QJUKKAN$ = CALC_JUKKAN$(TM)
!' リアルタイム月齢を求める
LET QMAGE = TM - SAKU(I)
IF QMAGE < 0 THEN
   LET QMAGE = TM - SAKU(I - 1)
END IF
!' 正午月齢を求める
LET QMAGENOON = INT(TM) + 0.5 - SAKU(I)
IF QMAGENOON < 0 THEN
   LET QMAGENOON = INT(TM) + 0.5 - SAKU(I - 1)
END IF
!' 輝面比を求める
LET TM1 = INT(TM)
LET TM2 = TM - TM1 - 9 / 24
LET T = (TM2 + 0.5) / 36525 + (TM1 - 2451545) / 36525
LET QILLUMI = (1 - COS(PI * NORMALIZATION_ANGLE(LONGITUDE_MOON(T) - LONGITUDE_SUN(T)) / 180)) * 50
!' 月相を求める   輝面比の計算で求めた変数tを使用
LET QMPHASE = INT(NORMALIZATION_ANGLE(LONGITUDE_MOON(T) - LONGITUDE_SUN(T)) / 360 * 28 + 0.5)
LET QMPHASE = MOD(QMPHASE, 28)
END SUB
 

戯言です

 投稿者:lark12_long  投稿日:2014年 9月 3日(水)08時02分54秒
  十進basicの愛用者の一人です
私は、マイクロソフト系N88basicを、長年使っていました

よって、十進basicも、Microsoft互換モードで、使用してます
Microsoft互換モードでも、標準(JIS FullBasic)モードの
ステートメントの殆どが動きます

標準モードで抵抗感を感じるのは、数式記述の前に、
letを記述しなければいけないことです

それと、コメント指定が!なのも、
’の方の慣れてるもんで抵抗感を感じます

規格なので、何とかせ~とは、よう言い得ませんが....


 

Re: 戯言です

 投稿者:しばっち  投稿日:2014年 9月 3日(水)22時39分7秒
  > No.3483[元記事へ]

lark12_longさんへのお返事です。

> 標準モードで抵抗感を感じるのは、数式記述の前に、
> letを記述しなければいけないことです

> それと、コメント指定が!なのも、
> ’の方の慣れてるもんで抵抗感を感じます

もし、プログラムの作成時(入力時)のことを言われているのなら
let文は記述しなくても実行するだけで自動修正されます。
注釈「'」もそのままで実行できます。

例えば
'
a=1

と入力しても
実行すれば
!'
LET a=1
と自動変換されます。

まずはお試しあれ。


 

しばっち様

 投稿者:lark12_long  投稿日:2014年 9月 4日(木)22時09分35秒
  有難うございました

参考になりました
 

不具合の報告

 投稿者:山中和義  投稿日:2014年 9月10日(水)11時36分0秒
  行列式を計算するプログラムを各モードで実行した場合、結果が異なります。

行列式
| a  b  c | = 1
| d  e  f |
| g  h  i |

| a^2  b^2  c^2 | = 1
| d^2  e^2  f^2 |
| g^2  h^2  i^2 |

を満たすものを探す。


!!OPTION ARITHMETIC RATIONAL
DIM M(3,3)
DIM X(3,3)
FOR A=2 TO 9
   LET M(1,1)=A
   LET X(1,1)=A*A
   FOR B=A TO 9
      LET M(1,2)=B
      LET X(1,2)=B*B
      FOR C=B TO 9
         LET M(1,3)=C
         LET X(1,3)=C*C
         FOR D=2 TO 9
            LET M(2,1)=D
            LET X(2,1)=D*D
            FOR E=2 TO 9
               LET M(2,2)=E
               LET X(2,2)=E*E
               FOR F=2 TO 9
                  LET M(2,3)=F
                  LET X(2,3)=F*F
                  FOR G=2 TO 9
                     LET M(3,1)=G
                     LET X(3,1)=G*G
                     FOR H=2 TO 9
                        LET M(3,2)=H
                        LET X(3,2)=H*H
                        FOR I=2 TO 9
                           LET M(3,3)=I
                           LET X(3,3)=I*I

                           IF DET(M)=1 THEN
                              PRINT DET(X) !debug
                              IF DET(X)=1 THEN
                                 MAT PRINT M;
                                 STOP
                              END IF
                           END IF

                        NEXT I
                     NEXT H
                  NEXT G
               NEXT F
            NEXT E
         NEXT D
      NEXT C
   NEXT B
NEXT A
END



10進、1000桁モード

 :
 :
-1975
387
1327
2267
-1505
1
2  2  3
9  7  6
4  3  2


2進、複素数、有理数モード

 :
 :
217
237
-51
769
1
2  2  3
3  4  2
7  9  6


10進、1000桁モードでは、2進、複素数、有理数モードで求まる値が抜けるようです。



DATA 2,2,3
DATA 3,4,2
DATA 7,9,6
DIM M(3,3),X(3,3)
FOR i=1 TO 3
   FOR J=1 TO 3
      READ T
      LET M(i,J)=T
      LET X(i,J)=T*T
   NEXT J
NEXT i
IF DET(M)=1 THEN MAT PRINT M;
IF DET(X)=1 THEN MAT PRINT X; !bug bug bug  10進、1000桁モード
IF DET3(M)=1 THEN MAT PRINT M;
IF DET3(X)=1 THEN MAT PRINT X;
END
EXTERNAL FUNCTION DET3(M(,)) !3行3列の行列式の値
LET DET3=M(1,1)*M(2,2)*M(3,3)+M(1,2)*M(2,3)*M(3,1)+M(1,3)*M(2,1)*M(3,2) &
&       -M(1,3)*M(2,2)*M(3,1)-M(1,1)*M(2,3)*M(3,2)-M(1,2)*M(2,1)*M(3,3)
END FUNCTION

 

Re: 不具合の報告

 投稿者:白石 和夫  投稿日:2014年 9月10日(水)13時09分59秒
  > No.3486[元記事へ]

オプション―数値メニューで「表示桁数を多く」に
チェックを付けて実行してみるとわかりますが,
DET関数にわずかな誤差があります。
今回は2進モードで正しい値が求まり
10進モードに誤差がある結果となっていますが,
使用しているアルゴリズムは同じなので,
どちらも同じように誤差を含む可能性があります。
行列に関する演算は,計算結果の正確さを保証するのが難しいので,
理論的な計算が必要な場合は有理数モードで実行してください。
 

Re: 不具合の報告

 投稿者:山中和義  投稿日:2014年 9月10日(水)22時35分8秒
  > No.3487[元記事へ]

白石 和夫さんへのお返事です。

> 理論的な計算が必要な場合は有理数モードで実行してください。

次のプログラムのように展開式を使った関数を用いると、どのモードも結果は一致します。
定義した関数DET3は、32ビット整数の範囲で、計算結果は整数として保証されるのでしょうか。
偶々、浮動小数点による近似値が、整数(真の値)と一致したと考えるのでしょうか。


DATA 2,2,3
DATA 3,4,2
DATA 7,9,6
DIM M(3,3),X(3,3)
FOR i=1 TO 3
   FOR J=1 TO 3
      READ T
      LET M(i,J)=T
      LET X(i,J)=T*T
   NEXT J
NEXT i
IF DET(M)=1 THEN MAT PRINT M;
IF DET(X)=1 THEN MAT PRINT X; !10進、1000桁モード
IF DET3(M)=1 THEN MAT PRINT M;
IF DET3(X)=1 THEN MAT PRINT X;
END
EXTERNAL FUNCTION DET3(M(,)) !3行3列の行列式の値
LET DET3=M(1,1)*M(2,2)*M(3,3)+M(1,2)*M(2,3)*M(3,1)+M(1,3)*M(2,1)*M(3,2) &
&       -M(1,3)*M(2,2)*M(3,1)-M(1,1)*M(2,3)*M(3,2)-M(1,2)*M(2,1)*M(3,3)
END FUNCTION

 

マウスでの入力

 投稿者:ルーン  投稿日:2014年 9月10日(水)22時56分54秒
   グラフィックの表示プログラムで、一部分を拡大するために、
プログラムの動作の結果のグラフィック画面から、マウスのクリック&ドラッグで、
マウスの左クリックのスタート座標と終了座標を読み取る場合、
画面上にマウスの動きに合わせて、X座標基準の正方形を破線で表示させる(要は、フォトショップの正方形範囲選択画面)方法ってあるんでしょうか?
(マウス移動中順次画素のデータを読んで移動する毎に書き換えていくのはあまりに面倒なので)
 

マウスでの 入力

 投稿者:ルーン  投稿日:2014年 9月10日(水)23時03分33秒
   書き足りませんでしたが、あくまでプログラムの実行中、マウスからの入力待ち状態での
座標入力方法です。
 

Re: 不具合の報告

 投稿者:GAI  投稿日:2014年 9月11日(木)07時10分11秒
  > No.3488[元記事へ]

山中和義さんへのお返事です。

> 次のプログラムのように展開式を使った関数を用いると、どのモードも結果は一致します。
> 定義した関数DET3は、32ビット整数の範囲で、計算結果は整数として保証されるのでしょうか。
> 偶々、浮動小数点による近似値が、整数(真の値)と一致したと考えるのでしょうか。
>
>
> DATA 2,2,3
> DATA 3,4,2
> DATA 7,9,6
> DIM M(3,3),X(3,3)
> FOR i=1 TO 3
>    FOR J=1 TO 3
>       READ T
>       LET M(i,J)=T
>       LET X(i,J)=T*T
>    NEXT J
> NEXT i
> IF DET(M)=1 THEN MAT PRINT M;
> IF DET(X)=1 THEN MAT PRINT X; !10進、1000桁モード
> IF DET3(M)=1 THEN MAT PRINT M;
> IF DET3(X)=1 THEN MAT PRINT X;
> END
> EXTERNAL FUNCTION DET3(M(,)) !3行3列の行列式の値
> LET DET3=M(1,1)*M(2,2)*M(3,3)+M(1,2)*M(2,3)*M(3,1)+M(1,3)*M(2,1)*M(3,2) &
> &       -M(1,3)*M(2,2)*M(3,1)-M(1,1)*M(2,3)*M(3,2)-M(1,2)*M(2,1)*M(3,3)
> END FUNCTION
>

>

上記のプログラムはその前のLET DET3 とどう違うんでしょうか?
これで定義していたらやはり10進、1000桁モード
で結果(MAT PRINT Xを拾わない。)がちがうような気がします。

PARI/GP
という計算ソフトを用いて

| a  b  c |
| d  e  f | ==>a,b,c;d,e,f;g,h,i
| g  h  i |

を探したら、結構沢山現れてびっくりしました。

2,2,3;3,4,2;7,9,6
2,2,3;9,7,6;4,3,2
2,3,3;3,2,5;5,9,7
2,3,3;5,7,9;3,5,2
2,3,4;6,7,9;3,2,2
2,3,5;3,2,3;9,5,7
2,3,5;3,2,9;3,5,7
2,3,6;4,2,9;3,2,7
2,3,7;2,4,9;3,2,6
2,3,9;3,2,5;5,3,7
2,4,9;3,2,6;2,3,7
3,3,5;4,3,4;4,5,9
3,3,5;5,4,9;3,4,4
3,4,4;3,3,5;5,4,9
3,4,4;5,9,4;3,5,3
3,5,7;2,3,5;3,2,9
4,5,9;3,3,5;4,3,4
5,7,9;3,5,2;2,3,3
6,7,9;3,2,2;2,3,4
 

Re: 不具合の報告

 投稿者:白石和夫  投稿日:2014年 9月11日(木)09時25分2秒
  > No.3488[元記事へ]

十進BASICの古いバージョンのDET関数は計算結果の正確さを重視して小行列式を計算する再帰アルゴリズムを用いていたのですが,次数が高くなると格段に遅くなるので,現バージョンは掃出し法で計算しています。
計算の途中に除算を含むので誤差が出やすくなっています。
2次,3次,限定であれば,利用者定義関数を用いて途中計算の精度を保証していくのが確実です。

行列演算は,JIS規格の5.6.4(3)の意味での正確さを保証するのは困難です。
JISの正確さの規定は,表5.1にある「数値関数」に対してのみ適用されるものと解釈しています。
たとえば,

10 DATA  1E18, 123456789, -1E18
20 DATA 1,1,1
30 DIM a(3),b(3)
40 MAT READ a,b
50 PRINT DOT(a,b)
60 END

のようなプログラムに対して正確さを保証するのはかなり面倒です。







 

Re: マウスでの入力

 投稿者:白石和夫  投稿日:2014年 9月11日(木)09時39分19秒
  > No.3489[元記事へ]

SAMPLEプログラムの \Complex\sin_2.BAS のような感じでいいのでしょうか?

>  グラフィックの表示プログラムで、一部分を拡大するために、
> プログラムの動作の結果のグラフィック画面から、マウスのクリック&ドラッグで、
> マウスの左クリックのスタート座標と終了座標を読み取る場合、
> 画面上にマウスの動きに合わせて、X座標基準の正方形を破線で表示させる(要は、フォトショップの正方形範囲選択画面)方法ってあるんでしょうか?
> (マウス移動中順次画素のデータを読んで移動する毎に書き換えていくのはあまりに面倒なので)
 

Re: マウスでの入力

 投稿者:ルーン  投稿日:2014年 9月11日(木)22時46分17秒
  > No.3493[元記事へ]

白石和夫さんへのお返事です。

> SAMPLEプログラムの \Complex\sin_2.BAS のような感じでいいのでしょうか?
>

 ありがとうございます。
多分何処かには在ると思ってたんですが、こんなところにあったんですね。
早速、アレンジして組み込んでみました。
 

マンデルブロー集合

 投稿者:ルーン  投稿日:2014年 9月11日(木)23時50分3秒
   基本は10年近く前に作った、”マンデルブロー集合”の計算プログラムです。
当時のパソコンでは、このサイズだと、結果が出るまで数時間かかってたと思います。
はるか昔、まだCPUが8080の頃、初めてBASICで組んで、結果待ちに3日以上かかったのも思い出です。
複素数モードにしたらもっと早くなるかもしれませんが、プリター出力と共にそれは宿題とですね。


最初に左下XY座標値と座標幅を入力(Xs=-2.1  Ys=-1.4  S=2.8で集合全体が出ます。)
後は結果を見て、マウスのドラッグで好きな範囲を選択して拡大していきます。
 繰り返し回数K=250ですが、拡大率が大きくなると、K=1000位にしないと
集合外ぎりぎりの点も入ってきてしまい、やや結果が甘くなります。


100 input prompt "Xs=":Xs
110 input prompt "Ys=":Ys
120 input prompt "S=":s
130 let pit=s/500
140 LET CT=0
1010 LET Ts=TIME
1020 SET BITMAP SIZE 530,550
1030 SET WINDOW 0,529,0,549
1040 SET POINT STYLE 1
1050 LET x$=STR$(Xs)
1060 LET Y$=STR$(Ys)
1070 LET s$=STR$(s)
1100 LET SS$="Xs="&X$&" :Ys="&Y$&" :S="&s$    ! 左下XY座標値と座標幅を表示
1110 PLOT TEXT ,AT 5,530 :SS$
2000 for m=0 to 499
2010    for n=0 to 499
2020       LET  x=Xs+(m*pit)
2030       LET  y=Ys+(n*pit)
2031       let px=x
2032       let py=y
2035       LET a=0
2040       FOR k=1 TO 250            ! この数値を大きくする場合3000行からの色指標のオーバーに注意
2050          LET  Z=x^2+y^2
2060          LET  Cx=x^2-y^2+px
2070          LET  Cy=2*x*y+py
2080          if Z>4 then gosub 3000
2090          let  x=Cx
2100          LET  y=Cy
2105          LET Ct=Ct+1
2110          if a=1 then 2220
2200       next k
2210       gosub 4000
2220    next n
2230 next m
2500 GOTO 5000
3000 LET  c=k
3020 LET  c=c+2
3050 set point color c
3060 PLOT POINTS:m,n
3070 LET  a=1
3080 return
4000 rem if a=1 then return
4010 set point color 1
4020 plot points:m,n
4030 RETURN
5000 LET Ct$=STR$(Ct)                ! 繰り返し回数と計算時間を表示
5010 LET Te=TIME-Ts
5020 LET T$=STR$(Te)
5030 LET ST$=Ct$&"  T="&T$
5040 PLOT TEXT ,AT 5,510 :ST$
6000 CHARACTER INPUT PROMPT " DRAW GRID?(y/n)":D$    ! 結果に10×10のグリッドを入れるか?
6010 IF D$="n" THEN 7000
6020 DRAW GRID(50,50)
7000 PAUSE "拡大する範囲を指定してください"      ! 正方形領域を取得する
7010 CALL GetSquare(Bx,Ty,Tx,By)
8010 LET Xs=Xs+(S*(Bx/500))
8020 LET Ys=Ys+(S*(By/500))
8030 LET S=S*(ABS(Tx-Bx)/500)
8040 CLEAR
8050 GOTO 130
10000 end

   ! マウスによる正方形領域取得副プログラム

   EXTERNAL SUB GetSquare(l,t,r,b)
      ASK LINE STYLE LStyle
      SET DRAW MODE NOTXOR
      SET LINE STYLE 2
      DO
         MOUSE POLL l,t,i,j
      LOOP WHILE i=0
      LET l0=l
      LET t0=t
      LET r0=l0
      LET b0=t0
      PLOT LINES: l0,t0; l0,b0; r0,b0; r0,t0; l0,t0
      DO WHILE i=1
         MOUSE POLL r,b,i,j
         LET w=r-l
         LET h=t-b
         IF ABS(h) < ABS(w) THEN
            LET b=t-SGN(h)*ABS(w)
         ELSE
            LET r=l+SGN(w)*ABS(h)
         END IF
         IF l0<>l OR r0<>r OR b0<>b OR t0<>t THEN
            PLOT LINES: l0,t0; l0,b0; r0,b0; r0,t0; l0,t0
            PLOT LINES: l,t; l,b; r,b; r,t; l,t
            LET l0=l
            LET t0=t
            LET r0=r
            LET b0=b
         END IF
      LOOP
      WAIT DELAY 1
      PLOT LINES: l,t; l,b; r,b; r,t; l,t
      SET DRAW MODE OVERWRITE
      SET LINE STYLE LStyle
      IF l>r THEN SWAP l,r
      IF b>t THEN SWAP b,t
   END SUB
 

マンデルブロー集合修正

 投稿者:ルーン  投稿日:2014年 9月12日(金)00時29分40秒
  > No.3495[元記事へ]

 色指標オーバーエラー防止のために、3000行を
  3000  c=MOD(k,250)
 に変えてください。
 

Re: 不定方程式の解

 投稿者:山中和義  投稿日:2014年 9月13日(土)13時28分42秒
  > No.3474[元記事へ]

問題
a,b,c,dは、整数とする。

行列式
| a  b | = 1
| c  d |

| a^2  b^2 | = 1
| c^2  d^2 |

を満たすものを探しなさい。

答え
ad-bc=1
a^2d^2-b^2c^2=(ad-bc)(ad+bc)=ad+bc=1
連立方程式を解いて、ad=1、bc=0 ∴a=d=±1 かつ( b=0 または c=0 )
よって、
| ±1    0 | = | 1    0 | = 1
|   c  ±1 |   | c^2  1 |
または、
| ±1    b | = | 1  b^2 | = 1
|   0  ±1 |   | 0  1   |
ただし、複号同順とする。
(終り)


--------------------------------------------------------------

問題
a,b,c,d,e,f,g,h,iは、2以上10以下の整数とする。

行列式
| a  b  c | = 1
| d  e  f |
| g  h  i |

| a^2  b^2  c^2 | = 1
| d^2  e^2  f^2 |
| g^2  h^2  i^2 |

を満たすものを探しなさい。

答え
9^9=387420489通りの検索になるが、工夫して計算量を減らす。

 a b c  転置  a d g
 d e f  →   b e h
 g h i      c f i

  ↓180°回転   ↓180°回転

 i h g  転置  i f c
 f e d  →   h e b
 c b a      g d a

式で表すと、
 aei+bfg+cdh-ceg-bdi-afh → aei+dhc+gbf-gec-dbi-ahf
      ↓              ↓
 iea+hdc+gfb-gec-hfa-idb → iea+fbg+chd-ceg-fha-ibd

は同値なので、
 2≦c≦g≦9、2≦a≦i≦9
とする。


また、
| a  b  c | = a| e f |- b| d f | +c| d e |
| d  e  f |    | h i |   | g i |   | g h |
| g  h  i |
P1=ei-fh、P2=di-fg、P3=dh-egとすると、
=aP1-bP2+cP3
X=aP1, Y=bP2, Z=cP3 とすると、
=X-Y+Z

| a^2  b^2  c^2 | = a^2| e^2 f^2 | - b^2| d^2 f^2 | +c^2| d^2 e^2 |
| d^2  e^2  f^2 |      | h^2 i^2 |      | g^2 i^2 |     | g^2 h^2 |
| g^2  h^2  i^2 |
Q1=ei+fh、Q2=di+fg、Q3=dh+egとすると、e^2i^2-f^2h^2=(ei-fh)(ei+fh)など より、
=aP1aQ1-bP1bQ2+cP3cQ3
X'=aQ1, Y'=bQ2, Z'=cQ3 とすると、
=XX'-YY'+ZZ'

よって、不定方程式
 X-Y+Z=1
 XX'-YY'+ZZ'=1
を得る。


LET S=0
FOR E=2 TO 10
   FOR i=2 TO 10
      FOR F=2 TO 10
         FOR H=2 TO 10
            LET P1=E*i-F*H
            LET Q1=E*i+F*H
            FOR D=2 TO 10
               FOR G=2 TO 10
                  LET P2=D*i-F*G
                  LET Q2=D*i+F*G
                  LET P3=D*H-E*G
                  LET Q3=D*H+E*G

                  FOR A=2 TO i !対称性(180°回転)
                     LET X=A*P1
                     LET XX=A*Q1
                     FOR C=2 TO G !対称性(転置)
                        LET Z=C*P3
                        LET ZZ=C*Q3
                        FOR B=2 TO 10
                           LET Y=B*P2
                           LET YY=B*Q2
                           IF X-Y+Z=1 AND X*XX-Y*YY+Z*ZZ=1 THEN !題意を満たすもの

                              IF A=i AND C=G THEN !対称性(転置、180°回転)
                                 IF D>=B AND H>=B THEN
                                    PRINT A;B;C
                                    PRINT D;E;F
                                    PRINT G;H;i
                                    PRINT
                                    LET S=S+1
                                 END IF
                              ELSE
                                 PRINT A;B;C
                                 PRINT D;E;F
                                 PRINT G;H;i
                                 PRINT
                                 LET S=S+1
                              END IF

                           END IF
                        NEXT B
                     NEXT C
                  NEXT A

               NEXT G
            NEXT D
         NEXT H
      NEXT F
   NEXT i
NEXT E
PRINT S; "通り"
END


実行結果

4  3  2
2  2  3
9  7  6

4  2  3
9  2  5
10  3  6

2  4  3
3  2  2
6  9  7

2  3  5
3  2  3
9  5  7

2  3  2
4  2  3
9  6  7

2  3  3
3  2  5
5  9  7

5  3  6
2  2  3
9  4  10

4  3  4
5  3  3
9  5  4

5  2  3
9  3  2
7  3  5

5  2  3
3  3  2
7  9  5

3  2  3
5  3  2
7  5  9

3  2  4
2  3  2
7  6  9

3  5  2
2  3  3
5  7  9

3  2  2
2  3  4
6  7  9

3  4  4
3  3  5
5  4  9

3  2  2
6  3  5
10  4  9

3  2  4
6  3  10
5  2  9

3  5  3
3  4  4
5  9  4

5  3  3
4  4  3
9  4  5

2  2  3
3  4  2
7  9  6

2  2  3
9  4  10
5  3  6

3  9  2
2  5  3
3  7  5

3  3  2
2  5  3
9  7  5

4  4  3
3  5  3
4  9  5

2  2  3
3  5  6
4  9  10

2  3  2
5  6  3
9  10  4

2  3  2
7  6  9
3  2  4

2  6  3
3  7  2
4  9  2

2  2  3
9  7  6
4  3  2

2  3  3
5  7  9
3  5  2

3  4  2
5  9  2
6  10  3

3  5  2
2  9  3
5  7  3

3  2  2
10  9  4
6  5  3

3  3  2
7  9  5
5  2  3

3  5  3
4  9  5
4  4  3

3  2  2
6  9  7
2  4  3

2  3  2
4  10  9
3  6  5

37 通り


 

分割数の和

 投稿者:山中和義  投稿日:2014年 9月14日(日)07時00分11秒
  問題
正の整数が書かれたカードが何枚かあり、全てのカードの和は15であるとする。
1以上15以下の任意の整数kに対し、書かれた数の和がkになるように何枚かを選び出すことができという。
またその選び方は、同じ数の書かれたカードを区別しないものとするとただ1通りである。
このようなカードの組合せはどのようなものが可能か、全ての組合せを探して下さい。
例
 5の場合、
  1,1,1,1,1
  1,1,1,2
  1,1,3
  1,2,2
 の4通り

参考サイト http://oeis.org/A126796

考察
1が少なくとも1つある分割数を考えればよい。

自明なもの
 1,1,1,…,1
 └ n個  ┘

 1,1,1,…,1, k  ただし、1≦k≦[(n+1)/2]
 └ n-k個 ┘

 n=2^k-1
 1,2,4,8,…,2^(k-1)

 n=Σk
 1,2,3,4,…,k
(終り)



LET N=15 !枚数の最大
DIM A(N) !数字の並び
LET A(1)=1 !番兵
PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(2,N-1,A,N)
PRINT C; "通り"

PRINT T(N,N); "通り"
END

EXTERNAL SUB try(P,M,A(),N) !バックトラック法で検索する
FOR i=A(P-1) TO M !nを昇順の並びで分割する
   LET A(P)=i

   IF M-i=0 THEN !分割が終わったなら
      DIM B(N) !1からnまでの数 ※フラグ
      MAT B=ZER
      LET B(A(1))=1 !組み合わせ(動的計画法) 1つ目
      LET T=A(1) !※最大値
      FOR J=2 TO P !1つずつ選ぶ(2つ目以降)
         LET W=A(J)
         FOR K=T TO 1 STEP -1 !その数との和
            IF B(K)=1 THEN LET B(K+W)=1
         NEXT K
         LET B(W)=1 !その数のみ
         LET T=T+W
      NEXT J
      FOR K=1 TO N !1からnまでの数字がつくれたか
         IF B(K)=0 THEN EXIT FOR
      NEXT K
      IF K>N THEN !可能なら
         LET C=C+1 !結果を表示する
         FOR J=1 TO P
            PRINT A(J);
         NEXT J
         PRINT
      END IF
   ELSE
      CALL try(P+1,M-i,A,N) !次へ
   END IF
NEXT i
END SUB

EXTERNAL FUNCTION T(n,k) !漸化式
IF k<=1 THEN
   LET T=1
ELSE
   IF n<2*k-1 THEN
      LET T=T(n,INT((n+1)/2))
   ELSE
      LET T=T(n,k-1)+T(n-k,k)
   END IF
END IF
END FUNCTION

 

Re: 分割数の和

 投稿者:GAI  投稿日:2014年 9月14日(日)10時33分44秒
  > No.3498[元記事へ]

山中和義さんへのお返事です。

> 問題
> 正の整数が書かれたカードが何枚かあり、全てのカードの和は15であるとする。
> 1以上15以下の任意の整数kに対し、書かれた数の和がkになるように何枚かを選び出すことができという。
> またその選び方は、同じ数の書かれたカードを区別しないものとするとただ1通りである。
> このようなカードの組合せはどのようなものが可能か、全ての組合せを探して下さい。
> 例
>  5の場合、
>   1,1,1,1,1
>   1,1,1,2
>   1,1,3
>   1,2,2
>  の4通り
>

これだと、その選び方は、同じ数の書かれたカードを区別しないものとするとただ1通りである。
の条件に反し
1,1,1,2
で2を構成する方法が 1+1,2
の2通り存在することになる。
よって答えは 3通りになります。
 

Re: 分割数の和

 投稿者:山中和義  投稿日:2014年 9月14日(日)15時14分30秒
  > No.3498[元記事へ]

発展問題
正の整数が書かれたカードが何枚かあり、全てのカードの和は15であるとする。
1以上15以下の任意の整数kに対し、書かれた数の和がkになるように何枚かを選び出すことができるという。
またその選び方は、同じ数の書かれたカードを区別しないものとするとただ1通りである。
このようなカードの組合せはどのようなものが可能か、全ての組合せを探して下さい。
例
 5の場合、
  1,1,1,1,1
  1,1,3
  1,2,2
 の3通り

 2,1+1や1+1+1,1+2なので、1,1,1,2を除く。


考察


!1種類の数の場合
!1,1,1,…,1
!└ a個 ┘
!題意より、a=n

LET N=15
PRINT "1が";STR$(N);"個"

PRINT


!2種類の数の場合
!1がa個あるので、1からaまでの数はこれで表せるので、2番目の数はa+1である。
!1,1,…,1,  a+1,a+1,…,a+1
!└ a個 ┘  └   b個   ┘
!題意より、a+(a+1)b=n ∴(a+1)(b+1)=n+1
!不定方程式を解く。

LET M=N+1
FOR A=2 TO M-1
   IF MOD(M,A)=0 THEN !n+1の約数なら(1とn+1は除く)
      LET B=M/A
      PRINT "1が";STR$(A-1);"個、"; STR$(A);"が";STR$(B-1);"個"
   END IF
NEXT A

PRINT


!3種類の数の場合
!1,1,…,1,  a+1,a+1,…,a+1,  (a+1)(b+1),(a+1)(b+1),…,(a+1)(b+1)=a+(a+1)b+1
!└ a個 ┘   └   b個   ┘    └           c個          ┘
!題意より、a+(a+1)b+(a+1)(b+1)c=n ∴(a+1)(b+1)(c+1)=n+1
!不定方程式を解く。

LET M=N+1
FOR A=2 TO M-1
   IF MOD(M,A)=0 THEN !n+1の約数なら
      FOR B=2 TO M/A-1
         IF MOD(M/A,B)=0 THEN !(n+1)/aの約数なら
            LET C=(M/A)/B
            PRINT "1が";STR$(A-1);"個、";
            PRINT STR$(A);"が";STR$(B-1);"個、";
            PRINT STR$(A*B);"が";STR$(C-1);"個"
         END IF
      NEXT B
   END IF
NEXT A

PRINT


!4種類の数の場合
!1,…,1,  a+1,…,a+1,  (a+1)(b+1),…,(a+1)(b+1),  (a+b)(b+1)(c+1),…,(a+b)(b+1)(c+1)=a+(a+1)b+{a+(a+1)b+1}c+1
!└a個┘  └ b個 ┘    └      c個      ┘           └           d個          ┘
!題意より、a +(a+1)b +(a+1)(b+1)c +(a+1)(b+1)(c+1)d = n ∴(a+1)(b+1)(c+1)(d+1)=n+1
!不定方程式を解く。

LET M=N+1
FOR A=2 TO M-1
   IF MOD(M,A)=0 THEN !n+1の約数なら
      LET M1=M/A
      FOR B=2 TO M1-1
         IF MOD(M1,B)=0 THEN !(n+1)/aの約数なら
            LET M2=M1/B
            FOR C=2 TO M2-1
               IF MOD(M2,C)=0 THEN !(n+1)/(ab)の約数なら
                  LET D=M2/C
                  PRINT "1が";STR$(A-1);"個、";
                  PRINT STR$(A);"が";STR$(B-1);"個、";
                  PRINT STR$(A*B);"が";STR$(C-1);"個、";
                  PRINT STR$(A*B*C);"が";STR$(D-1);"個"
               END IF
            NEXT C
         END IF
      NEXT B
   END IF
NEXT A

PRINT


!5種類の数の場合
!  :
!  :

END


実行結果

1が15個

1が1個、2が7個
1が3個、4が3個
1が7個、8が1個

1が1個、2が1個、4が3個
1が1個、2が3個、8が1個
1が3個、4が1個、8が1個

1が1個、2が1個、4が1個、8が1個

 

Re: 分割数の和

 投稿者:山中和義  投稿日:2014年 9月15日(月)10時57分49秒
  > No.3500[元記事へ]

> 発展問題
> 正の整数が書かれたカードが何枚かあり、全てのカードの和は15であるとする。
> 1以上15以下の任意の整数kに対し、書かれた数の和がkになるように何枚かを選び出すことができるという。
> またその選び方は、同じ数の書かれたカードを区別しないものとするとただ1通りである。
> このようなカードの組合せはどのようなものが可能か、全ての組合せを探して下さい。
> 例
>  5の場合、
>   1,1,1,1,1
>   1,1,3
>   1,2,2
>  の3通り
>
>  2,1+1や1+1+1,1+2なので、1,1,1,2を除く。


考察
1,…,1,  a+1,…,a+1,  (a+1)(b+1),…,(a+1)(b+1),  (a+1)(b+1)(c+1),…,(a+1)(b+1)(c+1),   …
└a個┘  └ b個 ┘    └      c個      ┘           └           d個          ┘
題意より、a +(a+1)b +(a+1)(b+1)c +(a+1)(b+1)(c+1)d + … = n ∴(a+1)(b+1)(c+1)(d+1) … = n+1
不定方程式を解く。

したがって、数の並びには、n+1の約数が現れる。


構造が見えてきたので、再帰呼出しでプログラムをまとめてみる。


LET N=15

DIM X(N) !個数
PUBLIC NUMERIC C !場合の数
CALL try(1,N+1,X)
PRINT C; "通り"
END

EXTERNAL SUB try(P,M,X()) !バックトラック法で検索する
LET X(P)=M !p種類揃ったなら

LET C=C+1 !結果を表示する
LET T=1
FOR i=1 TO P
   PRINT STR$(T);"が";STR$(X(i)-1);"個、";
   LET T=T*X(i)
NEXT i
PRINT


FOR A=2 TO M-1
   IF MOD(M,A)=0 THEN !約数なら
      LET X(P)=A
      CALL try(P+1,M/A,X) !次へ
   END IF
NEXT A
END SUB


実行結果

1が15個、
1が1個、2が7個、
1が1個、2が1個、4が3個、
1が1個、2が1個、4が1個、8が1個、
1が1個、2が3個、8が1個、
1が3個、4が3個、
1が3個、4が1個、8が1個、
1が7個、8が1個、
8 通り



n=2014のとき、n+1=2015=5×13×31

1が2014個、
1が4個、5が402個、
1が4個、5が12個、65が30個、
1が4個、5が30個、155が12個、
1が12個、13が154個、
1が12個、13が4個、65が30個、
1が12個、13が30個、403が4個、
1が30個、31が64個、
1が30個、31が4個、155が12個、
1が30個、31が12個、403が4個、
1が64個、65が30個、
1が154個、155が12個、
1が402個、403が4個、
13 通り


 

Re: 分割数の和

 投稿者:GAI  投稿日:2014年 9月16日(火)12時21分16秒
  > No.3501[元記事へ]

山中和義さんへのお返事です。

すっきりしたプログラムで記述できるんですね。


> n=2014のとき、n+1=2015=5×13×31
>
> 1が2014個、
> 1が4個、5が402個、
> 1が4個、5が12個、65が30個、
> 1が4個、5が30個、155が12個、
> 1が12個、13が154個、
> 1が12個、13が4個、65が30個、
> 1が12個、13が30個、403が4個、
> 1が30個、31が64個、
> 1が30個、31が4個、155が12個、
> 1が30個、31が12個、403が4個、
> 1が64個、65が30個、
> 1が154個、155が12個、
> 1が402個、403が4個、
>  13 通り


これを真似て
n=8639
で実行したら大変なことになりました。
(とても人間業では不可能です。)
なんと76864 通りでした。
(断トツの多さです。第2位 n=9215 の 45568 通り)
 

オフレコ

 投稿者:SECOND  投稿日:2014年 9月17日(水)12時22分55秒
  過去の神業数学らしきものの見え隠れについて、妙な事を、考えてみた。

十進BASIC の諸兄なら、数理的因果律は、あたりまえのことで、
それに反する事は、無いと言い切って頂けるだろう。そうでないように見える時も、
仕掛けが隠れているだけだと。

ならば、現在は、過去から見る無限の果て。「起源」が有る?と、その因は?
「因果律に反する所」になるので・・無限列 のままの方が、無理でなくなる。
 無限列へ抵抗する頭と、その理由も探せない不可思議 もある・・
・・・
有史以前ず~っと、無限な数学が、既存?となってしまうが・・
それは何処に? 脳が? まさか?


こんなものを投稿する所ではないので、ボツにしていたプログラムを付録。

!--------------------------------------------------------------------------------------
!バウンド・ボール on complex( Ver 7.5.0以降で動作)
!
!動作範囲を、凸角の、内角を含む多角形まで、広げた。
!十進BASICは、複素数モードにて 2次元座標を、1つの変数で指定したり、移動する事が、
!描画においても、行なえるので、(ver.7.5.0以降) 動作空間を、複素数平面上へ移した。
!--------------------------------------------------------------------------------------

!ボールを、速くするには、Step⊿を大きく、周期.02 を小さく。
!  )
!LET m0=0.23                    !ボールの Step⊿・・大きすぎると、凸角反射失敗する
! (
!  )         ↓・・・設定周期.02秒 小さいほど、消費電力 大きくなる。
!LET t2=t2+(.02-MOD(t1-t0,86400))/20  !20ms-検出周期(t1-t0)=偏差 →t2(積分 Gain=1/20)
! (
!--------------------------------------------------------------------------------------

OPTION ARITHMETIC COMPLEX      !複素数平面
LET m_=15                      !最大角数
LET ma=14                      !開始角数
LET m0=0.23                    !ボールの Step⊿
LET r=0.7                      !ボールの半径
LET r0=5                       !計算上の多角形 頂点~中心点 (±1 変化の中央)
DIM p(m_+1), s(m_+1), rec(3 TO m_, m_)
SET WINDOW -7,7, -7,7
SET TEXT background "opaque"
RANDOMIZE 6                    !引数を消すと、起動ごとに、再現されない。

DEF apex_(i)=(r0+2*RND-1)*EXP(COMPLEX(0,a1+ag*(i+(RND-3.5)/3)))  !各頂点 p(i)

FUNCTION apex(i)
   IF mlb=1 OR rec(ma,i)=0 THEN LET rec(ma,i)=apex_(i)
   LET apex=rec(ma,i)
END FUNCTION

DO
   CLEAR
   SET DRAW MODE overwrite
   SET LINE COLOR "silver"
   LET ag=2*PI/ma              !標準の(頂点間の中心角) =外角(辺の延長と隣辺の角度)
   LET a1=1.5*PI-ag/2          !標準 p(1) の方向。(↓方向-頂点間の中心角/2)
   LET p(1)=apex(1)
   FOR i=1 TO ma
      IF i< ma THEN LET p(i+1)=apex(i+1) ELSE LET p(i+1)=p(1) !各頂点
      LET s(i)=p(i+1)-p(i)
      PLOT LINES: p(i); p(i+1)                    !計算用の壁。辺 s(i)
   NEXT i
   LET s(i)=s(1)
   !                      s3          s4 4 s3
   !       p3          4──3      5/  \3
   !   s3/  \s2    s4│    │s2   s5\    /s2   ・・・
   !   p1───p2      1──2        1─2
   !       s1             s1             s1
   !
   SET LINE width 5                               !ボール(半径r) の当る外壁
   SET LINE COLOR "black"                         !---------------------------------
   LET a=(PI-arg(s(1)/s(ma)))/2                   !p(1)内角の1/2
   LET d1=r/SIN(a)*EXP(COMPLEX(0,arg(s(ma))-a))   !計算用 多角形頂点 ~外壁 多角形頂点
   FOR i=1 TO ma
      LET a=(PI-arg(s(i+1)/s(i)))/2               !p(i+1)内角の1/2
      LET d2=r/SIN(a)*EXP(COMPLEX(0,arg(s(i))-a)) !計算用 多角形頂点 ~外壁 多角形頂点
      PLOT LINES: p(i)+d1; p(i+1)+d2
      LET d1=d2
   NEXT i
   SET LINE width 1
   !---
   PLOT TEXT,AT 5.8 , 6.26: "停止"
   PLOT TEXT,AT 5.62, 5.68: "ボタン"
   PLOT LINES: 5.5,5.5; 6.95,5.5; 6.95,6.95 ; 5.5,6.95 ; 5.5,5.5
   PLOT TEXT,AT -6.7,-6.9: "左(順送り)右(逆送り)クリック:角数の選択= "& STR$(ma)& "  長押し0.5秒で早送り"
   CALL play00
   LET bma=ma
   IF 0< mlb THEN LET ma=MOD(ma-2,m_-2)+3 ELSE LET ma=MOD(ma-4,m_-2)+3 !角数 Loop 3,4,5,6,,m_,3,4,,
LOOP UNTIL 5.5< mox AND 5.5< moy
DRAW disk WITH SCALE(r)*SHIFT(bb)          !停止直前のボール表示

SUB play00
   SET DRAW MODE NOTXOR                    !2度書きで消える NOTXOR モード
   SET LINE COLOR 8
   LET nb=0
   LET b=p(1)*0.999                        !ボールの発射位置
   LET i=arg(s(1))+SQR(2)*PI/ma/1.1313     !ボールの発射角度
   LET m=m0*EXP(COMPLEX(0,i))              !ボールの step ベクトル
   LET t0=TIME
   DO
      DRAW disk WITH SCALE(r)*SHIFT(b)     !ボールを書く
      PLOT LINES : b;                      !履歴線を(書く・消す)
      SET DRAW mode explicit               !画像加工終り、表示の常時更新 (Normal)
      !------------
      IF 0< t2 THEN WAIT DELAY t2          !t2: 制御出力の休止秒。
      LET t1=TIME                          !t1: 前の周期の終り。※TIME は 約.05秒毎の更新。
      LET t2=t2+(.02-MOD(t1-t0,86400))/20  !20ms-検出周期(t1-t0)=偏差 →t2(積分 Gain=1/20)
      LET t0=t1                            !t0: 次の周期の始め= 前の周期の終り
      !------------
      LET bb=b
      LET b=b+m
      FOR n=1 TO ma
         IF n<>nb THEN                     !n=nb 反射完了フラグな為、n=nb 状態の進入×
            CALL Reflex                    !反射処理
            IF n=nb THEN EXIT FOR          !n=nb 反射完了、b の更新まで全ての反射処理×
         END IF
      NEXT n
      IF mbak=0 OR mlb=0 AND mrb=0 THEN
         LET mbak=2*(mlb+mrb)
      ELSE
         LET mbak=mbak-1.001/5             !左クリック押続け、約0.5秒後オートリピートへ入る
         WAIT DELAY .1                     !オートリピート間隔
      END IF
      MOUSE POLL mox,moy,mlb,mrb           !マウスの状態取得
      SET DRAW mode hidden                 !画像加工始め、表示更新を一時停止 (Abnormal)
      DRAW disk WITH SCALE(r)*SHIFT(bb)    !ボールだけを消す
   LOOP UNTIL mbak< mrb OR mbak< mlb       !左クリックは、Leading Edge 検出
   PLOT LINES
END SUB

!-------------------------------------------------------------
!n番辺のベクトル s(n)
! 1/s(n)=  水平に向ける回転移動ベクトルとして使用、
!     常に、水平相対な 姿勢で、交点、反射方向、、を求める
!               y =im(m) /re(m) *(x-re(b) )+im(b) …回転前の、ボール軌跡
!im(p1)=im(p2)= y =im(rm)/re(rm)*(x-re(rb))+im(rb) …回転後の、ボール軌跡
!
!  *s(n)= 再び元に戻す
!
! ※p1-1e-15, p2+1e-15 の 1e-15 は、真値が p1=x or p2=x
!   の場合に、計算丸めで x< p1 or p2< x 区間外になるのを防止
!-------------------------------------------------------------
SUB Reflex
   LET rm=m /s(n)                               !水平な「辺」に相対な m  (stepベクトル)
   IF 0<=im(rm) THEN EXIT SUB                   ! rm が「辺」に平行、又は上向き、交点なし
   LET rb=b /s(n)                               !   「辺」に相対な b  (m の延長予測点)
   LET rbb=bb /s(n)                             !   「辺」に相対な bb (1つ前の b) 描画済み先頭
   LET p1=p(n) /s(n) -1e-15                     !   「辺」に相対な下限
   LET p2=p(n+1) /s(n) +1e-15                   !   「辺」に相対な上限
   IF im(p1)< im(rb) THEN EXIT SUB              !     rb  が「辺」に未接触、交点なし
   IF im(rbb)<=im(p1) THEN EXIT SUB             !π< 内角を挟む他領域。rbb が「辺」以下、交点なし
   LET x=(im(p1)-im(rb))*re(rm)/im(rm)+re(rb)   !rm の延長 直線の「辺」との交点x
   IF x< re(p1) OR re(p2)< x THEN EXIT SUB      !        「辺」の区間外、交点なし
   LET m=conj(rm) *s(n)                         !反射方向 conj.   stepベクトル m 復元
   LET b=COMPLEX(x,im(p1)) *s(n)                !延長予測点を、反射点に切詰め、b 復元
   LET nb=n                                     !反射辺の番号、履歴
END SUB

END

!----------------------------------------------------
!左クリック:(順送り) 動作中の多角形3→15 上書き 循環。
!       新しい形で、上書きしていきます。
!       ( 過去1周分は、記憶 保持)
!
!右クリック:(逆送り) 動作中の多角形3←15 再生 循環。
!       過去1周分、上書きせず、巡回する。
!       ( 空の場合は、新しい形)
!
!(左 or 右) どちらも、長押しは、オート・リピートする。
!
!画面右上「停止ボタン」(左 or 右)クリック:終了。
!----------------------------------------------------
!上記を「ヘルプ」として、此処まで セーブ。
 

デバッグ

 投稿者:SECOND  投稿日:2014年 9月20日(土)12時27分26秒
  !◇Amusement_Program [8]マンデルブロ集合の外周で、散歩」
!http://6317.teacup.com/basic/bbs/t7/#8
!拡大を進めて行く内に、白い縦線が現れたり、真っ白になって フリーズ、
!になっていましたので、"拡大の限界" の表示と、入力制限を加えました。(み)
!
!※座標が、限界を超えて微細化すると、for~next の step が止まり、
! 下の例の様に、自力の脱出が出来なくなっていました。

OPTION ARITHMETIC DECIMAL    !complex での限界が あまり鮮明でないので。

CALL test( 5e-15 )  !正常 STEP の限界
CALL test( 4e-15 )  !無限ループになる

SUB test( dx)
   PRINT "-----"
   FOR x=1 TO 1+1e-14 STEP dx
      FOR y=1 TO 1+1e-14 STEP dx
         PRINT x,y
      NEXT y
   NEXT x
END SUB

END
 

トランプゲームの創作

 投稿者:GAI  投稿日:2014年 9月22日(月)10時19分35秒
  トランプ52枚をよくシャッフルして
4枚テーブルへ並べる。
この4枚の数字の合計をして、その合計が素数ならそこで終了。
素数でないならさらに4枚を並べていく。
このように続けて行ったとき、全てのトランプが無くなってしまう確率はどれ位か?
(4枚ずつの13組が全てそれぞれの和が合成数)
論理的にこの確率は求まるものでしょうか。
しばらく挑戦していたんですが場合の処理が多岐に膨らんでいったので諦めてモンテカルロ法的に、プログラムでこの試行を100万回やってみたら24503回が完成できました。
従って統計的確率は0.024503・・・ 位だとは思われますがこの数値が妥当であるかを確認して頂きませんか?


また、4枚並べたときに素数でないとき5枚目を並べることに挑戦でき、それでも5枚の合計が素数でないなら
6枚目も挑戦できる(以下何枚でも)とルールを変更すれば、既に場に出たカードの種類が判明しているので
次のカードを出すか、出さないかをある程度確率的に戦略を取れそう。
(次のカードを出すときそれで素数になる確率が0.5以上ならばカードを出すことをしない。従って新たに4枚まとめてテーブルに出すことになる。これを戦略にする。)
このルールで全てのカードが無くなる確率はいかほどになるのか?
(この経過を上手くプログラムにする力量がないのでよろしくお願いします。)

確率に頼ってやれば、素数かどうかの判定回数が増えるし、また頼らないとすると判定回数は少ないが、4枚が素数になることの割合が高くなるという微妙な関係になる。
また一枚を加える確率の判定基準を1/2以外にするときそれはどんな確率規準が最も適切になるのかなどいろいろ知りたい所です。
 

数独

 投稿者:永野護  投稿日:2014年 9月22日(月)14時22分11秒
  private  bool  判定(int ix,int iy)  //ナンプレ条件の判定(行と列のみ判定)
{  int i,j;int  x=tb[ix,iy];
for(i=0;i<9;i++) if (ix  !=i  && x==tb[i,iy]) return  (false);
for(i=0;i<9;i++) if (iy  !=i  && x==tb[ix,i]) return  (false);
return  numpre();  //  ここが再帰的になる
}


private  bool  numpre()
{  int i,j,k;
for (i=0;i<9;i++)
  for (j=0;j<9;j++)
   if (tb[i,j]==0)
{ for (k=1;k<10;k++)
  {tb[i,j]=k;
   if  (判定(i,j)) return true;
}
tb[i,j]=0; return false;
}
return true;
}

以上はVisual  C#.NETによるアルゴリズムとデーター構造(白井豊 著:ゆたか創造社)に掲載されていた
ナンプレを解くプログラムの一部です。結果出力部などは省略しています。
これを十進BASICで書き直せばどのようになるのでしょうか。
よろしくお願いします。

 

Re: 数独

 投稿者:山中和義  投稿日:2014年 9月23日(火)10時02分29秒
  > No.3507[元記事へ]

永野護さんへのお返事です。

> private  bool  判定(int ix,int iy)  //ナンプレ条件の判定(行と列のみ判定)
> {  int i,j;int  x=tb[ix,iy];
> for(i=0;i<9;i++) if (ix  !=i  && x==tb[i,iy]) return  (false);
> for(i=0;i<9;i++) if (iy  !=i  && x==tb[ix,i]) return  (false);
> return  numpre();  //  ここが再帰的になる
> }
>
>
> private  bool  numpre()
> {  int i,j,k;
> for (i=0;i<9;i++)
>   for (j=0;j<9;j++)
>    if (tb[i,j]==0)
> { for (k=1;k<10;k++)
>   {tb[i,j]=k;
>    if  (判定(i,j)) return true;
> }
> tb[i,j]=0; return false;
> }
> return true;
> }


PUBLIC NUMERIC FALSE,TRUE !システム定数
LET FALSE=0
LET TRUE=-1

DATA 0,7,0, 0,0,0, 0,0,5 !難問
DATA 0,0,6, 0,2,0, 0,0,0
DATA 0,9,0, 1,0,0, 3,0,0

DATA 0,0,0, 0,0,4, 0,0,2
DATA 0,8,0, 0,0,0, 0,1,0
DATA 5,0,0, 3,0,0, 0,0,0

DATA 0,0,4, 0,0,7, 0,6,0
DATA 0,0,0, 0,8,0, 1,0,0
DATA 2,0,0, 0,0,0, 0,9,0

PUBLIC NUMERIC tb(0 TO 8, 0 TO 8)
MAT READ tb

LET dummy=numpre(dummy)

END

EXTERNAL FUNCTION check(ix,iy) !ナンプレ条件の判定
LET x=tb(ix,iy)
FOR i=0 TO 8 !行
   IF ix<>i AND x=tb(i,iy) THEN
      LET check=FALSE
      EXIT FUNCTION
   END IF
NEXT i
FOR i=0 TO 8 !列
   IF iy<>i AND x=tb(ix,i) THEN
      LET check=FALSE
      EXIT FUNCTION
   END IF
NEXT i
LET bx=INT(ix/3)*3 !ブロック
LET by=INT(iy/3)*3
FOR i=0 TO 2
   FOR J=0 TO 2
      IF (ix<>bx+i OR iy<>by+J) AND x=tb(bx+i,by+J) THEN
         LET check=FALSE
         EXIT FUNCTION
      END IF
   NEXT J
NEXT i

LET check=numpre(dummy) !ここが再帰的になる
END FUNCTION

EXTERNAL FUNCTION numpre(dummy)
FOR i=0 TO 8 !9×9
   FOR J=0 TO 8
      IF tb(i,J)=0 THEN !未定義なら
         FOR k=1 TO 9 !1から9までの数を置いてみる
            LET tb(i,J)=k
            IF check(i,J)<>FALSE THEN !この数でよいなら
               LET numpre=TRUE
               EXIT FUNCTION
            END IF
         NEXT k
         LET tb(i,J)=0 !元に戻す
         LET numpre=FALSE
         EXIT FUNCTION
      END IF
   NEXT J
NEXT i
MAT PRINT tb; !結果を表示する
LET numpre=TRUE
END FUNCTION

 

数独

 投稿者:永野護  投稿日:2014年 9月24日(水)10時03分18秒
  わかりやすい解説ありがとうございました。
お忙しい中、恐縮です。
敬具
 

Re: トランプゲームの創作

 投稿者:しばっち  投稿日:2014年 9月24日(水)21時05分34秒
  > No.3506[元記事へ]

GAIさんへのお返事です。

> 従って統計的確率は0.024503・・・ 位だとは思われますがこの数値が妥当であるかを確認して頂きませんか?
とりあえず作ってみました。
下記のプログラムでもこれに近い値が出ました。

DIM CARD(52)
RANDOMIZE
LET M=10000 !'試行回数
FOR K=1 TO M
   FOR I=1 TO 52
      LET CARD(I)=MOD(I-1,13)+1 !'トランプ52枚
   NEXT I
   FOR I=1 TO 52
      LET J=INT(RND*52)+1
      SWAP CARD(I),CARD(J) !'カードシャッフル
   NEXT I
   LET FL=0 !'フラグをリセット
   FOR J=1 TO 52 !'上からカードを引いていく
      LET S=S+CARD(J)
      IF MOD(J,4)=0 THEN !'4枚目なら
         IF ISPRIME(S)=1 THEN '!素数ならループを抜ける
            LET FL=1 !'フラグセット
            EXIT FOR
         END IF
         LET S=0
      END IF
   NEXT J
   IF FL=0 THEN LET COUNT=COUNT+1 !'カウントする
NEXT K
PRINT COUNT;COUNT/M
END

EXTERNAL  FUNCTION ISPRIME(X) !'素数か
FOR I=2 TO SQR(X)
   IF MOD(X,I)=0 THEN
      LET ISPRIME=0
      EXIT FUNCTION
   END IF
NEXT I
LET ISPRIME=1
END FUNCTION

> また、4枚並べたときに素数でないとき5枚目を並べることに挑戦でき、それでも5枚の合計が素数でないなら
> 6枚目も挑戦できる(以下何枚でも)とルールを変更すれば、既に場に出たカードの種類が判明しているので
> 次のカードを出すか、出さないかをある程度確率的に戦略を取れそう。
> (次のカードを出すときそれで素数になる確率が0.5以上ならばカードを出すことをしない。従って新たに4枚まとめてテーブルに出すことになる。これを戦略にする。)

下記のプログラムでいいのかあまり自信がありません。(細かいところの解釈についても)
まず、「素数になる確率が0.5以上」この部分の求め方についてですが
残りのカードを種類ごとにカウントし、例えば現在のカード合計Sが30だとすると
次の素数は1~13の範囲で31,37,41,43まで、つまり1,7,11,13のカードの枚数の合計SSと
残りのカード枚数から求めています。これでいいのかは分かりません。

> このルールで全てのカードが無くなる確率はいかほどになるのか?

プログラムの結果として、並べるカードの枚数が増えるとそれだけ素数になる確率も増えるということでしょうか。

DIM CARD(52),A(13),V(52)
RANDOMIZE
LET M=10000 !'試行回数
FOR K=1 TO M
   FOR I=1 TO 52
      LET CARD(I)=MOD(I-1,13)+1 !'トランプ52枚
   NEXT I
   FOR I=1 TO 52
      LET J=INT(RND*52)+1
      SWAP CARD(I),CARD(J) !'カードシャッフル
   NEXT I
   LET S=0
   LET NUM=0
   LET FL=0 !'フラグリセット
   FOR J=1 TO 52 !'上からカードを引いていく
      LET S=S+CARD(J)
      LET NUM=NUM+1
      IF NUM=4 THEN !'4枚引いたら
         IF ISPRIME(S)=1 THEN
            LET FL=1
            LET V(NUM)=V(NUM)+1
            EXIT FOR
         END IF
      END IF
      IF NUM>=4 THEN !'5枚目以降を引く前に
         MAT A=ZER
         FOR L=J+1 TO 52
            LET A(CARD(L))=A(CARD(L))+1 !'残りのカードを種類ごとにカウント
         NEXT L
         LET SS=0
         FOR L=1 TO 13
            IF ISPRIME(S+L)=1 THEN !'次に素数となる数L
               LET SS=SS+A(L) !'その数Lのカードの合計枚数
            END IF
         NEXT L
         IF J<52 AND SS/(52-J)>=.5 THEN !'50%以上なら「戦略」を発動。カードは出さない
         !' PRINT "戦略";K
            LET NUM=0
            LET P=P+1 !'戦略発動回数
            LET S=0
         ELSE
            IF ISPRIME(S)=1 THEN !'素数ならループを抜ける
               LET FL=1 !'フラグセット
               LET V(NUM)=V(NUM)+1 !'その時のカードの枚数
               EXIT FOR
            END IF
         END IF
      END IF
   NEXT J
   IF FL=0 THEN LET COUNT=COUNT+1 !'カウントする
NEXT K
PRINT COUNT;COUNT/M
PRINT P
FOR I=1 TO 52
   IF V(I)>0 THEN PRINT I;":";V(I)
NEXT I
END

EXTERNAL  FUNCTION ISPRIME(X) !'素数か
FOR I=2 TO SQR(X)
   IF MOD(X,I)=0 THEN
      LET ISPRIME=0
      EXIT FUNCTION
   END IF
NEXT I
LET ISPRIME=1
END FUNCTION
 

Re: トランプゲームの創作

 投稿者:GAI  投稿日:2014年 9月25日(木)12時20分21秒
  > No.3510[元記事へ]

しばっちさんへのお返事です。


プログラムの提供ありがとうございます。
このプログラムのお陰で、数百万回の試行を一瞬のうちに追跡することが可能になります。
「戦略」を行使するかの判断に使う確率の数値をいろいろ変化させながら調査しました。

> IF J<52 AND SS/(52-J)>=.5 THEN !'50%以上なら「戦略」を発動。カードは出さない
            ↑ の数字を変える

100000回の試行での調査
[確率] :   [達成回数確率]
0.5  :   0.00005
0.4    :   0.00012
0.3    :   0.00279
0.2    :   0.02765
0.1    :   0.02875
0.05   :      0.02805


そこで確率0.1~0.2あたりをもっと追跡すると
300000回の試行での調査
[確率] :   [達成回数確率]
0.17  :   0.02912
0.16   :   0.02894
0.15   :   0.02912
0.14   :   0.02945
0.13   :   0.02948
0.12   :      0.02812


このことは、次のカードで和が素数になる確率が高くなるとそれだけ4枚ずつカードを出す回数が増えていくので、
偶然に左右され、それぞれでの素数判定のチェックに引っ掛かる可能性が高くなる。
また、確率に余り頼らないとすると、1枚ずつカードを安全に引いて行けるが、逆にそれぞれでの素数判定の回数が増えるので素数になるカードを引いてしまう割合が高くなりやはり最後まで到達しずらくなる。

この2つの微妙なバランスで最適な戦略が存在する。


上記の調査により戦略を行使する基準は次のカードで和が素数になる確率が1割3分~1割4分以上であればカードを一枚追加してオープンすることを避け、新たに4枚のカードを開いて再スタートをしていくことにより、先の機械的に4枚ずつでの達成確率
0.024503・・・
を上回れる
0.029以上の確率で全部のカードを処理することができる。


しかし、思った以上に確率を上げることは難しいんですね。
やはり運は天にまかせるしかないか!

 
 

ルールを変えて

 投稿者:GAI  投稿日:2014年 9月26日(金)20時00分18秒
  トランプを一枚ずつ出していき、出したカードの数の合計がすべて合成数(素数になったら終わりのルール)になって全てのカードが掃けることを起こしたい。
そのようにできるスタートのトランプの配列を求めるプログラムは作れますか?
また全部で何通りあるかも知りたい。
 

Re: ルールを変えて

 投稿者:しばっち  投稿日:2014年 9月28日(日)17時31分32秒
  > No.3512[元記事へ]

GAIさんへのお返事です。

> トランプを一枚ずつ出していき、出したカードの数の合計がすべて合成数(素数になったら終わりのルール)になって全てのカードが掃けることを起こしたい。
> そのようにできるスタートのトランプの配列を求めるプログラムは作れますか?

下記のプログラムは貪欲なアルゴリズムにより
1通りの並べ方を探索します。全探索は行っていません。


DIM CARD(52)
RANDOMIZE
FOR I=1 TO 52
   LET CARD(I)=MOD(I-1,13)+1
NEXT I
FOR I=1 TO 52
   LET J=INT(RND*52)+1
   SWAP CARD(I),CARD(J)
NEXT I
LET S=0
FOR K=1 TO 52
   FOR I=1 TO 52
      IF CARD(I)<>0 AND ISPRIME(S+CARD(I))=0 THEN EXIT FOR
   NEXT I
   IF I>52 THEN
      PRINT "探索失敗です"
      STOP
   END IF
   LET S=S+CARD(I)
   PRINT K;":";CARD(I),S
   LET CARD(I)=0
NEXT K
END

EXTERNAL  FUNCTION ISPRIME(X)
LET ISPRIME=0
FOR I=2 TO SQR(X)
   IF MOD(X,I)=0 THEN EXIT FUNCTION
NEXT I
LET ISPRIME=1
END FUNCTION
 

バイオリズム

 投稿者:しばっち  投稿日:2014年 9月28日(日)17時32分46秒
  バイオリズムに科学的根拠はありません

BIRTHYEARに誕生年(西暦)を
BIRTHMONTHに誕生月を
BIRTHDAYに誕生日を設定してください


DIM MM(12)
CALL GINIT(800,600)
MAT READ MM
DATA 31,28,31,30,31,30,31,31,30,31,30,31
'誕生年(西暦)を設定してください↓
LET BIRTHYEAR=
'誕生月を設定してください↓
LET BIRTHMONTH=
'誕生日を設定してください↓
LET BIRTHDAY=
LET T1=YMDT2JD(BIRTHYEAR,BIRTHMONTH,BIRTHDAY)
LET D$=DATE$
LET YEAR=VAL(D$(1:4))
LET MONTH=VAL(D$(5:6))
LET DAY=VAL(D$(7:8))
IF MONTH=2 AND (MOD(YEAR,100)<>0 AND MOD(YEAR,4)=0 OR MOD(YEAR,400)=0) THEN LET MM(2)=29
LET LENGTH=YMDT2JD(YEAR,MONTH,DAY)-T1
LET TT=LENGTH-DAY
LET PW=23 !'身体
LET SW=28 !'感情
LET IW=33 !'知性
LET PP=MOD(TT,PW)
LET SS=MOD(TT,SW)
LET II=MOD(TT,IW)
LET YS=300
LET XS=100
LET HH=60
LET A$="バイオリズム"
SET TEXT HEIGHT HH
SET TEXT COLOR 7
PLOT TEXT,AT 400-HH*LEN(A$)/2,100:A$
SET LINE COLOR 7
PLOT LINES:XS,YS;100+32*20,YS
PLOT LINES:XS,YS-120;XS+32*20,YS-120;XS+32*20,YS+120;XS,YS+120;XS,YS-120
SET TEXT HEIGHT 10
FOR J=1 TO MM(MONTH)
   IF MOD(J,5)=0 THEN
      PLOT LINES:XS+20*J,YS-10;XS+20*J,YS+10
      PLOT TEXT,AT XS+20*J-5,YS-15:STR$(J)
   ELSE
      PLOT LINES:XS+20*J,YS-5;XS+20*J,YS+5
   END IF
NEXT  J
SET LINE COLOR 5
PLOT LINES:XS+20*DAY,YS+15;XS+20*DAY,YS+100
PLOT LINES:XS+20*DAY,YS+15;XS+20*DAY+5,YS+25
PLOT LINES:XS+20*DAY,YS+15;XS+20*DAY-5,YS+25
SET LINE COLOR 1
FOR J=1 TO MM(MONTH) !'身体
   LET YY=YS+100*SIN(PI*(PP+J)/PW)
   PLOT LINES:XS+J*20,YY;
NEXT J
SET LINE COLOR 2
PLOT LINES
FOR J=1 TO MM(MONTH) !'感情
   LET YY=YS+100*SIN(PI*(SS+J)/SW)
   PLOT LINES:XS+J*20,YY;
NEXT J
SET LINE COLOR 4
PLOT LINES
FOR J=1 TO MM(MONTH) !'知性
   LET YY=YS+100*SIN(PI*(II+J)/IW)
   PLOT LINES:XS+J*20,YY;
NEXT J
PLOT LINES
SET TEXT HEIGHT 20
SET LINE COLOR 1
PLOT LINES:XS,450;XS+100,450
PLOT TEXT,AT XS+110,460:"身体"
SET LINE COLOR 2
PLOT LINES:XS,480;XS+100,480
PLOT TEXT,AT XS+110,490:"感情"
SET LINE COLOR 4
PLOT LINES:XS,510;XS+100,510
PLOT TEXT,AT XS+110,520:"知性"
PLOT TEXT,AT 320,460:"誕生日 "&STR$(BIRTHYEAR)&"年"&STR$(BIRTHMONTH)&"月"&STR$(BIRTHDAY)&"日"
PLOT TEXT,AT 320,490:"  今日 "&STR$(YEAR)&"年"&STR$(MONTH)&"月"&STR$(DAY)&"日"
PLOT TEXT,AT 320,520:"経過日数 "&STR$(LENGTH)&"日"
PLOT TEXT,AT XS,550:"曲線と軸が交わる日が要注意日です"
END

EXTERNAL  FUNCTION YMDT2JD(GYEAR, GMONTH, GDAY)
IF GMONTH < 3 THEN
   LET CALC_GYEAR = GYEAR - 1
   LET CALC_GMONTH = GMONTH + 12
ELSE
   LET CALC_GYEAR = GYEAR
   LET CALC_GMONTH = GMONTH
END IF
LET Y = INT(365.25 * CALC_GYEAR) + INT(CALC_GYEAR / 400) - INT(CALC_GYEAR / 100)
LET YMDT2JD = Y + INT(30.59 * (CALC_GMONTH - 2)) + 1721088 + GDAY
END FUNCTION

EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,YSIZE-1,0
SET POINT STYLE 1
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
CLEAR
END SUB
 

数独レゾルバ試作

 投稿者:lark12_long  投稿日:2014年 9月29日(月)02時52分52秒
  数独の解を求めるプログラム試作しました

空白枡における置数可能数字を、
順次仮置し再帰的に総当り探索して、
解を求めるものです

初期盤面データは、data文で与えます

通常の数独問題の解の個数は1個ですが、
複数解がある場合も、全ての解を求めます

lark12_long


'  数独求解ax.bas
'  9×9数独をプログラムで解く
'  再帰的総当り法
'
'  複数個の解が有る場合は、全てを解く
'
'  マウス左クリックで1時停止、右クリックで終了
'
gx=1000
gy=1000

'描画エリアの背景色着色範囲設定
set area color 1  '黒
plot area : -gx,-gy;-gx,gy;gx,gy;gx,-gy

set window 0,900,0,900
'----------------------------------------------------------------
'初期データ
'DATA 0,0,4, 0,0,0, 0,5,0
'DATA 0,0,8, 0,0,0, 2,0,9
'DATA 0,0,3, 0,0,4, 0,0,0
'DATA 0,0,0, 0,2,0, 3,8,0
'DATA 0,0,0, 5,0,7, 0,0,0
'DATA 0,4,6, 0,3,0, 0,0,0
'DATA 0,0,0, 2,0,0, 4,0,0
'DATA 3,0,7, 0,0,0, 9,0,0
'DATA 0,9,0, 0,0,0, 5,0,0

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

'data 0,0,0,0,0,0,0,0,0
'data 0,0,0,0,0,0,0,0,0
'data 0,0,0,0,0,0,0,0,0
'data 0,0,0,0,0,0,0,0,0
'data 0,0,0,0,0,0,0,0,0
'data 0,0,0,0,0,0,0,0,0
'data 0,0,0,0,0,0,0,0,0
'data 0,0,0,0,0,0,0,0,0
'data 0,0,0,0,0,0,0,0,0

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

'H20-06-28(土)、朝日新聞
'data 1,0,0,0,0,0,0,6,0
'data 0,9,0,0,6,7,0,0,3
'data 0,0,8,0,9,0,0,0,0
'data 0,0,0,1,0,0,0,9,0
'data 0,6,3,0,0,0,5,2,0
'data 0,4,0,0,0,5,0,0,0
'data 0,0,0,0,3,0,7,0,0
'data 2,0,0,7,8,0,0,1,0
'data 0,8,0,0,0,0,0,0,4

'H20-07-05(土)、朝日新聞 47秒
'data 0,2,7,0,0,0,0,0,0
'data 5,0,0,7,0,0,4,0,0
'data 9,0,0,0,0,3,2,8,0
'data 0,4,0,0,0,0,9,0,0
'data 0,0,0,0,2,0,0,0,0
'data 0,0,6,0,0,0,0,1,0
'data 0,6,1,3,0,0,0,0,8
'data 0,0,9,0,0,4,0,0,6
'data 0,0,0,0,0,0,5,2,0

'H20-07-12、朝日新聞
'data 3,5,6,0,0,2,0,1,0
'data 8,0,0,0,6,3,0,0,9
'data 1,0,0,5,7,0,0,0,0
'data 0,0,9,8,0,0,0,3,5
'data 0,3,8,0,0,0,6,7,0
'data 6,4,0,0,0,7,9,0,0
'data 0,0,0,0,8,5,0,0,1
'data 4,0,0,9,3,0,0,0,6
'data 0,1,0,6,0,0,5,9,8

'H20-07-19,朝日新聞
'data 8,0,0,0,0,0,0,3,0
'data 0,7,0,0,9,0,0,2,1
'data 0,0,4,6,0,0,0,0,0
'data 0,0,5,0,4,0,0,0,0
'data 0,8,0,3,0,2,0,5,0
'data 0,0,0,0,7,0,8,0,0
'data 0,0,0,0,0,6,5,0,0
'data 5,3,0,0,2,0,0,1,0
'data 0,1,0,0,0,0,0,0,6

'H20-07-26,朝日新聞
'data 0,0,0,2,0,0,0,0,1
'data 5,0,0,3,0,8,2,0,6
'data 0,1,0,0,0,7,4,0,0
'data 0,3,0,0,6,0,0,0,0
'data 4,0,5,0,0,0,8,0,2
'data 0,0,0,0,5,0,0,1,0
'data 0,0,1,6,0,0,0,7,0
'data 2,0,7,4,0,9,0,0,5
'data 3,0,0,0,0,5,0,0,0

'H20-08-02,朝日新聞
'data 0,6,0,0,0,1,0,0,0
'data 4,0,1,0,3,0,0,9,0
'data 0,3,0,5,0,0,8,0,0
'data 0,0,9,0,0,0,0,4,0
'data 1,0,0,0,6,0,0,0,2
'data 0,8,0,0,0,0,9,0,0
'data 0,0,8,0,0,4,0,1,0
'data 0,7,0,0,9,0,2,0,6
'data 0,0,0,7,0,0,0,3,0

'2008-8-23難易度5
'data 0,0,0,5,0,0,2,3,0
'data 9,0,0,0,8,0,0,0,0
'data 0,0,6,0,0,0,0,0,7
'data 0,4,0,7,0,0,0,0,0
'data 0,0,3,0,0,0,0,0,0
'data 2,7,0,0,0,9,0,1,0
'data 1,0,0,0,0,0,8,0,0
'data 3,0,0,0,5,0,0,0,0
'data 0,9,7,0,0,6,0,0,0

'2010-9-18朝日新聞
'data 0,0,0,4,0,1,0,2,0
'data 0,1,0,0,7,0,0,0,6
'data 0,0,5,0,0,0,8,0,0
'data 6,0,0,1,0,0,0,9,0
'data 0,0,9,0,2,0,6,0,0
'data 0,2,0,0,0,8,0,0,3
'data 0,0,7,0,0,0,3,0,0
'data 8,0,0,0,5,0,0,0,0
'data 0,0,0,0,0,0,0,0,0

'世界一難しいナンクロ(1)
'data 0,0,5,3,0,0,0,0,0
'data 8,0,0,0,0,0,0,2,0
'data 0,7,0,0,1,0,5,0,0
'data 4,0,0,0,0,5,3,0,0
'data 0,1,0,0,7,0,0,0,6
'data 0,0,3,2,0,0,0,8,0
'data 0,6,0,5,0,0,0,0,9
'data 0,0,4,0,0,0,0,3,0
'data 0,0,0,0,0,9,7,0,0

'世界一難しいナンクロ(2)
'data 0,2,6,0,0,1,0,0,0
'data 0,0,0,0,0,0,0,0,3
'data 0,0,0,0,4,3,0,0,5
'data 9,0,1,0,0,0,0,0,0
'data 0,0,7,0,0,0,6,0,0
'data 0,0,0,0,0,0,8,0,4
'data 4,0,0,9,2,0,0,0,0
'data 5,0,0,0,0,0,0,0,0
'data 0,0,0,8,0,0,7,1,0


'朝日H22-10-23
'data 0,9,0,0,1,0,0,6,0
'data 4,0,1,0,0,9,3,0,0
'data 0,0,0,0,6,0,0,5,0
'data 0,0,6,0,4,0,1,0,0
'data 3,0,0,8,0,5,0,0,9
'data 0,0,5,0,2,0,7,0,0
'data 0,3,0,0,9,0,0,0,0
'data 0,0,4,1,0,0,8,0,6
'data 0,8,0,0,5,0,0,3,0


'例題2 複数解あり
'data 2,8,4,0,0,0,0,7,9
'data 1,0,0,0,4,8,5,0,6
'data 0,9,0,0,0,2,0,0,1
'data 0,4,8,0,0,0,0,0,0
'data 0,2,0,0,0,0,0,3,0
'data 0,0,0,0,0,0,1,0,0
'data 0,0,0,3,0,0,0,9,0
'data 0,0,7,6,8,0,0,0,4
'data 0,5,0,0,0,0,6,1,3

'H26-09-18 複数解あり
data 1,0,0,0,0,0,0,0,0
data 0,6,0,2,0,0,0,0,0
data 0,0,0,0,0,0,3,0,0
data 0,4,0,0,0,0,0,0,0
data 0,0,0,0,5,0,0,0,0
data 0,0,0,0,0,0,0,6,0
data 0,0,7,0,0,0,0,0,0
data 0,0,0,0,0,8,0,0,0
data 0,0,0,0,0,0,0,0,9

'---------------------------------------------------------------------

dim m(0 to 8,0 to 8)           'ボード領域
dim q(0 to 8,0 to 8,0 to 8)    '置数可能数字エリヤ
mat read m                     '問題を読み込む
dim flag(0 to 8,0 to 8)        '既置数済みサイン

'初期設定済升目サインセット
for p=0 to 80
   row=int(p/9)                '行と列に換算する
   col=mod(p,9)
   if m(row,col)<>0 then
      flag(row,col)=1
   end if
next p

'置数可能な数字の設定
'初期空白マスに、置数可能数1~9を仮設定
for i=0 to 8
  for j=0 to 8
    for k=0 to 8
      if flag(i,j)=0 then
        q(i,j,k)=k+1
      end if
    next k
  next j
next i

'置数可能数字絞り込み
'既置数済み数字を、置数可能数エリアより削除
for p=0 to 80
  i=int(p/9)
  j=mod(p,9)
  bi=int(i/3)*3
  bj=int(j/3)*3
  if flag(i,j)=1 then
     wk=m(i,j)                'wk=初期設定済み升目(i,j)の数字
     for iw=0 to 8            '縦行サーチ
       if flag(iw,j)=0 then   'wkと同じ数字は、置数不可なので
          q(iw,j,wk-1)=0      '置数可能数字候補を削除
       end if
     next iw
     for jw=0 to 8             '横行サーチ
       if flag(i,jw)=0 then    'wkと同じ数字は、置数不可なので
          q(i,jw,wk-1)=0       '置数可能数字候補を削除
       end if
     next jw
     'ブロック
     for x=0 to 2
       for y=0 to 2
        if flag(bi+x,bj+y)=0 then
          q(bi+x,bj+y,wk-1)=0
        end if
       next y
     next x
  end if
next p

'置数可能数左寄せ
'q(i,j,0)=1,q(i,j,3)=3,q(i,j,8)=9 となっていたら
'q(i,j,0)=1,q(i,j,1)=3,q(i,j,2)=9 の様に左詰めにする
for i=0 to 8
  for j=0 to 8
    if flag(i,j)=0 then
      cn2=0
      do while cn2<9
        cn1=0
        do while q(i,j,cn1)<>0
          cn1=cn1+1
          if cn1=9 then exit do
        loop
        for k=cn1+1 to 8
          q(i,j,k-1)=q(i,j,k)
          q(i,j,k)=0
        next k
        cn2=cn2+1
      loop
    end if
  next j
next i

call draw

call backtrack(0)   '解探索、左上からの連番
'----------------------------------------------------------------

function checkrule(row,col,k)   '既に同じ数があるかどうか確認する
   checkrule=0
   for y=0 to 8  '列
      if m(y,col)=k then exit function  '同じ数が見つかったので、NG
   next y

   for x=0 to 8  '行
      if m(row,x)=k then exit function  '同じ数が見つかったので、NG
   next x

    'ブロック
    bx=int(col/3)*3
    by=int(row/3)*3
    for x=0 to 2
      for y=0 to 2
         if m(by+y,bx+x)=k then exit function  '同じ数が見つかったので、NG
      next y
    next x

    checkrule=1   '同じ数値は見つからないので、OK
end function
'----------------------------------------------------------------
sub draw
   set line width 2
   set draw mode hidden

   '画面クリヤ
   line(10,10)-(700,700),1,bf

   set text color 5
   set text font "MS 明朝",20

   '解カウンタ表示
   plot text, at 150,650:"解個数="
   plot text, at 400,650,using "######":cnt

   'マス目インデクス描画
   for i=0 to 8
      plot text, at 120+i*50,550,using "###":i
   next i
   for j=0 to 8
      plot text, at  50,500-j*50,using "###":j
   next j

   '再描画
   set text color 5

   for p=0 to 80

       row=int(p/9) '行と列に換算する
       col=mod(p,9)

      set text color 5-flag(col,row)*1
      plot text, at 120+row*50,500-col*50,using "###":m(col,row)

   next p

   '升目罫線描画
   for i=0 to 8
      for j=0 to 8
         line(100+(i+1)*50,500-j*50)-(100+(i+1)*50+50,500-(j-1)*50),5,b
      next j
   next i

   '升目ブロック境界線描画
   for i=0 to 8 step 3
      for j=0 to 8 step 3
        line(100+(i+1)*50,500-j*50-100)-(100+(i+3)*50+50,500-(j-3)*50-100),4,b
      next j
   next i
   set draw mode explicit
   mouse poll xm,ym,left,right
   if right=1 then stop
   do while left=1
     mouse poll xm,ym,left,right
   loop

end sub


'----------------------------------------------------------------
sub backtrack(p) '位置pを調査する
   local row,col,i
   if p<9*9 then             'すべてが埋まるまで継続
       row=int(p/9)          '行と列に換算する
       col=mod(p,9)
      if m(row,col)<>0 then  '既に数字があれば
         call backtrack(p+1) '次の枡へ
      else                   'なけらば
         for i=0 to 8                      '
            k=q(row,col,i)                 '置数可能数をセット
            if k=0 then i=8                '0は不可なのでパス
            if checkrule(row,col,k)=1 then '矛盾なく置ければ
                m(row,col)=k               'ここに置いてみる
                call backtrack(p+1)        '次の枡へ
                                           'ここへ戻ったら置数不可なので
                m(row,col)=0               '取り消す
            end if
         next i
        'call draw                         '途中経過表示
      end if
   else                'すべて埋まったら
     'mat print using "# # # # # # # # #": m     '解をテキスト画面表示する
     'print
      cnt=cnt+1        '解カウンタ+1
      call draw
     'input aa$
   end if
end sub

 

数独の複数解

 投稿者:lark12_long  投稿日:2014年10月 1日(水)17時28分54秒
  数独の複数解

123 000 000
456 000 000
789 000 000
000 123 000
000 456 000
000 789 000
000 000 123
000 000 456
000 000 789

上記の初期置数状態の時の解の数は、
いくつ有るんでしょうか

先般投稿した数独レゾルバで解かしたら、
283,576通りの解を得ました
 

Re: 数独

 投稿者:SECOND  投稿日:2014年10月 2日(木)16時43分55秒
  > No.3508[元記事へ]

エピソード
先の投稿「山中 氏 投稿から引用」文でも、以下の様に、完成結果を、
false で帰してやると、 複数個の解を全て表示できます。

1個の解の表示しか出来ないプログラムでも「最後の枡を埋める」局面をみると、
1つ手前までの全ての解を展開して、再試行しており、それを1段延長させる。
「最後の枡で完成」していても、表示だけに留め、常に失敗したように帰す。と、
取り得る完成 全てを果す、ついには、枡(0,0) より食み出て 探索しようとするが、
再帰の場合、リターンスタックは、メインだけになり、false で、正常終了する。

(
  )
EXTERNAL FUNCTION numpre(dummy)
(
  )
!1個の解の表示で終らせる
!------------------------------
MAT PRINT tb; !結果を表示する
LET numpre=TRUE      !←構造的には、これを、false にするのみ
END FUNCTION         !↓見やすくするだけの意味。
!------------------------------

! 複数個の解を全て表示
!------------------------------
LET cnt=cnt+1        !メイン側に、PUBLIC NUMERIC cnt を追加しないと、
PRINT cnt            !外部関数内の変数は、原則 localで、cnt 累計不能
MAT PRINT tb;        !結果を表示する
PRINT "次の探索中";
!
LET numpre=FALSE     !完成しなかった事にして、再サーチさせる
END FUNCTION
!------------------------------

!------------------------------
「lark12_long 氏 投稿から引用」このサンプルは、短時間で70個、テストに好適
!例題2 複数解あり
DATA 2,8,4,0,0,0,0,7,9
DATA 1,0,0,0,4,8,5,0,6
DATA 0,9,0,0,0,2,0,0,1
DATA 0,4,8,0,0,0,0,0,0
DATA 0,2,0,0,0,0,0,3,0
DATA 0,0,0,0,0,0,1,0,0
DATA 0,0,0,3,0,0,0,9,0
DATA 0,0,7,6,8,0,0,0,4
DATA 0,5,0,0,0,0,6,1,3
 

S=±1^4±2^4±3^4 … ±2014^4 の値

 投稿者:山中和義  投稿日:2014年10月 7日(火)22時39分33秒
  問題
式 S=±1±2±3 … ±n を考えます。
上記の式の右辺で±の演算子を自由にかえて計算します。
このとき、Sが非負整数となるとき、その最小値はいくつでしょうか。

また、
 S=±1^2±2^2±3^2 … ±n^2
 S=±1^3±2^3±3^3 … ±n^3
 S=±1^4±2^4±3^4 … ±n^4
   :
   :
では、どうでしょうか。

考察
2^n通りを実際に計算してみる。

1乗の場合
 S: n
 0:   3 4 7 8 11 12 ┌┐ ┌┐
 1: 1 2 5 6 9 10 13 │↓ │↓ …

2乗の場合
 S: n
 0:     7 8 11 12 15 16 ┌┐ ┌┐
 1: 1   6 9 10 13 14 17 │↓ │↓ …
 2: 4
 3: 2 5
 4: 3


大きなnに対して、0と1の振動に入るようだ。


OPTION ARITHMETIC RATIONAL !多桁の整数
PUBLIC NUMERIC C !最大値
DIM A(50) !並び
FOR N=1 TO 50 !第n項まで ※25以上は困難
   LET C=9999999999999999
   CALL try(1,0,N,A)
   PRINT N; C
NEXT N
END
EXTERNAL SUB try(K,S,N,A()) !バックトラック法で検証する
OPTION ARITHMETIC RATIONAL !多桁の整数
FOR B=-1 TO 1 STEP 2 !Σ±k^m
   LET SS=S+B*K^2 !※2乗
   LET A(K)=B
   IF K=N THEN !第n項なら
   !!!MAT PRINT A;
      IF SS>=0 AND SS<C THEN LET C=SS !最大値を記録する
   ELSE
      CALL try(K+1,SS,N,A) !次へ
   END IF
NEXT B
END SUB



S=±0^m±1^m±2^m±3^m±4^m … =±偶数±奇数±偶数±奇数±偶数 … である。
これより、Sの偶奇の振動は、
   S: n
 偶数: 0 3 4 7 8 11 12 │↑ │↑ …
 奇数: 1 2 5 6 9 10 13 └┘ └┘

 例 2乗の場合(Sの値)
 偶数: 0 4 4 0 0 0 0 0 │↑ │↑ …
 奇数: 1 3 3 1 1 1 1 1 └┘ └┘
(終わり)


式をつくる方法
●1乗
まず、
 +0=0
 +0+1=1
 +0-1+2=1
 +0+1+2-3=+0-1-2+3=0
となる。
ここで、±0±1±2 … ±x=Aのとき、
      (x+1)
     -(x+2)
     -(x+3)
 +)   (x+4)
 -----------  ※符号の並びは、Thue-Morse sequenceである。
         0
なので、±0±1±2 … ±(x+4)は、Aとできる。

n=5の場合、[5/4]=1、5≡1(mod 4)より、1を基準にして、+1 +(+2-3-4+5)=1
n=14の場合、
 [14/4]=3、14≡2(mod 4)より、2を基準にして、
 -1+2 +(+3-4-5+6) +(+7-8-9+10) +(+11-12-13+14)=1

●2乗
±1^2±2^2 … ±x^2=Aのとき、
      (x+1)^2=x^2+2x+1
     -(x+2)^2=x^2+4x+4
     -(x+3)^2=x^2+6x+9
      (x+4)^2=x^2+8x+16
     -(x+5)^2=x^2+10x+25
      (x+6)^2=x^2+12x+36
      (x+7)^2=x^2+14x+49
 +)  -(x+8)^2=x^2+16x+64
 ------------------------
             =0
なので、±0^2±1^2±2^2 … ±(x+8)^2は、Aとできる。

●3乗
±1^3±2^3 … ±x^3=Aのとき、
  (x+1)^3-(x+2)^3-(x+3)^3+(x+4)^3  -(x+5)^3+(x+6)^3+(x+7)^3-(x+8)^3
 -(x+9)^3+(x+10)^3+(x+11)^3-(x+12)^3  +(x+13)^3-(x+14)^3-(x+15)^3+(x+16)^3
 =0
なので、±0^3±1^3±2^3 … ±(x+16)^3は、Aとできる。

●4乗
±1^4±2^4 … ±x^4=Aのとき、
  (x+1)^4-(x+2)^4-(x+3)^4+(x+4)^4  -(x+5)^4+(x+6)^4+(x+7)^4-(x+8)^4           ┐1536
 -(x+9)^4+(x+10)^4+(x+11)^4-(x+12)^4  +(x+13)^4-(x+14)^4-(x+15)^4+(x+16)^4    ┘
 -(x+17)^4+(x+18)^4+(x+19)^4-(x+20)^4  +(x+21)^4-(x+22)^4-(x+23)^4+(x+24)^4   ┐-1536
  (x+25)^4-(x+26)^4-(x+27)^4+(x+28)^4  -(x+29)^4+(x+30)^4+(x+31)^4-(x+32)^4   ┘
 =0
なので、±0^4±1^4±2^4 … ±(x+32)^4は、Aとできる。


これを適用すれば、

S=±1^4±2^4±3^4 … ±2014^4 のとき、
Σk^4=6635387114994287より、奇数である。
nを32で割ったときの剰余を考えれば、2014÷32=62あまり30 なので、
 x=30として、1つの例
 +0^4+1^4-2^4-3^4-4^4-5^4-6^4-7^4-8^4-9^4-10^4
 +11^4-12^4+13^4-14^4-15^4-16^4+17^4+18^4-19^4+20^4
 +21^4+22^4+23^4-24^4+25^4-26^4+27^4+28^4-29^4-30^4
 =1
から、1となる。


式を構成するには、和が [(Σk^m)/2] になるk^mの組を探せばよい。樹形図を描いて確認する。


OPTION ARITHMETIC RATIONAL !多桁の整数
LET N=30 !=2014 mod 32
LET M=4 !4 !※4乗

PUBLIC NUMERIC F(3000) !f(x)=x^m
LET S=0 !Σk^m
FOR K=1 TO N
   LET T=K^M
   LET F(K)=T
   LET S=S+T
NEXT K
LET S2=INT(S/2)
PRINT S; S2

PUBLIC NUMERIC C !場合の数
LET C=0
DIM A(N) !演算子の並び
MAT A=ZER
CALL try(2,S2,N,M,A) !※対称性 +1^m±2^m±3^m …
PRINT C; "通り"
END

EXTERNAL SUB try(P,S,N,M,A()) !バックトラック法で検証する
OPTION ARITHMETIC RATIONAL !多桁の整数
FOR K=P TO N !k^m の組み合わせ
   LET SS=S-F(K) !f(k)=k^m
   IF SS<0 THEN EXIT FOR !これ以降は可能性なし

   LET A(K)=1
   IF SS=0 THEN !結果を表示する
      LET C=C+1
      !!MAT PRINT A;

      PRINT "PRINT "; !BASIC言語の式を表示する
      FOR i=1 TO N
         IF A(i)=0 THEN PRINT "+"; ELSE PRINT "-"; !演算子
         PRINT STR$(i);"^";STR$(M); !項
         IF i<N AND MOD(i,20)=0 THEN !行を分割する
            PRINT "  &" !行末
            PRINT "&    "; !継続行
         END IF
      NEXT i
      PRINT

      PRINT
   ELSE
      CALL try(K+1,SS,N,M,A) !次へ
   END IF
   LET A(K)=0
NEXT K
END SUB

 

Re: S=±1^4±2^4±3^4 … ±2014^4 の値

 投稿者:山中和義  投稿日:2014年10月 8日(水)10時00分2秒
  > No.3518[元記事へ]

実際に式を作成して確認してみました。


式をつくるプログラム

DATA 0,1,1,1,1,1,1,1,1,1 !30=2014 mod 32
DATA 0,1,0,1,1,1,0,0,1,0
DATA 0,0,0,1,0,1,0,0,1,1

10 DATA 0,1,1,0, 1,0,0,1, 1,0,0,1, 0,1,1,0 !+32 thue-morse sequence
   DATA 1,0,0,1, 0,1,1,0, 0,1,1,0, 1,0,0,1

   PRINT "PRINT "; !BASIC言語の式(PRINT文)を表示する
   FOR K=1 TO 30
      READ A

      IF A=0 THEN PRINT "+"; ELSE PRINT "-";
      PRINT USING "####": K;
      PRINT "^4";
      IF K<30 AND MOD(K,10)=0 THEN
         PRINT "  &"
         PRINT "&     ";
      END IF
   NEXT K
   PRINT "  &"
   PRINT "&       &"
   PRINT "&     ";

   FOR J=0 TO 62-1 !=[2014/32]
      RESTORE 10
      FOR i=1 TO 32
         READ A

         LET K=J*32+i+30
         IF A=0 THEN PRINT "+"; ELSE PRINT "-";
         PRINT USING "####": K;
         PRINT "^4";
         IF K<2014 AND MOD(i,16)=0 THEN
            PRINT "  &"
            PRINT "&     ";
         END IF
      NEXT i
      PRINT "  &"
      PRINT "&     ";
   NEXT J
   PRINT
   PRINT "END"

END


実行結果

PRINT +   1^4-   2^4-   3^4-   4^4-   5^4-   6^4-   7^4-   8^4-   9^4-  10^4  &
&     +  11^4-  12^4+  13^4-  14^4-  15^4-  16^4+  17^4+  18^4-  19^4+  20^4  &
&     +  21^4+  22^4+  23^4-  24^4+  25^4-  26^4+  27^4+  28^4-  29^4-  30^4  &
&       &
&     +  31^4-  32^4-  33^4+  34^4-  35^4+  36^4+  37^4-  38^4-  39^4+  40^4+  41^4-  42^4+  43^4-  44^4-  45^4+  46^4  &
&     -  47^4+  48^4+  49^4-  50^4+  51^4-  52^4-  53^4+  54^4+  55^4-  56^4-  57^4+  58^4-  59^4+  60^4+  61^4-  62^4  &
&       &
&     +  63^4-  64^4-  65^4+  66^4-  67^4+  68^4+  69^4-  70^4-  71^4+  72^4+  73^4-  74^4+  75^4-  76^4-  77^4+  78^4  &
&     -  79^4+  80^4+  81^4-  82^4+  83^4-  84^4-  85^4+  86^4+  87^4-  88^4-  89^4+  90^4-  91^4+  92^4+  93^4-  94^4  &
&       &
&     +  95^4-  96^4-  97^4+  98^4-  99^4+ 100^4+ 101^4- 102^4- 103^4+ 104^4+ 105^4- 106^4+ 107^4- 108^4- 109^4+ 110^4  &
&     - 111^4+ 112^4+ 113^4- 114^4+ 115^4- 116^4- 117^4+ 118^4+ 119^4- 120^4- 121^4+ 122^4- 123^4+ 124^4+ 125^4- 126^4  &
&       &
&     + 127^4- 128^4- 129^4+ 130^4- 131^4+ 132^4+ 133^4- 134^4- 135^4+ 136^4+ 137^4- 138^4+ 139^4- 140^4- 141^4+ 142^4  &
&     - 143^4+ 144^4+ 145^4- 146^4+ 147^4- 148^4- 149^4+ 150^4+ 151^4- 152^4- 153^4+ 154^4- 155^4+ 156^4+ 157^4- 158^4  &
&       &
&     + 159^4- 160^4- 161^4+ 162^4- 163^4+ 164^4+ 165^4- 166^4- 167^4+ 168^4+ 169^4- 170^4+ 171^4- 172^4- 173^4+ 174^4  &
&     - 175^4+ 176^4+ 177^4- 178^4+ 179^4- 180^4- 181^4+ 182^4+ 183^4- 184^4- 185^4+ 186^4- 187^4+ 188^4+ 189^4- 190^4  &
&       &
&     + 191^4- 192^4- 193^4+ 194^4- 195^4+ 196^4+ 197^4- 198^4- 199^4+ 200^4+ 201^4- 202^4+ 203^4- 204^4- 205^4+ 206^4  &
&     - 207^4+ 208^4+ 209^4- 210^4+ 211^4- 212^4- 213^4+ 214^4+ 215^4- 216^4- 217^4+ 218^4- 219^4+ 220^4+ 221^4- 222^4  &
&       &
&     + 223^4- 224^4- 225^4+ 226^4- 227^4+ 228^4+ 229^4- 230^4- 231^4+ 232^4+ 233^4- 234^4+ 235^4- 236^4- 237^4+ 238^4  &
&     - 239^4+ 240^4+ 241^4- 242^4+ 243^4- 244^4- 245^4+ 246^4+ 247^4- 248^4- 249^4+ 250^4- 251^4+ 252^4+ 253^4- 254^4  &
&       &
&     + 255^4- 256^4- 257^4+ 258^4- 259^4+ 260^4+ 261^4- 262^4- 263^4+ 264^4+ 265^4- 266^4+ 267^4- 268^4- 269^4+ 270^4  &
&     - 271^4+ 272^4+ 273^4- 274^4+ 275^4- 276^4- 277^4+ 278^4+ 279^4- 280^4- 281^4+ 282^4- 283^4+ 284^4+ 285^4- 286^4  &
&       &
&     + 287^4- 288^4- 289^4+ 290^4- 291^4+ 292^4+ 293^4- 294^4- 295^4+ 296^4+ 297^4- 298^4+ 299^4- 300^4- 301^4+ 302^4  &
&     - 303^4+ 304^4+ 305^4- 306^4+ 307^4- 308^4- 309^4+ 310^4+ 311^4- 312^4- 313^4+ 314^4- 315^4+ 316^4+ 317^4- 318^4  &
&       &
&     + 319^4- 320^4- 321^4+ 322^4- 323^4+ 324^4+ 325^4- 326^4- 327^4+ 328^4+ 329^4- 330^4+ 331^4- 332^4- 333^4+ 334^4  &
&     - 335^4+ 336^4+ 337^4- 338^4+ 339^4- 340^4- 341^4+ 342^4+ 343^4- 344^4- 345^4+ 346^4- 347^4+ 348^4+ 349^4- 350^4  &
&       &
&     + 351^4- 352^4- 353^4+ 354^4- 355^4+ 356^4+ 357^4- 358^4- 359^4+ 360^4+ 361^4- 362^4+ 363^4- 364^4- 365^4+ 366^4  &
&     - 367^4+ 368^4+ 369^4- 370^4+ 371^4- 372^4- 373^4+ 374^4+ 375^4- 376^4- 377^4+ 378^4- 379^4+ 380^4+ 381^4- 382^4  &
&       &
&     + 383^4- 384^4- 385^4+ 386^4- 387^4+ 388^4+ 389^4- 390^4- 391^4+ 392^4+ 393^4- 394^4+ 395^4- 396^4- 397^4+ 398^4  &
&     - 399^4+ 400^4+ 401^4- 402^4+ 403^4- 404^4- 405^4+ 406^4+ 407^4- 408^4- 409^4+ 410^4- 411^4+ 412^4+ 413^4- 414^4  &
&       &
&     + 415^4- 416^4- 417^4+ 418^4- 419^4+ 420^4+ 421^4- 422^4- 423^4+ 424^4+ 425^4- 426^4+ 427^4- 428^4- 429^4+ 430^4  &
&     - 431^4+ 432^4+ 433^4- 434^4+ 435^4- 436^4- 437^4+ 438^4+ 439^4- 440^4- 441^4+ 442^4- 443^4+ 444^4+ 445^4- 446^4  &
&       &
&     + 447^4- 448^4- 449^4+ 450^4- 451^4+ 452^4+ 453^4- 454^4- 455^4+ 456^4+ 457^4- 458^4+ 459^4- 460^4- 461^4+ 462^4  &
&     - 463^4+ 464^4+ 465^4- 466^4+ 467^4- 468^4- 469^4+ 470^4+ 471^4- 472^4- 473^4+ 474^4- 475^4+ 476^4+ 477^4- 478^4  &
&       &
&     + 479^4- 480^4- 481^4+ 482^4- 483^4+ 484^4+ 485^4- 486^4- 487^4+ 488^4+ 489^4- 490^4+ 491^4- 492^4- 493^4+ 494^4  &
&     - 495^4+ 496^4+ 497^4- 498^4+ 499^4- 500^4- 501^4+ 502^4+ 503^4- 504^4- 505^4+ 506^4- 507^4+ 508^4+ 509^4- 510^4  &
&       &
&     + 511^4- 512^4- 513^4+ 514^4- 515^4+ 516^4+ 517^4- 518^4- 519^4+ 520^4+ 521^4- 522^4+ 523^4- 524^4- 525^4+ 526^4  &
&     - 527^4+ 528^4+ 529^4- 530^4+ 531^4- 532^4- 533^4+ 534^4+ 535^4- 536^4- 537^4+ 538^4- 539^4+ 540^4+ 541^4- 542^4  &
&       &
&     + 543^4- 544^4- 545^4+ 546^4- 547^4+ 548^4+ 549^4- 550^4- 551^4+ 552^4+ 553^4- 554^4+ 555^4- 556^4- 557^4+ 558^4  &
&     - 559^4+ 560^4+ 561^4- 562^4+ 563^4- 564^4- 565^4+ 566^4+ 567^4- 568^4- 569^4+ 570^4- 571^4+ 572^4+ 573^4- 574^4  &
&       &
&     + 575^4- 576^4- 577^4+ 578^4- 579^4+ 580^4+ 581^4- 582^4- 583^4+ 584^4+ 585^4- 586^4+ 587^4- 588^4- 589^4+ 590^4  &
&     - 591^4+ 592^4+ 593^4- 594^4+ 595^4- 596^4- 597^4+ 598^4+ 599^4- 600^4- 601^4+ 602^4- 603^4+ 604^4+ 605^4- 606^4  &
&       &
&     + 607^4- 608^4- 609^4+ 610^4- 611^4+ 612^4+ 613^4- 614^4- 615^4+ 616^4+ 617^4- 618^4+ 619^4- 620^4- 621^4+ 622^4  &
&     - 623^4+ 624^4+ 625^4- 626^4+ 627^4- 628^4- 629^4+ 630^4+ 631^4- 632^4- 633^4+ 634^4- 635^4+ 636^4+ 637^4- 638^4  &
&       &
&     + 639^4- 640^4- 641^4+ 642^4- 643^4+ 644^4+ 645^4- 646^4- 647^4+ 648^4+ 649^4- 650^4+ 651^4- 652^4- 653^4+ 654^4  &
&     - 655^4+ 656^4+ 657^4- 658^4+ 659^4- 660^4- 661^4+ 662^4+ 663^4- 664^4- 665^4+ 666^4- 667^4+ 668^4+ 669^4- 670^4  &
&       &
&     + 671^4- 672^4- 673^4+ 674^4- 675^4+ 676^4+ 677^4- 678^4- 679^4+ 680^4+ 681^4- 682^4+ 683^4- 684^4- 685^4+ 686^4  &
&     - 687^4+ 688^4+ 689^4- 690^4+ 691^4- 692^4- 693^4+ 694^4+ 695^4- 696^4- 697^4+ 698^4- 699^4+ 700^4+ 701^4- 702^4  &
&       &
&     + 703^4- 704^4- 705^4+ 706^4- 707^4+ 708^4+ 709^4- 710^4- 711^4+ 712^4+ 713^4- 714^4+ 715^4- 716^4- 717^4+ 718^4  &
&     - 719^4+ 720^4+ 721^4- 722^4+ 723^4- 724^4- 725^4+ 726^4+ 727^4- 728^4- 729^4+ 730^4- 731^4+ 732^4+ 733^4- 734^4  &
&       &
&     + 735^4- 736^4- 737^4+ 738^4- 739^4+ 740^4+ 741^4- 742^4- 743^4+ 744^4+ 745^4- 746^4+ 747^4- 748^4- 749^4+ 750^4  &
&     - 751^4+ 752^4+ 753^4- 754^4+ 755^4- 756^4- 757^4+ 758^4+ 759^4- 760^4- 761^4+ 762^4- 763^4+ 764^4+ 765^4- 766^4  &
&       &
&     + 767^4- 768^4- 769^4+ 770^4- 771^4+ 772^4+ 773^4- 774^4- 775^4+ 776^4+ 777^4- 778^4+ 779^4- 780^4- 781^4+ 782^4  &
&     - 783^4+ 784^4+ 785^4- 786^4+ 787^4- 788^4- 789^4+ 790^4+ 791^4- 792^4- 793^4+ 794^4- 795^4+ 796^4+ 797^4- 798^4  &
&       &
&     + 799^4- 800^4- 801^4+ 802^4- 803^4+ 804^4+ 805^4- 806^4- 807^4+ 808^4+ 809^4- 810^4+ 811^4- 812^4- 813^4+ 814^4  &
&     - 815^4+ 816^4+ 817^4- 818^4+ 819^4- 820^4- 821^4+ 822^4+ 823^4- 824^4- 825^4+ 826^4- 827^4+ 828^4+ 829^4- 830^4  &
&       &
&     + 831^4- 832^4- 833^4+ 834^4- 835^4+ 836^4+ 837^4- 838^4- 839^4+ 840^4+ 841^4- 842^4+ 843^4- 844^4- 845^4+ 846^4  &
&     - 847^4+ 848^4+ 849^4- 850^4+ 851^4- 852^4- 853^4+ 854^4+ 855^4- 856^4- 857^4+ 858^4- 859^4+ 860^4+ 861^4- 862^4  &
&       &
&     + 863^4- 864^4- 865^4+ 866^4- 867^4+ 868^4+ 869^4- 870^4- 871^4+ 872^4+ 873^4- 874^4+ 875^4- 876^4- 877^4+ 878^4  &
&     - 879^4+ 880^4+ 881^4- 882^4+ 883^4- 884^4- 885^4+ 886^4+ 887^4- 888^4- 889^4+ 890^4- 891^4+ 892^4+ 893^4- 894^4  &
&       &
&     + 895^4- 896^4- 897^4+ 898^4- 899^4+ 900^4+ 901^4- 902^4- 903^4+ 904^4+ 905^4- 906^4+ 907^4- 908^4- 909^4+ 910^4  &
&     - 911^4+ 912^4+ 913^4- 914^4+ 915^4- 916^4- 917^4+ 918^4+ 919^4- 920^4- 921^4+ 922^4- 923^4+ 924^4+ 925^4- 926^4  &
&       &
&     + 927^4- 928^4- 929^4+ 930^4- 931^4+ 932^4+ 933^4- 934^4- 935^4+ 936^4+ 937^4- 938^4+ 939^4- 940^4- 941^4+ 942^4  &
&     - 943^4+ 944^4+ 945^4- 946^4+ 947^4- 948^4- 949^4+ 950^4+ 951^4- 952^4- 953^4+ 954^4- 955^4+ 956^4+ 957^4- 958^4  &
&       &
&     + 959^4- 960^4- 961^4+ 962^4- 963^4+ 964^4+ 965^4- 966^4- 967^4+ 968^4+ 969^4- 970^4+ 971^4- 972^4- 973^4+ 974^4  &
&     - 975^4+ 976^4+ 977^4- 978^4+ 979^4- 980^4- 981^4+ 982^4+ 983^4- 984^4- 985^4+ 986^4- 987^4+ 988^4+ 989^4- 990^4  &
&       &
&     + 991^4- 992^4- 993^4+ 994^4- 995^4+ 996^4+ 997^4- 998^4- 999^4+1000^4+1001^4-1002^4+1003^4-1004^4-1005^4+1006^4  &
&     -1007^4+1008^4+1009^4-1010^4+1011^4-1012^4-1013^4+1014^4+1015^4-1016^4-1017^4+1018^4-1019^4+1020^4+1021^4-1022^4  &
&       &
&     +1023^4-1024^4-1025^4+1026^4-1027^4+1028^4+1029^4-1030^4-1031^4+1032^4+1033^4-1034^4+1035^4-1036^4-1037^4+1038^4  &
&     -1039^4+1040^4+1041^4-1042^4+1043^4-1044^4-1045^4+1046^4+1047^4-1048^4-1049^4+1050^4-1051^4+1052^4+1053^4-1054^4  &
&       &
&     +1055^4-1056^4-1057^4+1058^4-1059^4+1060^4+1061^4-1062^4-1063^4+1064^4+1065^4-1066^4+1067^4-1068^4-1069^4+1070^4  &
&     -1071^4+1072^4+1073^4-1074^4+1075^4-1076^4-1077^4+1078^4+1079^4-1080^4-1081^4+1082^4-1083^4+1084^4+1085^4-1086^4  &
&       &
&     +1087^4-1088^4-1089^4+1090^4-1091^4+1092^4+1093^4-1094^4-1095^4+1096^4+1097^4-1098^4+1099^4-1100^4-1101^4+1102^4  &
&     -1103^4+1104^4+1105^4-1106^4+1107^4-1108^4-1109^4+1110^4+1111^4-1112^4-1113^4+1114^4-1115^4+1116^4+1117^4-1118^4  &
&       &
&     +1119^4-1120^4-1121^4+1122^4-1123^4+1124^4+1125^4-1126^4-1127^4+1128^4+1129^4-1130^4+1131^4-1132^4-1133^4+1134^4  &
&     -1135^4+1136^4+1137^4-1138^4+1139^4-1140^4-1141^4+1142^4+1143^4-1144^4-1145^4+1146^4-1147^4+1148^4+1149^4-1150^4  &
&       &
&     +1151^4-1152^4-1153^4+1154^4-1155^4+1156^4+1157^4-1158^4-1159^4+1160^4+1161^4-1162^4+1163^4-1164^4-1165^4+1166^4  &
&     -1167^4+1168^4+1169^4-1170^4+1171^4-1172^4-1173^4+1174^4+1175^4-1176^4-1177^4+1178^4-1179^4+1180^4+1181^4-1182^4  &
&       &
&     +1183^4-1184^4-1185^4+1186^4-1187^4+1188^4+1189^4-1190^4-1191^4+1192^4+1193^4-1194^4+1195^4-1196^4-1197^4+1198^4  &
&     -1199^4+1200^4+1201^4-1202^4+1203^4-1204^4-1205^4+1206^4+1207^4-1208^4-1209^4+1210^4-1211^4+1212^4+1213^4-1214^4  &
&       &
&     +1215^4-1216^4-1217^4+1218^4-1219^4+1220^4+1221^4-1222^4-1223^4+1224^4+1225^4-1226^4+1227^4-1228^4-1229^4+1230^4  &
&     -1231^4+1232^4+1233^4-1234^4+1235^4-1236^4-1237^4+1238^4+1239^4-1240^4-1241^4+1242^4-1243^4+1244^4+1245^4-1246^4  &
&       &
&     +1247^4-1248^4-1249^4+1250^4-1251^4+1252^4+1253^4-1254^4-1255^4+1256^4+1257^4-1258^4+1259^4-1260^4-1261^4+1262^4  &
&     -1263^4+1264^4+1265^4-1266^4+1267^4-1268^4-1269^4+1270^4+1271^4-1272^4-1273^4+1274^4-1275^4+1276^4+1277^4-1278^4  &
&       &
&     +1279^4-1280^4-1281^4+1282^4-1283^4+1284^4+1285^4-1286^4-1287^4+1288^4+1289^4-1290^4+1291^4-1292^4-1293^4+1294^4  &
&     -1295^4+1296^4+1297^4-1298^4+1299^4-1300^4-1301^4+1302^4+1303^4-1304^4-1305^4+1306^4-1307^4+1308^4+1309^4-1310^4  &
&       &
&     +1311^4-1312^4-1313^4+1314^4-1315^4+1316^4+1317^4-1318^4-1319^4+1320^4+1321^4-1322^4+1323^4-1324^4-1325^4+1326^4  &
&     -1327^4+1328^4+1329^4-1330^4+1331^4-1332^4-1333^4+1334^4+1335^4-1336^4-1337^4+1338^4-1339^4+1340^4+1341^4-1342^4  &
&       &
&     +1343^4-1344^4-1345^4+1346^4-1347^4+1348^4+1349^4-1350^4-1351^4+1352^4+1353^4-1354^4+1355^4-1356^4-1357^4+1358^4  &
&     -1359^4+1360^4+1361^4-1362^4+1363^4-1364^4-1365^4+1366^4+1367^4-1368^4-1369^4+1370^4-1371^4+1372^4+1373^4-1374^4  &
&       &
&     +1375^4-1376^4-1377^4+1378^4-1379^4+1380^4+1381^4-1382^4-1383^4+1384^4+1385^4-1386^4+1387^4-1388^4-1389^4+1390^4  &
&     -1391^4+1392^4+1393^4-1394^4+1395^4-1396^4-1397^4+1398^4+1399^4-1400^4-1401^4+1402^4-1403^4+1404^4+1405^4-1406^4  &
&       &
&     +1407^4-1408^4-1409^4+1410^4-1411^4+1412^4+1413^4-1414^4-1415^4+1416^4+1417^4-1418^4+1419^4-1420^4-1421^4+1422^4  &
&     -1423^4+1424^4+1425^4-1426^4+1427^4-1428^4-1429^4+1430^4+1431^4-1432^4-1433^4+1434^4-1435^4+1436^4+1437^4-1438^4  &
&       &
&     +1439^4-1440^4-1441^4+1442^4-1443^4+1444^4+1445^4-1446^4-1447^4+1448^4+1449^4-1450^4+1451^4-1452^4-1453^4+1454^4  &
&     -1455^4+1456^4+1457^4-1458^4+1459^4-1460^4-1461^4+1462^4+1463^4-1464^4-1465^4+1466^4-1467^4+1468^4+1469^4-1470^4  &
&       &
&     +1471^4-1472^4-1473^4+1474^4-1475^4+1476^4+1477^4-1478^4-1479^4+1480^4+1481^4-1482^4+1483^4-1484^4-1485^4+1486^4  &
&     -1487^4+1488^4+1489^4-1490^4+1491^4-1492^4-1493^4+1494^4+1495^4-1496^4-1497^4+1498^4-1499^4+1500^4+1501^4-1502^4  &
&       &
&     +1503^4-1504^4-1505^4+1506^4-1507^4+1508^4+1509^4-1510^4-1511^4+1512^4+1513^4-1514^4+1515^4-1516^4-1517^4+1518^4  &
&     -1519^4+1520^4+1521^4-1522^4+1523^4-1524^4-1525^4+1526^4+1527^4-1528^4-1529^4+1530^4-1531^4+1532^4+1533^4-1534^4  &
&       &
&     +1535^4-1536^4-1537^4+1538^4-1539^4+1540^4+1541^4-1542^4-1543^4+1544^4+1545^4-1546^4+1547^4-1548^4-1549^4+1550^4  &
&     -1551^4+1552^4+1553^4-1554^4+1555^4-1556^4-1557^4+1558^4+1559^4-1560^4-1561^4+1562^4-1563^4+1564^4+1565^4-1566^4  &
&       &
&     +1567^4-1568^4-1569^4+1570^4-1571^4+1572^4+1573^4-1574^4-1575^4+1576^4+1577^4-1578^4+1579^4-1580^4-1581^4+1582^4  &
&     -1583^4+1584^4+1585^4-1586^4+1587^4-1588^4-1589^4+1590^4+1591^4-1592^4-1593^4+1594^4-1595^4+1596^4+1597^4-1598^4  &
&       &
&     +1599^4-1600^4-1601^4+1602^4-1603^4+1604^4+1605^4-1606^4-1607^4+1608^4+1609^4-1610^4+1611^4-1612^4-1613^4+1614^4  &
&     -1615^4+1616^4+1617^4-1618^4+1619^4-1620^4-1621^4+1622^4+1623^4-1624^4-1625^4+1626^4-1627^4+1628^4+1629^4-1630^4  &
&       &
&     +1631^4-1632^4-1633^4+1634^4-1635^4+1636^4+1637^4-1638^4-1639^4+1640^4+1641^4-1642^4+1643^4-1644^4-1645^4+1646^4  &
&     -1647^4+1648^4+1649^4-1650^4+1651^4-1652^4-1653^4+1654^4+1655^4-1656^4-1657^4+1658^4-1659^4+1660^4+1661^4-1662^4  &
&       &
&     +1663^4-1664^4-1665^4+1666^4-1667^4+1668^4+1669^4-1670^4-1671^4+1672^4+1673^4-1674^4+1675^4-1676^4-1677^4+1678^4  &
&     -1679^4+1680^4+1681^4-1682^4+1683^4-1684^4-1685^4+1686^4+1687^4-1688^4-1689^4+1690^4-1691^4+1692^4+1693^4-1694^4  &
&       &
&     +1695^4-1696^4-1697^4+1698^4-1699^4+1700^4+1701^4-1702^4-1703^4+1704^4+1705^4-1706^4+1707^4-1708^4-1709^4+1710^4  &
&     -1711^4+1712^4+1713^4-1714^4+1715^4-1716^4-1717^4+1718^4+1719^4-1720^4-1721^4+1722^4-1723^4+1724^4+1725^4-1726^4  &
&       &
&     +1727^4-1728^4-1729^4+1730^4-1731^4+1732^4+1733^4-1734^4-1735^4+1736^4+1737^4-1738^4+1739^4-1740^4-1741^4+1742^4  &
&     -1743^4+1744^4+1745^4-1746^4+1747^4-1748^4-1749^4+1750^4+1751^4-1752^4-1753^4+1754^4-1755^4+1756^4+1757^4-1758^4  &
&       &
&     +1759^4-1760^4-1761^4+1762^4-1763^4+1764^4+1765^4-1766^4-1767^4+1768^4+1769^4-1770^4+1771^4-1772^4-1773^4+1774^4  &
&     -1775^4+1776^4+1777^4-1778^4+1779^4-1780^4-1781^4+1782^4+1783^4-1784^4-1785^4+1786^4-1787^4+1788^4+1789^4-1790^4  &
&       &
&     +1791^4-1792^4-1793^4+1794^4-1795^4+1796^4+1797^4-1798^4-1799^4+1800^4+1801^4-1802^4+1803^4-1804^4-1805^4+1806^4  &
&     -1807^4+1808^4+1809^4-1810^4+1811^4-1812^4-1813^4+1814^4+1815^4-1816^4-1817^4+1818^4-1819^4+1820^4+1821^4-1822^4  &
&       &
&     +1823^4-1824^4-1825^4+1826^4-1827^4+1828^4+1829^4-1830^4-1831^4+1832^4+1833^4-1834^4+1835^4-1836^4-1837^4+1838^4  &
&     -1839^4+1840^4+1841^4-1842^4+1843^4-1844^4-1845^4+1846^4+1847^4-1848^4-1849^4+1850^4-1851^4+1852^4+1853^4-1854^4  &
&       &
&     +1855^4-1856^4-1857^4+1858^4-1859^4+1860^4+1861^4-1862^4-1863^4+1864^4+1865^4-1866^4+1867^4-1868^4-1869^4+1870^4  &
&     -1871^4+1872^4+1873^4-1874^4+1875^4-1876^4-1877^4+1878^4+1879^4-1880^4-1881^4+1882^4-1883^4+1884^4+1885^4-1886^4  &
&       &
&     +1887^4-1888^4-1889^4+1890^4-1891^4+1892^4+1893^4-1894^4-1895^4+1896^4+1897^4-1898^4+1899^4-1900^4-1901^4+1902^4  &
&     -1903^4+1904^4+1905^4-1906^4+1907^4-1908^4-1909^4+1910^4+1911^4-1912^4-1913^4+1914^4-1915^4+1916^4+1917^4-1918^4  &
&       &
&     +1919^4-1920^4-1921^4+1922^4-1923^4+1924^4+1925^4-1926^4-1927^4+1928^4+1929^4-1930^4+1931^4-1932^4-1933^4+1934^4  &
&     -1935^4+1936^4+1937^4-1938^4+1939^4-1940^4-1941^4+1942^4+1943^4-1944^4-1945^4+1946^4-1947^4+1948^4+1949^4-1950^4  &
&       &
&     +1951^4-1952^4-1953^4+1954^4-1955^4+1956^4+1957^4-1958^4-1959^4+1960^4+1961^4-1962^4+1963^4-1964^4-1965^4+1966^4  &
&     -1967^4+1968^4+1969^4-1970^4+1971^4-1972^4-1973^4+1974^4+1975^4-1976^4-1977^4+1978^4-1979^4+1980^4+1981^4-1982^4  &
&       &
&     +1983^4-1984^4-1985^4+1986^4-1987^4+1988^4+1989^4-1990^4-1991^4+1992^4+1993^4-1994^4+1995^4-1996^4-1997^4+1998^4  &
&     -1999^4+2000^4+2001^4-2002^4+2003^4-2004^4-2005^4+2006^4+2007^4-2008^4-2009^4+2010^4-2011^4+2012^4+2013^4-2014^4  &
&
END


 

Re: S=±1^4±2^4±3^4 … ±2014^4 の値

 投稿者:山中和義  投稿日:2014年10月 8日(水)20時04分3秒
  > No.3519[元記事へ]

恒等式 (x+1)^m-(x+2)^m-(x+3)^m+(x+4)^m … =0 の確認

符号を、項数が2^(m+1)個のThue-Morse sequenceに対応させればよい。

考察
xのm次の多項式(x+p)^m、m=0,1,2,3,…とする。
x^(m-k)の係数は、二項定理から、COMB(m,k)p^k である。
いま、mを固定しておいて、p=1,2,3,…,2^(m+1)として、Σ±(x+p)^m を考える。
その和は、x^(m-k)の係数では、COMB(m,k){±1^m±2^m±3^m± … ±(2^(m+1))^m} となる。
ここで、Σ±p^kに着目すると、
m=0のとき、
 1^0-2^0 = 0
m=1のとき、
 1^0-2^0-3^0+4^0 = 0
  1^1-2^1-3^1+4^1 = 0
m=2のとき、
 1^0-2^0-3^0+4^0 -5^0+6^0+7^0-8^0 = 0
  1^1-2^1-3^1+4^1 -5^1+6^1+7^1-8^1 = 0
  1^2-2^2-3^2+4^2 -5^2+6^2+7^2-8^2 = 0
m=3のとき、
 1^0-2^0-3^0+4^0 -5^0+6^0+7^0-8^0  -9^0+10^0+11^0-12^0 +13^0-14^0-15^0+16^0 = 0
 1^1-2^1-3^1+4^1 -5^1+6^1+7^1-8^1  -9^1+10^1+11^1-12^1 +13^1-14^1-15^1+16^1 = 0
 1^2-2^2-3^2+4^2 -5^2+6^2+7^2-8^2  -9^2+10^2+11^2-12^2 +13^2-14^2-15^2+16^2 = 0
 1^3-2^3-3^3+4^3 -5^3+6^3+7^3-8^3  -9^3+10^3+11^3-12^3 +13^3-14^3-15^3+16^3 = 0
m=4のとき、

 :
 :

なので、0となる。
(終わり)



OPTION ARITHMETIC RATIONAL !多桁の整数

LET M=4 !m乗

DIM B(0 TO 2^(M+1)-1) !2^(m+1) thue-morse sequence
LET B(0)=0
FOR K=0 TO M
   LET T=2^K
   FOR J=0 TO T-1 !前半分を反転させる
      LET B(J+T)=1-B(J)
   NEXT J
NEXT K
MAT PRINT B;

DIM A(0 TO M) !m次の多項式
MAT A=ZER
FOR P=1 TO 2^(M+1)
   PRINT "(";STR$(P);"+x)";
   IF M>1 THEN PRINT "^";STR$(M);
   PRINT " =";
   FOR K=M TO 0 STEP -1 !(x+p)^mの展開
      LET C=COMB(M,K)*P^K !x^(m-k)の係数
      PRINT C;
      IF B(P-1)=0 THEN LET A(K)=A(K)+C ELSE LET A(K)=A(K)-C !和
   NEXT K
   PRINT

   MAT PRINT A;
NEXT P

END


実行結果

0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0  1  1  0  1  0  0  1

(1+x)^4 = 1  4  6  4  1
1  4  6  4  1

(2+x)^4 = 16  32  24  8  1
0 -4 -18 -28 -15

(3+x)^4 = 81  108  54  12  1
-1 -16 -72 -136 -96

(4+x)^4 = 256  256  96  16  1
0  0  24  120  160

(5+x)^4 = 625  500  150  20  1
-1 -20 -126 -380 -465

(6+x)^4 = 1296  864  216  24  1
0  4  90  484  831

(7+x)^4 = 2401  1372  294  28  1
1  32  384  1856  3232

(8+x)^4 = 4096  2048  384  32  1
0  0  0 -192 -864

(9+x)^4 = 6561  2916  486  36  1
-1 -36 -486 -3108 -7425

(10+x)^4 = 10000  4000  600  40  1
0  4  114  892  2575

(11+x)^4 = 14641  5324  726  44  1
1  48  840  6216  17216

(12+x)^4 = 20736  6912  864  48  1
0  0 -24 -696 -3520

(13+x)^4 = 28561  8788  1014  52  1
1  52  990  8092  25041

(14+x)^4 = 38416  10976  1176  56  1
0 -4 -186 -2884 -13375

(15+x)^4 = 50625  13500  1350  60  1
-1 -64 -1536 -16384 -64000

(16+x)^4 = 65536  16384  1536  64  1
0  0  0  0  1536

(17+x)^4 = 83521  19652  1734  68  1
-1 -68 -1734 -19652 -81985

(18+x)^4 = 104976  23328  1944  72  1
0  4  210  3676  22991

(19+x)^4 = 130321  27436  2166  76  1
1  80  2376  31112  153312

(20+x)^4 = 160000  32000  2400  80  1
0  0 -24 -888 -6688

(21+x)^4 = 194481  37044  2646  84  1
1  84  2622  36156  187793

(22+x)^4 = 234256  42592  2904  88  1
0 -4 -282 -6436 -46463

(23+x)^4 = 279841  48668  3174  92  1
-1 -96 -3456 -55104 -326304

(24+x)^4 = 331776  55296  3456  96  1
0  0  0  192  5472

(25+x)^4 = 390625  62500  3750  100  1
1  100  3750  62692  396097

(26+x)^4 = 456976  70304  4056  104  1
0 -4 -306 -7612 -60879

(27+x)^4 = 531441  78732  4374  108  1
-1 -112 -4680 -86344 -592320

(28+x)^4 = 614656  87808  4704  112  1
0  0  24  1464  22336

(29+x)^4 = 707281  97556  5046  116  1
-1 -116 -5022 -96092 -684945

(30+x)^4 = 810000  108000  5400  120  1
0  4  378  11908  125055

(31+x)^4 = 923521  119164  5766  124  1
1  128  6144  131072  1048576

(32+x)^4 = 1048576  131072  6144  128  1
0  0  0  0  0



 

Re: S=±1^4±2^4±3^4 … ±2014^4 の値

 投稿者:GAI  投稿日:2014年10月 9日(木)21時34分56秒
  > No.3520[元記事へ]

山中和義さんへのお返事です。



OPTION ARITHMETIC RATIONAL !多桁の整数

LET M=4 !m乗

DIM B(0 TO 2^(M+1)-1) !2^(m+1) thue-morse sequence
LET B(0)=0
FOR K=0 TO M
   LET T=2^K
   FOR J=0 TO T-1 !前半分を反転させる
      LET B(J+T)=1-B(J)
   NEXT J
NEXT K
FOR i=0 TO 2^(M+1)-1
   PRINT USING  "###":i;
NEXT i
MAT PRINT USING "  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #":B

END

<実行結果>
  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0  1  1  0  1  0  0  1

の様にthue-morse sequenceにより0~31が2つのグループに分かれる。
(この2つのグループで4乗での和が同一をなす。)
上記の"0"に相当する上列の集合
{0,3,5,6,9,10,12,15,17,18,20,23,24,27,29,30}<----------これを"evil numbers"と呼ぶらしい。
に相当するものが、下記の排他的論理和でのプログラム


OPTION ARITHMETIC RATIONAL !多桁の整数

LET M=4 !m乗

DIM B(0 TO 2^(M+1)-1)
LET B(0)=0
FOR K=0 TO M
   LET T=2^K
   FOR J=1 TO 2*(T-1)+1
      LET B(J)=BITXOR(J-1,2*(J-1))  !排他的論理和
   NEXT J
NEXT K
FOR i=0 TO 2^(M+1)-1
   PRINT USING  "####":i;
NEXT i
MAT PRINT USING "  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##":B

END

<実行結果>
   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
   0   0   3   6   5  12  15  10   9  24  27  30  29  20  23  18  17  48  51  54  53  60  63  58  57  40  43  46  45  36  39  34

によって順番は崩れるが要素としては同一なものが取り出せる。


この関連が面白いと思いました。
 

同じものを含むものを配る

 投稿者:山中和義  投稿日:2014年10月13日(月)09時29分0秒
  問題
10個のうち同じものをそれぞれ 4,3,2,1個ずつ含む a,a,a,a, b,b,b, c,c, d を、
A,B,C,Dの4人に分配する方法の数を求めよ。
条件1 1個ももらえない場合もありえるものとする。
条件2 少なくとも1個以上はもらえるものとする。

考察
条件1のとき、
aを4人に配る方法は、H(4,4)通り
bを4人に配る方法は、H(4,3)通り
cを4人に配る方法は、H(4,2)通り
dを4人に配る方法は、H(4,1)通り
なので、H(4,4)*H(4,3)*H(4,2)*H(4,1)=28000通り

同じものが、
 m種類、それぞれb[k](1≦k≦m)個ずつ
とすると、F0(n)= Π[k=1,m]H(n,b[k])


条件2のとき、
特定の1人に全部配る場合、1通り
特定の2人に全部配る場合、
 全部配る方法は、H(2,4)*H(2,3)*H(2,2)*H(2,1)=120通り
 そのうち1人だけがもらう方法は、C(2,1)*1=2通り
 よって、120-2=118通り
特定の3人に全部配る場合、
 H(3,4)*H(3,3)*H(3,2)*H(3,1)-C(3,2)*118-C(3,1)*1=2343通り
特定の4人に全部配る場合、
 H(4,4)*H(4,3)*H(4,2)*H(4,1)-C(4,3)*2343-C(4,2)*118-C(4,1)*1=17916通り

F1(n)= F0(n) - Σ[k=1,n-1]C(n,k)F1(k)
(終わり)



LET M=4 !m種類
DATA 4,3,2,1 !個数
LET N=4 !n人
DIM B(4)
MAT READ B
PRINT F0(M,B,N); "通り"
PRINT F1(M,B,N); "通り"
END

EXTERNAL FUNCTION H(N,R) !重複組合せ H(n,r)=C(n+r-1,r)
LET H=COMB(N+R-1,R)
END FUNCTION

EXTERNAL FUNCTION F0(M,B(),N) !条件1
LET S=1 !Π[k=1,m]H(n,b[k])
FOR K=1 TO M
   LET S=S*H(N,B(K))
NEXT K
LET F0=S
END FUNCTION

EXTERNAL FUNCTION F1(M,B(),N) !条件2
LET S=0 !特定のk人に全部配る Σ[k=1,n-1]C(n,k)F1(k)
FOR K=1 TO N-1
   LET S=S+COMB(N,K)*F1(M,B,K)
NEXT K
LET F1=F0(M,B,N)-S
END FUNCTION



別解
aをAに配った個数をaA個と表すとする。
次の連立方程式を解く。
 条件2のとき、
     a  b  c  d
 A: aA bA cA dA ≧1 ←行の和
 B: aB bB cB dB ≧1
 C: aC bC cC dC ≧1
 D: aD bD cD dD ≧1
    =4 =3 =2 =1
    ↑列の和
配る個数は、a,b,c,dの順に分割数を利用して決めていく。
(終わり)



LET M=4 !m種類
DATA 4,3,2,1 !個数
LET N=4 !n人
DIM B(4)
MAT READ B
DIM A(N,M) !並び
PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(1,1, B(1), M,B, N, A)
PRINT C;"通り"
END

EXTERNAL SUB try(x,y,S, M,B(),N, A(,)) !バックトラック法で検索する
IF x=N THEN !最後の人のとき
   LET A(x,y)=S !残り全部
   IF y=M THEN !最後のもののとき
      DIM w(M),Aw(N) !0個の人があるかどうか確認する ※条件2
      MAT w=CON      !条件1の場合、不要(削除する)
      MAT Aw=A*w !行の和
      FOR i=1 TO N
         IF Aw(i)=0 THEN EXIT FOR
      NEXT i
      IF i>N THEN !いないなら

         LET C=C+1 !結果を表示する
         !!MAT PRINT A;
      END IF
   ELSE
      CALL try(1,y+1,B(y+1), M,B,N, A) !次のものへ
   END IF
ELSE
   FOR i=S TO 0 STEP -1 !x番目の人にy番目のものをi個配る
      LET A(x,y)=i
      CALL try(x+1,y,S-i, M,B,N, A) !次の人へ
   NEXT i
END IF
END SUB


 

ファン・デル・ヴェルデン数(Van der Waerden number)

 投稿者:山中和義  投稿日:2014年10月14日(火)10時25分34秒
  問題
1から8までの8個の異なる数を、2つの集まりAとBに振り分けるとき、
「どんな3つの数を選んでも互いの差は全て異なる」
ようにするためにはどのように振り分けたら良いか?

答え
{ 1, 2, 5, 6 } { 3, 4, 7, 8 }
{ 1, 3, 6, 8 } { 2, 4, 5, 7 }
{ 1, 4, 5, 8 } { 2, 3, 6, 7 }
以上、3通り
(終わり)


類題
タイルが1列に並んでいる。それらに2種類の色を塗っていく。
ただし、等間隔に3つ以上同じ色を塗らないようにする。
何枚まで塗ることができるか。

答え
1種類では、2枚まで
2種類では、8枚まで
3種類では、26枚まで
4種類では、75枚まで ※ここから処理困難になる
 :
 :
(終わり)

参考サイト
ファン・デル・ヴェルデン数(Van der Waerden number)
  http://mathworld.wolfram.com/vanderWaerdenNumber.html
  http://oeis.org/A005346

参考サイト
 私的数学塾 http://www004.upp.so-net.ne.jp/s_honma/index.htm 内
  お茶の時間
   パズル&クイズ
    数の組合せ2 http://www004.upp.so-net.ne.jp/s_honma/relax/number4.htm



LET R=2 !r種類
LET K=3 !長さk

DIM A(8) !並び ※※※W(r,k)-1の値
LET A(1)=1 !※対称性

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(2,R,K,A)
PRINT C; "通り"
END

EXTERNAL SUB try(P,R,K,A())
FOR i=1 TO R
   LET D=1 !間隔(公差)
   DO
      LET T=P
      FOR J=1 TO K-1 !等間隔に3つ並ぶ(等差数列)かどうか確認する
         LET T=T-D
         IF T<1 THEN EXIT DO !これ以降は可能性なし
         IF A(T)<>i THEN EXIT FOR
      NEXT J
      IF J>K-1 THEN EXIT DO !NGの場合
      LET D=D+1 !次へ
   LOOP
   IF J<K THEN !題意を満たすなら
      LET A(P)=i
      IF P=UBOUND(A) THEN !すべて埋まったなら
         LET C=C+1 !結果を表示する
         MAT PRINT A;

         FOR x=1 TO R !集合ごとに
            PRINT " {";
            LET FLG=0 !継続フラグ
            FOR y=1 TO UBOUND(A)
               IF A(y)=x THEN
                  IF FLG=1 THEN PRINT ","; !最初ならカンマはつけない
                  PRINT STR$(y);
                  LET FLG=1
               END IF
            NEXT y
            PRINT "}";
         NEXT x
         PRINT

      ELSE
         CALL try(P+1,R,K,A) !次へ
      END IF
   END IF
NEXT i
END SUB


実行結果

1  1  2  2  1  1  2  2

{1,2,5,6} {3,4,7,8}
1  2  1  2  2  1  2  1

{1,3,6,8} {2,4,5,7}
1  2  2  1  1  2  2  1

{1,4,5,8} {2,3,6,7}
3 通り

 

リー代数

 投稿者:永野護  投稿日:2014年10月14日(火)11時49分34秒
  最近リー代数について調べています。
本の説明は抽象的でよくわかりません。
リー代数の簡単な具体例をあげていただけないでしょうか。
 

DK(Durand-Kerner)法について

 投稿者:tibita  投稿日:2014年10月14日(火)17時32分32秒
  C言語のプログラミングについて勉強しています。
8次の代数方程式をDK法で解き、実部、虚部の解を共にモニタ上に出力するプログラムを作りたいのですが、C言語で書かれたサンプルプログラムを書いていただけませんか?
 

Re: DK(Durand-Kerner)法について

 投稿者:山中和義  投稿日:2014年10月16日(木)10時37分3秒
  > No.3525[元記事へ]

tibitaさんへのお返事です。

> C言語のプログラミングについて勉強しています。
> 8次の代数方程式をDK法で解き、実部、虚部の解を共にモニタ上に出力するプログラムを作りたいのですが、C言語で書かれたサンプルプログラムを書いていただけませんか?


代数方程式
 p(z)=z^8-36z^7+546z^6-4536z^5+22449z^4-67284z^3+118124z^2-109584z+40320
の解

最近の言語では、COMPLEX(複素数)を扱えるので、記述はより簡潔になると思います。

下記のANSI C程度のサンプルは、実部と虚部( x1(n), x2(n) )を分離して計算しています。



//DKA(Durand-Kerner-Aberth)法によるn次代数方程式f(x)=0の解法

#include <stdio.h>
#include <math.h>

#define PI 3.14159265358979323846
#define N 8 //n次

int main(void)
{
   double a[N+1] = {40320,-109584,118124,-67284,22449,-4536,546,-36,1}; //係数
   double x1[N],x2[N]; //n個の根(実部、虚部)
   int i,j;

   for (i=0; i<=N; i++) a[i]/=a[N]; //x^n+a[n-1]/a[n]*x^(n-1)+ … + a[1]/a[n]*x+a[0]/a[n]の形へ

   double r=1.0, r0, t; //初期値を仮定する
   for (i=1; i<=N; i++) {
      r0=pow(fabs(N*a[i]),1.0/i);
      if (r<r0) r=r0;
   }
   for (i=1; i<=N; i++) { //半径rの円に等間隔に配置する
      t=2.0*PI/N*(i-3.0/4.0);
      x1[i-1]=-a[N-1]/N+r*cos(t); //アーバスの初期値
      x2[i-1]=r*sin(t);
   }

   double e,f1,f2,w1,w2,p1,p2,a1,a2,norm;
   do {
      e=0.0;

      for (i=0; i<N; i++) {
         f1=1.0; //分子 f(zi)、実部=f1,虚部=f2
         f2=0.0; //※a(0)=1
         for (j=N-1; j>=0; j--) { //ホーナー法 f(z)=( … ((z+a[n-1])*z+a[n-2])*z+a[n-3])* … +a[1])*z+a[0]
            w1=f1*x1[i]-f2*x2[i]; //f*z=(f1+i*f2)*(x1+i*x2)=(f1*x1-f2*x2)+i*(f1*x2+f2*x1)
            w2=f2*x1[i]+f1*x2[i];
            f1=w1+a[j]; //f=z+a[j]
            f2=w2;
         }

         p1=1.0; //分母 Π[j=1,N,i≠j](zi-zj)、実部=p1,虚部=p2
         p2=0.0;
         for (j=0; j<N; j++) {
           if (j!=i) {
               w1=p1*(x1[i]-x1[j])-p2*(x2[i]-x2[j]); //p*(zi-zj)
               w2=p1*(x2[i]-x2[j])+p2*(x1[i]-x1[j]);
               p1=w1; //p=(zi-zj)
               p2=w2;
            }
         }

         t=p1*p1+p2*p2; //分子÷分母 (f1+i*f2)/(p1+i*p2)=(f1+i*f2)(p1-i*p2)/(p1*p1+p2*p2)
         if (t==0.0) {
            printf("0では割れません。\n");
            return 1;
         }
         a1=(f1*p1+f2*p2)/t;
         a2=(f2*p1-f1*p2)/t;
         norm=sqrt(a1*a1+a2*a2);
         if (e<norm) e=norm; //最大値

         x1[i]-=a1; //k回目の近似根 zi[k+1]=zi[k]-f(zi[k])/Π[j=1,N,i≠j](zi[k]-zj[k])
         x2[i]-=a2;
      }
   } while (e>1.0e-10); //収束するまで ※調整が必要である

   for (i=0; i<N; i++) printf( "x%d  実部=%f  虚部=%f\n", i,x1[i],x2[i]);

   return 0;
}


実行結果

x0  実部=1.000000  虚部=0.000000
x1  実部=2.000000  虚部=-0.000000
x2  実部=3.000000  虚部=-0.000000
x3  実部=5.000000  虚部=-0.000000
x4  実部=8.000000  虚部=-0.000000
x5  実部=7.000000  虚部=-0.000000
x6  実部=6.000000  虚部=0.000000
x7  実部=4.000000  虚部=0.000000
続行するには何かキーを押してください . . .



参考資料 数値計算の基礎 http://www7.ocn.ne.jp/~kawa1/numeric.pdf

 

お返事ありがとうございます

 投稿者:tibita  投稿日:2014年10月16日(木)15時13分39秒
  お返事ありがとうございます.
complex.hをincludeすると,虚部の数字も0ではなくなるのでしょうか?
また,aberthの初期値以外にも有効な初期値の与え方(2次収束の場合で)はいくつかあるでしょうか?
度々の質問ですいません.
 

Re: お返事ありがとうございます

 投稿者:山中和義  投稿日:2014年10月16日(木)17時06分34秒
  > No.3527[元記事へ]

tibitaさんへのお返事です。

> complex.hをincludeすると,虚部の数字も0ではなくなるのでしょうか?

この計算では、上位6桁の精度が0になっただけです。
ちなみに、このプログラムでは、complex.h は不要です。


> aberthの初期値以外にも有効な初期値の与え方(2次収束の場合で)はいくつかあるでしょうか?

数学的背景は、専門書(数値計算)を参照してください。 私にはわかりません。

 

Re: DK(Durand-Kerner)法について

 投稿者:山中和義  投稿日:2014年10月17日(金)15時13分50秒
  > No.3526[元記事へ]

tibitaさんへのお返事です。


complex.h を使ったサンプルです。 CPad 2.31 + Borland C++ Complier 5.5 で確認しました。



//DKA(Durand-Kerner-Aberth)法によるn次代数方程式f(x)=0の解法

#include <stdio.h>
#include <math.h>
#include <complex.h>

#define PI 3.14159265358979323846
#define N 8 //n次

int main(void)
{
   double a[N+1] = {40320,-109584,118124,-67284,22449,-4536,546,-36,1}; //係数
   complex<double> x[N]; //n個の根(実部、虚部)
   int i,j;

   for (i=0; i<=N; i++) a[i]/=a[N]; //x^n+a[n-1]/a[n]*x^(n-1)+ … + a[1]/a[n]*x+a[0]/a[n]の形へ

   double r=1.0, r0; //初期値を仮定する
   for (i=1; i<=N; i++) {
      r0=pow(fabs(N*a[i]),1.0/i);
      if (r<r0) r=r0;
   }
   for (i=0; i<N; i++) { //半径rの円に等間隔に配置する
      x[i]=-a[N-1]/N+r*exp(2.0*PI/N*((i+1)-3.0/4.0)*(0,1)); //アーバスの初期値
   }

   double e,norm;
   do {
      e=0.0;

      for (i=0; i<N; i++) {
         complex<double> f,p,t;

         f=1.0; //分子 f(zi) ※a(n)=1
         for (j=N-1; j>=0; j--)
            f=f*x[i]+a[j]; //ホーナー法 f(z)=( … ((z+a[n-1])*z+a[n-2])*z+a[n-3])* … +a[1])*z+a[0]

         p=1.0; //分母 Π[j=1,N,i≠j](zi-zj)
         for (j=0; j<N; j++)
           if (j!=i) p*=x[i]-x[j]; //p*(zi-zj)

         //分子÷分母 (f1+i*f2)/(p1+i*p2)=(f1+i*f2)(p1-i*p2)/(p1*p1+p2*p2)
         if (abs(p)==0.0) {
            printf("0では割れません。\n");
            return 1;
         }
         t=f/p;
         norm=abs(t);
         if (e<norm) e=norm; //最大値

         x[i]-=t; //k回目の近似根 zi[k+1]=zi[k]-f(zi[k])/Π[j=1,N,i≠j](zi[k]-zj[k])
      }
   } while (e>1.0e-10); //収束するまで ※調整が必要である

   for (i=0; i<N; i++) printf("x%d  実部=%f  虚部=%f\n", i,real(x[i]),imag(x[i]));

   return 0;
}


実行結果

D:\My Documents\C>test
x0  実部=3.000000  虚部=0.000000
x1  実部=4.000000  虚部=0.000000
x2  実部=7.000000  虚部=0.000000
x3  実部=2.000000  虚部=0.000000
x4  実部=1.000000  虚部=0.000000
x5  実部=6.000000  虚部=0.000000
x6  実部=5.000000  虚部=0.000000
x7  実部=8.000000  虚部=0.000000
-- Press any key to exit (Input "c" to continue) --


 

Re: DK(Durand-Kerner)法について

 投稿者:山中和義  投稿日:2014年10月17日(金)16時33分7秒
  > No.3529[元記事へ]


> //DKA(Durand-Kerner-Aberth)法によるn次代数方程式f(x)=0の解法
>
> #include <stdio.h>
> #include <math.h>
> #include <complex.h>
>
> #define PI 3.14159265358979323846
> #define N 8 //n次
>
> int main(void)
> {
>    double a[N+1] = {40320,-109584,118124,-67284,22449,-4536,546,-36,1}; //係数
>    complex<double> x[N]; //n個の根(実部、虚部)
>    int i,j;
>
>    for (i=0; i<=N; i++) a[i]/=a[N]; //x^n+a[n-1]/a[n]*x^(n-1)+ … + a[1]/a[n]*x+a[0]/a[n]の形へ
>
>    double r=1.0, r0; //初期値を仮定する
>    for (i=1; i<=N; i++) {
>       r0=pow(fabs(N*a[i]),1.0/i);
>       if (r<r0) r=r0;
>    }
>    for (i=0; i<N; i++) { //半径rの円に等間隔に配置する
>       x[i]=-a[N-1]/N+r*exp(2.0*PI/N*((i+1)-3.0/4.0)*(0,1)); //アーバスの初期値
>    }
>
>    double e,norm;
>    do {
>       e=0.0;
>


訂正します。



int main(void)
{
   double a[N+1] = {40320,-109584,118124,-67284,22449,-4536,546,-36,1}; //係数
   complex<double> Zi(0.0,1.0); //虚数単位
   complex<double> x[N]; //n個の根(実部、虚部)
   int i,j;

   for (i=0; i<=N; i++) a[i]/=a[N]; //x^n+a[n-1]/a[n]*x^(n-1)+ … + a[1]/a[n]*x+a[0]/a[n]の形へ

   double r=1.0, r0; //初期値を仮定する
   for (i=1; i<=N; i++) {
      r0=pow(fabs(N*a[i]),1.0/i);
      if (r<r0) r=r0;
   }
   for (i=0; i<N; i++) { //半径rの円に等間隔に配置する
      x[i]=-a[N-1]/N+r*exp(2.0*PI/N*((i+1)-3.0/4.0)*Zi); //アーバスの初期値
   }

   double e,norm;
   do {
      e=0.0;

  :
  :



実行結果

D:\My Documents\C>test
x0  実部=1.000000  虚部=0.000000
x1  実部=2.000000  虚部=-0.000000
x2  実部=3.000000  虚部=-0.000000
x3  実部=5.000000  虚部=0.000000
x4  実部=8.000000  虚部=-0.000000
x5  実部=7.000000  虚部=0.000000
x6  実部=6.000000  虚部=-0.000000
x7  実部=4.000000  虚部=-0.000000
-- Press any key to exit (Input "c" to continue) --


 

モグラたたき(もどき)

 投稿者:しばっち  投稿日:2014年10月19日(日)18時32分21秒
  緑の丸を左クリックする


DIM MX(3),MY(3),NX(3),NY(3)
RANDOMIZE
LET XSIZE=900
LET YSIZE=700
LET SIZE=700
LET TI=1 !'表示時間
CALL GINIT(XSIZE,YSIZE)
SET TEXT HEIGHT 25
SET TEXT JUSTIFY "LEFT" , "TOP"
SET TEXT COLOR 7
LET N=8 !'マスの数 N*N
DIM X(N,N),Y(N,N)
LET RR=SIZE/N/2
LET R=RR/1.5 !'丸の大きさ R=RR~RR/3
FOR I=1 TO N
   FOR J=1 TO N
      LET X(J,I)=RR+(J-1)*SIZE/N
      LET Y(J,I)=RR+(I-1)*SIZE/N
   NEXT J
NEXT I
FOR I=0 TO SIZE STEP SIZE/N
   CALL LINE(I,0,I,SIZE,7)
   CALL LINE(0,I,SIZE,I,7)
NEXT I
LET TY=TIME
PLOT TEXT ,AT 740,300:"残り時間"
DO
   CALL BOXFULL(740,330,XSIZE,360,0)
   SET TEXT COLOR 7
   PLOT TEXT ,AT 740,330:"   "&STR$(INT(120-TIME+TY))
   LET Z=RND
   LET NN=1
   IF Z<.4 THEN LET NN=2
   IF Z<.1 THEN LET NN=3
   FOR K=1 TO NN !'丸の数
      LET S=INT(RND*N)+1
      LET T=INT(RND*N)+1
      LET MX(K)=X(S,T)
      LET MY(K)=Y(S,T)
      CALL CIRCLEFULL(MX(K),MY(K),R,4)
   NEXT K
   MAT NX=MX
   MAT NY=MY
   LET TT=TIME
   LET L=0
   DO
      FOR K=1 TO NN
         MOUSE POLL XX,YY,LEFT,RIGHT
         IF TIME-TT>TI THEN !'時間オーバーならミス
            LET MISS=MISS+NN-L
            CALL BOXFULL(740,150,XSIZE,180,0)
            SET TEXT COLOR 7
            PLOT TEXT ,AT 740,120:" MISS"
            PLOT TEXT ,AT 740,150:"  "&STR$(MISS)
            EXIT DO
         END IF
         IF SQR((MX(K)-XX)^2+(MY(K)-YY)^2)<R AND LEFT=1 THEN !'時間内に丸を左クリック
            CALL CIRCLEFULL(MX(K),MY(K),R,2)
            BEEP
            LET SC=SC+1
            LET L=L+1
            LET MX(K)=0
            LET MY(K)=0
            CALL BOXFULL(740,70,XSIZE,100,0)
            SET TEXT COLOR 7
            PLOT TEXT ,AT 740,40:"SUCCESS"
            PLOT TEXT ,AT 740,70:"  "&STR$(SC)
            WAIT DELAY .1
            IF L=NN THEN EXIT DO
         END IF
      NEXT K
   LOOP
   FOR K=1 TO NN
      CALL CIRCLEFULL(NX(K),NY(K),R,0)
   NEXT K
   LET TT=RND*2+TIME
   DO
   LOOP UNTIL TT-TIME<=0 !'適当な待ち時間
LOOP WHILE TIME-TY<=120 !'プレイ時間 120秒
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"
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
CLEAR
END SUB

EXTERNAL SUB CIRCLEFULL(X,Y,RR,C)
SET COLOR C
DRAW DISK WITH SCALE(RR)*SHIFT(X,Y)
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

EXTERNAL SUB LINE(XS,YS,XE,YE,C)
SET COLOR C
PLOT LINES
PLOT LINES:XS,YS;XE,YE
END SUB
 

曜日が同じ

 投稿者:山中和義  投稿日:2014年10月20日(月)15時40分36秒
  各月の1日目の剰余を考えると、
・3月と11月
・4月と7月
・9月と12月
は、曜日は毎年同じです。

それぞれの日数間(等差数列、63日(7日×9週))を考えると、
・4/4, 6/6, 8/8, 10/10, 12/12 の曜日は毎年同じです。※1
・3/3, 5/5, 7/7 の曜日は毎年同じです。
・9/9, 11/11 の曜日は毎年同じです。

同様に、
・5/9, 9/5, 7/11, 11/7 の曜日は※1と毎年同じです。

3月以降の万年カレンダーをつくり確認しました。


DATA 31,30,31,30,31,31,30,31,30,31 !3月,4月,5月,…
!!DATA 31,28,31,30,31,30,31,31,30,31,30,31 !平年
!!DATA 31,29,31,30,31,30,31,31,30,31,30,31 !うるう年
LET S=0
FOR M=3 TO 12 !各月
!!FOR M=1 TO 12 !各月
   READ A !日数を得る
   FOR i=1 TO MOD(S,7) !開始位置を前の月に合わせる
      PRINT "   ";
   NEXT i
   FOR D=1 TO A !日にちを記入する
      PRINT USING "###": D;
      IF MOD(S+D,7)=0 THEN
         IF D<=7 THEN PRINT USING "  ##月": M ELSE PRINT !週単位
      END IF
   NEXT D
   PRINT
   LET S=S+A
NEXT M
!!PRINT S !検算
END


実行結果

  1  2  3  4  5  6  7   3月
  8  9 10 11 12 13 14
 15 16 17 18 19 20 21
 22 23 24 25 26 27 28
 29 30 31
           1  2  3  4   4月
  5  6  7  8  9 10 11
 12 13 14 15 16 17 18
 19 20 21 22 23 24 25
 26 27 28 29 30
                 1  2   5月
  3  4  5  6  7  8  9
 10 11 12 13 14 15 16
 17 18 19 20 21 22 23
 24 25 26 27 28 29 30
 31
     1  2  3  4  5  6   6月
  7  8  9 10 11 12 13
 14 15 16 17 18 19 20
 21 22 23 24 25 26 27
 28 29 30
           1  2  3  4   7月
  5  6  7  8  9 10 11
 12 13 14 15 16 17 18
 19 20 21 22 23 24 25
 26 27 28 29 30 31
                    1   8月
  2  3  4  5  6  7  8
  9 10 11 12 13 14 15
 16 17 18 19 20 21 22
 23 24 25 26 27 28 29
 30 31
        1  2  3  4  5   9月
  6  7  8  9 10 11 12
 13 14 15 16 17 18 19
 20 21 22 23 24 25 26
 27 28 29 30
              1  2  3  10月
  4  5  6  7  8  9 10
 11 12 13 14 15 16 17
 18 19 20 21 22 23 24
 25 26 27 28 29 30 31

  1  2  3  4  5  6  7  11月
  8  9 10 11 12 13 14
 15 16 17 18 19 20 21
 22 23 24 25 26 27 28
 29 30
        1  2  3  4  5  12月
  6  7  8  9 10 11 12
 13 14 15 16 17 18 19
 20 21 22 23 24 25 26
 27 28 29 30 31

 

DK法について

 投稿者:tibita  投稿日:2014年10月20日(月)17時20分16秒
  度々のお返事ありがとうございます.
コメント文も書いていただき,とても助かりました.
このサンプルプログラムをもとに勉強していきます.
ありがとうございます.
 

ナンバープレース探索プログラムを、速くする

 投稿者:SECOND  投稿日:2014年10月21日(火)18時36分38秒
  !ナンバープレース探索プログラムを、速くする。
!
!再帰なし、再帰あり1,2,3の、4タイプを、まとめた。
!処理は、分岐無しで直線状に行き来しており、再帰なしの Normal の方が?
!-------------------------------------------------------------------
DEBUG ON

OPTION ARITHMETIC NATIVE
DECLARE FUNCTION numplace, numpla1, numpla2, numpla3, OUTPUT_, checkout$
LET crlf$= CHR$(13)& CHR$(10)
OPTION BASE 0
DIM tb(8,8), copy(8,8)   !問題を置く配列
DIM i0(80),j0(80)        !1)
DIM u3(80,3),v3(80,3)    !2)
DIM q(80,9)              !3)
DIM qp(80)               !Normal型 専用。q() の各消費量( 初期値 0)
!--------------
! 実行前の準備
!--------------

SUB pre_ready
!------------------------------------------------
!1)空白の座標だけを、高速に調査できるように、
!  連続 番号で、座標を並べた i0(s),j0(s) 作成
!------------------------------------------------
   LET s9=-1
   FOR i=0 TO 8
      FOR j=0 TO 8
         IF tb(i,j)=0 THEN
            LET s9=s9+1
            LET i0(s9)=i
            LET j0(s9)=j
         END IF
      NEXT j
   NEXT i
   !------------------------------------------------------
   !2)空白の座標の全てについて、
   !  各々、所属する3x3枠で、その縦横列5個所を除く、
   !  他4箇所の 座標を並べた u3(s,0~3),v3(s,0~3) 作成
   !------------------------------------------------------
   FOR s=0 TO s9
      LET i=i0(s)
      LET j=j0(s)
      LET p=0
      FOR u=INT(i/3)*3 TO INT(i/3)*3 +2
         FOR v=INT(j/3)*3 TO INT(j/3)*3 +2
            IF u<>i AND v<>j THEN
               LET u3(s,p)=u
               LET v3(s,p)=v
               LET p=p+1
            END IF
         NEXT v
      NEXT u
   NEXT s
   !---------------------------------------------
   !3)空白の座標の全てについて、
   !  初期値の有る個所から 受ける制限で、
   !  取り得る数を、予め格納する q(s,0~9) 作成
   !---------------------------------------------
   FOR s=0 TO s9
      LET p=0
      FOR k=1 TO 9
      !------------ 縦横列チェック
         FOR w=0 TO 8
            IF k=tb(w,j0(s)) OR k=tb(i0(s),w) THEN EXIT FOR  !false
         NEXT w
         IF 8< w THEN
         !------------ 3x3 枠の残り4箇所チェック
            IF     k=tb(u3(s,0),v3(s,0)) OR k=tb(u3(s,1),v3(s,1)) THEN  !false
            ELSEIF k=tb(u3(s,2),v3(s,2)) OR k=tb(u3(s,3),v3(s,3)) THEN  !false
            ELSE                                                        !OK.
               LET q(s,p)=k
               LET p=p+1
            END IF
         END IF
      NEXT k
      LET q(s,p)=0    !終端マーク
   NEXT s
END SUB

!----------------------------------------------
! メイン プログラム
!----------------------------------------------
MAT READ tb
! MAT tb=TRN(tb)               !転置( 長時間かかる問題が、転置すると一瞬で終る事もある)
CALL pre_ready               !準備
PRINT "問題"
MAT PRINT tb;                !問題表示
MAT copy=tb
!
LET z$="0132"                !実行する型だけを、任意な順と個数 並べる
!
FOR sel=1 TO LEN(z$)
   MAT tb=copy
   LET cnt=0
   SELECT CASE z$(sel:sel)
   CASE "0"
      LET T$="Normal型"      !再帰を使わない。1番の最高速
      LET t0=TIME
      LET res= numplace
      LET t1=TIME-t0
   CASE "1"
      LET T$="再帰1型"      !単一文の再帰型。2番速
      LET t0=TIME
      LET res= numpla1(0)
      LET t1=TIME-t0
   CASE "2"
      LET T$="再帰2型"      !2つの文にまたがる再帰型。最も遅い4番速
      LET t0=TIME
      LET res= numpla2(0)
      LET t1=TIME-t0
   CASE "3"
      LET T$="再帰3型"      !再帰2型の速度向上型。3番速
      LET t0=TIME
      LET res= numpla3(0)
      LET t1=TIME-t0
   END SELECT
   IF res=0 THEN PRINT "false after (";cnt;"通り)"
   PRINT USING T$& " 実行時間#####.### sec":MOD( t1,86400)
   PRINT
NEXT sel
PRINT "終了"

!----------------------------------------------
! ●1つ完成 の表示と、正誤の確認
!----------------------------------------------

!単一解。又は、複数解の全表示。
!---------------
FUNCTION OUTPUT_
   LET cnt=cnt+1
   PRINT "(";cnt;")";checkout$(tb)   !正誤の確認 再検査( NG.なら、戻らず停止)
   MAT PRINT tb;
   LET OUTPUT_=1                     !●( 引数=1:1解で終了。引数=0:複数解 )
END FUNCTION

!複数解の場合で 高速に その個数を調べる時
!----------------
!FUNCTION OUTPUT_
!   LET cnt=cnt+1
!   IF MOD(cnt,1000)=0 THEN PRINT "(";cnt;")"
!   LET OUTPUT_=0                     !●( 引数=1:1解で終了。引数=0:複数解 )
!END FUNCTION


!----------------------------------------------
! 問題を解く本体( 再帰無し Normal型 )
!----------------------------------------------
FUNCTION numplace
   MAT qp=ZER
   FOR s=0 TO s9
      LET i=i0(s)
      LET j=j0(s)
      FOR p=qp(s) TO 9                 ! s ごとの候補 q() のポインター p
         LET k=q(s,p)                  !候補の数字 k
         IF k=0 THEN EXIT FOR          !NG. k の使い切り
         !------------ 縦横列チェック
         FOR w=0 TO 8
            IF k=tb(w,j) OR k=tb(i,w) THEN EXIT FOR  !next k
         NEXT w
         IF 8< w THEN
         !------------ 3x3 枠の残り4箇所チェック
            IF     k=tb(u3(s,0),v3(s,0)) OR k=tb(u3(s,1),v3(s,1)) THEN  !next k
            ELSEIF k=tb(u3(s,2),v3(s,2)) OR k=tb(u3(s,3),v3(s,3)) THEN  !next k
            ELSE
               LET tb(i,j)=k
               IF s=s9 THEN LET k=OUTPUT_   !●1つ完成
               LET qp(s)=p+1                !次の開始 p 記憶( 再帰では同位置に戻り
               EXIT FOR                         !next p を通るので qp()自体、不要)
            END IF                     !next k
         END IF                        !next k
      NEXT p
      IF k=0 THEN
      !------------ NG. k の使い切り
         LET tb(i,j)=0
         LET qp(s)=0
         LET s=s-2                     !1つ手前の s で、やり直し
         IF s< -1 THEN EXIT FOR        !探索限界で、終了
      END IF
   NEXT s
   LET numplace=k
END FUNCTION


!----------------------------------------------
! 問題を解く本体( 再帰型1)
!----------------------------------------------
FUNCTION numpla1(s)
   IF s9< s THEN
      LET numpla1=OUTPUT_      !●1つ完成
   ELSE
      local i,j,p
      LET numpla1=1            !preset true
      LET i=i0(s)
      LET j=j0(s)
      FOR p=0 TO 8
         LET k=q(s,p)
         IF k=0 THEN EXIT FOR
         !------------ 縦横列チェック
         FOR w=0 TO 8
            IF k=tb(w,j) OR k=tb(i,w) THEN EXIT FOR  ! next k
         NEXT w
         IF 8< w THEN
         !------------ 3x3 枠の残り4箇所チェック
            IF     k=tb(u3(s,0),v3(s,0)) OR k=tb(u3(s,1),v3(s,1)) THEN  !next k
            ELSEIF k=tb(u3(s,2),v3(s,2)) OR k=tb(u3(s,3),v3(s,3)) THEN  !next k
            ELSE
               LET tb(i,j)=k
               IF 0< numpla1(s+1) THEN EXIT FUNCTION
            END IF
         END IF
      NEXT p
      !------------ NG. k の使い切り
      LET tb(i,j)=0
      LET numpla1=0
   END IF
END FUNCTION


!----------------------------------------------
! 問題を解く本体( 再帰型2)
!----------------------------------------------
FUNCTION numpla2(s)
   IF s9< s THEN
      LET numpla2=OUTPUT_      !●1つ完成
   ELSE
      local p
      LET numpla2=1            !preset true
      FOR p=0 TO 8
         LET k=q(s,p)
         IF k=0 THEN EXIT FOR
         IF 0< test(s,k) THEN EXIT FUNCTION
      NEXT p
      !------------ NG. k の使い切り
      LET tb(i0(s),j0(s))=0
      LET numpla2=0
   END IF
END FUNCTION

FUNCTION test(s,k)
   LET test=0
   LET i=i0(s)
   LET j=j0(s)
   !------------ 縦横列チェック
   FOR w=0 TO 8
      IF k=tb(w,j) OR k=tb(i,w) THEN EXIT FUNCTION  ! next k
   NEXT w
   !------------ 3x3 枠の残り4箇所チェック
   IF k=tb(u3(s,0),v3(s,0)) OR k=tb(u3(s,1),v3(s,1)) THEN EXIT FUNCTION  ! next k
   IF k=tb(u3(s,2),v3(s,2)) OR k=tb(u3(s,3),v3(s,3)) THEN EXIT FUNCTION  ! next k
   !------------
   LET tb(i,j)=k
   LET test=numpla2(s+1)
END FUNCTION


!----------------------------------------------
! 問題を解く本体( 再帰型3)  再帰2の速度向上
!----------------------------------------------
FUNCTION numpla3(s)
   IF s9< s THEN
      LET numpla3=OUTPUT_      !●1つ完成
   ELSE
      LET numpla3=1
      IF 0< test3(s) THEN EXIT FUNCTION
      !------------ NG. k の使い切り
      LET tb(i0(s),j0(s))=0
      LET numpla3=0
   END IF
END FUNCTION

FUNCTION test3(s)
   local p
   LET test3=0           !preset false
   FOR p=0 TO 8
      LET k=q(s,p)
      IF k=0 THEN EXIT FUNCTION  !NG.
      LET i=i0(s)
      LET j=j0(s)
      !------------ 縦横列チェック
      FOR w=0 TO 8
         IF k=tb(w,j) OR k=tb(i,w) THEN EXIT FOR  ! next k
      NEXT w
      IF 8< w THEN
      !------------ 3x3 枠の残り4箇所チェック
         IF     k=tb(u3(s,0),v3(s,0)) OR k=tb(u3(s,1),v3(s,1)) THEN  ! next k
         ELSEIF k=tb(u3(s,2),v3(s,2)) OR k=tb(u3(s,3),v3(s,3)) THEN  ! next k
         !------------
         ELSE
            LET tb(i,j)=k
            LET test3=numpla3(s+1)
         END IF
      END IF
   NEXT p
END FUNCTION


!----------------------------------------------
! tb(,) の解が 規則通りに並んでいるかを 検査
!----------------------------------------------
FUNCTION checkout$(tb(,))
   local i,j
   LET w$=""
   FOR k=1 TO 9
      FOR z=0 TO 8 STEP 3
         LET i1=0
         LET i2=0
         LET i3=0
         FOR w=z TO z+2
         !------------ 横列チェック
            FOR j=8 TO 0 STEP -1
               IF k=tb(w,j) THEN EXIT FOR        !ok
            NEXT j
            IF j< 0 THEN LET w$=w$& crlf$& STR$(w+1)& "行目、横方向に "& STR$(k)& " 無し"
            !------------ 縦列チェック
            FOR i=8 TO 0 STEP -1
               IF k=tb(i,w) THEN EXIT FOR        !ok
            NEXT i
            IF i< 0 THEN LET w$=w$& crlf$& STR$(w+1)& "列目、縦方向に "& STR$(k)& " 無し"
            !------------ 3x3 チェック
            IF     6<=i THEN
               LET i3=1
            ELSEIF 3<=i THEN
               LET i2=1
            ELSEIF 0<=i THEN
               LET i1=1
            END IF
         NEXT w
         IF i1=0 THEN LET w$=w$& crlf$& "(1行,"& STR$(z+1)& "列)┏ から右下3x3に "& STR$(k)& " 無し"
         IF i2=0 THEN LET w$=w$& crlf$& "(4行,"& STR$(z+1)& "列)┏ から右下3x3に "& STR$(k)& " 無し"
         IF i3=0 THEN LET w$=w$& crlf$& "(7行,"& STR$(z+1)& "列)┏ から右下3x3に "& STR$(k)& " 無し"
      NEXT z
   NEXT k
   IF w$="" THEN
      LET checkout$="OK"
   ELSE
      PRINT w$
      MAT PRINT tb;
      PRINT T$;" (";cnt;")";"でエラー、以降の中止"
      STOP
   END IF
END FUNCTION


! http://www.sudoku.name/index-jp.php
!( #5300 )上級++  ※1 通りの解を持つ
DATA 3,0,0,0,0,2,0,0,0
DATA 0,0,6,0,0,0,0,9,0
DATA 0,0,9,0,0,4,0,0,3
DATA 0,9,0,0,0,0,0,0,5
DATA 0,5,0,8,0,0,0,6,0
DATA 8,0,0,0,3,0,0,1,0
DATA 2,0,0,9,0,0,3,0,0
DATA 0,6,0,0,0,0,4,0,0
DATA 0,0,0,1,0,0,0,0,7

! http://www.sudoku.name/index-jp.php
!( #5425 )上級++  ※(7行,2列)を、1→0 に改変、21 通りの解を持つ
DATA 0,8,0, 0,0,0, 4,0,0
DATA 6,0,0, 2,0,0, 0,0,0
DATA 0,9,0, 4,0,0, 0,2,0
DATA 9,0,0, 0,0,6, 1,0,0
DATA 0,0,2, 9,0,0, 5,0,0
DATA 0,0,3, 0,0,0, 0,0,6
DATA 0,0,0, 0,0,4, 0,3,0
DATA 0,0,0, 0,0,7, 0,0,5
DATA 0,0,5, 0,0,0, 0,7,0

END
 

Re: ナンバープレース探索プログラムを、速くする

 投稿者:SECOND  投稿日:2014年10月21日(火)23時22分24秒
  > No.3534[元記事へ]

起動後1回のみで、2回目以降の実行ができないバグが見つかり、
以下の、訂正を行ないました。み。
編集前コピーされた方には、すみません、もう一度コピーしなおして下さい。

1)DIM q(80,8) → DIM q(80,9)
2)q(s,0~9) 作成 に、LET q(s,p)=0  !終端マーク  ← 追加。
3)FUNCTION numplace の冒頭に、MAT qp=ZER  ← 追加。
4)FUNCTION numplace 前半、FOR p=qp(s) TO 8 → FOR p=qp(s) TO 9
5)FUNCTION numplace 後半、IF k=0 OR 8< p THEN → IF k=0 THEN
 

C曲線、ドラゴン曲線と2進法

 投稿者:山中和義  投稿日:2014年10月22日(水)16時42分39秒
  参考サイト http://sorauta.bufsiz.jp/Fractal/cdragon.html


!C曲線と2進法
LET N=7 !n次
SET WINDOW -15,10,-20,5
!!DRAW grid
LET X=0 !開始位置を原点とする
LET Y=0
PLOT LINES: X,Y;
FOR i=0 TO 2^N-1
   LET T=i
   LET S=0 !1の個数 mod 4
   DO WHILE T>0
      LET S=MOD(S+MOD(T,2),4)
      LET T=INT(T/2)
   LOOP
   PRINT S
   SELECT CASE S !各方向へ移動する
   CASE 0 !左
      LET X=X-1
   CASE 1 !上
      LET Y=Y+1
   CASE 2 !右
      LET X=X+1
   CASE 3 !下
      LET Y=Y-1
   CASE ELSE
   END SELECT
   PLOT LINES: X,Y;
NEXT i
END




!ドラゴン曲線と2進法
LET N=8 !n次
SET WINDOW -20,10,-15,15
!!DRAW grid
LET X=0 !開始位置を原点とする
LET Y=0
PLOT LINES: X,Y;
FOR i=0 TO 2^N-1
   LET T=i
   LET S=0 !桁数 mod 4
   LET W0=-1
   DO WHILE T>0
      LET W=MOD(T,2)
      IF W<>W0 THEN !ただし、同じ数字が連続する場合、まとめて1桁と数える
         LET S=MOD(S+1,4)
         LET W0=W
      END IF
      LET T=INT(T/2)
   LOOP
   PRINT S
   SELECT CASE S !各方向へ移動する
   CASE 0 !左
      LET X=X-1
   CASE 1 !上
      LET Y=Y+1
   CASE 2 !右
      LET X=X+1
   CASE 3 !下
      LET Y=Y-1
   CASE ELSE
   END SELECT
   PLOT LINES: X,Y;
NEXT i
END



 

C曲線

 投稿者:しばっち  投稿日:2014年10月23日(木)23時10分57秒
  CALL GINIT(640,400)
OPTION BASE 0
LET L=300
INPUT PROMPT "LEVEL=":NO
LET Y0=100
LET X0=400
LET R=45*NO
LET N=NO+1
DIM NN(N+1),LL(N+1)
DO
   LET R=R+45
   DO WHILE N>0
      LET NN(SP)=N
      LET LL(SP)=L
      LET SP=SP+1
      LET N=N-1
      LET L=L/SQR(2)
      LET R=R-90
   LOOP
   LET SP=SP-1
   LET N=NN(SP)
   LET L=LL(SP)
   IF N=1 THEN
      IF R>=360 THEN LET R=MOD(R+360,360)
      LET X=X0+COS(R*PI/180)*L
      LET Y=Y0-SIN(R*PI/180)*L
      CALL LINE(X0,Y0,X,Y,7)
      LET X0=X
      LET Y0=Y
   END IF
   LET N=N-1
   LET R=R+45
   LET L=L/SQR(2)
LOOP WHILE SP>0
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"
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
CLEAR
END SUB

EXTERNAL SUB LINE(XS,YS,XE,YE,C)
SET COLOR C
PLOT LINES
PLOT LINES:XS,YS;XE,YE
END SUB
 

Re: C曲線、ドラゴン曲線と2進法

 投稿者:山中和義  投稿日:2014年10月24日(金)10時22分27秒
  > No.3536[元記事へ]

作図の処理を簡素化するため、複素平面で考えます。

C曲線

!C曲線と2進法
OPTION ARITHMETIC COMPLEX !複素平面
LET N=7 !n次
SET WINDOW -10,15,-20,5
!!DRAW grid
LET Z=0 !開始位置を原点とする
PLOT LINES: Z;
FOR i=0 TO 2^N-1
   LET T=i
   LET S=0 !1の個数
   DO WHILE T>0
      LET S=S+MOD(T,2)
      LET T=INT(T/2)
   LOOP
   PRINT i; S; BSTR$(i,2)
   LET Z=Z+EXP(COMPLEX(0,1)*2*PI*S/4) !各方向へ移動する
   PLOT LINES: Z;
NEXT i
END



ドラゴン曲線

!ドラゴン曲線と2進法
OPTION ARITHMETIC COMPLEX !複素平面
LET N=8 !n次
SET WINDOW -10,20,-15,15
!!DRAW grid
LET Z=0 !開始位置を原点とする
PLOT LINES: Z;
FOR i=0 TO 2^N-1
   LET T=i
   LET S=0 !桁数
   LET W0=-1 !1つ前の数字
   DO WHILE T>0
      LET W=MOD(T,2)
      IF W<>W0 THEN !ただし、同じ数字が連続する場合、まとめて1桁と数える
         LET S=S+1
         LET W0=W
      END IF
      LET T=INT(T/2)
   LOOP
   PRINT i; S; BSTR$(i,2)
   LET Z=Z+EXP(COMPLEX(0,1)*2*PI*S/4) !各方向へ移動する
   PLOT LINES: Z;
NEXT i
END


その2

!ドラゴン曲線と2進法
OPTION ARITHMETIC COMPLEX !複素平面
LET N=8 !n次
SET WINDOW -10,20,-15,15
!!DRAW grid
LET Z=0 !開始位置を原点とする
PLOT LINES: Z;
FOR i=0 TO 2^N-1
   LET T=i
   IF T>0 THEN
      DO WHILE MOD(T,2)=0 !2で割り切れる間は割っていく
         LET T=T/2
      LOOP
      IF MOD(T,4)=1 THEN LET S=S+1 ELSE LET S=S-1
   ELSE
      LET S=0 !桁数 ※0から連続処理する場合
   END IF
   PRINT i; S; BSTR$(i,2)
   LET Z=Z+EXP(COMPLEX(0,1)*2*PI*S/4) !各方向へ移動する
   PLOT LINES: Z;
NEXT i
END


その3 k番目の折り目に着目する

!ドラゴン曲線と2進法
OPTION ARITHMETIC COMPLEX !複素平面
LET N=8 !n次
SET WINDOW -10,20,-15,15
!!DRAW grid
LET Z=0 !開始位置を原点とする
PLOT LINES: Z;
LET S=0
FOR K=1 TO 2^N
   LET Z=Z+EXP(COMPLEX(0,1)*2*PI*S/4) !各方向へ移動する
   PLOT LINES: Z;
   LET P=BITAND(K,-K) !k番目の折り目 1:山折り、0:谷折り
   LET T=BITAND(P,BITNOT(INT(K/2)))/P !※32bit整数の範囲
   IF T=1 THEN LET S=S+1 ELSE LET S=S-1
   PRINT K; T; S; BSTR$(K,2)
NEXT K
END


 

タペストリーのグラフ

 投稿者:SECOND  投稿日:2014年10月24日(金)21時25分6秒
  !山中さん紹介の、参考サイト http://sorauta.bufsiz.jp/Fractal/cdragon.html から、

!タペストリーのグラフ

SET WINDOW -1.5, 1.5, -1.5, 1.5
DIM A(4,4),B(4,4)
!
LET n=8
!------------------------
! /'\. C曲線 左回りのタペストリー
! ──・
SET VIEWPORT 0, .5, .5, 1
MAT A=SCALE(1/SQR(2))*ROTATE( PI/4)               !L
MAT B=SCALE(1/SQR(2))*ROTATE(-PI/4)*SHIFT(.5,.5)  !L C曲線
CALL tapestry

!------------------------
! ──・ C曲線 右回りのタペストリー
! \./'
SET VIEWPORT .5, 1, .5, 1
MAT A=SCALE(1/SQR(2))*ROTATE(-PI/4)                !R
MAT B=SCALE(1/SQR(2))*ROTATE( PI/4)*SHIFT(.5,-.5)  !R C曲線
CALL tapestry

!------------------------
! /''\ ドラゴン曲線 左回りのタペストリー
! ──・
SET VIEWPORT 0, .5, 0, .5
MAT A=SCALE(1/SQR(2))*ROTATE( PI/4)               !L
MAT B=SCALE(1/SQR(2))*ROTATE( PI/4*3)*SHIFT(1,0)  !L ドラゴン
CALL tapestry
!
!------------------------
! ──・ ドラゴン曲線 右回りのタペストリー
! \../
SET VIEWPORT .5, 1, 0, .5
MAT A=SCALE(1/SQR(2))*ROTATE(-PI/4)               !R
MAT B=SCALE(1/SQR(2))*ROTATE(-PI/4*3)*SHIFT(1,0)  !R ドラゴン
CALL tapestry

!------------------------
SUB tapestry
   FOR agl=0 TO 1.51*PI STEP 0.5*PI
      DRAW test(n) WITH SHIFT(-0.5, 0.5)*ROTATE(agl)
   NEXT agl
END SUB

PICTURE test(k)
   IF 0< k THEN
      DRAW test(k-1) WITH A
      DRAW test(k-1) WITH B
   ELSE
      PLOT LINES: 0,0;1,0
   END IF
END PICTURE

END
 

Re: β,γをαを用いて表せ。

 投稿者:山中和義  投稿日:2014年10月26日(日)14時44分22秒
  > No.3149[元記事へ]

> 3次方程式 x^3+3x^2-1=0 の1つの解をαとする。
> (1) (2α^2+5α-1)^2 を aα^2+bα+c の形で表わせ。ただし、a,b,cは有理数とする。
> (2) 上の3次方程式のα以外の2つの解を(1)と同じ形の式で表わせ。


問題
f(x)=x^3+3x^2-1=0の1つの解をαとすると、他の2つの解は、α^2+2α-2, -α^2-3α-1となることを示せ。

類題
f(x)=x^3+3x^2-1=0の1つの解をαとする。
g(α)=α^2+2α-2とすると、他の2つの解は、g(α), g(g(α)) となることを示せ。
また、g(α)=-α^2-3α-1としても同様であることを示せ。


答え
f(α)=α^3+3α^2-1=0 に注意して、f(α^2+2α-2)≡0、f(-α^2-3α-1)≡0 を確認すればよい。
(終わり)


答え
x=X-1 とおくと、f(x)=f(X-1)=(X-1)^3+3(X-1)^2-1=X^3-3X+1=0 となる。

DKA法などで、3つの解を数値計算で求めると、

!DKA(Durand-Kerner-Aberth)法によるn次代数方程式f(x)=0の解法

OPTION ARITHMETIC COMPLEX !複素数を扱う

LET cEps=1E-10 !精度  ※調整が必要である

LET N=3 !n次
DIM a(0 TO N) !係数 a[n]*x^n+a[n-1]*x^(n-1)+ … + a[1]*x+a[0]
DATA 1,-3,0,1 !1-3x+x^3
MAT READ a


LET w0=a(N) !x^n+a[n-1]/a[n]*x^(n-1)+ … + a[1]/a[n]*x+a[0]/a[n]の形へ
FOR i=0 TO N
   LET a(i)=a(i)/w0
NEXT i

DIM x(N) !n個の根
LET r=1 !初期値を仮定する
FOR i=1 TO N
   LET r0=ABS(N*a(i))^(1/i)
   IF r<r0 THEN LET r=r0
NEXT i
FOR i=1 TO N !半径rの円に等間隔に配置する
   LET x(i)=-a(N-1)/N+r*EXP(2*PI/N*(i-3/4)*COMPLEX(0,1)) !アーバスの初期値
NEXT i

DO
   LET e=0

   FOR i=1 TO N
      LET f=1 ! !分子  f(zi)  ※a(n)=1
      FOR j=N-1 TO 0 STEP -1 !ホーナー法  f(z)=( … ((z+a[n-1])*z+a[n-2])*z+a[n-3])* … +a[1])*z+a[0]
         LET f=f*x(i)+a(j)
      NEXT j

      LET p=1 !分母  Π[j=1,N,i≠j](zi-zj)
      FOR j=1 TO N
         IF j<>i THEN LET p=p*(x(i)-x(j)) !p*(zi-zj)
      NEXT j

      IF ABS(p)=0 THEN !分子÷分母
         PRINT "0では割れません。"
         STOP
      END IF
      LET t=f/p
      LET norm=ABS(t)
      IF e<norm THEN LET e=norm !最大値

      LET x(i)=x(i)-t !k回目の近似根  zi[k+1]=zi[k]-f(zi[k])/Π[j=1,N,i≠j](zi[k]-zj[k])
   NEXT i

LOOP UNTIL e<cEps !収束するまで

FOR i=1 TO N
   PRINT "x";STR$(i);" = ";x(i)
NEXT i

END


実行結果

x1 = ( 1.53208888623796  3.67341984631965E-40)
x2 = (-1.87938524157182 -2.02261168410892E-50)
x3 = ( .347296355333861 -1.71056941445901E-49)

となる。


解析的には、
実数解 2cos40°, 2cos80°, 2cos160°である。
実数解 2cos(2π/9), 2cos(4π/9), 2cos(8π/9)


PRINT 2*COS(RAD(40)); 2*COS(RAD(80)); 2*COS(RAD(160)) !3つの実数解
LET a=2*COS(RAD(40)) !その1つ
PRINT a; a^2-2; -a^2-a+2 !β,γはαで表される
PRINT -(a+(a^2-2)+(-a^2-a+2)) !解と係数の関係より、-(α+β+γ)
PRINT a*(a^2-2)+(a^2-2)*(-a^2-a+2)+(-a^2-a+2)*a !αβ+βγ+γα
PRINT -a*(a^2-2)*(-a^2-a+2) !-αβγ
DEF f(x)=x^3-3*x+1
PRINT f(a); f(a^2-2); f(-a^2-a+2) !解となる
END



3つの解がわかっている場合、巡回関数g(α)は連立方程式を解けばよい。


LET N=3
DIM x(0 TO N-1) !n個の解
LET x(0)=2*COS(2*PI/9) !α[0]
LET x(1)=2*COS(4*PI/9) !α[1]
LET x(2)=2*COS(8*PI/9) !α[2]
DIM A(N,N),b(N)
FOR i=0 TO N-1 !解の巡回 g(α)=A+Bα+ … +Cα^(n-1)
   FOR J=0 TO N-1 !g(α[0])、g(α[1])、…
      LET A(i+1,J+1)=x(i)^J
   NEXT J
   LET b(i+1)=x(MOD(i+1,N)) !g(α[0])=α[1]、g(α[1])=α[2]、…
NEXT i
DIM y(N),iA(N,N) !連立方程式Ay=bを解く
MAT iA=INV(A)
MAT y=iA*b
MAT PRINT y; !A,B,…,C
END


実行結果

-2 -8.78203759713259E-17  1   ← β^2-2


これより、
X^3-3X+1=0の1つの解をβとすると、他の2つの解は、β^2-2, -β^2-β+2となる。



この結果を利用して、

α[i]=β[i]-1(i=1,2,3)より、
α[1]=β[1]-1=β-1=(α+1)-1=α
α[2]=β[2]-1=(β^2-2)-1={(α+1)^2-2}-1=α^2+2α-2
α[3]=β[3]-1=(-β^2-β+2)-1={-(α+1)^2-(α+1)+2}-1=-α^2-3α-1
(終わり)



X^3-3X+1=0の解析的な解
・その1
x=2cosΘとおくと、2{(4cosΘ)^3-3cosΘ}=-1 ∴cos3Θ=-1/2
これより、x=2cos40°, 2cos80°, 2cos160°

α^2-2について
2倍角の公式より、(2cos40°)^2-2=2{2(cos40°)^2-1}=2cos80°


・その2
zを複素数として、x=z+1/z とおくと、z^6+z^3+1=0
Z=z^3 とおいて、Z^2+Z+1=0 ∴Z=(-1±(√3)i)/2=ω, ω^2


OPTION ARITHMETIC COMPLEX
DEF pow(x,y)=EXP(y*LOG(x)) !x^y
LET w=(-1+SQR(-3))/2 !ω
LET z=pow(w,1/3) !z^3=Z
PRINT z+1/z; z^2+1/z^2; z^4+1/z^4
PRINT 2*COS(2*PI/9); 2*COS(4*PI/9); 2*COS(8*PI/9)
END


 

3次方程式を解く

 投稿者:山中和義  投稿日:2014年11月 1日(土)09時55分4秒
  3次方程式を解く - ラグランジュのリゾルベントと補助方程式(リゾルベントを解に持つ2次方程式)


2次方程式 x^2+ax+b=0 のとき、2つの解をα,βとすると、
L=(α-β)^2=(α+β)^2-4αβ=a^2-4b より、
連立方程式(行列による表現)
┌ 1  1 ┐┌ α ┐=┌ -a         ┐
└ 1 -1 ┘└ β ┘ └ √(a^2-4b) ┘
を解けばよい。
これより、解の公式を得る。
補足
リゾルベントと解の関係
 (α+β)+(α-β) = 2α
 (α+β)-(α-β) = 2β
または
α,β=((α+β)±(α-β))/2=((α+β)±√{(α-β)^2})/2=((α+β)±√{(α+β)^2-4αβ})/2=(-a±√{a^2-4b})/2


3次方程式 x^3+ax^2+bx+c=0 のとき、3つの解をα,β,γとすると、
L1
=(α+ωβ+ω^2γ)^3
=α^3+β^3+γ^3+6αβγ + 3ω(α^2β+β^2γ+γ^2α) + 3ω^2(αβ^2+βγ^2+γα^2)

L2
=(α+ω^2β+ωγ)^3
=α^3+β^3+γ^3+6αβγ + 3ω(αβ^2+βγ^2+γα^2) + 3ω^2(α^2β+β^2γ+γ^2α)
より、

L1+L2
=2(α+β+γ)^3 - 9(α+β+γ)(αβ+βγ+γα) + 27αβγ
=-2a^3+9ab-27c

L1L2
=((α+β+γ)^2 - 3(αβ+βγ+γα))^3
=(a^2-3b)^3

以上より、補助方程式 t^2 - (L1+L2)t + L1L2 = 0 ∴t^2 + (2a^3-9ab+27c)t + (a^2-3b)^3 = 0
この2次方程式の2つの解をt1,t2とすると、
連立方程式(行列による表現)
┌ 1  1     1    ┐┌ α ┐=┌ -a       ┐
│ 1  ω    ω^2 ││ β │ │ t1^(1/3) │
└ 1  ω^2  ω   ┘└ γ ┘ └ t2^(1/3) ┘
を解けばよい。
補足
リゾルベントと解の関係
 (α+β+γ)+    (α+ωβ+ω^2γ)+    (α+ω^2β+ωγ) = 3α
 (α+β+γ)+ω^2(α+ωβ+ω^2γ)+  ω(α+ω^2β+ωγ) = 3β
 (α+β+γ)+  ω(α+ωβ+ω^2γ)+ω^2(α+ω^2β+ωγ) = 3γ



OPTION ARITHMETIC COMPLEX !複素数

LET A=3 !x^3+Ax^2+Bx+C=0
LET B=0
LET C=-1

CALL Solve3EQU(A,B,C, x1,x2,x3)
PRINT x1 !解を表示する
PRINT x2
PRINT x3

DEF f(x)=x^3+A*x^2+B*x+C !検算
PRINT f(x1); f(x2); f(x3)


LET A=-8 !x^4+Ax^3+Bx^2+Cx+D
LET B=26
LET C=-44
LET D=40
CALL Solve4EQU(A,B,C,D, x1,x2,x3,x4)
PRINT x1
PRINT x2
PRINT x3
PRINT x4

DEF g(x)=x^4+A*x^3+B*x^2+C*x+D
PRINT g(x1); g(x2); g(x3); g(x4)

END


EXTERNAL FUNCTION pow(x,y) !べき乗 x^y
OPTION ARITHMETIC COMPLEX !複素数
LET pow=EXP(y*LOG(x)) !x^y
END FUNCTION


EXTERNAL SUB Solve2EQU(A,B, x1,x2) !2次方程式 x^2+Ax+B=0を解く
OPTION ARITHMETIC COMPLEX !複素数
LET L1=-A !α+β
LET L2=SQR(A^2-4*B) !α-β
LET x1=(L1+L2)/2
LET x2=(L1-L2)/2
END SUB


EXTERNAL SUB Solve3EQU(A,B,C, x1,x2,x3) !3次方程式 x^3+Ax^2+Bx+C=0を解く
OPTION ARITHMETIC COMPLEX !複素数
LET w=EXP(COMPLEX(0,1)*2*PI/3) !w ※1の原始3乗根
CALL Solve2EQU(2*A^3-9*A*B+27*C,(A^2-3*B)^3, t1,t2) !t^2+Pt+Q=0の2つの解
LET L1=-A !α+β+γ
LET L2=pow(t1,1/3) !α+ωβ+ω^2γ
LET L3=pow(t2,1/3) !α+ω^2β+ωγ
LET x1=(L1+    L2+    L3)/3
LET x2=(L1+w^2*L2+  w*L3)/3
LET x3=(L1+  w*L2+w^2*L3)/3
END SUB


EXTERNAL SUB Solve4EQU(A,B,C,D, x1,x2,x3,x4) !4次方程式 x^4+Ax^3+Bx^2+Cx+D=0を解く
OPTION ARITHMETIC COMPLEX !複素数
CALL Solve3EQU(-(3*A^2-8*B),3*A^4-16*A^2*B+16*B^2+16*A*C-64*D,-(A^3-4*A*B+8*C)^2, t1,t2,t3) !t^3+Pt^2+Qt+R=0の3つの解
LET L1=-A !α+β+γ+δ
FOR S1=-1 TO 1 STEP 2 !±を確定させる
   LET L2=S1*SQR(t1) !α+β-γ-δ
   FOR S2=-1 TO 1 STEP 2
      LET L3=S2*SQR(t2) !α-β+γ-δ
      FOR S3=-1 TO 1 STEP 2
         LET L4=S3*SQR(t3) !α-β-γ+δ

         LET x1=(L1+L2+L3+L4)/4
         LET x2=(L1+L2-L3-L4)/4
         LET x3=(L1-L2+L3-L4)/4
         LET x4=(L1-L2-L3+L4)/4
         IF ABS((((x1+A)*x1+B)*x1+C)*x1+D)<1E-13 THEN EXIT SUB !※調整が必要である
      NEXT S3
   NEXT S2
NEXT S1
PRINT "論理エラーです。"
STOP
END SUB



!--------------------------------------

EXTERNAL SUB Solve3EQU2(A,B,C, x1,x2,x3) !3次方程式 x^3+Ax^2+Bx+C=0を解く
OPTION ARITHMETIC COMPLEX !複素数
LET w=EXP(COMPLEX(0,1)*2*PI/3) !w ※1の原始3乗根

DIM M(3,3),x(3),n(3) !連立方程式 Mx=n
LET M(1,1)=1 !α+β+γ
LET M(1,2)=1
LET M(1,3)=1
LET M(2,1)=1 !α+ωβ+ω^2γ
LET M(2,2)=w
LET M(2,3)=w^2
LET M(3,1)=1 !α+ω^2β+ωγ
LET M(3,2)=w^2
LET M(3,3)=w

CALL Solve2EQU(2*A^3-9*A*B+27*C,(A^2-3*B)^3, t1,t2) !t^2+Pt+Q=0の2つの解
LET n(1)=-A
LET n(2)=pow(t1,1/3) !3乗根
LET n(3)=pow(t2,1/3)

DIM iM(3,3) !連立方程式を解く
MAT iM=INV(M)
MAT x=iM*n

LET x1=x(1)
LET x2=x(2)
LET x3=x(3)
END SUB


EXTERNAL SUB Solve4EQU2(A,B,C,D, x1,x2,x3,x4) !4次方程式 x^4+Ax^3+Bx^2+Cx+D=0を解く
OPTION ARITHMETIC COMPLEX !複素数

DIM M(4,4),x(4),n(4) !連立方程式 Mx=n
DATA 1, 1, 1, 1 !α+β+γ+δ
DATA 1, 1,-1,-1 !α+β-γ-δ
DATA 1,-1, 1,-1 !α-β+γ-δ
DATA 1,-1,-1, 1 !α-β-γ+δ
MAT READ M

CALL Solve3EQU2(-(3*A^2-8*B),3*A^4-16*A^2*B+16*B^2+16*A*C-64*D,-(A^3-4*A*B+8*C)^2, t1,t2,t3) !t^3+Pt^2+Qt+R=0の3つの解
LET n(1)=-A
FOR S1=-1 TO 1 STEP 2 !±を確定させる
   LET n(2)=S1*SQR(t1) !α+β-γ-δ
   FOR S2=-1 TO 1 STEP 2
      LET n(3)=S2*SQR(t2) !α-β+γ-δ
      FOR S3=-1 TO 1 STEP 2
         LET n(4)=S3*SQR(t3) !α-β-γ+δ

         DIM iM(4,4) !連立方程式を解く
         MAT iM=INV(M)
         MAT x=iM*n

         LET x1=x(1)
         LET x2=x(2)
         LET x3=x(3)
         LET x4=x(4)

         IF ABS((((x1+A)*x1+B)*x1+C)*x1+D)<1E-13 THEN EXIT SUB !※調整が必要である
      NEXT S3
   NEXT S2
NEXT S1
PRINT "論理エラーです。"
STOP
END SUB


 

Re: C曲線、ドラゴン曲線と2進法

 投稿者:SECOND  投稿日:2014年11月 1日(土)17時40分0秒
  > No.3538[元記事へ]

!2進数による、コッホの曲線

OPTION ARITHMETIC COMPLEX
SET WINDOW -.05, 1.05, -.15, .4
FOR n=0 TO 10
   CLEAR
   !----------------------
   ! 2進数 描画(上)
   !----------------------
   SET VIEWPORT 0,1, 1/2,1
   DRAW grid(.1,.1)
   LET Rn=1/SQR(3)^n                              !n次の縮小率
   LET rot0= EXP(COMPLEX(0, PI/6*MOD(n,2)))       !奇偶n次の、始点角 単位ベクトル
   LET rot=  EXP(COMPLEX(0, PI/3*(1-2*MOD(n,2)))) ! 〃  ステップ角 単位ベクトル
   !---
   LET s=rot0                !始点角
   LET z=s
   PLOT LINES: 0; z*Rn;      !始点0~z(i=0)
   FOR i=1 TO 2^n-1
      IF MOD( LOG(bitAND(i,-i))/LOG(2), 2)=0 THEN LET s=s*rot ELSE LET s=s/rot^2
      LET z=z+s
      PLOT LINES: z*Rn;      !z*(縮小率)
   NEXT i
   !----------------------
   ! 比較の 再帰描画(下)
   !----------------------
   SET VIEWPORT 0,1, 0,1/2
   DRAW grid(.1,.1)
   PLOT label,AT.03,.3:"比較の再帰 次数 "& STR$(n)
   DRAW koch(n)
   pause 1
NEXT n

PICTURE koch(k)
   IF 0< k THEN
      DRAW koch(k-1) WITH SCALE(1,-1)*ROTATE(PI/6)*SCALE(1/SQR(3))
      DRAW koch(k-1) WITH SHIFT(-1)*ROTATE(PI/6)*SCALE(1,-1)*SCALE(1/SQR(3))*SHIFT(1)
   ELSE
      PLOT LINES: 0;1
   END IF
END PICTURE

END
!------------------------------------------------------------------------
! o1o11ooo = (i)
! 1o1o1ooo = (-i)        ・・・(NOT i)+1 と同。
! oooo1ooo = bitAND(i,-i)  ・・・(i) の右端から数え、最初の「1」だけ残る。
! log( bitAND(i,-i))/log(2)  ・・・「1」の右側の"0"の個数
!
! コッホの曲線      「1」の右側の"0"の個数 が、奇数か偶数かで、
!                    ステップ差角を選ぶ。
!------------------------------------------------------------------------
 

迷路

 投稿者:しばっち  投稿日:2014年11月 6日(木)19時37分23秒
  ただの迷路ゲームです。
スタート地点「座標(1,1)左上」から、ゴール地点「座標(79,79)右下」を目指します。
表示画面の緑のボタンをマウスで左クリックします。
MAP表示 3回まで(緑の点が現在位置)
現在位置 2回まで表示。
「前」ボタン左クリックで"上"に進みます。

PUBLIC NUMERIC XSIZE,YSIZE,XS(4),YS(4),LOC,HELP,LT,FL,XX,YY,R,RR,TI,TY,MX,MY
PUBLIC STRING Z$(4)
LET XSIZE=700
LET YSIZE=700
CALL GINIT(XSIZE,YSIZE)
LET M=40 !'迷路サイズ 2*M*2*N
LET N=40
LET HELP=3 !'MAP表示回数
LET LOC=2 !'現在位置表示回数
DIM MAP(0 TO 2*M,0 TO 2*N)
FOR I=1 TO 4
   READ XS(I),YS(I),Z$(I)
NEXT I
DATA 0,-1,上
DATA -1,0,左
DATA 0,1,下
DATA 1,0,右
CALL MAKEMAZE(MAP,M,N)
IF MAP(1,1)<>0 OR MAP(2*M-1,2*N-1)<>0 THEN STOP !'エラー
LET TY=INT(TIME)
DO
LOOP WHILE TY=INT(TIME)
LET TY=INT(TIME)
LET XX=1
LET YY=1
LET R=1
DO
   LET I0=-3
   LET I1=3
   LET J0=-3
   LET J1=3
   LET Y=50
   SELECT CASE R !'画面表示
   CASE 1,3
      IF R=3 THEN
         SWAP I0,I1
         SWAP J0,J1
      END IF
      FOR I=I0 TO I1 STEP SGN(I1-I0)
         LET X=XSIZE/2-175
         FOR J=J0 TO J1 STEP SGN(J1-J0)
            IF XX+J>=0 AND YY+I>=0 AND XX+J<=2*M AND YY+I<=2*N THEN
               LET C=MAP(XX+J,YY+I)
               IF C=2 THEN LET C=0
               CALL BOXFULL(X,Y,X+50,Y+50,C)
               IF XX+J=2*M-1 AND YY+I=2*N-1 THEN
                  SET TEXT HEIGHT 50
                  SET TEXT COLOR 6
                  SET TEXT JUSTIFY "LEFT","TOP"
                  PLOT TEXT,AT X,Y:"G" !'ゴール目印
               END IF
            ELSE
               CALL BOXFULL(X,Y,X+50,Y+50,7)
            END IF
            LET X=X+50
         NEXT J
         LET Y=Y+50
      NEXT I
   CASE 2,4
      IF R=2 THEN
         SWAP J0,J1
      ELSE
         SWAP I0,I1
      END IF
      FOR I=I0 TO I1 STEP SGN(I1-I0)
         LET X=XSIZE/2-175
         FOR J=J0 TO J1 STEP SGN(J1-J0)
            IF XX+I>=0 AND YY+J>=0 AND XX+I<=2*N AND YY+J<=2*M THEN
               LET C=MAP(XX+I,YY+J)
               IF C=2 THEN LET C=0
               CALL BOXFULL(X,Y,X+50,Y+50,C)
               IF XX+I=2*M-1 AND YY+J=2*N-1 THEN
                  SET TEXT HEIGHT 50
                  SET TEXT COLOR 6
                  SET TEXT JUSTIFY "LEFT","TOP"
                  PLOT TEXT,AT X,Y:"G"
               END IF
            ELSE
               CALL BOXFULL(X,Y,X+50,Y+50,7)
            END IF
            LET X=X+50
         NEXT J
         LET Y=Y+50
      NEXT I
   END SELECT
   CALL BOX(XSIZE/2-175,50,XSIZE/2+175,400,2)
   CALL PUTCHARACTER(XSIZE/2-25,200,1.5)
   CALL DISPLOC
   IF LOC=0 AND FM=0 THEN
      CALL BOXFULL(0,YSIZE-150,150,YSIZE,0)
      LET FM=1
   END IF
   CALL DISPTIME
   IF XX=2*M-1 AND YY=2*N-1 THEN !'ゴール到達
      SET TEXT HEIGHT 70
      SET TEXT COLOR 6
      SET TEXT JUSTIFY "LEFT","TOP"
      PLOT TEXT ,AT 20,50:"Congratulations"
      STOP
   END IF
   IF HELP<>HH OR LOC<>LL THEN
      CALL BOXFULL(0,250,160,350,0)
      SET TEXT JUSTIFY "LEFT","TOP"
      SET TEXT HEIGHT 20
      PLOT TEXT ,AT 0,250:"MAP  残 "&STR$(HELP)
      PLOT TEXT ,AT 0,280:"位置 残 "&STR$(LOC)
      LET HH=HELP
      LET LL=LOC
   END IF
   LET S$=GETKEY$(XSIZE/2,YSIZE-150,100)
   IF S$<>"" THEN WAIT DELAY .1
   IF S$="4" THEN LET R=R+1
   IF S$="6" THEN LET R=R-1
   IF S$="2" THEN LET R=R+2
   IF R>4 THEN LET R=R-4
   IF R<1 THEN LET R=R+4
   IF S$="8" AND MAP(XX+XS(R),YY+YS(R))<>7 THEN
      LET XX=XX+XS(R)
      LET YY=YY+YS(R)
   END IF
   IF S$="M" AND HELP>0 THEN !'MAP表示
      CALL DISPLAYMAP(MAP,M,N,XX,YY)
      LET TT=INT(TIME)
      DO
      LOOP WHILE TT=INT(TIME)
      LET TT=INT(TIME)
      DO
         MOUSE POLL DMX,DMY,LEFT,RIGHT
      LOOP UNTIL INT(TIME)-TT>=HELP*4 OR LEFT=1 OR RIGHT=1 !'クリックするか、時間待ち
      CLEAR
      LET HELP=HELP-1
   END IF
   IF S$="L" THEN
      LET LT=INT(TIME)
      LET FL=0
      LET LOC=LOC-1
   END IF
   IF XX<0 THEN LET XX=0
   IF YY<0 THEN LET YY=0
   IF XX>2*M THEN LET XX=2*M
   IF YY>2*N THEN LET YY=2*N
   LET MAP(XX,YY)=2 !'足跡を残す(赤色)
LOOP
END

EXTERNAL  SUB MAKEMAZE(MAP(,),M,N) !'迷路作成
RANDOMIZE
MAT MAP=ZER
LET S=(M-1)*(N-1)
FOR I=0 TO 2*M
   LET MAP(I,0)=7
   LET MAP(I,2*N)=7
NEXT I
FOR I=0 TO 2*N
   LET MAP(0,I)=7
   LET MAP(2*M,I)=7
NEXT I
DO
   DO
      LET X=INT(RND*(M+1))
      LET Y=INT(RND*(N+1))
      LET X0=X*2
      LET Y0=Y*2
   LOOP WHILE MAP(X0,Y0)=0
   LET R=INT(RND*4)+1
   LET XN=X0+XS(R)*2
   LET YN=Y0+YS(R)*2
   IF XN>0 AND XN<2*M AND YN>0 AND YN<2*N AND MAP(XN,YN)=0 THEN
      IF X0=XN THEN
         FOR K=Y0 TO YN STEP SGN(YN-Y0)
            LET MAP(X0,K)=7
         NEXT K
      ELSE
         FOR K=X0 TO XN STEP SGN(XN-X0)
            LET MAP(K,Y0)=7
         NEXT K
      END IF
      LET X0=XN
      LET Y0=YN
      LET S=S-1
   END IF
LOOP WHILE S>0
END SUB

EXTERNAL  SUB DISPLAYMAP(MAP(,),M,N,XX,YY) !'地図表示
CLEAR
FOR I=0 TO 2*N
   FOR J=0 TO 2*M
      LET C=MAP(J,I)
      IF J=XX AND I=YY THEN LET C=4 !'現在の位置(緑)
      IF J=2*M-1 AND I=2*N-1 THEN LET C=6 !'ゴール(黄)
      CALL BOXFULL(J*XSIZE/(2*M+1),I*YSIZE/(2*N+1),(J+1)*XSIZE/(2*M+1),(I+1)*YSIZE/(2*N+1),C)
   NEXT J
NEXT I
END SUB

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"
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
SET COLOR MIX(242) 112/255,40/255,24/255
SET COLOR MIX(243) 8/255,40/255,56/255
SET COLOR MIX(244) 248/255,112/255,64/255
SET COLOR MIX(245) 40/255,88/255,248/255
SET COLOR MIX(246) 192/255,56/255,32/255
SET COLOR MIX(247) 248/255,248/255,248/255
SET COLOR MIX(248) 0/255,48/255,168/255
SET COLOR MIX(249) 192/255,104/255,80/255
SET COLOR MIX(250) 88/255,56/255,24/255
SET COLOR MIX(251) 248/255,200/255,184/255
SET COLOR MIX(252) 192/255,128/255,40/255
SET COLOR MIX(253) 144/255,144/255,160/255
SET COLOR MIX(254) 80/255,48/255,24/255
SET COLOR MIX(255) 248/255,208/255,88/255
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

EXTERNAL SUB BOX(XS,YS,XE,YE,C)
CALL LINE(XS,YS,XE,YS,C)
CALL LINE(XE,YS,XE,YE,C)
CALL LINE(XE,YE,XS,YE,C)
CALL LINE(XS,YE,XS,YS,C)
END SUB

EXTERNAL SUB LINE(XS,YS,XE,YE,C)
SET LINE COLOR C
PLOT LINES
PLOT LINES:XS,YS;XE,YE
END SUB

EXTERNAL FUNCTION AREA3(X1,Y1,X2,Y2,X3,Y3,PX,PY) !'PX,PYが三角形内か
LET T=TRIANGLE(X1,Y1,X2,Y2,X3,Y3)
LET A=TRIANGLE(X1,Y1,X2,Y2,PX,PY)
LET B=TRIANGLE(X2,Y2,X3,Y3,PX,PY)
LET C=TRIANGLE(X1,Y1,X3,Y3,PX,PY)
IF A+B+C=T THEN LET AREA3=-1 ELSE LET AREA3=0
END FUNCTION

EXTERNAL FUNCTION AREA4(X1,Y1,X2,Y2,X3,Y3,X4,Y4,PX,PY)
LET A=AREA3(X1,Y1,X2,Y2,X3,Y3,PX,PY)
IF A<>0 THEN
   LET AREA4=-1
   EXIT FUNCTION
END IF
LET B=AREA3(X1,Y1,X4,Y4,X3,Y3,PX,PY)
IF B<>0 THEN LET AREA4=-1 ELSE LET AREA4=0
END FUNCTION

EXTERNAL FUNCTION TRIANGLE(X1,Y1,X2,Y2,X3,Y3) !'三角形の面積
LET TRIANGLE=ABS(X1*Y2+X2*Y3+X3*Y1-X2*Y1-X3*Y2-Y3*X1)/2
END FUNCTION

EXTERNAL  FUNCTION GETKEY$(X,Y,SIZE) !'マウス入力
SET AREA COLOR 4
SET TEXT COLOR 7
PLOT AREA:X,Y-SIZE;X-SIZE,Y;X,Y+SIZE;X+SIZE,Y
IF HELP>0 THEN PLOT AREA:XSIZE-150,YSIZE-150;XSIZE,YSIZE-150;XSIZE,YSIZE;XSIZE-150,YSIZE
IF LOC>0 THEN PLOT AREA:0,YSIZE-150;150,YSIZE-150;150,YSIZE;0,YSIZE
CALL LINE(X-SIZE/2,Y-SIZE/2,X+SIZE/2,Y+SIZE/2,7)
CALL LINE(X+SIZE/2,Y-SIZE/2,X-SIZE/2,Y+SIZE/2,7)
SET TEXT JUSTIFY "CENTER","HALF"
SET TEXT HEIGHT SIZE/3
LET X1=X-SIZE/2
LET Y1=Y-SIZE/2
LET X2=X1
LET Y2=Y+SIZE/2
LET X3=X+SIZE/2
LET Y3=Y2
LET X4=X3
LET Y4=Y1
PLOT TEXT ,AT X,Y-SIZE/2: "前"
PLOT TEXT ,AT X-SIZE/2,Y: "左"
PLOT TEXT ,AT X+SIZE/2,Y: "右"
PLOT TEXT ,AT X,Y+SIZE/2: "後"
IF HELP>0 THEN PLOT TEXT ,AT XSIZE-75,YSIZE-75:"MAP"
IF LOC>0 THEN
   SET TEXT JUSTIFY "LEFT","HALF"
   SET TEXT HEIGHT SIZE/4
   PLOT TEXT ,AT 0,YSIZE-75:"現在位置"
END IF
SET AREA COLOR 2
SET TEXT JUSTIFY "CENTER","HALF"
LET GETKEY$=""
DO
   MOUSE POLL X0,Y0,LEFT,RIGHT
LOOP WHILE LEFT=1 OR RIGHT=1
DO
   CALL DISPTIME
   CALL DISPLOC
   MOUSE POLL X0,Y0,LEFT,RIGHT
LOOP UNTIL LEFT=1 OR RIGHT=1
IF AREA4(X,Y-SIZE,X1,Y1,X,Y,X4,Y4,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :X,Y-SIZE;X1,Y1;X,Y;X4,Y4
   PLOT TEXT ,AT X,Y-SIZE/2: "前"
   LET GETKEY$="8"
END IF
IF AREA4(X1,Y1,X-SIZE,Y,X2,Y2,X,Y,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :X1,Y1;X-SIZE,Y;X2,Y2;X,Y
   PLOT TEXT ,AT X-SIZE/2,Y: "左"
   LET GETKEY$="4"
END IF
IF AREA4(X,Y,X2,Y2,X,Y+SIZE,X3,Y3,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :X,Y;X2,Y2;X,Y+SIZE;X3,Y3
   PLOT TEXT ,AT X,Y+SIZE/2: "後"
   LET GETKEY$="2"
END IF
IF AREA4(X4,Y4,X,Y,X3,Y3,X+SIZE,Y,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :X4,Y4;X,Y;X3,Y3;X+SIZE,Y
   PLOT TEXT ,AT X+SIZE/2,Y: "右"
   LET GETKEY$="6"
END IF
IF HELP>0 AND AREA4(XSIZE-150,YSIZE-150,XSIZE,YSIZE-150,XSIZE,YSIZE,XSIZE-150,YSIZE,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :XSIZE-150,YSIZE-150;XSIZE,YSIZE-150;XSIZE,YSIZE;XSIZE-150,YSIZE
   PLOT TEXT ,AT XSIZE-75,YSIZE-75:"MAP"
   LET GETKEY$="M"
END IF
IF LOC>0 AND AREA4(0,YSIZE-150,150,YSIZE-150,150,YSIZE,0,YSIZE,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :0,YSIZE-150;150,YSIZE-150;150,YSIZE;0,YSIZE
   SET TEXT JUSTIFY "LEFT","HALF"
   PLOT TEXT ,AT 0,YSIZE-75:"現在位置"
   LET GETKEY$="L"
END IF
END FUNCTION

EXTERNAL  SUB DISPTIME !'時間表示
IF INT(TIME)<>TI THEN
   LET TI=INT(TIME)
   CALL BOXFULL(XSIZE-150,200,XSIZE,300,0)
   SET TEXT COLOR 7
   SET TEXT HEIGHT 20
   SET TEXT JUSTIFY "LEFT","TOP"
   PLOT TEXT ,AT XSIZE-150,200:"経過時間"
   PLOT TEXT ,AT XSIZE-100,240:STR$(INT(TIME-TY))&"s"
END IF
END SUB

EXTERNAL  SUB DISPLOC !'位置表示
IF INT(TIME)-LT<55 THEN LET C=7 ELSE LET C=2
IF LOC>0 AND INT(TIME)-LT<60 AND (MX<>XX OR MY<>YY OR R<>RR) THEN
   SET TEXT COLOR C
   SET TEXT HEIGHT 20
   SET TEXT JUSTIFY "LEFT","TOP"
   CALL BOXFULL(XSIZE-150,40,XSIZE,120,0)
   PLOT TEXT ,AT XSIZE-150,40:"現在位置"
   PLOT TEXT ,AT XSIZE-120,80:"("&STR$(XX)&","&STR$(YY)&")"
   CALL BOXFULL(0,0,140,140,0)
   CALL LINE(50,80,110,80,C)
   CALL LINE(80,50,80,110,C)
   SET TEXT JUSTIFY "CENTER","HALF"
   PLOT TEXT ,AT 40,80:Z$(MOD(R,4)+1)
   PLOT TEXT ,AT 120,80:Z$(MOD(R+2,4)+1)
   PLOT TEXT ,AT 80,40:Z$(R)
   PLOT TEXT ,AT 80,120:Z$(MOD(R+1,4)+1)
   LET MX=XX
   LET MY=YY
   LET RR=R
END IF
IF INT(TIME)-LT>60 AND FL=0 THEN
   CALL BOXFULL(XSIZE-150,0,XSIZE,120,0)
   CALL BOXFULL(0,0,140,140,0)
   LET FL=1
END IF
END SUB

EXTERNAL  SUB PUTCHARACTER(XX,YY,SIZE)
LET X=XX
LET Y=YY
DO
   READ IF MISSING THEN EXIT DO: A$
   FOR J=1 TO LEN(A$) STEP 2
      LET C=BVAL(A$(J:J+1),16)
      CALL BOXFULL(X,Y,X+SIZE,Y+SIZE,C)
      LET X=X+SIZE
   NEXT J
   LET X=XX
   LET Y=Y+SIZE
LOOP
DATA "0000F2F2000000000000F3F3F2F2F4F4F4F4F2F2F3F3000000000000F2F20000"
DATA "0000F2F2000000000000F3F3F2F2F4F4F4F4F2F2F3F3000000000000F2F20000"
DATA "F2F2F4F4F2F20000F3F3F5F5F5F5F4F4F4F4F5F5F5F5F3F30000F2F2F4F4F2F2"
DATA "F2F2F4F4F2F20000F3F3F5F5F5F5F4F4F4F4F5F5F5F5F3F30000F2F2F4F4F2F2"
DATA "F2F2F4F4F4F4F2F2F5F5F3F3F3F3F3F3F3F3F3F3F3F3F5F5F2F2F4F4F4F4F2F2"
DATA "F2F2F4F4F4F4F2F2F5F5F3F3F3F3F3F3F3F3F3F3F3F3F5F5F2F2F4F4F4F4F2F2"
DATA "F2F2F6F6F4F4F7F7F3F3F5F5F5F5F5F5F5F5F5F5F5F5F3F3F4F4F4F4F6F6F2F2"
DATA "F2F2F6F6F4F4F7F7F3F3F5F5F5F5F5F5F5F5F5F5F5F5F3F3F4F4F4F4F6F6F2F2"
DATA "0000F2F2F4F4F7F7F8F8F5F5F3F3F3F3F3F3F3F3F5F5F8F8F4F4F4F4F2F20000"
DATA "0000F2F2F4F4F7F7F8F8F5F5F3F3F3F3F3F3F3F3F5F5F8F8F4F4F4F4F2F20000"
DATA "0000F2F2F6F6F7F7F3F3F8F8F8F8F8F8F8F8F8F8F8F8F3F3F6F6F6F6F2F20000"
DATA "0000F2F2F6F6F7F7F3F3F8F8F8F8F8F8F8F8F8F8F8F8F3F3F6F6F6F6F2F20000"
DATA "00000000F2F2F7F7F8F8F9F9FAFAFBFBFBFBFAFAF9F9F8F8F2F2F2F200000000"
DATA "00000000F2F2F7F7F8F8F9F9FAFAFBFBFBFBFAFAF9F9F8F8F2F2F2F200000000"
DATA "000000000000F7F7F9F9FBFBFAFAF9F9F9F9FAFAF9F9F9F9F3F3000000000000"
DATA "000000000000F7F7F9F9FBFBFAFAF9F9F9F9FAFAF9F9F9F9F3F3000000000000"
DATA "000000000000F7F7F3F3FBFBFBFBFBFBFBFBFBFBF9F9F8F8F5F5FCFC00000000"
DATA "000000000000F7F7F3F3FBFBFBFBFBFBFBFBFBFBF9F9F8F8F5F5FCFC00000000"
DATA "00000000F2F2FDFDF8F8FEFEFBFBFBFBFBFBF9F9FEFEF5F5FFFFF8F8F2F20000"
DATA "00000000F2F2FDFDF8F8FEFEFBFBFBFBFBFBF9F9FEFEF5F5FFFFF8F8F2F20000"
DATA "0000F2F2FFFFFFFFFCFCF5F5FEFEFEFEFEFEFEFEFFFFFFFFF5F5F8F8F2F20000"
DATA "0000F2F2FFFFFFFFFCFCF5F5FEFEFEFEFEFEFEFEFFFFFFFFF5F5F8F8F2F20000"
DATA "0000F2F2FBFBF9F9F3F3F3F3F5F5F5F5F5F5F5F5FFFFF5F5F5F5F8F8F6F6F2F2"
DATA "0000F2F2FBFBF9F9F3F3F3F3F5F5F5F5F5F5F5F5FFFFF5F5F5F5F8F8F6F6F2F2"
DATA "F2F2F4F4FBFBF9F9F8F8F8F8F3F3F8F8F8F8F8F8FFFFF5F5F5F5FCFCF6F6F2F2"
DATA "F2F2F4F4FBFBF9F9F8F8F8F8F3F3F8F8F8F8F8F8FFFFF5F5F5F5FCFCF6F6F2F2"
DATA "F2F2F4F4F3F3F3F3F4F4F4F4F3F3F5F5F5F5F3F3F8F8FFFFFCFCF3F3F4F4F2F2"
DATA "F2F2F4F4F3F3F3F3F4F4F4F4F3F3F5F5F5F5F3F3F8F8FFFFFCFCF3F3F4F4F2F2"
DATA "F2F2F4F40000F3F3F5F5F8F8F8F8F3F3F3F3F4F4F4F4F6F6F3F30000F4F4F2F2"
DATA "F2F2F4F40000F3F3F5F5F8F8F8F8F3F3F3F3F4F4F4F4F6F6F3F30000F4F4F2F2"
DATA "0000F2F200000000F3F3F3F3F3F300000000F3F3F5F5F5F5F3F30000F2F20000"
DATA "0000F2F200000000F3F3F3F3F3F300000000F3F3F5F5F5F5F3F30000F2F20000"
END SUB
 

迷路

 投稿者:しばっち  投稿日:2014年11月 6日(木)19時38分58秒
  画面表示を変えてみました。
3マス先までを表示

PUBLIC NUMERIC XSIZE,YSIZE,XS(4),YS(4),LOC,HELP,LT,FL,XX,YY,TI,TY,MX,MY,LL
LET XSIZE=700
LET YSIZE=700
CALL GINIT(XSIZE,YSIZE)
LET M=40
LET N=40
LET HELP=3
LET LOC=2
LET XA=XSIZE/2-175
LET XB=XSIZE/2+175
LET YA=50
LET YB=400
DIM MAP(0 TO 2*M,0 TO 2*N)
FOR I=1 TO 4
   READ XS(I),YS(I)
NEXT I
DATA 0,-1
DATA -1,0
DATA 0,1
DATA 1,0
CALL MAKEMAZE(MAP,M,N)
IF MAP(1,1)<>0 OR MAP(2*M-1,2*N-1)<>0 THEN STOP
LET TY=INT(TIME)
DO
LOOP WHILE TY=INT(TIME)
LET TY=INT(TIME)
LET XX=1
LET YY=1
IF MAP(1,2)=0 THEN LET R=3
IF MAP(2,1)=0 THEN LET R=4
DO
   SET VIEWPORT XA/XSIZE,XB/XSIZE,(YSIZE-YB)/YSIZE,(YSIZE-YA)/YSIZE
   SET WINDOW 0,XSIZE-1,YSIZE-1,0
   CALL BOXFULL(0,0,XSIZE,YSIZE,0)
   CALL 壁
   FOR I=0 TO 3 !'MAPデータ走査,画面表示(3マス先まで)
      SELECT CASE R
      CASE 1
         IF YY-I-1>=0 THEN LET P0=MAP(XX,YY-1-I) ELSE LET P0=7
         IF XX-1>=0 AND YY-I>=0 THEN LET L0=MAP(XX-1,YY-I) ELSE LET L0=7
         IF XX+1<=2*M AND YY-I>=0 THEN LET R0=MAP(XX+1,YY-I) ELSE LET R0=7
      CASE 2
         IF XX-I-1>=0 THEN LET P0=MAP(XX-I-1,YY) ELSE LET P0=7
         IF YY+1<=2*N AND XX-I>=0 THEN LET L0=MAP(XX-I,YY+1) ELSE LET L0=7
         IF YY-1>=0 AND XX-I>=0 THEN  LET R0=MAP(XX-I,YY-1) ELSE LET R0=7
      CASE 3
         IF YY+I+1<=2*N THEN LET P0=MAP(XX,YY+I+1) ELSE LET P0=7
         IF XX+1<=2*M AND YY+I<=2*N THEN LET L0=MAP(XX+1,YY+I) ELSE LET L0=7
         IF XX-1>=0 AND YY+I<=2*N THEN LET R0=MAP(XX-1,YY+I) ELSE LET R0=7
      CASE 4
         IF XX+I+1<=2*M THEN LET P0=MAP(XX+I+1,YY) ELSE LET P0=7
         IF XX+I<=2*M AND YY-1>=0 THEN LET L0=MAP(XX+I,YY-1) ELSE LET L0=7
         IF XX+I<=2*M AND YY+1<=2*N THEN LET R0=MAP(XX+I,YY+1) ELSE LET R0=7
      END SELECT
      IF P0<>7 AND L0<>7 THEN CALL 左折路(I)
      IF P0<>7 AND R0<>7 THEN CALL 右折路(I)
      IF P0=7 AND L0<>7 AND R0<>7 THEN
         CALL T字路(I)
         EXIT FOR
      ELSEIF P0=7 AND L0<>7 AND R0=7 THEN
         CALL 左曲がり(I)
         EXIT FOR
      ELSEIF P0=7 AND R0<>7 AND L0=7 THEN
         CALL 右曲がり(I)
         EXIT FOR
      ELSEIF P0=7 AND L0=7 AND R0=7 THEN
         CALL 行き止まり(I)
         EXIT FOR
      END IF
   NEXT I
   CALL BOX(0,0,XSIZE,YSIZE,2)
   SET VIEWPORT 0,1,0,1
   SET WINDOW 0,XSIZE-1,YSIZE-1,0
   CALL DISPLOC
   IF LOC=0 AND FM=0 THEN
      CALL BOXFULL(0,YSIZE-150,150,YSIZE,0)
      LET FM=1
   END IF
   CALL DISPTIME
   IF XX=2*M-1 AND YY=2*N-1 THEN !'ゴール到達
      SET TEXT HEIGHT 70
      SET TEXT COLOR 6
      SET TEXT JUSTIFY "LEFT","TOP"
      PLOT TEXT ,AT 20,50:"Congratulations"
      STOP
   END IF
   CALL BOXFULL(0,250,160,350,0)
   SET TEXT JUSTIFY "LEFT","TOP"
   SET TEXT HEIGHT 20
   SET TEXT COLOR 7
   PLOT TEXT ,AT 0,250:"MAP  残 "&STR$(HELP)
   PLOT TEXT ,AT 0,280:"位置 残 "&STR$(LOC)
   LET S$=GETKEY$(XSIZE/2,YSIZE-150,100)
   IF S$<>"" THEN WAIT DELAY .1
   IF S$="4" THEN LET R=R+1
   IF S$="6" THEN LET R=R-1
   IF S$="2" THEN LET R=R+2
   IF R>4 THEN LET R=R-4
   IF R<1 THEN LET R=R+4
   IF S$="8" AND MAP(XX+XS(R),YY+YS(R))<>7 THEN
      LET XX=XX+XS(R)
      LET YY=YY+YS(R)
   END IF
   IF S$="M" AND HELP>0 THEN !'MAP表示
      CALL DISPLAYMAP(MAP,M,N,XX,YY)
      LET TT=INT(TIME)
      DO
      LOOP WHILE TT=INT(TIME)
      LET TT=INT(TIME)
      DO
         MOUSE POLL DMX,DMY,LEFT,RIGHT
      LOOP UNTIL INT(TIME)-TT>=HELP*4 OR LEFT=1 OR RIGHT=1 !'クリックするか、時間待ち
      CLEAR
      LET HELP=HELP-1
   END IF
   IF S$="L" THEN
      LET LT=INT(TIME)
      LET FL=0
      LET LOC=LOC-1
   END IF
   IF XX<0 THEN LET XX=0
   IF YY<0 THEN LET YY=0
   IF XX>2*M THEN LET XX=2*M
   IF YY>2*N THEN LET YY=2*N
   LET MAP(XX,YY)=2 !'足跡を残す(赤色)
LOOP
END

EXTERNAL  SUB 壁
LET XM=XSIZE/2
LET YM=YSIZE/2
PLOT LINES:0,0;XM-20,YM-20
PLOT LINES:0,YSIZE;XM-20,YM+20
PLOT LINES:XSIZE,0;XM+20,YM-20
PLOT LINES:XSIZE,YSIZE;XM+20,YM+20
PLOT LINES:XM-20,YM-20;XM-20,YM+20
PLOT LINES:XM+20,YM-20;XM+20,YM+20
END SUB

EXTERNAL  SUB 行き止まり(N)
IF N=0 THEN
   CALL BOXFULL(0,0,XSIZE,YSIZE,0)
   PLOT LINES:0,0;20,20
   PLOT LINES:XSIZE,0;XSIZE-20,20
   PLOT LINES:XSIZE,YSIZE;XSIZE-20,YSIZE-20
   PLOT LINES:0,YSIZE;20,YSIZE-20
   PLOT LINES:20,20;XSIZE-20,20;XSIZE-20,YSIZE-20;20,YSIZE-20;20,20
ELSE
   LET L=80*N
   LET SIZE=-L/8+340/8
   CALL BOXFULL(L,0,XSIZE-L,YSIZE,0)
   PLOT LINES:L,L;XSIZE-L,L
   PLOT LINES:L,YSIZE-L;XSIZE-L,YSIZE-L
   PLOT LINES:L,L;L,YSIZE-L
   PLOT LINES:XSIZE-L,L;XSIZE-L,YSIZE-L
END IF
END SUB

EXTERNAL  SUB T字路(N)
LET L=80*N
LET SIZE=-L/8+340/8
CALL BOXFULL(L,0,XSIZE-L,YSIZE,0)
PLOT LINES:L,L+SIZE;XSIZE-L,L+SIZE
PLOT LINES:L,YSIZE-L-SIZE;XSIZE-L,YSIZE-L-SIZE
PLOT LINES:L,L;L,YSIZE-L
PLOT LINES:XSIZE-L,L;XSIZE-L,YSIZE-L
END SUB

EXTERNAL  SUB 右曲がり(N)
LET R=XSIZE-N*80
LET SIZE=R/8-260/8
CALL BOXFULL(R,0,XSIZE-R+SIZE,YSIZE,0)
PLOT LINES:R,R-SIZE;XSIZE-R+SIZE,R-SIZE
PLOT LINES:R,YSIZE-R+SIZE;XSIZE-R+SIZE,YSIZE-R+SIZE
PLOT LINES:R,R;R,YSIZE-R
PLOT LINES:XSIZE-R+SIZE,YSIZE-R+SIZE;XSIZE-R+SIZE,R-SIZE
END SUB

EXTERNAL  SUB 左曲がり(N)
LET L=N*80
LET SIZE=-L/8+340/8
CALL BOXFULL(L,0,XSIZE-L-SIZE,YSIZE,0)
PLOT LINES:L,L+SIZE;XSIZE-L-SIZE,L+SIZE
PLOT LINES:L,YSIZE-L-SIZE;XSIZE-L-SIZE,YSIZE-L-SIZE
PLOT LINES:L,L;L,YSIZE-L
PLOT LINES:XSIZE-L-SIZE,YSIZE-L-SIZE;XSIZE-L-SIZE,L+SIZE
END SUB

EXTERNAL  SUB 左折路(N)
LET L=N*80
LET SIZE=-L/8+340/8
CALL BOXFULL(L,0,L+SIZE,YSIZE,0)
PLOT LINES:L,L;L,YSIZE-L
PLOT LINES:L,L+SIZE;L+SIZE,L+SIZE
PLOT LINES:L,YSIZE-L-SIZE;L+SIZE,YSIZE-L-SIZE
PLOT LINES:L+SIZE,L+SIZE;L+SIZE,YSIZE-L-SIZE
END SUB

EXTERNAL  SUB 右折路(N)
LET R=XSIZE-N*80
LET SIZE=R/8-260/8
CALL BOXFULL(R,0,R-SIZE,YSIZE,0)
PLOT LINES:R,R;R,YSIZE-R
PLOT LINES:R,R-SIZE;R-SIZE,R-SIZE
PLOT LINES:R,YSIZE-R+SIZE;R-SIZE,YSIZE-R+SIZE
PLOT LINES:R-SIZE,YSIZE-R+SIZE;R-SIZE,R-SIZE
END SUB

EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET POINT STYLE 1
SET COLOR MODE "REGULAR"
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
CLEAR
SET LINE COLOR 7
SET AREA COLOR 0
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

EXTERNAL SUB LINE(XS,YS,XE,YE,C)
SET COLOR C
PLOT LINES
PLOT LINES:XS,YS;XE,YE
END SUB

EXTERNAL SUB BOX(XS,YS,XE,YE,C)
CALL LINE(XS,YS,XE,YS,C)
CALL LINE(XE,YS,XE,YE,C)
CALL LINE(XE,YE,XS,YE,C)
CALL LINE(XS,YE,XS,YS,C)
END SUB

EXTERNAL  SUB MAKEMAZE(MAP(,),M,N) !'迷路作成
RANDOMIZE
MAT MAP=ZER
LET S=(M-1)*(N-1)
FOR I=0 TO 2*M
   LET MAP(I,0)=7
   LET MAP(I,2*N)=7
NEXT I
FOR I=0 TO 2*N
   LET MAP(0,I)=7
   LET MAP(2*M,I)=7
NEXT I
DO
   DO
      LET X=INT(RND*(M+1))
      LET Y=INT(RND*(N+1))
      LET X0=X*2
      LET Y0=Y*2
   LOOP WHILE MAP(X0,Y0)=0
   LET R=INT(RND*4)+1
   LET XN=X0+XS(R)*2
   LET YN=Y0+YS(R)*2
   IF XN>0 AND XN<2*M AND YN>0 AND YN<2*N AND MAP(XN,YN)=0 THEN
      IF X0=XN THEN
         FOR K=Y0 TO YN STEP SGN(YN-Y0)
            LET MAP(X0,K)=7
         NEXT K
      ELSE
         FOR K=X0 TO XN STEP SGN(XN-X0)
            LET MAP(K,Y0)=7
         NEXT K
      END IF
      LET X0=XN
      LET Y0=YN
      LET S=S-1
   END IF
LOOP WHILE S>0
END SUB

EXTERNAL  SUB DISPLAYMAP(MAP(,),M,N,XX,YY)
SET VIEWPORT 0,1,0,1
SET WINDOW 0,XSIZE-1,YSIZE-1,0
CLEAR
FOR I=0 TO 2*N
   FOR J=0 TO 2*M
      LET C=MAP(J,I)
      IF J=XX AND I=YY THEN LET C=4
      IF J=2*M-1 AND I=2*N-1 THEN LET C=6
      CALL BOXFULL(J*XSIZE/(2*M+1),I*YSIZE/(2*N+1),(J+1)*XSIZE/(2*M+1),(I+1)*YSIZE/(2*N+1),C)
   NEXT J
NEXT I
END SUB

EXTERNAL FUNCTION AREA3(X1,Y1,X2,Y2,X3,Y3,PX,PY)
LET T=TRIANGLE(X1,Y1,X2,Y2,X3,Y3)
LET A=TRIANGLE(X1,Y1,X2,Y2,PX,PY)
LET B=TRIANGLE(X2,Y2,X3,Y3,PX,PY)
LET C=TRIANGLE(X1,Y1,X3,Y3,PX,PY)
IF A+B+C=T THEN LET AREA3=-1 ELSE LET AREA3=0
END FUNCTION

EXTERNAL FUNCTION AREA4(X1,Y1,X2,Y2,X3,Y3,X4,Y4,PX,PY)
LET A=AREA3(X1,Y1,X2,Y2,X3,Y3,PX,PY)
IF A<>0 THEN
   LET AREA4=-1
   EXIT FUNCTION
END IF
LET B=AREA3(X1,Y1,X4,Y4,X3,Y3,PX,PY)
IF B<>0 THEN LET AREA4=-1 ELSE LET AREA4=0
END FUNCTION

EXTERNAL FUNCTION TRIANGLE(X1,Y1,X2,Y2,X3,Y3)
LET TRIANGLE=ABS(X1*Y2+X2*Y3+X3*Y1-X2*Y1-X3*Y2-Y3*X1)/2
END FUNCTION

EXTERNAL  FUNCTION GETKEY$(X,Y,SIZE)
SET AREA COLOR 4
SET TEXT COLOR 7
PLOT AREA:X,Y-SIZE;X-SIZE,Y;X,Y+SIZE;X+SIZE,Y
IF HELP>0 THEN PLOT AREA:XSIZE-150,YSIZE-150;XSIZE,YSIZE-150;XSIZE,YSIZE;XSIZE-150,YSIZE
IF LOC>0 THEN PLOT AREA:0,YSIZE-150;150,YSIZE-150;150,YSIZE;0,YSIZE
CALL LINE(X-SIZE/2,Y-SIZE/2,X+SIZE/2,Y+SIZE/2,7)
CALL LINE(X+SIZE/2,Y-SIZE/2,X-SIZE/2,Y+SIZE/2,7)
SET TEXT JUSTIFY "CENTER","HALF"
SET TEXT HEIGHT SIZE/3
LET X1=X-SIZE/2
LET Y1=Y-SIZE/2
LET X2=X1
LET Y2=Y+SIZE/2
LET X3=X+SIZE/2
LET Y3=Y2
LET X4=X3
LET Y4=Y1
PLOT TEXT ,AT X,Y-SIZE/2: "前"
PLOT TEXT ,AT X-SIZE/2,Y: "左"
PLOT TEXT ,AT X+SIZE/2,Y: "右"
PLOT TEXT ,AT X,Y+SIZE/2: "後"
IF HELP>0 THEN PLOT TEXT ,AT XSIZE-75,YSIZE-75:"MAP"
IF LOC>0 THEN
   SET TEXT JUSTIFY "LEFT","HALF"
   SET TEXT HEIGHT SIZE/4
   PLOT TEXT ,AT 0,YSIZE-75:"現在位置"
END IF
SET AREA COLOR 2
SET TEXT JUSTIFY "CENTER","HALF"
LET GETKEY$=""
DO
   MOUSE POLL X0,Y0,LEFT,RIGHT
LOOP WHILE LEFT=1 OR RIGHT=1
DO
   CALL DISPTIME
   CALL DISPLOC
   MOUSE POLL X0,Y0,LEFT,RIGHT
LOOP UNTIL LEFT=1 OR RIGHT=1
IF AREA4(X,Y-SIZE,X1,Y1,X,Y,X4,Y4,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :X,Y-SIZE;X1,Y1;X,Y;X4,Y4
   PLOT TEXT ,AT X,Y-SIZE/2: "前"
   LET GETKEY$="8"
END IF
IF AREA4(X1,Y1,X-SIZE,Y,X2,Y2,X,Y,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :X1,Y1;X-SIZE,Y;X2,Y2;X,Y
   PLOT TEXT ,AT X-SIZE/2,Y: "左"
   LET GETKEY$="4"
END IF
IF AREA4(X,Y,X2,Y2,X,Y+SIZE,X3,Y3,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :X,Y;X2,Y2;X,Y+SIZE;X3,Y3
   PLOT TEXT ,AT X,Y+SIZE/2: "後"
   LET GETKEY$="2"
END IF
IF AREA4(X4,Y4,X,Y,X3,Y3,X+SIZE,Y,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :X4,Y4;X,Y;X3,Y3;X+SIZE,Y
   PLOT TEXT ,AT X+SIZE/2,Y: "右"
   LET GETKEY$="6"
END IF
IF HELP>0 AND AREA4(XSIZE-150,YSIZE-150,XSIZE,YSIZE-150,XSIZE,YSIZE,XSIZE-150,YSIZE,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :XSIZE-150,YSIZE-150;XSIZE,YSIZE-150;XSIZE,YSIZE;XSIZE-150,YSIZE
   PLOT TEXT ,AT XSIZE-75,YSIZE-75:"MAP"
   LET GETKEY$="M"
END IF
IF LOC>0 AND AREA4(0,YSIZE-150,150,YSIZE-150,150,YSIZE,0,YSIZE,X0,Y0)<>0 AND LEFT=1 THEN
   PLOT AREA :0,YSIZE-150;150,YSIZE-150;150,YSIZE;0,YSIZE
   SET TEXT JUSTIFY "LEFT","HALF"
   PLOT TEXT ,AT 0,YSIZE-75:"現在位置"
   LET GETKEY$="L"
END IF
END FUNCTION

EXTERNAL  SUB DISPTIME
IF INT(TIME)<>TI THEN
   LET TI=INT(TIME)
   CALL BOXFULL(XSIZE-150,200,XSIZE,300,0)
   SET TEXT COLOR 7
   SET TEXT HEIGHT 20
   SET TEXT JUSTIFY "LEFT","TOP"
   PLOT TEXT ,AT XSIZE-150,200:"経過時間"
   PLOT TEXT ,AT XSIZE-100,240:STR$(INT(TIME-TY))&"s"
END IF
END SUB

EXTERNAL  SUB DISPLOC
IF INT(TIME)-LT<55 THEN LET C=7 ELSE LET C=2
IF LOC>0 AND INT(TIME)-LT<60 AND (MX<>XX OR MY<>YY OR INT(TIME)-LT<>LL) THEN
   SET TEXT COLOR C
   SET TEXT HEIGHT 20
   SET TEXT JUSTIFY "LEFT","TOP"
   CALL BOXFULL(XSIZE-150,40,XSIZE,120,0)
   PLOT TEXT ,AT XSIZE-150,40:"現在位置"
   PLOT TEXT ,AT XSIZE-120,80:"("&STR$(XX)&","&STR$(YY)&")"
   LET MX=XX
   LET MY=YY
   LET LL=INT(TIME)-LT
END IF
IF INT(TIME)-LT>60 AND FL=0 THEN
   CALL BOXFULL(XSIZE-150,0,XSIZE,120,0)
   LET FL=1
END IF
END SUB
 

迷路

 投稿者:しばっち  投稿日:2014年11月 6日(木)19時39分50秒
  RPG風の要素を加えてみました
敵親玉(LEVEL10(3階))を倒すことが目的です。
LEVEL以外のパラメータはダミーです。
マウスではなく、キーボード入力です。
テンキーの"2","4","6","8"キーで移動。
スペースキーでMAP表示。緑の点は現在位置。更に"2","4","6","8"キーでスクロール。再度スペースキーで戻る
迷路は3階建てです

PUBLIC NUMERIC 罠,宝,階段
DIM 敵数(0 TO 10)
RANDOMIZE
CALL GINIT(700,700)
SET TEXT JUSTIFY "LEFT" , "TOP"
SET TEXT BACKGROUND "OPAQUE"
SET TEXT COLOR 7
LET M=120 !'迷路サイズ 2*M*2*N
LET N=120
LET LEVEL=1 !'初期レベル
LET 罠=-999
LET 宝=-99
LET 階段=-12345
DIM MAP(3,0 TO 2*M,0 TO 2*N)
CALL MAKEMAZE(MAP,M,N)
MAT READ 敵数
DATA 35,30,25,20,16,15,13,10,7,3,1 !'レベルごとの敵数
FOR FLOOR=1 TO 3
   FOR I=1 TO 20
      DO
         LET X=INT(RND*2*M)+1
         LET Y=INT(RND*2*N)+1
      LOOP UNTIL MAP(FLOOR,X,Y)=0
      LET MAP(FLOOR,X,Y)=宝 !'宝位置設定
   NEXT I
   FOR I=1 TO 15
      DO
         LET X=INT(RND*2*M)+1
         LET Y=INT(RND*2*N)+1
      LOOP UNTIL MAP(FLOOR,X,Y)=0
      LET MAP(FLOOR,X,Y)=罠 !'罠位置設定
   NEXT I
   READ LS,LE
   DATA 0,2 !'1F
   DATA 3,6 !'2F
   DATA 7,10 !'3F
   FOR LEV=LS TO LE !'階層ごとに敵レベル設定
      FOR I=1 TO 敵数(LEV)
         DO
            LET X=INT(RND*2*M)+1
            LET Y=INT(RND*2*N)+1
         LOOP UNTIL MAP(FLOOR,X,Y)=0
         LET MAP(FLOOR,X,Y)=-10*(LEV+1)
      NEXT I
   NEXT LEV
NEXT FLOOR
FOR I=1 TO 10 !'階段設定 1階と2階
   DO
      LET X=INT(RND*2*M)+1
      LET Y=INT(RND*2*N)+1
   LOOP UNTIL MAP(1,X,Y)=0 AND MAP(2,X,Y)=0
   LET MAP(1,X,Y)=階段
   LET MAP(2,X,Y)=階段
NEXT I
FOR I=1 TO 10 !'階段設定 2階と3階
   DO
      LET X=INT(RND*2*M)+1
      LET Y=INT(RND*2*N)+1
   LOOP UNTIL MAP(2,X,Y)=0 AND MAP(3,X,Y)=0
   LET MAP(2,X,Y)=階段
   LET MAP(3,X,Y)=階段
NEXT I
CLEAR
LET FLOOR=1
CALL BOX(40,440,500,670,7)
DO
   LET XX=INT(RND*2*M)+1 !'初期位置
   LET YY=INT(RND*2*N)+1
LOOP UNTIL MAP(FLOOR,XX,YY)=0
DO !'メインループ
   CALL DISPLAY(MAP,XX,YY,FLOOR,M,N)
   CALL 情報表示(XX,YY,LEVEL,FLOOR)
   LET S$=INKEY$(1)
   IF POS("4Ll:",S$)>0 AND MAP(FLOOR,XX-1,YY)<>7 THEN LET XX=XX-1
   IF POS("6Rr]",S$)>0 AND MAP(FLOOR,XX+1,YY)<>7 THEN LET XX=XX+1
   IF POS("2Dd\",S$)>0 AND MAP(FLOOR,XX,YY+1)<>7 THEN LET YY=YY+1
   IF POS("8Uu[",S$)>0 AND MAP(FLOOR,XX,YY-1)<>7 THEN LET YY=YY-1
   IF POS("Mm "&CHR$(13),S$)>0 THEN
      CALL 地図表示(MAP,FLOOR,M,N,XX,YY)
      CLEAR
      CALL BOX(40,440,500,670,7)
   END IF
   IF XX<0 THEN LET XX=0
   IF YY<0 THEN LET YY=0
   IF XX>2*M THEN LET XX=2*M
   IF YY>2*N THEN LET YY=2*N
   CALL DISPLAY(MAP,XX,YY,FLOOR,M,N)
   LET C=MAP(FLOOR,XX,YY)
   LET FL=0
   IF C=宝 THEN
      CALL 文章表示("宝を見つけた")
      LET Z=RND
      LET T=(LEVEL-1)/9
      IF Z<.1*(2*T+1) AND LEVEL<10 THEN
         CALL 文章表示("レベルが上がった")
         LET LEVEL=LEVEL+1
      ELSEIF Z<.4 THEN
         CALL 文章表示("武器を手に入れた")
      ELSEIF Z<.5 THEN
         CALL 文章表示("薬を手に入れた")
      ELSEIF Z<.7 THEN
         LET H=INT(RND*100*LEVEL)
         CALL 文章表示("体力が"&STR$(H)&"回復した")
      ELSEIF Z<.9 THEN
         LET H=INT(RND*100*LEVEL)
         CALL 文章表示("ゴールド"&STR$(H)&"手に入れた")
      END IF
      LET MAP(FLOOR,XX,YY)=0
   ELSEIF C=罠 THEN
      CALL 文章表示("敵の罠に捕まった")
      IF RND<.5 THEN
         LET H=INT(RND*100)
         CALL 文章表示("体力が"&STR$(H)&"減った")
      END IF
      LET MAP(FLOOR,XX,YY)=0
   ELSEIF C=階段 AND FL=0 THEN
      CALL 文章表示("階段を見つけた")
      CALL 文章表示("どうしますか?")
      IF FLOOR=1 THEN
         CALL 文章表示("階段を上る(1) そのまま(2)")
         DO
            LET D$=INKEY$(1)
         LOOP UNTIL D$="1" OR D$="2"
         IF D$="1" THEN LET FLOOR=2
         LET FL=1
      ELSEIF FLOOR=3 THEN
         CALL 文章表示("階段を下りる(1) そのまま(2)")
         DO
            LET D$=INKEY$(1)
         LOOP UNTIL D$="1" OR D$="2"
         IF D$="1" THEN LET FLOOR=2
         LET FL=1
      ELSE
         IF MAP(1,XX,YY)=階段 AND MAP(2,XX,YY)=階段 THEN
            CALL 文章表示("階段を下りる(1) そのまま(2)")
            DO
               LET D$=INKEY$(1)
            LOOP UNTIL D$="1" OR D$="2"
            IF D$="1" THEN LET FLOOR=1
            LET FL=1
         ELSE
            CALL 文章表示("階段を上る(1) そのまま(2)")
            DO
               LET D$=INKEY$(1)
            LOOP UNTIL D$="1" OR D$="2"
            IF D$="1" THEN LET FLOOR=3
            LET FL=1
         END IF
      END IF
   ELSEIF C<0 AND MOD(-C,10)=0 THEN
      LET LEV=-C/10-1
      CALL 文章表示("LEVEL"&STR$(LEV)&"の敵が現れた。")
      CALL 文章表示("どうしますか?")
      CALL 文章表示("戦う(1) 逃げる(2)")
      DO
         LET D$=INKEY$(1)
      LOOP UNTIL D$="1" OR D$="2"
      IF D$="1" THEN
         IF LEVEL<LEV THEN !'即死
            CALL 文章表示("あなたは死にました")
            CALL 文章表示("GAME OVER")
            STOP
         ELSEIF LEVEL>LEV THEN !'瞬殺
            CALL 文章表示("敵を倒した")
            LET Z=RND
            LET T=(LEVEL-1)/9
            IF Z<.1*(2*T+1) AND LEVEL<10 THEN
               CALL 文章表示("レベルが上がった")
               LET LEVEL=LEVEL+1
            ELSEIF Z<.4 THEN
               CALL 文章表示("武器を手に入れた")
            ELSEIF Z<.8 THEN
               LET H=INT(RND*100*LEVEL)
               CALL 文章表示("ゴールド"&STR$(H)&"手に入れた")
            END IF
         ELSE
            CALL 文章表示("戦闘が始まった")
            DO
               LET Z=RND
               IF Z<.3 THEN
                  CALL 文章表示("敵を倒した")
                  IF LEV=10 THEN
                     CALL 文章表示("あなたは敵の親玉を倒した")
                     CALL 文章表示("Congratulations !!")
                     CALL 文章表示("GAME OVER")
                     STOP
                  END IF
                  LET T=(LEVEL-1)/9
                  IF Z<.15*(2*T+1) AND LEVEL<10 THEN
                     CALL 文章表示("レベルが上がった")
                     LET LEVEL=LEVEL+1
                  END IF
                  EXIT DO
               ELSEIF Z<.5 THEN
                  LET H=INT(RND*100)
                  CALL 文章表示(STR$(H)&"のダメージを受けた")
               ELSEIF Z<.8 THEN
                  LET H=INT(RND*100*LEVEL)
                  CALL 文章表示("敵に"&STR$(H)&"のダメージを与えた")
               END IF
            LOOP
         END IF
         LET MAP(FLOOR,XX,YY)=0 !'遭遇するとクリア
      ELSE
         IF LEV>=9 AND LEV>=LEVEL THEN
            CALL 文章表示("だめだ、逃げ切れない")
            CALL 文章表示("あなたは死にました")
            CALL 文章表示("GAME OVER")
            STOP
         ELSE
            LET MAP(FLOOR,XX,YY)=0
            DO !'逃げるとワープ?
               LET XX=INT(RND*2*M)
               LET YY=INT(RND*2*N)
            LOOP UNTIL MAP(FLOOR,XX,YY)=0
            CALL 文章表示("逃げ切れた")
         END IF
      END IF
   END IF
   IF C<>階段 THEN LET MAP(FLOOR,XX,YY)=2 !'足跡を残す
LOOP
END

EXTERNAL  SUB DISPLAY(MAP(,,),XX,YY,FLOOR,M,N)
SET TEXT HEIGHT 40
FOR I=-3 TO 3
   LET X=0
   FOR J=-4 TO 4
      IF XX+J>=0 AND YY+I>=0 AND XX+J<=2*M AND YY+I<=2*N THEN
         LET C=MAP(FLOOR,XX+J,YY+I)
         IF C=階段 THEN
            SET TEXT COLOR 5
            PLOT TEXT ,AT X,Y:"階"
         ELSEIF C=宝 THEN
            SET TEXT COLOR 6
            PLOT TEXT ,AT X,Y:"宝"
         ELSE
            IF C<0 OR C=2 THEN LET C=0
            CALL BOXFULL(X,Y,X+50,Y+50,C)
         END IF
      ELSE
         CALL BOXFULL(X,Y,X+50,Y+50,1)
      END IF
      LET X=X+50
   NEXT J
   LET Y=Y+50
NEXT I
CALL BOX(0,0,450,350,2)
CALL PUTCHARACTER(200,150,3)
END SUB

EXTERNAL  SUB MAKEMAZE(MAP(,,),M,N) !'迷路作成
RANDOMIZE
DIM XS(4),YS(4)
SET TEXT HEIGHT 20
FOR I=1 TO 4
   READ XS(I),YS(I)
NEXT I
DATA -1,0
DATA 1,0
DATA 0,1
DATA 0,-1
FOR FLOOR=1 TO 3
   LET S=(M-1)*(N-1)
   LET SS=S
   CALL BOXFULL(230,230,500,260,0)
   PLOT TEXT ,AT 230,230:"迷路作成中です..."&STR$(FLOOR)
   CALL BOXFULL(150,270,550,300,8)
   FOR I=0 TO 2*M
      LET MAP(FLOOR,I,0)=7
      LET MAP(FLOOR,I,2*N)=7
   NEXT I
   FOR I=0 TO 2*N
      LET MAP(FLOOR,0,I)=7
      LET MAP(FLOOR,2*M,I)=7
   NEXT I
   DO
      DO
         LET X=INT(RND*(M+1))
         LET Y=INT(RND*(N+1))
         LET X0=X*2
         LET Y0=Y*2
      LOOP WHILE MAP(FLOOR,X0,Y0)=0
      LET R=INT(RND*4)+1
      LET XN=X0+XS(R)*2
      LET YN=Y0+YS(R)*2
      IF XN>0 AND XN<2*M AND YN>0 AND YN<2*N AND MAP(FLOOR,XN,YN)=0 THEN
         IF X0=XN THEN
            FOR K=Y0 TO YN STEP SGN(YN-Y0)
               LET MAP(FLOOR,X0,K)=7
            NEXT K
         ELSE
            FOR K=X0 TO XN STEP SGN(XN-X0)
               LET MAP(FLOOR,K,Y0)=7
            NEXT K
         END IF
         LET X0=XN
         LET Y0=YN
         LET S=S-1
      END IF
      IF MOD(INT((SS-S)/SS*100),10)=0 THEN CALL BOXFULL(150,270,150+INT((SS-S)/SS*400),300,4)
   LOOP WHILE S>0
   CALL BOXFULL(150,270,550,300,4)
NEXT FLOOR
WAIT DELAY .1
END SUB

EXTERNAL  SUB 地図表示(MAP(,,),FLOOR,M,N,ZX,ZY)
LET XX=ZX
IF XX-17<0 THEN LET XX=ABS(XX-17)+1
LET YY=ZY
IF YY-17<0 THEN LET YY=ABS(YY-17)+1
SET TEXT HEIGHT 15
DO
   LET Y=0
   CLEAR
   FOR I=-17 TO 17
      LET X=0
      FOR J=-17 TO 17
         IF XX+J>=0 AND YY+I>=0 AND XX+J<=2*M AND YY+I<=2*N THEN
            LET C=MAP(FLOOR,XX+J,YY+I)
            IF C=罠 THEN
               SET TEXT COLOR 3
               PLOT TEXT ,AT X,Y:"罠"
            ELSEIF C=宝 THEN
               SET TEXT COLOR 6
               PLOT TEXT ,AT X,Y:"宝"
            ELSEIF C=階段 THEN
               SET TEXT COLOR 5
               PLOT TEXT ,AT X,Y:"階"
            ELSEIF MOD(-C,10)=0 THEN
               LET LEV=-C/10-1
               SET TEXT COLOR LEV+1
               PLOT TEXT ,AT X,Y:"敵" !'LEV=0..青 LEV=1..赤 LEV=2..紫 LEV=3..緑
            END IF
            IF XX+J=ZX AND YY+I=ZY THEN LET C=4
            IF C>=0 THEN CALL BOXFULL(X,Y,X+20,Y+20,C)
         ELSE
            CALL BOXFULL(X,Y,X+20,Y+20,1)
         END IF
         LET X=X+20
      NEXT J
      LET Y=Y+20
   NEXT I
   LET S$=INKEY$(1)
   IF POS("4Ll:",S$)>0 THEN LET XX=XX-10
   IF POS("6Rr]",S$)>0 THEN LET XX=XX+10
   IF POS("2Dd\",S$)>0 THEN LET YY=YY+10
   IF POS("8Uu[",S$)>0 THEN LET YY=YY-10
   IF S$=" " OR S$=CHR$(13) THEN EXIT DO
   IF XX=<0 THEN LET XX=0
   IF XX>=2*M THEN LET XX=2*M
   IF YY<=0 THEN LET YY=0
   IF YY>=2*N THEN LET YY=2*N
LOOP
END SUB

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"
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 0,0,1
SET COLOR MIX(2) 1,0,0
SET COLOR MIX(3) 1,0,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 1,1,0
SET COLOR MIX(7) 1,1,1
SET COLOR MIX(9) BVAL("A4",16)/255,BVAL("91",16)/255,BVAL("76",16)/255
SET COLOR MIX(10) BVAL("E2",16)/255,BVAL("CB",16)/255,BVAL("A6",16)/255
SET COLOR MIX(11) BVAL("6F",16)/255,BVAL("55",16)/255,BVAL("31",16)/255
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

EXTERNAL SUB BOX(XS,YS,XE,YE,C)
CALL LINE(XS,YS,XE,YS,C)
CALL LINE(XE,YS,XE,YE,C)
CALL LINE(XE,YE,XS,YE,C)
CALL LINE(XS,YE,XS,YS,C)
END SUB

EXTERNAL SUB LINE(XS,YS,XE,YE,C)
SET COLOR C
PLOT LINES
PLOT LINES:XS,YS;XE,YE
END SUB

EXTERNAL  SUB 文章表示(X$)
DIM M(460,200)
CALL BOX(40,440,500,670,0)
ASK PIXEL ARRAY (40,465) M
CALL BOXFULL(40,440,500,670,0)
MAT PLOT CELLS, IN 40,440;499,639:M
CALL BOX(40,440,500,670,7)
SET TEXT COLOR 7
SET TEXT HEIGHT 18
PLOT TEXT ,AT 40,640:X$
END SUB

EXTERNAL  SUB 情報表示(XX,YY,LEVEL,FLOOR)
CALL BOXFULL(490,40,680,250,0)
CALL BOX(490,40,680,250,7)
SET TEXT COLOR 7
SET TEXT HEIGHT 20
PLOT TEXT ,AT 500,40:"LEVEL "&STR$(LEVEL)
PLOT TEXT ,AT 500,70:STR$(FLOOR)&"階"
PLOT TEXT ,AT 500,100:"座標("&STR$(XX)&","&STR$(YY)&")"
END SUB

EXTERNAL  FUNCTION INKEY$(X)
SELECT CASE X
CASE 0
   LET LEFTKEY$=CHR$(37)&"4Ll"
   LET RIGHTKEY$=CHR$(39)&"6Rr"
   LET UPKEY$=CHR$(38)&"8Uu"
   LET DOWNKEY$=CHR$(40)&"2Dd"
   LET CRKEY$=" "&CHR$(13)&" "&CHR$(13)
   DO
      FOR I=1 TO 4
         LET L=GetKeyState(ORD(LEFTKEY$(I:I)))
         LET U=GetKeyState(ORD(UPKEY$(I:I)))
         LET R=GetKeyState(ORD(RIGHTKEY$(I:I)))
         LET D=GetKeyState(ORD(DOWNKEY$(I:I)))
         LET S=GetKeyState(ORD(CRKEY$(I:I)))
         IF L<0 OR U<0 OR R<0 OR D<0 OR S<0 THEN EXIT DO !'キーを押すまで
      NEXT I
   LOOP
   DO
      LET FL=0
      FOR I=1 TO 4
         LET LL=GetKeyState(ORD(LEFTKEY$(I:I)))
         LET UU=GetKeyState(ORD(UPKEY$(I:I)))
         LET RR=GetKeyState(ORD(RIGHTKEY$(I:I)))
         LET DD=GetKeyState(ORD(DOWNKEY$(I:I)))
         LET SS=GetKeyState(ORD(CRKEY$(I:I)))
         IF LL<0 OR UU<0 OR RR<0 OR DD<0 OR SS<0 THEN LET FL=1 !'キーを離すまで
      NEXT I
   LOOP WHILE FL=1
   IF L<0 THEN LET INKEY$="4"
   IF U<0 THEN LET INKEY$="8"
   IF R<0 THEN LET INKEY$="6"
   IF D<0 THEN LET INKEY$="2"
   IF S<0 THEN LET INKEY$=" "
CASE 1
   CHARACTER INPUT CLEAR:S$
   LET INKEY$=S$
END SELECT
END FUNCTION

EXTERNAL  SUB PUTCHARACTER(XX,YY,SIZE)
LET Y=YY
LET X=XX
FOR I=1 TO 16
   READ A$
   FOR J=1 TO 16
      LET C=BVAL(A$(J:J),16)
      CALL BOXFULL(X,Y,X+SIZE,Y+SIZE,C)
      LET X=X+SIZE
   NEXT J
   LET X=XX
   LET Y=Y+SIZE
NEXT I
DATA 0000000000000000
DATA 0000000770000000
DATA 0000000990000000
DATA 0700077777700000
DATA 0700799779970000
DATA 0700700990070000
DATA 0700999999990000
DATA 07091A0AA0A19000
DATA 070009AAAA977700
DATA 0707719009711170
DATA 6669911111716170
DATA 0AA1199669711170
DATA 0990011111177700
DATA 0000077777700000
DATA 00000BB00BB00000
DATA 00000BB00BB00000
END SUB
 

Re: 3次方程式を解く

 投稿者:山中和義  投稿日:2014年11月10日(月)10時46分53秒
  > No.3541[元記事へ]

因数分解による


2次方程式 x^2+Ax+B=0

チルンハウス変換 x=X-A/2 すると、(X-A/2)^2+A(X-A/2)+B=X^2-(A^2-4B)/4
1次の項が消えて、X^2-P=(X+√P)(X-√P)の形となる。これより、X=±√P=±√(A^2-4B)/2
よって、x=±√(A^2-4B)/2 -A/2



同様に、x=X-A/3、x=X-A/4より、X^3+PX+Q=0、X^4+PX^2+QX+R=0 を考える。


3次方程式

X^3+(-3yz)X+(y^3+z^3)=(X+y+z)(X+ωy+ω^2z)(X+ω^2y+ωz)より、Xの3次方程式とみなすと、
x1=-(    y+    z)
x2=-(  ωy+ω^2z)
x3=-(ω^2y+  ωz)

X^3-PX+Q=0と係数を比較すると、P=3yz、Q=y^3+z^3
2つの解y^3,z^3をもつ2次方程式 t^2-Qt+P^3/27=0 を考える。

カルダノの方法に相当する。



4次方程式

X^4+y^4+z^4+w^4-2(X^2y^2+X^2z^2+X^2w^2+y^2z^2+y^2w^2+z^2w^2)+8Xyzw=(X+y+z+w)(X+y-z-w)(X-y+z-w)(X-y-z+w)より、
x1=-( y+z+w)
x2=-( y-z-w)
x3=-(-y+z-w)
x4=-(-y-z+w)

X^4+PX^2+QX+R=0と係数を比較すると、P=-2(y^2+z^2+w^2)、Q=8yzw、R=y^4+z^4+w^4-2(y^2z^2+y^2w^2+z^2w^2)
3つの解y^2,z^2,w^2をもつ3次方程式 t^3+(P/2)t^2+(P^2/16-R/4)t-Q^2/64=0 を考える。
ただし、8yzw=Qを満たすy,z,wを選ぶ。

オイラーの方法に相当する。




OPTION ARITHMETIC COMPLEX !複素数

LET A=3 !x^3+Ax^2+Bx+C=0
LET B=0
LET C=-1

CALL Solve3EQU(A,B,C, x1,x2,x3)
PRINT x1 !解を表示する
PRINT x2
PRINT x3

DEF f(x)=x^3+A*x^2+B*x+C !検算
PRINT f(x1); f(x2); f(x3)


LET A=-8 !x^4+Ax^3+Bx^2+Cx+D
LET B=26
LET C=-44
LET D=40
CALL Solve4EQU(A,B,C,D, x1,x2,x3,x4)
PRINT x1
PRINT x2
PRINT x3
PRINT x4

DEF g(x)=x^4+A*x^3+B*x^2+C*x+D
PRINT g(x1); g(x2); g(x3); g(x4)

END


EXTERNAL FUNCTION pow(x,y) !べき乗 x^y
OPTION ARITHMETIC COMPLEX !複素数
IF x=0 THEN LET pow=0 ELSE LET pow=EXP(y*LOG(x)) !x^y
END FUNCTION


EXTERNAL SUB Solve2EQU(A,B, x1,x2) !2次方程式 x^2+Ax+B=0 を解く
OPTION ARITHMETIC COMPLEX !複素数
LET x1=-SQR(A^2-4*B)/2 -A/2
LET x2= SQR(A^2-4*B)/2 -A/2
END SUB


EXTERNAL SUB Solve3EQU(A,B,C, x1,x2,x3) !3次方程式 x^3+Ax^2+Bx+C=0 を解く
OPTION ARITHMETIC COMPLEX !複素数
LET w=EXP(COMPLEX(0,1)*2*PI/3) !w ※1の原始3乗根
LET P=-A^2/3+B !チルンハウス変換 x=X-A/3
LET Q=2*A^3/27-A*B/3+C
CALL Solve2EQU(-Q,(-P)^3/27, t1,t2) !解の1つ
LET r1=pow(t1,1/3)
LET r2=(-P)/(3*r1) !(-P)=3yzより
LET x1=-(    r1+    r2) -A/3
LET x2=-(  w*r1+w^2*r2) -A/3
LET x3=-(w^2*r1+  w*r2) -A/3
END SUB


EXTERNAL SUB Solve4EQU(A,B,C,D, x1,x2,x3,x4) !4次方程式 x^4+Ax^3+Bx^2+Cx+D=0 を解く
OPTION ARITHMETIC COMPLEX !複素数
LET P=-3*A^2/8+B !チルンハウス変換 x=X-A/4
LET Q=A^3/8-A*B/2+C
LET R=-3*A^4/256+A^2*B/16-A*C/4+D
CALL Solve3EQU(P/2,P^2/16-R/4,-Q^2/64, t1,t2,t3) !3つの解
FOR S1=-1 TO 1 STEP 2 !±を確定させる
   LET r1=S1*SQR(t1)
   FOR S2=-1 TO 1 STEP 2
      LET r2=S2*SQR(t2)
      FOR S3=-1 TO 1 STEP 2
         LET r3=S3*SQR(t3)

         LET x1=-( r1+r2+r3) -A/4
         LET x2=-( r1-r2-r3) -A/4
         LET x3=-(-r1+r2-r3) -A/4
         LET x4=-(-r1-r2+r3) -A/4

         IF ABS(8*r1*r2*r3-Q)<1E-13 THEN EXIT SUB !※調整が必要である
      NEXT S3
   NEXT S2
NEXT S1
PRINT "論理エラーです。"
STOP
END SUB


 

多変数多項式の計算 mPOLY.LIB

 投稿者:山中和義  投稿日:2014年11月15日(土)23時16分42秒
  サブルーチン mPOLY.LIB


!mPOLY.LIB

!多変数多項式の演算(加減乗算) p(a,b,c, … ,y,z)=ΣN*a^A*b^B*c^C* … *y^Y*z^Z

! 式 p(項,変数)
!     係数   変数
! 項\ 0   v1  v2  v3  …
!   0: k   -   -   -   …
!   1: c1 e11 e12 e13 …   項 c1*(v1^e11)*(v2^e12)*(v3^e13)* … の意
!   2: c2 e21 e22 e23 …
!   3: c3 e31 e32 e33 …
!         :
!         :
!   k: ck ek1 ek2 ek3 …

! 例 p=a^2*b+3*a*b+2*b
! p(0 TO 3, 0 TO 2) として、
!     係数   変数
! 項\ 0   a   b
!   0: 3   -   -
!   1: 1   2   1
!   2: 3   1   1
!   3: 2   0   1


!表示関連

EXTERNAL SUB PolyPrint(p(,)) !多変数多項式を表示する
OPTION ARITHMETIC RATIONAL
LET K=p(0,0) !項の数
IF K>0 THEN
   FOR i=1 TO K !各項について
      LET t=p(i,0) !係数の部分
      IF t<>0 THEN !0は非表示
         LET FLG=0

         IF t>0 THEN !符号を演算子として表示する
           IF i>1 THEN PRINT "+"; !第1項目は表示しない
         ELSE
            PRINT "-";
         END IF

         LET t=ABS(t) !定数の部分
         IF t<>1 THEN !1は非表示
            CALL DispNum(t)
            LET FLG=1 !分子を表示した
         END IF

         LET s=0
         FOR e=1 TO N !次数の部分
            IF p(i,e)>0 THEN !べき乗数が正の場合
               CALL DispVar(v$(e:e),p(i,e))
               LET FLG=1 !分子を表示した
            ELSEIF p(i,e)<0 THEN
               LET s=s+1
            END IF
         NEXT e

         IF s>0 THEN !べき乗数が負の場合、分数で表示する
            IF FLG=0 THEN PRINT "1"; !分子が定数±1のとき

            IF s>1 THEN PRINT "/("; ELSE PRINT "/";
            FOR e=1 TO N !次数の部分
               IF p(i,e)<0 THEN CALL DispVar(v$(e:e),ABS(p(i,e)))
            NEXT e
            IF s>1 THEN PRINT ")";
            LET FLG=1 !分母を表示した
        END IF

         IF FLG=0 THEN PRINT "1"; !定数±1のみのとき
      END IF
   NEXT i

   IF K=1 AND p(1,0)=0 THEN PRINT "0"; !定数項0のみのとき

ELSE
   PRINT "NUL"; !未定義である

END IF
END SUB

EXTERNAL SUB DispNum(t) !数値を表示する ※1,(-2),(3/4),(-5/6)など
OPTION ARITHMETIC RATIONAL
IF t=INT(t) AND t>=0 THEN !非負の整数なら
   PRINT STR$(t);
ELSE !負の整数、有理数なら
   PRINT "(";STR$(t);")";
END IF
END SUB

EXTERNAL SUB DispVar(x$,t) !x^t形式で変数を表示する
OPTION ARITHMETIC RATIONAL
IF t<>0 THEN !x^0は非表示
   PRINT x$; !変数
   IF t<>1 THEN !x^1の1は非表示
      PRINT "^"; !次数
      CALL DispNum(t)
   END IF
END IF
END SUB


EXTERNAL SUB PolyPrintCollect(p(,),x$) !変数xの多項式とみなして表示する
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
CALL PolyCopy(p, t) !次数の昇順に並べる
LET e=idx(x$)
LET K=t(0,0)
FOR i=1 TO K-1 !バブルソート O(n^2)
   LET A=t(i,e)
   FOR J=i+1 TO K
      LET B=t(J,e)
      IF A>B THEN !iとjを交換する

         LET A=B

         FOR m=0 TO N !swap it
            LET t(K+1,m)=t(i,m) !iを作業領域へ
         NEXT m
         FOR m=0 TO N
            LET t(i,m)=t(J,m) !j→i
         NEXT m
         FOR m=0 TO N
            LET t(J,m)=t(K+1,m) !i(作業領域)→j
         NEXT m

      END IF
   NEXT J
NEXT i

DIM s(0 TO MAX_TERM, 0 TO N)
LET u=t(1,e)
LET i=1
DO
   PRINT "+("; !同類項(次数が同じ値のもの)で括る
   LET J=0
   DO
      LET J=J+1
      FOR m=0 TO N !copy it
         LET s(J,m)=t(i,m)
      NEXT m
      LET s(J,e)=0 !この次数は除く

      LET i=i+1 !次へ
      LET w=t(i,e)
   LOOP WHILE i<=K AND w=u !異なる次数が現れたら
   LET s(0,0)=J
   CALL PolyPrint(s) !表示する
   PRINT ")";
   CALL DispVar(x$,u) !この次数の変数を表示する

   LET u=w !次へ
LOOP UNTIL i>K
END SUB


!演算関連

EXTERNAL SUB PolyAdd(p(,),q(,), r(,)) !加算 r=p+q ※r≠p、r≠qの配列を指定する
OPTION ARITHMETIC RATIONAL
CALL PolyCopy(p, r) !そのままコピーする

LET M=p(0,0) !項の数
FOR J=1 TO q(0,0) !項を末尾に加える
   FOR e=0 TO N !次数、係数
      LET r(M+J,e)=q(J,e)
   NEXT e
NEXT J

LET r(0,0)=M+q(0,0) !項の数
CALL PolySimplify(r) !同類項をまとめる、0サプレス
END SUB


EXTERNAL SUB PolySubtract(p(,),q(,), r(,)) !減算 r=p-q ※r≠p、r≠qの配列を指定する
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
CALL PolyMultiplyC(q,-1, t) !(-1)倍
CALL PolyAdd(p,t, r) !p-q
END SUB


EXTERNAL SUB PolyMultiply(p(,),q(,), r(,)) !乗算 r=p*q ※r≠p、r≠qの配列を指定する
OPTION ARITHMETIC RATIONAL
LET M=0
FOR i=1 TO p(0,0) !項と項をかける
   FOR J=1 TO q(0,0)
      LET M=M+1
      FOR e=1 TO N !次数
         LET r(M,e)=p(i,e)+q(J,e)
      NEXT e
      LET r(M,0)=p(i,0)*q(J,0) !係数
   NEXT J
NEXT i
LET r(0,0)=M !項の数
CALL PolySimplify(r) !同類項をまとめる、0サプレス
END SUB


EXTERNAL SUB PolyMultiplyC(p(,),k, r(,)) !乗算(定数倍) r=k*p
OPTION ARITHMETIC RATIONAL
LET M=p(0,0)
FOR i=1 TO M
   FOR e=1 TO N !次数
      LET r(i,e)=p(i,e)
   NEXT e
   LET r(i,0)=k*p(i,0) !係数
NEXT i
LET r(0,0)=M !項の数
END SUB


EXTERNAL SUB PolyDivide(p(,), f1(,), r(,)) !除算(単項式による) r=p/f1
OPTION ARITHMETIC RATIONAL
LET M=p(0,0)
FOR i=1 TO M
   FOR e=1 TO N !次数
      LET r(i,e)=p(i,e)-f1(1,e)
   NEXT e
   LET r(i,0)=p(i,0)/f1(1,0) !係数
NEXT i
LET r(0,0)=M !項の数
END SUB


EXTERNAL SUB PolyCommonFactor(p(,), f1(,)) !共通因数を得る(共通因数で括る)
OPTION ARITHMETIC RATIONAL
LET G=p(1,0) !copy it
FOR e=1 TO N
   LET f1(1,e)=p(1,e)
NEXT e
FOR i=2 TO p(0,0)
   LET G=gcd(G,p(i,0)) !係数
   FOR e=1 TO N !次数
      LET f1(1,e)=MIN(f1(1,e),p(i,e))
   NEXT e
NEXT i
LET f1(1,0)=G
LET f1(0,0)=1 !項の数
END SUB

EXTERNAL FUNCTION gcd(a,b) !最大公約数
OPTION ARITHMETIC RATIONAL
DO UNTIL b=0
   LET t=b
   LET b=MOD(a,b)
   LET a=t
LOOP
LET gcd=ABS(a)
END FUNCTION


!演算関連2

EXTERNAL SUB PolyComposition(p(,),x$,q(,), r(,)) !合成関数 P(x=Q) ※r≠p、r≠qの配列を指定する
OPTION ARITHMETIC RATIONAL
MAT r=ZER
LET r(0,0)=1 !定数0
LET r(1,0)=0

CALL PolyDegree(p,x$, mx,mn) !次数の最大値、最小値を得る

DIM T2(0 TO MAX_TERM, 0 TO N), T3(0 TO MAX_TERM, 0 TO N)
FOR ii=mx TO mn STEP -1 !ホーナー法による
   CALL PolyMultiply(r,q, T3) !T[n]*X+T[n-1]

   CALL PolyCoefficient(p,x$,ii, T2) !係数 ※多項式
   CALL PolyAdd(T3,T2, r)
NEXT ii
FOR ii=0 TO mn-1 !残り部分
   CALL PolyMultiply(r,q, T3)
   CALL PolyCopy(T3,r)
NEXT ii
END SUB


EXTERNAL SUB PolyPowN(f(,),K, fk(,)) !べき乗 f^k
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
MAT fk=ZER !定数 1
LET fk(0,0)=1
LET fk(1,0)=1
FOR i=1 TO K
   CALL PolyMultiply(fk,f, t) !fk=fk*f
   CALL PolyCopy(t, fk)
NEXT i
END SUB


!deg(f)≧deg(g)≧0、gの最高次の係数は単項式 として、f÷g=商q余りr を求める
EXTERNAL SUB PolyQuotientRemainder(f(,),g(,),x$, q(,),r(,)) !f÷g=商q余りr
OPTION ARITHMETIC RATIONAL
DIM t1(0 TO MAX_TERM, 0 TO N), t2(0 TO MAX_TERM, 0 TO N)
DIM p(0 TO MAX_TERM, 0 TO N), u(0 TO MAX_TERM, 0 TO N)
CALL PolyDegree(f,x$, mx1,mn1) !次数を得る
CALL PolyDegree(g,x$, mx2,mn2)
MAT q=ZER !q,rの初期値
LET q(0,0)=1
CALL PolyCopy(f, r)
CALL PolyCoefficient(g,x$,mx2, p) !P
FOR i=mx1 TO mx2 STEP -1 !筆算による
   CALL PolyCoefficient(r,x$,i, u) !A
   LET e=idx(x$)
   FOR J=0 TO u(0,0) !x^k倍
      LET u(J,e)=u(J,e)+(i-mx2)
   NEXT J
   CALL PolyDivide(u,p, u) !Q=A/P

   CALL PolyAdd(q,u, t2) !q=ΣQ
   CALL PolyCopy(t2, q)

   CALL PolyMultiply(u,g, t1) !r=r-Qg
   CALL PolySubtract(r,t1, t2)
   CALL PolyCopy(t2, r)
NEXT i
CALL PolySimplify(r) !0に注意する
END SUB


!共通ルーチン

EXTERNAL SUB PolyCopy(p(,), q(,)) !コピーする LET q=p
OPTION ARITHMETIC RATIONAL
LET K=p(0,0) !項の数
FOR i=1 TO K
   FOR e=0 TO N !係数、次数
      LET q(i,e)=p(i,e)
   NEXT e
NEXT i
LET q(0,0)=K !項の数
END SUB


EXTERNAL SUB PolySimplify(r(,)) !同類項をまとめるなどの簡約化を行う
OPTION ARITHMETIC RATIONAL
LET K=r(0,0) !項の数
LET W=0

FOR i=1 TO K
   LET T=r(i,0) !係数が0のものを篩う
   IF T<>0 THEN

      FOR j=i+1 TO K !同類項を探す
         CALL IsEqualDegree(r,i, r,j,  rc) !次数が同じなら、同類項!
         IF rc<>0 THEN
            LET T=T+r(j,0) !前方へ吸収する
            LET r(j,0)=0 !後方は削除する
         END IF
      NEXT j

      IF T<>0 THEN !係数が0なら、無効!
         LET W=W+1

         LET r(W,0)=T !係数
         IF i>W THEN !前方へ吸収する ※ガーベジ・コレクション
            FOR e=1 TO N !次数
               LET r(W,e)=r(i,e)
            NEXT e
         END IF
      END IF

   END IF
NEXT i

IF W=0 THEN
   LET r(0,0)=1 !定数0
   FOR e=0 TO N
      LET r(1,e)=0
   NEXT e
ELSE
   LET r(0,0)=W !項の数
END IF
END SUB


EXTERNAL SUB PolySimplify2(r(,)) !同類項をまとめるなどの簡約化を行う ※i^2=-1、ω^2+ω+1=0 を適用する
OPTION ARITHMETIC RATIONAL
LET K=r(0,0) !項の数
LET W=K

FOR i=1 TO K !虚数i、ωの条件式を適用する ※x^k=Aのとき、x^m≡A^int(m/k) x^mod(m,k)
   LET e=idx("i") !虚数i
   IF e>0 THEN
      LET T=INT(r(i,e)/2) !i^2=-1を適用する ※i^3=-iなど
      LET r(i,0)=(-1)^MOD(T,2)*r(i,0) !係数
      LET r(i,e)=MOD(r(i,e),2) !次数
   END IF

   LET e=idx("w") !ω(x^3-1=0の3つの解の内、虚数解の1つをωとする)
   IF e>0 THEN
      LET r(i,e)=MOD(r(i,e),3) !ω^3=1を適用する ※ω^5=ω^2など

      !ω^2+ω+1=0を適用する。すなわち、Aω^2=-Aω-Aとする。
      IF r(i,e)=2 THEN !Aω^2なら
         LET r(i,0)=-r(i,0) !係数 -Aω
         LET r(i,e)=1 !次数

         LET W=W+1 !-Aを後方に追加する
         FOR J=0 TO N !copy it
            LET r(W,J)=r(i,J)
         NEXT J
         LET r(W,e)=0
      END IF

   END IF
NEXT i

LET r(0,0)=W !項の数


CALL PolySimplify(r) !a+bi、a+bω(a+bω+cω^2)の形へ
END SUB


EXTERNAL SUB PolyCoefficient(p(,),x$,m, t(,)) !変数xにおけるm次の係数(多項式)を得る
OPTION ARITHMETIC RATIONAL
LET K=0
LET J=idx(x$) !桁位置を確認する
FOR i=1 TO p(0,0) !すべての項を検索する
   IF p(i,J)=m THEN !同じ次数なら
      LET K=K+1
      FOR e=0 TO N !copy it
         LET t(K,e)=p(i,e)
      NEXT e
      LET t(K,J)=0 !該当する変数は除く
   END IF
NEXT i
IF K=0 THEN
   LET t(0,0)=1 !定数0
   FOR e=0 TO N
      LET t(1,e)=0
   NEXT e
ELSE
   LET t(0,0)=K !項の数
END IF
END SUB


EXTERNAL SUB PolyDegree(p(,),x$, mx,mn) !変数xにおける次数の最大値と最小値を得る
OPTION ARITHMETIC RATIONAL
LET e=idx(x$) !桁位置を確認する
LET mx=p(1,e) !最大
LET mn=p(1,e) !最小
FOR i=2 TO p(0,0) !すべての項を検索する
   IF p(i,e)>mx THEN LET mx=p(i,e)
   IF p(i,e)<mn THEN LET mn=p(i,e)
NEXT i
END SUB


つづく

 

Re: 多変数多項式の計算 mPOLY.LIB

 投稿者:山中和義  投稿日:2014年11月15日(土)23時18分41秒
  > No.3547[元記事へ]

つづき



!マクロ

EXTERNAL FUNCTION idx(x$) !変数a,b,c,…を1,2,3,…へ
OPTION ARITHMETIC RATIONAL
LET idx=POS(v$,x$)
END FUNCTION


EXTERNAL SUB IsEqualDegree(p(,),i, q(,),j, rc) !多項式pの第i項の次数と多項式qの第j項の次数が等しいかどうか確認する
OPTION ARITHMETIC RATIONAL
LET rc=0
FOR e=1 TO N !次数が等しくないなら
   IF p(i,e)<>q(j,e) THEN EXIT SUB
NEXT e
LET rc=1 !等しい
END SUB


EXTERNAL SUB IsConst(p(,),i, rc) !多項式pの第i項が定数かどうか確認する
OPTION ARITHMETIC RATIONAL
LET rc=0
FOR e=1 TO N !次数が0以外なら
   IF p(i,e)<>0 THEN EXIT SUB
NEXT e
LET rc=1 !定数
END SUB



!----------------------------------------------

!文字列で表された多項式を符号化する Σ(-M/N)a^(-P/Q)  例 xy^5+(4/3)x^2y+z^(-1)

EXTERNAL SUB PolySet(s$, a(,)) !多項式を符号化する
OPTION ARITHMETIC RATIONAL
MAT a=ZER

LET p=1 !文字位置

LET K=1 !項数

CALL GetToken(p,s$, t$) !1番目の単項式の±は符号とみなす
LET s=1 !符号
IF t$="+" THEN
   LET p=p+1 !eat it
ELSEIF t$="-" THEN
   LET p=p+1 !eat it
   LET s=-1
END IF

CALL GetToken(p,s$, t$) !トークン
IF t$="" THEN
   PRINT "符号のみで項がありません。"; p
   STOP
END IF
DO WHILE t$<>"" !終端以外なら
   IF s=0 THEN
      IF t$="+" THEN !+演算子
         LET s=1
      ELSEIF t$="-" THEN !-演算子
         LET s=-1
      END IF
      LET p=p+1 !eat it

      LET K=K+1
   ELSE
      LET a(K,0)=s
      DO
         IF t$<>"" AND idx(t$)>0THEN !変数なら
            LET p=p+1 !eat it

            LET t=idx(t$)

            CALL GetToken(p,s$, t$)
            LET v=1
            IF t$="^" THEN !べき乗
               LET p=p+1 !eat it
               CALL GetRational(p,s$, v)
            END IF
            LET a(K,t)=a(K,t)+v
         ELSE
            CALL GetRational(p,s$, v) !係数
            LET a(K,0)=a(K,0)*v
         END IF

         CALL GetToken(p,s$, t$)
      LOOP UNTIL t$="+" OR t$="-" OR t$="" !±演算子、終端が現れるまで

      LET s=0 !次は±演算子である
   END IF

   CALL GetToken(p,s$, t$) !トークン
LOOP
IF s<>0 THEN
   PRINT "項がありません。"; p
   STOP
END IF
LET a(0,0)=K !項数
END SUB


EXTERNAL SUB GetToken(p,s$, t$) !1文字を得る
OPTION ARITHMETIC RATIONAL
LET t$=s$(p:p)
DO WHILE t$=" " !空白文字はスキップする
   LET p=p+1
   LET t$=s$(p:p)
LOOP
END SUB


EXTERNAL SUB GetRational(p,s$, v) !n,(±m/n)形式の数を得る
OPTION ARITHMETIC RATIONAL
CALL GetToken(p,s$, t$)
IF t$="(" THEN !負の数、有理数
   LET p=p+1 !eat it

   CALL GetToken(p,s$, t$)
   LET s=1 !符号を得る
   IF t$="+" THEN
      LET p=p+1 !eat it
   END IF
   IF t$="-" THEN
      LET p=p+1 !eat it
      LET s=-1
   END IF
   CALL GetInteger(p,s$, v1)
   !!!PRINT s; v1

   LET v2=1
   CALL GetToken(p,s$, t$)
   IF t$="/" THEN !有理数なら、分母を得る
      LET p=p+1 !eat it
      CALL GetInteger(p,s$, v2)
      !!!PRINT v2
   END IF
   LET v=s*v1/v2

   CALL GetToken(p,s$, t$)
   IF t$<>")" THEN
      PRINT ")がありません。"; p
      STOP
   END IF
   LET p=p+1 !eat it

ELSE !正の整数
   CALL GetInteger(p,s$, v)

END IF
END SUB


EXTERNAL SUB GetInteger(p,s$, v) !正の整数を得る
OPTION ARITHMETIC RATIONAL
CALL GetToken(p,s$, t$)
IF t$<"0" OR t$>"9" THEN
   PRINT "数字ではありません。"; p
   STOP
END IF
LET v=0
DO WHILE t$>="0" AND t$<="9" !連続する数字列を10進法の数とみなす
   LET v=v*10+VAL(t$)
   LET p=p+1
   LET t$=s$(p:p)
LOOP
END SUB



終わり

 

Re: 多変数多項式の計算 mPOLYMX.LIB

 投稿者:山中和義  投稿日:2014年11月15日(土)23時21分2秒
  > No.3548[元記事へ]

サブルーチン mPOLYMX.LIB


!mPOLYMX.LIB

!行列

!要素位置は、連番で指定する。 配列の1番目の要素a(x,,)に対応させる
!例 3×3の場合
! ┌ 0 1 2 ┐
! │ 3 4 5 │
! └ 6 7 8 ┘

EXTERNAL SUB MtxSet(p(,),x, a(,,)) !行列の要素に登録する LET a(x)=p
OPTION ARITHMETIC RATIONAL
LET K=p(0,0) !項の数を得る
FOR i=1 TO K
   FOR e=0 TO N !係数、次数
      LET a(x,i,e)=p(i,e)
   NEXT e
NEXT i
LET a(x,0,0)=K !項の数
END SUB

EXTERNAL SUB MtxGet(a(,,),x, p(,)) !行列の要素を得る LET p=a(x)
OPTION ARITHMETIC RATIONAL
LET K=a(x,0,0) !項の数を得る
FOR i=1 TO K
   FOR e=0 TO N !係数、次数
      LET p(i,e)=a(x,i,e)
   NEXT e
NEXT i
LET p(0,0)=K !項の数
END SUB


!表示関連

EXTERNAL SUB MtxPrint(P,Q,a(,,)) !行列を表示する
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
FOR i=0 TO P-1 !i行
   FOR J=0 TO Q-1 !j列
      CALL MtxGet(a,Q*i+J, t)
      CALL PolyPrint(t)
      PRINT "  ";
   NEXT J
   PRINT
NEXT i
END SUB


!演算関連

EXTERNAL SUB MtxZER(P,Q,a(,,)) !0にする A=O
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
CALL PolySet("0", t)
FOR i=0 TO P*Q-1
   CALL MtxSet(t,i, a)
NEXT i
END SUB

EXTERNAL SUB MtxIDN(M,a(,,)) !単位行列 A=E
OPTION ARITHMETIC RATIONAL
DIM t0(0 TO MAX_TERM, 0 TO N), t1(0 TO MAX_TERM, 0 TO N)
CALL PolySet("0", t0)
CALL PolySet("1", t1)
FOR i=0 TO M-1 !i行
   FOR J=0 TO M-1 !j列
      IF J=i THEN CALL MtxSet(t1,M*i+J, a) ELSE CALL MtxSet(t0,M*i+J, a)
   NEXT J
NEXT i
END SUB

EXTERNAL SUB MtxCopy(P,Q,a(,,), b(,,)) !コピーする B=A
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
FOR i=0 TO P*Q-1
   CALL MtxGet(a,i, t)
   CALL MtxSet(t,i, b)
NEXT i
END SUB

EXTERNAL SUB MtxAdd(P,Q,a(,,),b(,,), c(,,)) !和 C=A+B ※C≠A、C≠Bの配列を指定する
OPTION ARITHMETIC RATIONAL
DIM x(0 TO MAX_TERM, 0 TO N), y(0 TO MAX_TERM, 0 TO N), s(0 TO MAX_TERM, 0 TO N)
FOR i=0 TO P*Q-1
   CALL MtxGet(a,i, x)
   CALL MtxGet(b,i, y)
   CALL PolyAdd(x,y, s)
   CALL MtxSet(s,i, c)
NEXT i
END SUB

EXTERNAL SUB MtxSub(P,Q,a(,,),b(,,), c(,,)) !差 C=A-B ※C≠A、C≠Bの配列を指定する
OPTION ARITHMETIC RATIONAL
DIM x(0 TO MAX_TERM, 0 TO N), y(0 TO MAX_TERM, 0 TO N), s(0 TO MAX_TERM, 0 TO N)
FOR i=0 TO P*Q-1
   CALL MtxGet(a,i, x)
   CALL MtxGet(b,i, y)
   CALL PolySubtract(x,y, s)
   CALL MtxSet(s,i, c)
NEXT i
END SUB

EXTERNAL SUB MtxMul(P,Q,R,a(,,),b(,,), c(,,)) !積 C=AB ※C≠A、C≠Bの配列を指定する
OPTION ARITHMETIC RATIONAL
DIM x(0 TO MAX_TERM, 0 TO N), y(0 TO MAX_TERM, 0 TO N)
DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N)
FOR i=0 TO P-1 !i行
   FOR J=0 TO R-1 !j列
      MAT s=ZER !Σ
      LET s(0,0)=1
      FOR K=0 TO Q-1
         CALL MtxGet(a,Q*i+K, x) !p,q
         CALL MtxGet(b,R*K+J, y) !q,r
         CALL PolyMultiply(x,y, t)
         CALL PolyAdd(s,t, x)
         CALL PolyCopy(x,s)
      NEXT K
      CALL MtxSet(s,R*i+J, c) !p,r
   NEXT J
NEXT i
END SUB

EXTERNAL SUB MtxTRN(P,Q,a(,,), t(,,)) !転置 ※T≠Aの配列を指定する
OPTION ARITHMETIC RATIONAL
DIM x(0 TO MAX_TERM, 0 TO N)
FOR i=0 TO P-1 !行
   FOR J=0 TO Q-1 !列
      CALL MtxGet(a,Q*i+J, x)
      CALL MtxSet(x,P*J+i, t)
   NEXT J
NEXT i
END SUB

EXTERNAL SUB MtxTR(M,a(,,), t(,)) !トレース tr(A) ※T≠Aの配列を指定する
OPTION ARITHMETIC RATIONAL
DIM x(0 TO MAX_TERM, 0 TO N), y(0 TO MAX_TERM, 0 TO N)
MAT t=ZER !定数 0
LET t(0,0)=1
FOR i=0 TO M-1 !i対角線の和
   CALL MtxGet(a,M*i+i, x)
   CALL PolyAdd(t,x, y)
   CALL PolyCopy(y, t)
NEXT i
END SUB

!例 余因子展開 3×3の場合
! | 0 1 2 | = 0 | 4 5 |  - 3 | 1 2 |  + 6 | 1 2 |
! | 3 4 5 |     | 7 8 |      | 7 8 |      | 4 5 |
! | 6 7 8 |
EXTERNAL SUB MtxDET(M,a(,,), d(,)) !行列式 |A|
OPTION ARITHMETIC RATIONAL
IF M>1 THEN !m×m
   MAT d=ZER !定数 0
   LET d(0,0)=1

   DIM a2(0 TO (M-1)^2-1, 0 TO MAX_TERM, 0 TO N)
   DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N), u(0 TO MAX_TERM, 0 TO N)
   FOR R=0 TO M-1 !1列目で展開する
      LET X=0
      FOR i=0 TO M-1 !小行列式をつくる
         FOR J=1 TO M-1
            IF i=R THEN !行が同じなら、除く
            ELSE
               CALL MtxGet(a,M*i+J, s)
               CALL MtxSet(s,X, a2)
               LET X=X+1
            END IF
         NEXT J
      NEXT i
      CALL MtxDET(M-1,a2, t) !再帰呼び出し
      CALL MtxGet(a,M*R, s)
      CALL PolyMultiply(s,t, u)

      IF MOD(R,2)=0 THEN CALL PolyAdd(d,u, t) ELSE CALL PolySubtract(d,u, t) !Σ
      CALL PolyCopy(t,d)
   NEXT R
ELSE
   CALL MtxGet(a,0, d) !1×1の場合
END IF
END SUB


 

Re: 多変数多項式の計算(mPOLY.LIB、mPOLYMX.LIB)

 投稿者:山中和義  投稿日:2014年11月15日(土)23時24分34秒
  > No.3549[元記事へ]

使用例


例1 式の展開
(a+b+c)(a+ω^2b+ωc)(a+ωb+ω^2c)=a^3+b^3+c^3-3abc


OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="wabcdpqxyzi"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM f(0 TO 10, 0 TO N)
CALL PolySet("a+b+c", f)
CALL PolyPrint(f) !結果を表示する
PRINT

DIM g(0 TO 10, 0 TO N)
CALL PolySet("a+wb+w^2c", g)
CALL PolyPrint(g) !結果を表示する
PRINT

DIM h(0 TO 10, 0 TO N)
CALL PolySet("a+w^2b+wc", h)
CALL PolyPrint(h) !結果を表示する
PRINT


DIM s(0 TO 100, 0 TO N), t(0 TO 100, 0 TO N)
CALL PolyMultiply(f,g, s) !f*g
CALL PolyPrintCollect(s,"w") !結果を表示する
PRINT

CALL PolyMultiply(s,h, t) !(f*g)*h
CALL PolyPrintCollect(t,"w") !結果を表示する
PRINT

CALL PolySimplify2(t)

CALL PolyPrint(t) !結果を表示する
PRINT


!----------------------------------------------

CALL PolyMultiply(f,g, s) !f*g
CALL PolyPrintCollect(s,"w") !結果を表示する
PRINT

CALL PolyMultiply(s,h, t) !(f*g)*h
CALL PolyPrintCollect(t,"w") !結果を表示する
PRINT

DIM q(0 TO 100, 0 TO N), r(0 TO 100, 0 TO N)
CALL PolySet("w^2+w+1", s)
CALL PolyQuotientRemainder(t,s,"w", q,r)
CALL PolyPrintCollect(q,"w") !結果を表示する
PRINT
CALL PolyPrintCollect(r,"w") !結果を表示する
PRINT

END

MERGE "mPOLY.LIB" !多変数の多項式の計算


実行結果

a+b+c
a+wb+w^2c
a+w^2b+wc
(a^2+ab+ac)+(ab+b^2+bc)w+(ac+bc+c^2)w^2
(a^3+a^2b+a^2c)+(a^2c+a^2b+2abc+ab^2+ac^2)w+(a^2b+3abc+a^2c+ab^2+b^2c+bc^2+ac^2)w^2+(ab^2+ac^2+b^3+bc^2+b^2c+c^3)w^3+(abc+b^2c+bc^2)w^4
a^3+b^3+c^3-3abc
(a^2+ab+ac)+(ab+b^2+bc)w+(ac+bc+c^2)w^2
(a^3+a^2b+a^2c)+(a^2c+a^2b+2abc+ab^2+ac^2)w+(a^2b+3abc+a^2c+ab^2+b^2c+bc^2+ac^2)w^2+(ab^2+ac^2+b^3+bc^2+b^2c+c^3)w^3+(abc+b^2c+bc^2)w^4
(+a^2b+3abc+a^2c-b^3-c^3)+(ab^2+ac^2+b^3+c^3-abc)w+(abc+b^2c+bc^2)w^2
(a^3-3abc+b^3+c^3)




例2 判別式
x^3+px+q=0の判別式 D=-4p^3-27q^2 より、x^3+ax+bx+c=0の判別式を求める


OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="wpqabcdxyzi"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM f(0 TO MAX_TERM, 0 TO N)
CALL PolySet("x^3+ax^2+bx+c", f)
CALL PolyPrint(f) !結果を表示する
PRINT

DIM h(0 TO MAX_TERM, 0 TO N) !x=X-a/3
CALL PolySet("x-(1/3)a", h)
CALL PolyPrint(h) !結果を表示する
PRINT

DIM g(0 TO MAX_TERM, 0 TO N)
CALL PolyComposition(f,"x",h, g)
CALL PolyPrint(g) !結果を表示する
PRINT


DIM p(0 TO MAX_TERM, 0 TO N), q(0 TO MAX_TERM, 0 TO N)
CALL PolyCoefficient(g,"x",1, p)
CALL PolyPrint(p) !結果を表示する
PRINT
CALL PolyCoefficient(g,"x",0, q)
CALL PolyPrint(q) !結果を表示する
PRINT


DIM d(0 TO MAX_TERM, 0 TO N)
CALL PolySet("-4p^3-27q^2", d)
CALL PolyComposition(d,"p",p, h) !pに代入する
CALL PolyComposition(h,"q",q, d) !qに代入する
CALL PolyPrint(d) !結果を表示する
PRINT

END

MERGE "mPOLY.LIB" !多変数の多項式の計算


実行結果

x^3+ax^2+bx+c
x-(1/3)a
+x^3-(1/3)a^2x+(2/27)a^3+bx-(1/3)ab+c
-(1/3)a^2+b
+(2/27)a^3-(1/3)ab+c
-4a^3c+a^2b^2+18abc-27c^2-4b^3




例3 判別式
差積による
3次方程式x^3+px+q=0の判別式
答え
3つの解をa,b,cとすると、解と係数の関係より、
a+b+c=0
ab+bc+ca=p
abc=-q

まず、b,cを消去する。
1番目の式より、b+c=-a
2番目の式より、a(b+c)+bc=p ∴-a^2+bc=p ∴bc=p+a^2

これより、
(a-b)(c-a)
=-(a-b)(a-c)
=-{a^2-(b+c)a+bc}
=-{a^2-(-a)a+(p+a^2)}
=-3a^2-p

(b-c)^2
=(b+c)^2-4bc
=(-a)^2-4(p+a^2)
=-3a^2-4p
なので、

{(a-b)(b-c)(c-a)}^2
=(b-c)^2{(a-b)(c-a)}^2
=(-3a^2-4p)(-3a^2-p)^2
=-27a^6 -54pa^4 -27p^2a^2 -4p^3

a^3+pa+q=0を適用して、-4p^3-27q^2 となる。


∵
              -27a^3 -27pa   +27q
           --------------------------------------------------
 a^3+pa+q   ) -27a^6 -54pa^4         -27p^2a^2        -4p^3
              -27a^6 -27pa^4 -27qa^3
            -------------------------------------------------
                     -27pa^4 +27qa^3 -27p^2a^2        -4p^3
                     -27pa^4         -27p^2a^2 -27pqa
                  -------------------------------------------
                              27qa^3           +27pqa -4p^3
                              27qa^3           +27pqa +27q^2
                          -----------------------------------------
                                                      -4p^3-27q^2
(終わり)


OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="wpqabcdxyzi"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

CALL PolySet("-3a^2-p", f) !(-3a^2-4p)(-3a^2-p)^2
CALL PolyMultiply(f,f, g)
CALL PolySet("-3a^2-4p", f)
CALL PolyMultiply(f,g, h)
CALL PolyPrint(h) !結果を表示する
PRINT

CALL PolySet("a^3+pa+q", f)

CALL PolyQuotientRemainder(h,f,"a", g,d)
CALL PolyPrint(g) !結果を表示する
PRINT
CALL PolyPrint(d) !結果を表示する
PRINT

END

MERGE "mPOLY.LIB" !多変数の多項式の計算


実行結果

-27a^6-54pa^4-27p^2a^2-4p^3
-27a^3-27pa+27q
-4p^3-27q^2




終結式による
3次方程式 ax^3+bx^2+cx+d=0 の判別式
答え
終結式(シルベスター行列式)と判別式Dとの関係 Res(f,f')=(-1)^{n(n-1)/2}aD

Res(f,f') = | a   b   c   d   0 |
           | 0   a   b   c   d |
           | 3a  2b  c   0   0 |
           | 0   3a  2b  c   0 |
           | 0   0   3a  2b  c |

(2n-1)次の行列式で表される。
(終わり)


OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="abcde"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数 ※調整が必要である
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM a(0 TO 5^2-1, 0 TO MAX_TERM, 0 TO N) !5行5列の行列式

DIM f(0 TO MAX_TERM, 0 TO N), d(0 TO MAX_TERM, 0 TO N)

DATA "a",  "b",  "c",  "d",  "0" !f
DATA "0",  "a",  "b",  "c",  "d"
DATA "3a", "2b", "c",  "0",  "0" !f'
DATA "0",  "3a", "2b", "c",  "0"
DATA "0",  "0",  "3a", "2b", "c"

FOR i=0 TO 5-1 !行
   FOR J=0 TO 5-1 !列
      READ s$
      CALL PolySet(s$, f)
      CALL PolyPrint(f) !結果を表示する
      PRINT
      CALL MtxSet(f,5*i+J, a)
   NEXT J
NEXT i

CALL MtxDET(5,a, d)
CALL PolyPrint(d) !結果を表示する
PRINT

CALL PolySet("-a", f) !-aで割る
CALL PolyDivide(d,f, d)
CALL PolyPrint(d) !結果を表示する
PRINT

END

MERGE "mPOLY.LIB" !多変数の多項式の計算
MERGE "mPOLYMX.LIB" !多変数の多項式(行列関連)


実行結果

a
b
c
d
0
0
a
b
c
d
3a
2b
c
0
0
0
3a
2b
c
0
0
0
3a
2b
c
+4a^2c^3-ab^2c^2+4ab^3d-18a^2bcd+27a^3d^2
-4ac^3+b^2c^2-4b^3d+18abcd-27a^2d^2



 

Re: 多変数多項式の計算(mPOLY.LIB、mPOLYMX.LIB)

 投稿者:山中和義  投稿日:2014年11月17日(月)12時56分1秒
  > No.3550[元記事へ]

> 使用例

問題
1/(√2+√3+√5)の分母を有理化せよ。

答え
x=√2+√3+√5とすると、最小多項式は、x^8-40x^6+352x^4-960x^2+576 となる。
x^8-40x^6+352x^4-960x^2+576=0より、576=-x(x^7-40x^5+352x^3-960x) ∴1/x=-(x^7-40x^5+352x^3-960x)/576
x=√2+√3+√5を代入して、(3√2+2√3-√30)/12
(終わり)

係数は有理数なので、平方根などの計算は未サポートだが、

a=√2、b=√3、c=√5とおくと、
最小多項式は、
  (x-(a+b+c))(x-(a+b-c))(x-(a-b+c))(x-(a-b-c))(x-(-a+b+c))(x-(-a+b-c))(x-(-a-b+c))(x-(-a-b-c))
で求まるので、展開して、a^2-2=0、b^2-3=0、c^2-5=0を適用する。



OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="wabcdpqxyzi"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=500
!------------------------------ ここまでがサブルーチン

!最小多項式

DATA " a+b-c" !α1
DATA " a-b+c" !α2
DATA " a-b-c" !α3
DATA "-a+b+c" !α4
DATA "-a+b-c" !α5
DATA "-a-b+c" !α6
DATA "-a-b-c" !α7
DATA " a+b+c" !α8

DIM f(0 TO MAX_TERM, 0 TO N), g(0 TO MAX_TERM, 0 TO N), h(0 TO MAX_TERM, 0 TO N)
DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N)
CALL PolySet("1", s) !Πfk
FOR i=1 TO 8
   READ s$

   CALL PolySet(s$, g) !fk=x-αk
   CALL PolySet("x", h)
   CALL PolySubtract(h,g, f)
   CALL PolyPrint(f) !結果を表示する
   PRINT

   CALL PolyMultiply(s,f, t) !(x-α1)*(x-α2)* …
   !!CALL PolyPrint(t) !結果を表示する
   !!PRINT

   CALL PolyCopy(t, s)
NEXT i
CALL FmodA(s, f)
CALL PolyPrintCollect(f,"x") !結果を表示する
PRINT


!-------------------------------

!分子
CALL PolySet("0", g)
CALL PolyComposition(f,"x",g, h) !h=f(0)

CALL PolySubtract(h,f, t) !s=-(f-f(0))/x
CALL PolySet("x", g)
CALL PolyDivide(t,g, s)
CALL PolyPrintCollect(s,"x") !結果を表示する
PRINT

CALL PolySet("a+b+c", g) !x=a+b+c
CALL PolyComposition(s,"x",g, t)

CALL FmodA(t, s)
CALL PolyPrint(s) !結果を表示する
PRINT


!分母
CALL PolyDivide(s,h, t)
CALL PolyPrint(t) !結果を表示する
PRINT

END

EXTERNAL SUB FmodA(f(,), fm(,)) !fm≡f mod A, mod B, …
OPTION ARITHMETIC RATIONAL
DATA "a^2-2", "a"
DATA "b^2-3", "b"
DATA "c^2-5", "c"

DIM g(0 TO MAX_TERM, 0 TO N), q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)
CALL PolyCopy(f, fm)
FOR i=1 TO 3
   READ s$,x$
   CALL PolySet(s$, g)

   CALL PolyQuotientRemainder(fm,g,x$, q,r)
   !!CALL PolyPrintCollect(q,x$) !結果を表示する
   !!PRINT
   !!CALL PolyPrintCollect(r,x$) !結果を表示する
   !!PRINT

   CALL PolyCopy(r, fm)
NEXT i
END SUB


MERGE "mPOLY.LIB" !多変数の多項式の計算



実行結果

x-a-b+c
x-a+b-c
x-a+b+c
x+a-b-c
x+a-b+c
x+a+b-c
x+a+b+c
x-a-b-c
(576)+(-960)x^2+(352)x^4+(-40)x^6+x^8
(960)x+(-352)x^3+(40)x^5+(-1)x^7
-48abc+144a+96b
-(1/12)abc+(1/4)a+(1/6)b




別解
共役の数をかけると、有理数になる。
a+b+cなので、
  a+b-c
  a-b+c
  a-b-c
 -a+b+c
 -a+b-c
 -a-b+c
 -a-b-c
をかけることになる。

計算量を軽減するには、(a+b+c)(a+b-c)≡2abなので、分子と分母にab(a+b-c)をかければよい。



OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="wabcdxyzi"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=200
!------------------------------ ここまでがサブルーチン

!1/(√2+√3+√5)の分母を有理化せよ。

DATA " a+b+c" !分母
DATA " a+b-c"
DATA " a-b+c"
DATA " a-b-c"
DATA "-a+b+c"
DATA "-a+b-c"
DATA "-a-b+c"
DATA "-a-b-c"

DIM f(0 TO MAX_TERM, 0 TO N)
DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N)
CALL PolySet("1", s) !Π
FOR i=1 TO 8
   READ s$

   CALL PolySet(s$, f)
   CALL PolyPrint(f) !結果を表示する
   PRINT

   CALL PolyMultiply(s,f, t) !f1*f2* …
   CALL PolyPrint(t) !結果を表示する
   PRINT

   CALL PolyCopy(t, s)

   CALL FmodA(t, f)
   CALL PolyPrint(f)
   PRINT

   PRINT
NEXT i

END


※サブルーチン部分は同じ


実行結果

a+b+c
a+b+c
a+b+c

a+b-c
a^2+2ab+b^2-c^2
2ab

a-b+c
a^3+a^2b+a^2c-ab^2+2abc-b^3+b^2c-ac^2+bc^2-c^3
2abc-6a+4b

a-b-c
a^4-2a^2b^2-2a^2c^2+b^4-2b^2c^2+c^4
-24

-a+b+c
-a^5+a^4b+a^4c+2a^3b^2-2a^2b^3-2a^2b^2c+2a^3c^2-2a^2bc^2-2a^2c^3-ab^4+b^5+b^4c+2ab^2c^2-2b^3c^2-2b^2c^3-ac^4+bc^4+c^5
24a-24b-24c

-a+b-c
a^6-2a^5b-a^4b^2-3a^4c^2+4a^3b^3-a^2b^4-2a^2b^2c^2+4a^3bc^2+3a^2c^4-2ab^5+b^6-3b^4c^2+4ab^3c^2+3b^2c^4-2abc^4-c^6
48ab

-a-b+c
-a^7+a^6b+a^6c+3a^5b^2-2a^5bc-3a^4b^3-a^4b^2c+3a^5c^2-a^4bc^2-3a^4c^3-3a^3b^4+4a^3b^3c+3a^2b^5-a^2b^4c-2a^3b^2c^2-2a^2b^3c^2-2a^2b^2c^3+4a^3bc^3-3a^3c^4-a^2bc^4+3a^2c^5+ab^6-2ab^5c-b^7+b^6c-ab^4c^2+3b^5c^2-3b^4c^3+4ab^3c^3-ab^2c^4-3b^3c^4+3b^2c^5-2abc^5+ac^6+bc^6-c^7
48abc-144a-96b

-a-b-c
a^8-4a^6b^2-4a^6c^2+6a^4b^4+4a^4b^2c^2+6a^4c^4-4a^2b^6+4a^2b^4c^2+4a^2b^2c^4-4a^2c^6+b^8-4b^6c^2+6b^4c^4-4b^2c^6+c^8
576


 

Re: 多変数多項式の計算(mPOLY.LIB、mPOLYMX.LIB)

 投稿者:山中和義  投稿日:2014年11月19日(水)13時09分34秒
  > No.3551[元記事へ]

> 使用例

問題
3次方程式 x^3-3x+1=0 の1つの解をαとするとき、
 1/(α^2-α-2) - 1/(α^2+α-2) + 1/(α^2-2α+1) - 1/(α^2+2α+1)
の値を求めよ。

答え 有理化による
1/(α^2-α-2)≡Aα^2+Bα+Cと表されるなら、1=(Aα^2+Bα+C)(α^2-α-2)
右辺を展開して、左辺との係数比較より、A,B,Cの連立方程式を得る。
これを解いて、A=0、B=-1/3、C=-1/3となる。
同様に、
1/(α^2+α-2)≡(1)α+(-1)
1/(α^2-2α+1)≡(1)α+(2)
1/(α^2+2α+1)≡(-1/3)α+(2/3)
これより、与式=2
(終わり)


1/(α^2-α-2)の場合


OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="ABCa"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM f1(0 TO 10, 0 TO N), f2(0 TO 10, 0 TO N)
CALL PolySet("a^2-a-2", f1)
CALL PolyPrint(f1) !結果を表示する
PRINT

CALL PolySet("Aa^2+Ba+C", f2)
CALL PolyPrint(f2) !結果を表示する
PRINT

DIM g(0 TO MAX_TERM, 0 TO N)
CALL PolySet("a^3-3a+1", g)
CALL PolyPrint(g) !結果を表示する
PRINT


DIM t(0 TO MAX_TERM, 0 TO N)
CALL PolyMultiply(f1,f2, t)

DIM q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)
CALL PolyQuotientRemainder(t,g,"a", q,r)
CALL PolyPrintCollect(q,"a") !結果を表示する
PRINT
CALL PolyPrintCollect(r,"a") !結果を表示する
PRINT

END

MERGE "mPOLY.LIB" !多変数の多項式の計算


実行結果

a^2-a-2
Aa^2+Ba+C
a^3-3a+1
+(B-A)+(A)a
+(-2C-B+A)+(-4A+B-C)a+(A-B+C)a^2



連立方程式を解く


OPTION ARITHMETIC RATIONAL
DATA  1,-1,-2 !A
DATA -4, 1,-1
DATA  1,-1, 1
DATA  1, 0, 0 !b
DIM A(3,3),x(3),b(3) !Ax=b
MAT READ A
MAT READ b
DIM iA(3,3) !solve it
MAT iA=INV(A)
MAT x=iA*b
MAT PRINT x;
END


実行結果

0 -1/3 -1/3





答え 有理化による
0=α^3-3α+1=(α+1)(α^2-α-2)+3より、1/(α^2-α-2)=-(α+1)/3
一般に、0=f=Qg+Rより、1/g=-Q/R
同様に、
1/(α^2+α-2)=(1)α+(-1)
1/(α^2-2α+1)=(1)α+(2)
1/(α^2+2α+1)=(-1/3)α+(2/3)
これより、与式=2
(終わり)


OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="ABCa"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM f(0 TO 10, 0 TO N), g(0 TO 10, 0 TO N)
CALL PolySet("a^3-3a+1", f)
CALL PolyPrint(f) !結果を表示する
PRINT

CALL PolySet("a^2-a-2", g)
!CALL PolySet("a^2+a-2", g)
!CALL PolySet("a^2-2a+1", g)
!CALL PolySet("a^2+2a+1", g)
CALL PolyPrint(g) !結果を表示する
PRINT

DIM q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)
CALL PolyQuotientRemainder(f,g,"a", q,r)
CALL PolyPrintCollect(q,"a") !結果を表示する
PRINT
CALL PolyPrintCollect(r,"a") !結果を表示する
PRINT

END

MERGE "mPOLY.LIB" !多変数の多項式の計算


実行結果

a^3-3a+1
a^2-a-2
+(1)+(1)a
+(3)





答え 有理化による
拡張ユークリッドの互除法 fs+gt=k(f,g) より、
f(x)=x^3-3x+1、g(x)=x^2-x-2のとき、f(x)(1)+g(x)(-x-1)=3を得る。
f(α)=0から、g(α)(-α-1)=3 ∴1/g(α)=(-α-1)/3



OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="ABCa"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM f(0 TO 10, 0 TO N), g(0 TO 10, 0 TO N)
CALL PolySet("a^3-3a+1", f)
CALL PolyPrint(f) !結果を表示する
PRINT

CALL PolySet("a^2-a-2", g)
!CALL PolySet("a^2+a-2", g)
!CALL PolySet("a^2-2a+1", g)
!CALL PolySet("a^2+2a+1", g)
CALL PolyPrint(g) !結果を表示する
PRINT

DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N), c(0 TO MAX_TERM, 0 TO N)
CALL PolyExtendedGCD(f,g,"a", s,t,c)
CALL PolyPrint(s) !結果を表示する
PRINT
CALL PolyPrint(t) !結果を表示する
PRINT
CALL PolyPrint(c) !結果を表示する
PRINT

END


!拡張ユークリッド互除法 f(x)S(x)+g(x)T(x)=Kgcd(f(x),g(x))=C(x)となるS(x),T(x),C(x)を求める。
EXTERNAL SUB PolyExtendedGCD(a(,),b(,),x$, s(,),t(,),c(,)) !拡張ユークリッド互除法
OPTION ARITHMETIC RATIONAL
IF b(0,0)=1 AND b(1,0)=0 THEN !!--- IF b=0 THEN
!!--- s=1 !※f(x)*1+0*0=f(x)とする
   CALL PolySet("1", s)
   !!--- t=0
   CALL PolySet("0", t)
   !!--- c=a
   CALL PolyCopy(a, c)
ELSE
!!--- q=INT(a/b), r=MOD(a,b)
   DIM q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)

   CALL isConst(a,1, rc1)
   CALL isConst(b,1, rc2)
   IF (a(0,0)=1 AND rc1<>0) AND (b(0,0)=1 AND rc2<>0) THEN !定数項のみなら
      MAT q=ZER
      LET q(1,0)=INT(a(1,0)/b(1,0))
      LET q(0,0)=1
      MAT r=ZER
      LET r(1,0)=MOD(a(1,0),b(1,0))
      LET r(0,0)=1
   ELSE
      CALL PolyQuotientRemainder(a,b,x$, q,r)
   END IF

   !!--- CALL ExGCD(b,r, u,v,c) !k=n-1,…,3,2 まで続ける
   !!--- s=v
   DIM u(0 TO MAX_TERM, 0 TO N)
   CALL PolyExtendedGCD(b,r,x$, u,s,c)

   !!--- t=u-v*q
   DIM w(0 TO MAX_TERM, 0 TO N)
   CALL PolyMultiply(s,q, w)
   CALL PolySubtract(u, w, t)
END IF
END SUB


MERGE "mPOLY.LIB" !多変数の多項式の計算


実行結果

a^3-3a+1
a^2-a-2
1
-a-1
3


 

Re: 多変数多項式の計算(mPOLY.LIB、mPOLYMX.LIB)

 投稿者:山中和義  投稿日:2014年11月22日(土)16時10分9秒
  > No.3552[元記事へ]

> 使用例

逆行列を求める。

一般に、分数式になるので、|A|倍のものを求める。



OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="abcdefghi"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

!LET M=3
!DATA "1", "2",  "5"
!DATA "1", "-1", "1"
!DATA "0", "1",  "2"

!LET M=2
!DATA "a", "b"
!DATA "c", "d"

LET M=3
DATA "a", "b", "c"
DATA "d", "e", "f"
DATA "g", "h", "i"

DIM a(0 TO M*M-1, 0 TO MAX_TERM, 0 TO N)
DIM f(0 TO MAX_TERM, 0 TO N)
FOR i=0 TO M*M-1
   READ s$
   CALL PolySet(s$, f)
   CALL MtxSet(f,i, a)
NEXT i

DIM d(0 TO MAX_TERM, 0 TO N)
CALL MtxDET(M,a, d) !|A|の値
CALL PolyPrint(d)
PRINT

PRINT

!逆行列 ※|A|倍、余因子行列A~を表示する
DIM w(0 TO (M-1)*(M-1)-1, 0 TO MAX_TERM, 0 TO N)
FOR i=0 TO M-1 !i行
   FOR J=0 TO M-1 !j列
      CALL MtxAij(M,a,J,i, w) !Ajiに注意する
      CALL MtxDET(M-1,w, d)
      CALL PolyMultiplyC(d,(-1)^(i+j), d) !余因子
      CALL PolyPrint(d)
      PRINT "  ";
   NEXT J
   PRINT
NEXT i

END


EXTERNAL SUB MtxAij(M,a(,,),i,J, aij(,,)) !行列Aのi,j成分を除いた行列Aij
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
LET K=0
FOR y=0 TO M-1
   IF y<>i THEN !i行を除く
      FOR x=0 TO M-1
         IF x<>J THEN !j列を除く
            CALL MtxGet(a,M*y+x, t) !copy it
            CALL MtxSet(t,K, aij)
            LET K=K+1
         END IF
      NEXT x
   END IF
NEXT y
END SUB


MERGE "mPOLY.LIB" !多変数の多項式の計算
MERGE "mPOLYMX.LIB" !多変数の多項式(行列関連)


実行結果

aei-afh-bdi+cdh+bfg-ceg

ei-fh  -bi+ch  bf-ce
-di+fg  ai-cg  -af+cd
dh-eg  -ah+bg  ae-bd


 

Re: 多変数多項式の計算(mPOLY.LIB、mPOLYMX.LIB)

 投稿者:山中和義  投稿日:2014年11月24日(月)14時10分2秒
  > No.3553[元記事へ]

> 使用例

> 3次方程式 x^3-3x+1=0 の1つの解をαとするとき、
>  1/(α^2-α-2) - 1/(α^2+α-2) + 1/(α^2-2α+1) - 1/(α^2+2α+1)
> の値を求めよ。


答え 通分による
第1項と第4項
1/(α^2-α-2) - 1/(α^2+2α+1)
=1/{(α+1)(α-2)} - 1/(α+1)^2
={(α+1) - (α-2)} / {(α+1)^2(α-2)}
=3 / (α^3-3α+1 -3)
=-1 ∵α^3-3α+1=0より
第3項と第2項
1/(α^2-2α+1) - 1/(α^2+α-2)
=1/(α-1)^2 - 1/{(α-1)(α+2)}
={(α+2) - (α-1)} / {(α-1)^2(α+2)}
=3 / (α^3-3α+1 +1)
=3 ∵α^3-3α+1=0より
よって、(-1)+3=2



OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="a"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM f(0 TO MAX_TERM, 0 TO N)
CALL PolySet("a^3-3a+1", f)



DIM q1(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL QSet("1","a^2-a-2", q1)

DIM q4(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL QSet("1","a^2+2a+1", q4)

DIM t1(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL QSub(q1,q4, t1)
CALL PolyPrintQ(t1)
PRINT

CALL QSimplify(t1,"a")
CALL PolyPrintQ(t1) !結果を表示する
PRINT


DIM t(0 TO MAX_TERM, 0 TO N), q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)
CALL MtxGet(t1,1, t) !分母
CALL PolyQuotientRemainder(t,f,"a", q,r)
CALL PolyPrint(r) !結果を表示する
PRINT

CALL MtxSet(r,1, t1) !分母を置き換える

PRINT

!---------------------------------------------

DIM q3(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL QSet("1","a^2-2a+1", q3)

DIM q2(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL QSet("1","a^2+a-2", q2)

DIM t2(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL QSub(q3,q2, t2)
CALL PolyPrintQ(t2)
PRINT

CALL QSimplify(t2,"a")
CALL PolyPrintQ(t2) !結果を表示する
PRINT


CALL MtxGet(t2,1, t) !分母
CALL PolyQuotientRemainder(t,f,"a", q,r)
CALL PolyPrint(r) !結果を表示する
PRINT

CALL MtxSet(r,1, t2) !分母を置き換える

PRINT

!---------------------------------------------

DIM t3(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL QAdd(t1,t2, t3)
CALL PolyPrintQ(t3)
PRINT

CALL QSimplify(t3,"a")
CALL PolyPrintQ(t3)
PRINT

END


!mPOLYQ.LIB

!分数式 p=f/g  ※分子p(0,,)、分母p(1,,)

EXTERNAL SUB QSet(a$,b$, q(,,)) ! !分数式を符号化する q=a/b
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
CALL PolySet(a$, t) !分子
CALL MtxSet(t,0, q)
CALL PolySet(b$, t) !分母
CALL MtxSet(t,1, q)
END SUB

EXTERNAL SUB NUMER(x(,,), f(,)) !xの分子(numerator)
OPTION ARITHMETIC RATIONAL
CALL MtxGet(x,0, f)
END SUB

EXTERNAL SUB DENOM(x(,,), f(,)) !xの分母(denominator)
OPTION ARITHMETIC RATIONAL
CALL MtxGet(x,1, f)
END SUB


!表示関連

EXTERNAL SUB PolyPrintQ(w(,,)) !分数式を表示する
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N)
CALL MtxGet(w,0, t) !分子
CALL PolyPrint(t)
PRINT " / ";
CALL MtxGet(w,1, t) !分母
CALL PolyPrint(t)
END SUB


!演算関連

EXTERNAL SUB QCopy(a(,,), b(,,)) !コピーする LET b=a
OPTION ARITHMETIC RATIONAL
CALL MtxCopy(1,2,a, b)
END SUB


EXTERNAL SUB QInv(a(,,), b(,,)) !逆数 b=1/a
OPTION ARITHMETIC RATIONAL
DIM p(0 TO MAX_TERM, 0 TO N), q(0 TO MAX_TERM, 0 TO N)
CALL MtxGet(a,0, p) !p/q
CALL MtxGet(a,1, q)
CALL MtxSet(q,0, b) !q/p
CALL MtxSet(p,1, b)
END SUB


EXTERNAL SUB QAdd(a(,,),b(,,), c(,,)) !加算 c=a+b  ※c≠a、c≠bの配列を指定する
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N), w(0 TO 3, 0 TO MAX_TERM, 0 TO N)
CALL MtxGet(b,0, t) !bの分子
CALL MtxSet(t,2, w)
CALL MtxGet(b,1, t) !bの分母
CALL MtxSet(t,0, w)
CALL MtxSet(t,3, w)
CALL PolySet("0", t) !( a0  a1 )( b1  0  ) = ( a0b1+a1b0  a1b1 )
CALL MtxSet(t,1, w)  !          ( b0  b1 )
CALL MtxMul(1,2,2,a,w, c)
END SUB


EXTERNAL SUB QSub(a(,,),b(,,), c(,,)) !減算 c=a-b  ※c≠a、c≠bの配列を指定する
OPTION ARITHMETIC RATIONAL
DIM t(0 TO MAX_TERM, 0 TO N), w(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL MtxGet(b,0, t) !分子を(-1)倍する
CALL PolyMultiplyC(t,-1, t)
CALL MtxSet(t,0, w)
CALL MtxGet(b,1, t)
CALL MtxSet(t,1, w)
CALL QAdd(a,w, c) !a-b
END SUB


EXTERNAL SUB QMul(a(,,),b(,,), c(,,)) !乗算 c=ab
OPTION ARITHMETIC RATIONAL
DIM p(0 TO MAX_TERM, 0 TO N), q(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N)
CALL MtxGet(a,0, p) !分子 a0b0
CALL MtxGet(b,0, q)
CALL PolyMultiply(p,q, t)
CALL MtxSet(t,0, c)
CALL MtxGet(a,1, p) !分母 a1b1
CALL MtxGet(b,1, q)
CALL PolyMultiply(p,q, t)
CALL MtxSet(t,1, c)
END SUB


EXTERNAL SUB QDiv(a(,,),b(,,), c(,,)) !除算 c=a/b
OPTION ARITHMETIC RATIONAL
DIM w(0 TO 1, 0 TO MAX_TERM, 0 TO N)
CALL QInv(b, w)
CALL QMul(a,w, c) !a(1/b)
END SUB


EXTERNAL SUB QPowN(a(,,),K, b(,,)) !べき乗 a^k
OPTION ARITHMETIC RATIONAL
DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N)
CALL MtxGet(a,0, t) !分子
CALL PolyPowN(t,K, s)
CALL MtxSet(s,0, b)
CALL MtxGet(a,1, t) !分母
CALL PolyPowN(t,K, s)
CALL MtxSet(s,1, b)
END SUB


EXTERNAL SUB QSimplify(a(,,),x$) !約分する
OPTION ARITHMETIC RATIONAL
DIM f(0 TO MAX_TERM, 0 TO N), g(0 TO MAX_TERM, 0 TO N)
CALL MtxGet(a,0, f) !分子を得る
CALL MtxGet(a,1, g) !分母を得る
DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N), c(0 TO MAX_TERM, 0 TO N)
CALL PolyExtendedGCD(f,g,x$, s,t,c) !拡張ユークリッド互除法 fs+gt=c
DIM q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)
CALL PolyQuotientRemainder(g,c,x$, q,r) !分母 g/c
CALL PolyCommonFactor(q, t) !係数を調整する
CALL PolyQuotientRemainder(q,t,x$, s,r)
CALL MtxSet(s,1, a)
CALL PolyQuotientRemainder(f,c,x$, q,r) !分子 f/c
CALL PolyQuotientRemainder(q,t,x$, s,r)
CALL MtxSet(s,0, a)
END SUB



!--------------------------

!拡張ユークリッド互除法 f(x)S(x)+g(x)T(x)=Kgcd(f(x),g(x))=C(x)となるS(x),T(x),C(x)を求める。
EXTERNAL SUB PolyExtendedGCD(a(,),b(,),x$, s(,),t(,),c(,)) !拡張ユークリッド互除法
OPTION ARITHMETIC RATIONAL
IF b(0,0)=1 AND b(1,0)=0 THEN !!--- IF b=0 THEN
!!--- s=1 !※f(x)*1+0*0=f(x)とする
   CALL PolySet("1", s)
   !!--- t=0
   CALL PolySet("0", t)
   !!--- c=a
   CALL PolyCopy(a, c)
ELSE
!!--- q=INT(a/b), r=MOD(a,b)
   DIM q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)

   CALL isConst(a,1, rc1)
   CALL isConst(b,1, rc2)
   IF (a(0,0)=1 AND rc1<>0) AND (b(0,0)=1 AND rc2<>0) THEN !定数項のみなら
      MAT q=ZER
      LET q(1,0)=INT(a(1,0)/b(1,0))
      LET q(0,0)=1
      MAT r=ZER
      LET r(1,0)=MOD(a(1,0),b(1,0))
      LET r(0,0)=1
   ELSE
      CALL PolyQuotientRemainder(a,b,x$, q,r)
   END IF

   !!--- CALL ExGCD(b,r, u,v,c) !k=n-1,…,3,2 まで続ける
   !!--- s=v
   DIM u(0 TO MAX_TERM, 0 TO N)
   CALL PolyExtendedGCD(b,r,x$, u,s,c)

   !!--- t=u-v*q
   DIM w(0 TO MAX_TERM, 0 TO N)
   CALL PolyMultiply(s,q, w)
   CALL PolySubtract(u, w, t)
END IF
END SUB



MERGE "mPOLY.LIB" !多変数の多項式の計算
MERGE "mPOLYMX.LIB" !多変数の多項式(行列関連)



実行結果

3a+3 / a^4+a^3-3a^2-5a-2
3 / a^3-3a-2
-3

3a-3 / a^4-a^3-3a^2+5a-2
3 / a^3-3a+2
1

-6 / -3
2 / 1


 

有理化

 投稿者:しばっち  投稿日:2014年11月26日(水)18時08分17秒
  数式処理ソフト使ってみた

http://sourceforge.net/project/showfiles.php?group_id=4933
https://www.wolframalpha.com/input/?i=1/%28%28sqrt%282%29%2Bsqrt%283%29%2B5%5E%281/2%29%29


Maxima 5.31.2 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.8 (a.k.a. GCL)
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) display2d:false;
(%o1) false
(%i2) algebraic: ture;
(%o2) ture
(%i3) ratsimp(1/(sqrt(a)+sqrt(b)+sqrt(c)));
(%o3) (sqrt(c)*(c-b+2*sqrt(a)*sqrt(b)-a)+sqrt(b)*(-c+b-a)+sqrt(a)
                                                          *(-c-b+a))
/(c^2+(-2*b-2*a)*c+b^2-2*a*b+a^2)
(%i4) ratsimp(1/(sqrt(a)+sqrt(b)+sqrt(c)+sqrt(d)));
(%o4) (sqrt(d)*(d^3+sqrt(c)*(sqrt(a)*(2*d^2+(-4*c+4*b-4*a)*d+2*c^2
                                           +(4*b-4*a)*c-6*b^2+4*a*b
                                           +2*a^2)
                            +sqrt(b)*(2*d^2+(-4*c-4*b+4*a)*d+2*c^2
                                           +(4*a-4*b)*c+2*b^2+4*a*b
                                           -6*a^2))
                   +sqrt(a)*sqrt(b)
                           *(2*d^2+(4*c-4*b-4*a)*d-6*c^2+(4*b+4*a)*c
                                  +2*b^2-4*a*b+2*a^2)+(-3*c-3*b-3*a)*d^2
                   +(3*c^2+(2*b+2*a)*c+3*b^2+2*a*b+3*a^2)*d-c^3+(b+a)*c^2
                   +(b^2-10*a*b+a^2)*c-b^3+a*b^2+a^2*b-a^3)
+sqrt(c)*(-d^3+(3*c+b+a)*d^2
               +sqrt(a)*sqrt(b)
                       *(-6*d^2+(4*c+4*b+4*a)*d+2*c^2+(-4*b-4*a)*c+2*b^2
                               -4*a*b+2*a^2)
               +(-3*c^2+(2*b+2*a)*c+b^2-10*a*b+a^2)*d+c^3+(-3*b-3*a)*c^2
               +(3*b^2+2*a*b+3*a^2)*c-b^3+a*b^2+a^2*b-a^3)
+sqrt(b)*(-d^3+(c+3*b+a)*d^2+(c^2+(2*b-10*a)*c-3*b^2+2*a*b+a^2)*d-c^3
               +(3*b+a)*c^2+(-3*b^2+2*a*b+a^2)*c+b^3-3*a*b^2+3*a^2*b-a^3)
+sqrt(a)*(-d^3+(c+b+3*a)*d^2+(c^2+(2*a-10*b)*c+b^2+2*a*b-3*a^2)*d-c^3
               +(b+3*a)*c^2+(b^2+2*a*b-3*a^2)*c-b^3+3*a*b^2-3*a^2*b+a^3))
/(d^4+(-4*c-4*b-4*a)*d^3+(6*c^2+(4*b+4*a)*c+6*b^2+4*a*b+6*a^2)*d^2
      +(-4*c^3+(4*b+4*a)*c^2+(4*b^2-40*a*b+4*a^2)*c-4*b^3+4*a*b^2+4*a^2*b
              -4*a^3)
       *d+c^4+(-4*b-4*a)*c^3+(6*b^2+4*a*b+6*a^2)*c^2
      +(-4*b^3+4*a*b^2+4*a^2*b-4*a^3)*c+b^4-4*a*b^3+6*a^2*b^2-4*a^3*b
      +a^4)
(%i5) ratsimp(1/(a^(1/2)+b^(1/3)));
(%o5) -(b^(1/3)*(sqrt(a)*b-a^2)-a*b+(a^(3/2)-b)*b^(2/3)+a^(5/2))/(b^2
                                                                 -a^3)
(%i6) ratsimp(1/(a^(1/3)+b^(1/3)));
(%o6) (b^(2/3)-a^(1/3)*b^(1/3)+a^(2/3))/(b+a)
(%i7) ratsimp(1/(a^(1/3)+b^(1/3)+c^(1/3)));
(%o7) -(c^(1/3)*(b^(1/3)*(c^2+(2*b-a)*c+b^2-a*b-2*a^2)
                +a^(1/3)*(c^2+(2*a-b)*c-2*b^2-a*b+a^2)
                +a^(2/3)*b^(2/3)*(-6*c+3*b+3*a))
+c^(2/3)*(-c^2+a^(1/3)*b^(2/3)*(3*c+3*b-6*a)
               +a^(2/3)*b^(1/3)*(3*c-6*b+3*a)+(-2*b-2*a)*c-b^2+7*a*b-a^2)
+a^(2/3)*(-c^2+(7*b-2*a)*c-b^2-2*a*b-a^2)
+b^(2/3)*(-c^2+(7*a-2*b)*c-b^2-2*a*b-a^2)
+a^(1/3)*b^(1/3)*(-2*c^2+(-b-a)*c+b^2+2*a*b+a^2))
/(c^3+(3*b+3*a)*c^2+(3*b^2-21*a*b+3*a^2)*c+b^3+3*a*b^2+3*a^2*b+a^3)


LET A=2
LET B=3
LET SS=SGN(A-B)
PRINT "1/(SQR(";A;")+SQR(";B;"))"
PRINT "=(";SIGN$(SS);"SQR(";A;")";SIGN$(-SS);"SQR(";B;"))/";ABS(A-B)
PRINT
LET A=2
LET B=3
LET C=5
PRINT "1/(SQR(";A;")+SQR(";B;")+SQR(";C;"))"
LET SS=SGN((A+B-C)^2-4*A*B)
PRINT "=(";SS*(A-B-C);"*SQR(";A;")";SIGN$(SS*(-A+B-C));"*SQR(";B;")";SIGN$(SS*(A+B-C));"*SQR(";C;")";SIGN$(SS);"2*SQR(";A*B*C;"))/";ABS((A+B-C)^2-4*A*B)
END

EXTERNAL  FUNCTION SIGN$(X)
IF ABS(X)=1 THEN
   IF X<0 THEN LET SIGN$="-" ELSE LET SIGN$="+"
ELSE
   IF X<0 THEN LET SIGN$="-"&STR$(-X) ELSE LET SIGN$="+"&STR$(X)
END IF
END FUNCTION

 

最小多項式

 投稿者:しばっち  投稿日:2014年11月26日(水)18時09分28秒
  DECLARE EXTERNAL FUNCTION COMB
OPTION BASE 0
DIM X(8),T(8)
!'最小多項式
!'(x-(a+b+c))(x-(a+b-c))(x-(a-b+c))(x-(a-b-c))(x-(-a+b+c))(x-(-a+b-c))(x-(-a-b+c))(x-(-a-b-c))
!'(x-a)(x-b)=x^2-(a+b)x+ab
!'(x-a)(x-b)(x-c)=x^3-(a+b+c)x^2+(ab+bc+ca)x-abc
!'(x-a)(x-b)(x-c)(x-d)=x^4-(a+b+c+d)x^3+(ab+ac+ad+bc+bd+cd)x^2-(abc+abd+bcd+acd)x+abcd
LET A=SQR(2)
LET B=SQR(3)
LET C=SQR(5)
FOR I=1 TO -1 STEP -2
   FOR J=1 TO -1 STEP -2
      FOR K=1 TO -1 STEP -2
         LET N=N+1
         LET X(N)=I*A+J*B+K*C
         PRINT "(X";SIGN$(-X(N));")";
      NEXT  K
   NEXT J
NEXT I
PRINT
FOR I=N TO 0 STEP-1
   LET K=(-1)^(N-I)*COMB(X,N,N-I,T,1)
   IF ABS(K)<1E-6 THEN LET K=0
   IF ABS(FP(K))<1E-6 THEN LET K=SGN(K)*INT(ABS(K))
   IF I=1 THEN
      PRINT SIGN$(K);"*X";
   ELSEIF I=N THEN
      PRINT "X^";STR$(I);
   ELSEIF I>0 THEN
      IF K<>0 THEN PRINT SIGN$(K);"*X^";STR$(I);
   ELSE
      PRINT SIGN$(K)
   END IF
NEXT I
END

EXTERNAL FUNCTION SIGN$(X)
IF ABS(X)=1 THEN
   IF X<0 THEN LET SIGN$="-" ELSE LET SIGN$=""
ELSE
   IF X<0 THEN LET SIGN$="-"&STR$(ABS(X)) ELSE LET SIGN$="+"&STR$(X)
END IF
END FUNCTION

EXTERNAL FUNCTION COMB(X(),N,R,A(),K)
IF R=0 THEN
   LET S=1
   FOR I=1 TO N
      IF A(I)=1 THEN LET S=S*X(I)
   NEXT I
   LET COMB=S
ELSE
   FOR I=K TO N-R+1
      LET A(I)=1
      LET SS=SS+COMB(X,N,R-1,A,I+1)
      LET A(I)=0
   NEXT I
   LET COMB=SS
END IF
END FUNCTION
 

行列式、逆行列、連立方程式

 投稿者:しばっち  投稿日:2014年11月26日(水)18時10分49秒
  LET N=6
DIM A$(N,N),B$(N),Y$(N),X$(N,N)
FOR I=1 TO N
   LET B$(I)="Y("&STR$(I)&")"
   FOR J=1 TO N
      LET A$(I,J)="X("&STR$(I)&","&STR$(J)&")"
   NEXT J
NEXT I
PRINT "行列式"
FOR I=2 TO N
   PRINT "DET"&STR$(I)&"=";
   PRINT DET$(I,A$)
   PRINT
NEXT I
PRINT
FOR I=2 TO N
   PRINT "逆行列";I;"*";I
   CALL INV(I,A$,X$)
   FOR J=1 TO I
      FOR K=1 TO I
         PRINT "X("&STR$(J)&","&STR$(K)&")=";X$(J,K)
      NEXT K
   NEXT J
   PRINT
NEXT I
PRINT
FOR I=2 TO N
   MAT Y$=NUL$
   CALL CRAMER(I,A$,B$,Y$)
   PRINT STR$(I);"元連立一次方程式"
   FOR J=1 TO I
      PRINT "X(";STR$(J);")=";Y$(J)
   NEXT J
   PRINT
NEXT I
END

EXTERNAL FUNCTION DET$(N,X$(,))
IF N=1 THEN
   LET DET$=X$(1,1)
   EXIT FUNCTION
ELSEIF N=2 THEN
   LET DET$=X$(1,1)&"*"&X$(2,2)&"-"&X$(2,1)&"*"&X$(1,2)
   EXIT FUNCTION
END IF
DIM D$(N),A$(N-1,N-1)
FOR K=1 TO N
   FOR I=1 TO N-1
      FOR J=1 TO N-1
         IF I>=K THEN
            LET A$(I,J)=X$(I+1,J+1)
         ELSE
            LET A$(I,J)=X$(I,J+1)
         END IF
      NEXT J
   NEXT I
   LET D$(K)=DET$(N-1,A$)
NEXT K
FOR I=1 TO N
   IF D$(I)(1:1)="+" THEN LET D$(I)(1:1)=""
   IF MOD(I,2)=1 THEN
      LET S$=S$&"+"&X$(I,1)&"*("&D$(I)&")"
   ELSE
      LET S$=S$&"-"&X$(I,1)&"*("&D$(I)&")"
   END IF
NEXT I
IF S$(1:1)="+" THEN LET S$(1:1)=""
LET DET$=S$
END FUNCTION

EXTERNAL  SUB INV(N,A$(,),B$(,))
DIM X$(N-1,N-1)
LET D$=DET$(N,A$)
FOR I=1 TO N
   FOR J=1 TO N
      LET P=0
      LET Q=0
      FOR K=1 TO N
         IF I<>K THEN
            LET P=P+1
            LET Q=0
            FOR L=1 TO N
               IF J<>L THEN
                  LET Q=Q+1
                  LET X$(P,Q)=A$(K,L)
               END IF
            NEXT L
         END IF
      NEXT K
      IF (-1)^(I+J)=-1 THEN LET SIGN$="-" ELSE LET SIGN$=""
      LET B$(I,J)=SIGN$&"("&DET$(N-1,X$)&")/("&D$&")"
   NEXT J
NEXT I
FOR I=1 TO N-1
   FOR J=I+1 TO N
      SWAP B$(I,J),B$(J,I)
   NEXT J
NEXT I
END SUB

EXTERNAL SUB CRAMER(N,X$(,),Y$(),D$())
DIM A$(N,N)
FOR I=1 TO N
   FOR J=1 TO N
      LET A$(I,J)=X$(I,J)
   NEXT J
NEXT I
LET DD$=DET$(N,A$)
FOR K=1 TO N
   FOR I=1 TO N
      FOR J=1 TO N
         IF J=K THEN LET A$(I,J)=Y$(I) ELSE LET A$(I,J)=X$(I,J)
      NEXT J
   NEXT I
   IF DD$(1:1)="+" THEN LET DD$(1:1)=""
   LET D$(K)="("&DET$(N,A$)&")/("&DD$&")"
NEXT K
END SUB
 

Re: 有理化

 投稿者:GAI  投稿日:2014年11月27日(木)07時32分56秒
  > No.3555[元記事へ]

しばっちさんへのお返事です。

> LET A=2
> LET B=3
> LET C=5
> PRINT "1/(SQR(";A;")+SQR(";B;")+SQR(";C;"))"
> LET SS=SGN((A+B-C)^2-4*A*B)
> PRINT "=(";SS*(A-B-C);"*SQR(";A;")";SIGN$(SS*(-A+B-C));"*SQR(";B;")";SIGN$(SS*(A+B-C));"*SQR(";C;")";SIGN$(SS);"2*SQR(";A*B*C;"))/";ABS((A+B-C)^2-4*A*B)
> END
>
> EXTERNAL  FUNCTION SIGN$(X)
> IF ABS(X)=1 THEN
>    IF X<0 THEN LET SIGN$="-" ELSE LET SIGN$="+"
> ELSE
>    IF X<0 THEN LET SIGN$="-"&STR$(-X) ELSE LET SIGN$="+"&STR$(X)
> END IF
> END FUNCTION
>

A=2,B=3,C=5 では結果はOKですが
A=2,B=3,C=11
A=7,B=11,C=13 とかでは一カ所符号が逆になる部分があるようです。
 

Re: 有理化

 投稿者:しばっち  投稿日:2014年11月27日(木)20時02分9秒
  > No.3558[元記事へ]

GAIさんへのお返事です。


> A=2,B=3,C=5 では結果はOKですが
> A=2,B=3,C=11
> A=7,B=11,C=13 とかでは一カ所符号が逆になる部分があるようです。

大変失礼いたしました。
とりあえず修正しておきました。

LET A=7
LET B=11
LET C=13
PRINT "1/(SQR(";A;")+SQR(";B;")+SQR(";C;"))"
LET SS=SGN((A+B-C)^2-4*A*B)
IF MOD(A-B-C,2)=0 AND MOD(-A+B-C,2)=0 AND MOD(C-A-B,2)=0 AND MOD((A+B-C)^2-4*A*B,2)=0 THEN LET S=2 ELSE LET S=1
PRINT "(";SIGN$(SS*(A-B-C)/S);"SQR(";A;")";SIGN$(SS*(-A+B-C)/S);"SQR(";B;")";SIGN$(SS*(C-A-B)/S);"SQR(";C;")";SIGN$(SS*2/S);"SQR(";A*B*C;"))/";ABS((A+B-C)^2-4*A*B)/S
END

EXTERNAL  FUNCTION SIGN$(X)
IF ABS(X)=1 THEN
   IF X<0 THEN LET SIGN$="-" ELSE LET SIGN$="+"
ELSE
   IF X<0 THEN LET SIGN$="-"&STR$(-X)&"*" ELSE LET SIGN$="+"&STR$(X)&"*"
END IF
END FUNCTION
 

Re: 多変数多項式の計算(mPOLY.LIB、mPOLYMX.LIB)

 投稿者:山中和義  投稿日:2014年11月28日(金)10時59分5秒
  > No.3554[元記事へ]

> 使用例

連立方程式を解く(直線と直線との交点)
Ax+By=P
Cx+Dy=Q

答え
行列で表記すると、
( A  B )( x ) = ( P )
( C  D )( y )   ( Q )
逆行列を左からかけて、
( x ) = { 1/(AD-BC) }(  D  -B )( P )
( y )                ( -C   A )( Q )
(終わり)

別解
x,yの1次式なので、xの1次式とみなして、第1式を第2式で割ると、余りはx^0の項が現れる。
すなわち、xが消去されたyの1次式が得られる。
yも同様である。
(終わり)


OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="ABCDEFPQRxyz"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM f(0 TO MAX_TERM, 0 TO N), g(0 TO MAX_TERM, 0 TO N)
CALL PolySet("Ax+By-P", f)
CALL PolySet("Cx+Dy-Q", g)

DIM q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)
CALL PolyQuotientRemainder(f,g,"x", q,r) !※←←←←←
CALL PolyPrint(q) !商
PRINT
CALL PolyPrint(r) !余り
PRINT

!整形する
DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N)
CALL PolySet("C", s) !除数のyの係数より ※←←←←←
CALL PolyMultiply(r,s, t)
CALL PolyPrintCollect(t,"y") !結果を表示する ※←←←←←
PRINT

END

MERGE "mPOLY.LIB" !多変数の多項式の計算



実行結果

A/C
By-P-ADy/C+AQ/C
+(-CP+AQ)+(-AD+BC)y




----------------------------------------------------------------

問題
円 x^2+y^2+Ax+By+C=0、直線 Px+Qy+R=0 との交点を求める。

答え
直線の方程式を変形して、y=-(Px+R)/Q
円の方程式に代入すると、(P^2+Q^2)x^2+(AQ^2+2PR-BPQ)x+(CQ^2-BQR+R^2)=0
xの2次方程式を解けばよい。
(終わり)

別解
曲線 f(x,y)=0 と n次関数 y=g(x) との交点

yの多項式とみなして、除算 f(x,y)÷(g(x)-y) を考える。
余りをr(x)とすると、r(x)=0の解を求める。

曲線
・直線(1次関数) Ax+By+C=0
・2次関数(放物線) Ax^2+Bx+C-y=0
・3次関数 Ax^3+Bx^2+Cx+D-y=0
・円 x^2+y^2+Ax+Bx+C=0
(終わり)



OPTION ARITHMETIC RATIONAL

PUBLIC STRING v$ !変数の定義 ※必要なものだけの列記でもよい
LET v$="ABCDPQRxy"

PUBLIC NUMERIC N !変数の数
LET N=LEN(v$)

PUBLIC NUMERIC MAX_TERM !最大の項数
LET MAX_TERM=50
!------------------------------ ここまでがサブルーチン

DIM f(0 TO MAX_TERM, 0 TO N), g(0 TO MAX_TERM, 0 TO N)
CALL PolySet("x^2+y^2+Ax+By+C", f)
CALL PolySet("Px+Qy+R", g)

DIM q(0 TO MAX_TERM, 0 TO N), r(0 TO MAX_TERM, 0 TO N)
CALL PolyQuotientRemainder(f,g,"y", q,r) !※←←←←←
CALL PolyPrint(q) !商
PRINT
CALL PolyPrint(r) !余り
PRINT

!整形する
DIM s(0 TO MAX_TERM, 0 TO N), t(0 TO MAX_TERM, 0 TO N)
CALL PolySet("Q^2", s) !除数のyの係数より ※←←←←←
CALL PolyMultiply(r,s, t)
CALL PolyPrintCollect(t,"x") !結果を表示する ※←←←←←
PRINT

END

MERGE "mPOLY.LIB" !多変数の多項式の計算



実行結果

y/Q+B/Q-Px/Q^2-R/Q^2
x^2+Ax+C-BPx/Q-BR/Q+P^2x^2/Q^2+2PRx/Q^2+R^2/Q^2
+(CQ^2-BQR+R^2)+(AQ^2+2PR-BPQ)x+(Q^2+P^2)x^2



 

プログラムの質問

 投稿者:GAI  投稿日:2014年11月29日(土)08時55分1秒
  for a=1 to 100
next a
ならa=1,2,3,・・・,100
に渡って変化するところを
素数だけに限って変化させるにはどうしたらいいのでしょうか?
a=2,3,5,7,11,13,・・・,97
での変化で動かしたい。
 

Re: プログラムの質問

 投稿者:山中和義  投稿日:2014年11月29日(土)09時56分56秒
  > No.3561[元記事へ]

GAIさんへのお返事です。

> for a=1 to 100
> next a
> ならa=1,2,3,・・・,100
> に渡って変化するところを
> 素数だけに限って変化させるにはどうしたらいいのでしょうか?
> a=2,3,5,7,11,13,・・・,97
> での変化で動かしたい。

素数は、通常のプログラム言語では、サポートされていませんので、
次のような関数ルーチンをつくり、素数判定を行います。
また、素数判定にはいくつかのアルゴリズムがあります。


OPTION ARITHMETIC RATIONAL !多桁整数
FOR P=2 TO 100
   IF P=prmdiv(P) THEN !PrimeQ

      PRINT P

   END IF
NEXT P
END

!ubasic.LIBより抜粋

EXTERNAL FUNCTION prmdiv(n) !1より大きな最小の約数 ※nは1より大きな整数
OPTION ARITHMETIC RATIONAL !多桁整数
IF MOD(n,2)=0 THEN !2の倍数
   LET prmdiv=2
ELSEIF MOD(n,3)=0 THEN !3の倍数
   LET prmdiv=3
ELSE
   FOR i=5 TO INTSQR(n) STEP 6
      IF MOD(n,i)=0 THEN !5,11,17,23,29,…
         LET prmdiv=i
         EXIT FUNCTION
      ELSEIF MOD(n,i+2)=0 THEN !7,13,19,25,31,…
         LET prmdiv=i+2
         EXIT FUNCTION
      END IF !+1,+3,+5は2の倍数(偶数)、+1,+4は3の倍数、+5は5の倍数
   NEXT i
   LET prmdiv=n !その数自身
END IF
END FUNCTION


 

Re: プログラムの質問

 投稿者:白石和夫  投稿日:2014年11月30日(日)10時39分13秒
  > No.3561[元記事へ]

ある数以下のすべての素数について順に調べたければ,エラトステネスの篩で素数が判定されたところで調査目的の副プログラムを呼び出して

100 DECLARE EXTERNAL SUB test
110 ! エラトステネスの篩
120 DIM s(1000)
130 MAT s=ZER
140 FOR i=2 TO 1000
150    IF s(i)=0 THEN
160       CALL test(i)
170       FOR  j=i^2 TO 1000 STEP i
180          LET s(j)=1
190       NEXT j
200    END IF
210 NEXT i
220 END
1000 EXTERNAL SUB test(p)
1010 PRINT p
1020 END SUB

のようにすればよいのですが,この場合,エラトステネスの篩が主で調査目的の副プログラムが従の関係になります。
主客を転倒させて調査目的のプログラムを主に持っていきたいときは,Full BASICのモジュールを用いて

100 DECLARE EXTERNAL FUNCTION Primes.NextPrime
110 DO
120    PRINT nextPrime
130 LOOP
140 END
1000 MODULE Primes
1010 PUBLIC FUNCTION NextPrime
1020 SHARE NUMERIC s(2 TO 100000), CurPrime
1030 MAT s=ZER
1040 LET CurPrime=1
1050 EXTERNAL FUNCTION NextPrime
1060    DO
1070       LET CurPrime=CurPrime+1
1080    LOOP UNTIL s(CurPrime)=0
1090    LET NextPrime=CurPrime
1100    FOR j=CurPrime^2 TO 100000 STEP CurPrime
1110       LET s(j)=1
1120    NEXT j
1130 END FUNCTION
1140 END MODULE

のように構成することもできます(アルゴリズムはエラトステネスの篩で変わりません)。モジュール内の変数は静的なので,NextPrime関数が呼び出されたとき,前回のCurPrimeが残っていて次の素数が求められます。

ただし,どちらを採用する場合でも,素数の上限をあらかじめ指定しておく必要があります。


 

固定小数点

 投稿者:minmi  投稿日:2014年12月 1日(月)20時05分8秒
  大学で数値計算について学んでいる者です.
今,C言語でdouble型の数をscanfで読み取り,読み込んだdouble型の浮動小数点数を
固定小数点数に変換し四則演算を行うプログラムを書きたいのですが,うまく書けません.
よろしければ,例となるようなプログラムを書いていただけませんでしょうか?
よろしくお願いします.
 

Re: 固定小数点

 投稿者:山中和義  投稿日:2014年12月 2日(火)18時51分6秒
  > No.3564[元記事へ]

minmiさんへのお返事です。

> 今,C言語でdouble型の数をscanfで読み取り,読み込んだdouble型の浮動小数点数を
> 固定小数点数に変換し四則演算を行うプログラムを書きたいのですが,うまく書けません.
> よろしければ,例となるようなプログラムを書いていただけませんでしょうか?

固定小数点の仕様がはっきりしませんので、システムが扱う整数の範囲で考えてみます。


整数の四則演算ができるとする。
右から4桁目(固定位置)が一の位と仮定して、小数点を含む数 123.45 を、123450 と表現する。


LET K=10^3 !小数点以下は3桁

LET X=123.45
LET Y= 67.8

LET A=INT(X*K) !符号化
LET B=INT(Y*K)
PRINT A; B

LET W=A+B !整数による演算
LET S=A-B
LET M=INT(A*B/K)
LET D=INT(A*K/B)
PRINT W; S; M; D

PRINT W/K; S/K; M/K; D/K !復号化

!検算
PRINT X+Y; X-Y; X*Y; X/Y

END


実行結果

123450  67800
191250  55650  8369910  1820
191.25  55.65  8369.91  1.82
191.25  55.65  8369.91  1.82079646017699



C言語(BCPad 2.3.1 + Borland C++ Compiler 5.5.1)に翻訳すると、


#include <stdio.h>

#define K 1000 //小数点以下は3桁

int main(void)
{
   double x,y;
   long a,b, w,s,m,d;

   scanf("%lf", &x); //x=123.45;
   scanf("%lf", &y); //y= 67.8;

   a=x*K; //符号化
   b=y*K;
   printf("%d  %d\n", a, b);

   w=a+b; //整数による演算
   s=a-b;
   m=a*b/K;
   d=a*K/b;
   printf("%ld  %ld  %ld  %ld\n", w,s,m,d);

   printf("%.3f  %.3f  %.3f  %.3f\n", (float)w/K, (float)s/K,(float)m/K, (float)d/K); //復号化


   printf("%f  %f  %f  %f\n", x+y, x-y, x*y, x/y); //検算

   return 0;
}


実行結果

123.45(改行)
67.8(改行)
123450  67799
191249  55651  -220148  1820
191.249  55.651  -220.148  1.820
191.250000  55.650000  8369.910000  1.820796
-- Press any key to exit (Input "c" to continue) --


乗算a*bでオーバーフロー(32ビット整数)が発生しているため正しい結果が得られません。
この場合、a/K*bならオーバーフローは発生しませんが、精度が落ちます。
ここは、64ビット整数で計算しないといけません。

 

Re: プログラムの質問

 投稿者:白石 和夫  投稿日:2014年12月 4日(木)10時24分33秒
  NextPrimeを次の素数を生成する副プログラムとし,CurPrimeを広域変数にしたほうが扱いやすいかもしれません(変数のCurPrimeは何度でも参照可能)。

100 DECLARE EXTERNAL SUB Primes.NextPrime
110 DECLARE EXTERNAL NUMERIC Primes.CurPrime
120 DO
130    CALL NextPrime
140    PRINT CurPrime
150 LOOP
160 END
1000 MODULE Primes
1010 PUBLIC SUB NextPrime
1020 PUBLIC NUMERIC CurPrime
1030 SHARE NUMERIC s(2 TO 100000)
1040 MAT s=ZER
1050 LET CurPrime=1
1060 EXTERNAL SUB NextPrime
1070    DO
1080       LET CurPrime=CurPrime+1
1090    LOOP UNTIL s(CurPrime)=0
1100    FOR j=CurPrime^2 TO 100000 STEP CurPrime
1110       LET s(j)=1
1120    NEXT j
1130 END SUB
1140 END MODULE

なお,限界に達するとエラーとなって止まります。エラーメッセージを出したくないときは,1080行前後にCurPrimeの値を検査するコードを追加してください。

 

Re: プログラムの質問

 投稿者:nagram  投稿日:2014年12月 9日(火)14時28分39秒
  > No.3566[元記事へ]

CurPrimeを広域変数にすると主プログラム内でCurPrimeの値を変更することが可能となり、CurePrime^2より小さく変更すれば、次にNextPrimeを実行したときには変更したCurPrimeの次の素数が得られます。
この性質を利用して、引数より大きな最小の素数を返す関数を作成しました。UBASICの関数nxtprm(n)と同じ機能です。
また、2と3の倍数をあらかじめ除き、配列sの大きさを3分の1に圧縮しました。

REM 関数 NextPrime(n) … nより大きい最小の素数。nは整数でなくともよい。
DECLARE EXTERNAL FUNCTION Primes.NextPrime
LET p=1
FOR i=1 TO 30
   LET p=NextPrime(p)
   PRINT p
NEXT i
RANDOMIZE
FOR i=1 TO 30
   LET a=INT(100000*RND)
   LET p=NextPrime(a)
   PRINT a;p
NEXT i
PRINT NextPrime(99990) ! maxn=100000のときの最大素数は99991。これより大きい引数はエラー。
END
!
MODULE Primes
PUBLIC FUNCTION NextPrime
SHARE NUMERIC s(33333),maxn,MaxPrime ! 配列sのサイズは変更可能だが、必ず定数で指定。
LET maxn=3*SIZE(s)+1 ! maxnまでの素数に対応
MAT s=ZER
WHEN EXCEPTION IN
   FOR i=8 TO maxn STEP 10 ! 5の倍数
      LET s(i)=1
      LET s(i+3)=1
   NEXT i
USE
END WHEN
LET MaxPrime=5
!          j=5,7,11,13,17,19,23,25,29,31,35,37,41,43,47,49,53,55,59,61,65,67,71,73,77,79
!   INT(j/3)=1,2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
!s(INT(j/3))=0,0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0
EXTERNAL FUNCTION NextPrime(n)
   IF n<5 THEN
      LET NextPrime=5
      IF n<3 THEN LET NextPrime=3
      IF n<2 THEN LET NextPrime=2
      EXIT FUNCTION
   END IF
   LET n=INT(n)
   LET k=MOD(n,6)
   IF k<>1 AND k<>5 THEN LET n=n-ABS(k-1)
   IF n<=MaxPrime^2 THEN CALL PrimeCheck(n)
   !
   IF MOD(MaxPrime,6)=1 THEN LET add=4 ELSE LET add=2
   WHEN EXCEPTION IN
      DO ! エラトステネスの篩
         LET ex=1
         DO
            LET MaxPrime=MaxPrime+add
            LET add=6-add
         LOOP UNTIL s(INT(MaxPrime/3))=0
         LET ex=0
         FOR j=MaxPrime^2 TO maxn STEP 6*MaxPrime
            LET s(INT(j/3))=1
            IF MOD(j+2*MaxPrime,3)>0 THEN LET s(INT((j+2*MaxPrime)/3))=1 ELSE LET s(INT((j+4*MaxPrime)/3))=1
         NEXT j
      LOOP UNTIL MaxPrime>=INT(SQR(n))
   USE
      IF ex=1 THEN EXIT FUNCTION ! エラー NextPrime=0
   END WHEN
   CALL PrimeCheck(n)
   SUB PrimeCheck(p) ! pより大きい素数の検索
      IF MOD(p,6)=1 THEN LET add=4 ELSE LET add=2
      WHEN EXCEPTION IN
         DO
            LET p=p+add
            LET add=6-add
         LOOP UNTIL s(INT(p/3))=0
         LET NextPrime=p
      USE ! エラー NextPrime=0
      END WHEN
      EXIT FUNCTION
   END SUB
END FUNCTION
END MODULE
 

負数の丸めに関するバグ報告

 投稿者:nagram  投稿日:2014年12月17日(水)19時51分52秒
  xを整数に丸める関数ROUND(x)を、10進モード・1000桁モードで実行すると誤った値を返すことがあります。
n>=0(整数)、0<d<1E-9、x=n+0.5+d としてROUND(-x)を実行すると、本来は -n-1 が得られるはずですが、上記モードでは -n を返します。
nの桁数にかかわらず 0<d<1E-9 で誤った値を返します(ただし10進モードでは 0<=n<1E5 の範囲)。
十進BASICのバージョンは7.7.6、OSはWindows8.1です。
ROUND(x,n)は問題ありません。dの値が0~0.1でROUND(-x)とROUND(-x,0)を比較しました。

LET n=7
PRINT "x=n+0.5+d のときの ROUND(-x) , ROUND(-x,0)"
PRINT "n=";n;"(>=0,整数)"
CALL rounding(0)               ! 問題なし
CALL rounding(EPS(n+.5))       ! 誤
CALL rounding(1E-10)           ! 誤
CALL rounding(1E-9-EPS(n+.5))  ! 誤
CALL rounding(1E-9)            ! 問題なし
CALL rounding(.1)              ! 問題なし
SUB rounding(d)
   LET x=n+.5+d
   PRINT "d=";d;", ROUND(";STR$(-x);")=";ROUND(-x);", ROUND(";STR$(-x);",0)=";ROUND(-x,0)
END SUB
END

この現象は、内部処理で負数を整数に丸める際にも生じているようです。
例えば、配列の添字や、関数ROUND(x,n)の第2引数nを負の小数で指定すると、上記と同様の結果になります。

DIM M(-4.5000000001 TO 2)  ! 本来は M(-5 TO 2) だが、M(-4 TO 2) となる。
PRINT LBOUND(M)
LET M(-2.5-7E-11)=9        ! 本来は M(-3)=9 だが、M(-2)=9 となる。
PRINT M(-3);M(-2)
PRINT ROUND(87654321.0987,-3.50000000002)  ! 本来は 87650000 だが、87654000 となる。
END
 

Re: 負数の丸めに関するバグ報告

 投稿者:白石和夫  投稿日:2014年12月20日(土)08時14分34秒
  > No.3568[元記事へ]

ご報告ありがとうございました。
的確な指摘で助かりました。
負数に対する内部の丸め処理で小数点以下10桁目以降を見ていなかったのが原因です。
近いうちに修正版を作成します。

 

仕様でしょうか

 投稿者:SECOND  投稿日:2014年12月20日(土)11時35分53秒
  以下は、仕様でしょうか。

LET w$="12345"
OPTION CHARACTER kanji   !←無効
LET w$(3:2)=" "
PRINT w$
STOP

!OPTION CHARACTER kanji   !←有効   !12 345
OPTION CHARACTER byte    !←有効   !1 2345

END
 

Re: 仕様でしょうか

 投稿者:白石和夫  投稿日:2014年12月20日(土)11時48分40秒
  > No.3570[元記事へ]

現バージョンは,OPTION CHARACTER文の重複チェックを怠っています。
結果として,コンパイラが最後に読んだ指示でプログラム単位の動作が決定されてしまいます。
 

Re: 仕様でしょうか

 投稿者:SECOND  投稿日:2014年12月20日(土)12時05分44秒
  > No.3571[元記事へ]

途中切替が、出来ると助かりますが、無理でしょうか。
 

Re: 仕様でしょうか

 投稿者:白石和夫  投稿日:2014年12月20日(土)15時41分42秒
  > No.3572[元記事へ]

SECONDさんへのお返事です。

> 途中切替が、出来ると助かりますが、無理でしょうか。

想定している使い方は,プログラム単位で分けるものです。

改修するとしたら重複をチェックすることになります。

実際には実行途中で切り替えるようにすることもできてしまう(と思われます)が,Full BASICのOPTION文は宣言文なので,その場合は,OPTION文とは異なる名称の文を用意することになります。
 

GSAVEすると色違いになる

 投稿者:しばっち  投稿日:2014年12月27日(土)18時58分53秒
  パレットを変更して、BMPファイル16色として保存すると
保存したファイルの画像の色が元の画像と違う色になっている。

LET XSIZE=400
LET YSIZE=400
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,YSIZE-1,0
SET POINT STYLE 1
SET COLOR MODE "REGULAR"
RANDOMIZE
FOR I=0 TO 15 !'適当にパレットを変更
   LET R=RND
   LET G=RND
   LET B=RND
   SET COLOR MIX(I) R,G,B
NEXT I
LET N=0
FOR R=200 TO 20 STEP -20
   SET COLOR N
   DRAW DISK WITH SCALE(R)*SHIFT(200,200)
   LET N=N+1
NEXT R
GSAVE "TEST.bmp","4bit" !'16色モードでBMP保存する
END
 

 戻る