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





Re: 素数多発関数の考察

 投稿者:山中和義  投稿日:2013年 1月 1日(火)11時50分8秒
  > No.2868[元記事へ]

GAIさんへのお返事です。

> f(n)=2*n^2-199
> の関数で素数を発生させるnの値の表(*は合成数の結果となるもの。)
> これより効率よい関数を探せないか?

●1次
素数は2と奇素数より、2n+3、n=0,1,2,3,…  ← 式1
素数判定法のひとつ試し割り法(提示した関数PrimeQ(n)を参照)より、6n+{1,5} ← 式2
発展させて、2,3,5と30n+{1,7,11,13,17,19,23,29}とすることもできる。

ひとつの式のみ採用すれば、式1が優位だが、式2は2つ採用すれば精度は上がる。

●2次
2n^2-199では、11項が負の数と1になるので、nをn+11として、2n^2+44n+43
オイラーが発見したn^2+n+41
n^2+999n+61



!素数を生成する変数nの整数係数多項式
!http://www.saoyagi2.net/integer/primegensearch.html

LET M=10000 !上限
LET C=0 !素数になる回数
FOR N=0 TO M
   !!LET P=2*N+3
   LET P=6*N+1
   !!LET P=6*N-1

   !!LET P=2*N^2+44*N+43 !2n^2-199より
   !!LET P=N^2+N+41 !オイラーが発見
   !!LET P=N^2+999*N+61

   LET W=PrimeQ(P)
   LET C=C+W
   !PRINT N; P; W !debg
NEXT N
PRINT C/(M+1)*100;"%"
END


!試行割算法

EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !2の倍数
   IF n=2 THEN LET PrimeQ=1 !2は素数
ELSEIF MOD(n,3)=0 THEN !3の倍数
   IF n=3 THEN LET PrimeQ=1 !3は素数
ELSE
   LET k=5
   DO WHILE k*k<=n !√nまで検証する
      IF MOD(n,k)=0 THEN !5,11,17,23,29,…
         EXIT FUNCTION
      ELSEIF MOD(n,k+2)=0 THEN !7,13,19,25,31,…
         EXIT FUNCTION
      END IF !+1,+3,+5は2の倍数(偶数)、+1,+4は3の倍数、+5は5の倍数
      LET k=k+6
   LOOP
   LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION

 

Re: 素数多発関数の考察

 投稿者:山中和義  投稿日:2013年 1月 2日(水)12時57分33秒
  > No.2920[元記事へ]

ウラムの螺旋

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

右斜めの数 1,3,7,13,21,…は、n^2+n+1、n=0,1,2,3,…
中央1を41に置き換えて、n^2+n+41


!ウラムの螺旋

LET M=25 !45

!!SET TEXT HEIGHT 0.0075
SET TEXT JUSTIFY "CENTER","HALF"
SET bitmap SIZE 600,600
SET WINDOW -M/2,M/2,-M/2,M/2

LET D=41 !中央の値
LET X=0
LET Y=0
SET TEXT COLOR 1+3*PrimeQ(D)
PLOT TEXT, AT X,Y: STR$(D)

LET DX=1 !移動方向
LET DY=1
FOR S=1 TO M !ステップ数
   FOR L=1 TO S !x軸方向
      LET D=D+1
      LET X=X+DX
      SET TEXT COLOR 1+3*PrimeQ(D)
      PLOT TEXT, AT X,Y: STR$(D)
   NEXT L
   LET DX=-DX

   FOR L=1 TO S !y軸方向
      LET D=D+1
      LET Y=Y+DY
      SET TEXT COLOR 1+3*PrimeQ(D)
      PLOT TEXT, AT X,Y: STR$(D)
   NEXT L
   LET DY=-DY
NEXT S

END


!試行割算法

EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !2の倍数
   IF n=2 THEN LET PrimeQ=1 !2は素数
ELSEIF MOD(n,3)=0 THEN !3の倍数
   IF n=3 THEN LET PrimeQ=1 !3は素数
ELSE
   LET k=5
   DO WHILE k*k<=n !√nまで検証する
      IF MOD(n,k)=0 THEN !5,11,17,23,29,…
         EXIT FUNCTION
      ELSEIF MOD(n,k+2)=0 THEN !7,13,19,25,31,…
         EXIT FUNCTION
      END IF !+1,+3,+5は2の倍数(偶数)、+1,+4は3の倍数、+5は5の倍数
      LET k=k+6
   LOOP
   LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION

 

カステラを切り分ける

 投稿者:山中和義  投稿日:2013年 1月 5日(土)10時11分26秒
  問題
9本のカステラを10人で切り分けたい。
包丁を使う回数を、できるだけ減らすには、どのように切り分けたらよいだろうか。
ただし、いくつかのカステラをまとめて、一気に切るということはしないものとする。

答え
エジプト分数より、9/10=1/2+1/3+1/15なので、両辺に10をかけて、9=5+10/3+2/3

1本目 ┌───────┬──────┐ 5 本をそれぞれ 2 等分して、1/2 ずつ分ける
   └───────┴──────┘ これは、5回
2本目 ┌───────┬──────┐
   └───────┴──────┘
3本目 ┌───────┬──────┐
   └───────┴──────┘
4本目 ┌───────┬──────┐
   └───────┴──────┘
5本目 ┌───────┬──────┐
   └───────┴──────┘
6本目 ┌────┬────┬────┐ 10/3 本をそれぞれ 3 等分して、1/3 ずつ分ける
   └────┴────┴────┘ これは、7回
7本目 ┌────┬────┬────┐
   └────┴────┴────┘
8本目 ┌────┬────┬────┐
   └────┴────┴────┘
9本目 ┌┬┬┬┬┬┬┬┬┬┬────┐ 2/3 本を 10 等分して、1/15 ずつ分ける
   └┴┴┴┴┴┴┴┴┴┴────┘ これは、9回
よって、5+7+9=21回

同じ大きさのものを同じ個数ずつ分けることになる。
(終り)

別解
9/10=1/2+1/5+1/5 9=5+2+2なので、1*5+4*2+4*2=21回
(終り)

参考 http://homepage1.nifty.com/haniu/cake.html


OPTION ARITHMETIC RATIONAL !有理数モード

LET m=9 !6 !7 !4 !2 !本数
LET n=10 !10 !8 !9 !5 !人数

LET s=0 !回数

LET x=n !save it
DO UNTIL m=0
   LET q=CEIL(n/m)
   IF x>q THEN
      LET s=s+(x-INT(x/q))
      PRINT x/q;"本をそれぞれ";q;"等分して、";
   ELSE
      LET s=s+(x-1)
      PRINT x/q;"本を";x;"等分して、";
   END IF
   PRINT "1/";STR$(q);" ずつ分ける"

   LET m=m*q-n !次へ
   LET n=n*q
LOOP

PRINT s;"回"

END

 

狭い場所でカード揃え

 投稿者:GAI  投稿日:2013年 1月 5日(土)17時59分16秒
  1~nの番号のカードを十分シャッフルしてから
表向きにしてテーブルの左の位置に重ねて置いておく。
そして、
テーブルの3カ所(左,中,右)にカードを動かしていく。
ただし、下のルールだけを頼りに操作する。
つまり、下にあるカードの数字は見えなく、また何枚が下にあるのかも
わからない。
以前の状態は一切関係なく、今見えているカードの数のみに依存して
操作を進めるものとする。


_は空枠であることを示す。

<ルール>
①(2,1,_)→1を2の上にのせる。
②2枚のカードが見えていたら、空き枠の左隣のカードで空きを埋める。
(右と左は繋がっていると考える。)
③j<kとし、(k,j,k-1)の配置が見えたら、k-1をkの上にのせる。
(両端が連続する数で左端の方が大きいものであり、中の数がより小さい場合)
④1枚しかカードが見えてないなら、そのカードを左隣へ動かす。
(右と左は繋がっていると考える。)
⑤3枚のカードが見えていたら、その3枚のうち最大の数の右隣に
 あるカードを右隣へ移動する。
(右と左は繋がっていると考える。)

*(左,中,右)にあるカード(重なっている場合は左端の数字が見える。)
 を示す。
<例1>
番号1~4の4枚のカードをシャッフルして
上から[2,1,3,4]であった場合の推移の様子

([2,1,3,4],_,_)
↓④
([1,3,4],_,2)
↓②
([3,4],1,2)
↓③
([2,3,4],1,_)
↓①
([1,2,3,4],_,_)

<例2>
同じく[4,3,2,1]であった場合の推移の様子

([4,3,2,1],_,_)
↓④
([3,2,1],_,4)
↓②
([2,1],3,4)
↓⑤
(1,[2,3],4)
↓⑤
(_,[1,2,3],4)
↓②
(4,[1,2,3],_)
↓②
(4,[2,3],1)
↓⑤
(4,3,[2,1])
↓⑤
(4,_,[3,2,1])
↓②
(_,4,[3,2,1])
↓②
(3,4,[2,1])
↓⑤
([2,3],4,1)
↓⑤
([1,2,3],4,_)
↓②
([1,2,3],_,4)
↓②
([2,3],1,4)
↓⑤
(3,[2,1],4)
↓⑤
(_,[3,2,1],4)
↓②
(4,[3,2,1],_)
↓②
(4,[2,1],3)
↓③
([3,4],[2,1],_)
↓②
([3,4],1,2)
↓③
([2,3,4],1,_)
↓①
([1,2,3,4],_,_)

このルールを守って操作する限り、必ず左の位置に上から1~nの順番に揃ったカードが
重なって終わる。

これが本当に52枚あるトランプでも達成できるのか確かめたいので
この操作をプログラム化して頂きたいです。


 

Re: 狭い場所でカード揃え

 投稿者:山中和義  投稿日:2013年 1月 6日(日)12時13分9秒
  > No.2949[元記事へ]

GAIさんへのお返事です。

> 1~nの番号のカードを十分シャッフルしてから

> <ルール>
> ①(2,1,_)→1を2の上にのせる。
> ②2枚のカードが見えていたら、空き枠の左隣のカードで空きを埋める。
> (右と左は繋がっていると考える。)
> ③j<kとし、(k,j,k-1)の配置が見えたら、k-1をkの上にのせる。
> (両端が連続する数で左端の方が大きいものであり、中の数がより小さい場合)
> ④1枚しかカードが見えてないなら、そのカードを左隣へ動かす。
> (右と左は繋がっていると考える。)
> ⑤3枚のカードが見えていたら、その3枚のうち最大の数の右隣に
>  あるカードを右隣へ移動する。
> (右と左は繋がっていると考える。)

52枚の場合、かなりの作業となります。


LET N=4 !カードの枚数

DIM m1(N),m2(N),m3(N) !カードの並び

SUB card_initialize(c(),N) !カードを整列する
   FOR i=1 TO N
      LET c(i)=i
   NEXT i
END SUB
RANDOMIZE
CALL card_initialize(m1,N)


SUB shuffle_randomize(c(),N) !ランダムにシャッフルする
   FOR i=N TO 2 STEP -1
      LET j=INT(RND*(i-1))+1 !1~i-1
      swap c(i),c(j)
   NEXT i
END SUB
CALL shuffle_randomize(m1,N)
!DATA 1,2,3,4
!!DATA 4,3,1,2
!MAT READ m1
!!!MAT PRINT m1; !debug

MAT m2=ZER
MAT m3=ZER

LET c1=N
LET c2=0
LET c3=0


SUB card_display(c(),N)
   PRINT "{";
   IF N>0 THEN
      PRINT STR$(c(N));
      FOR i=N-1 TO 1 STEP -1
         PRINT ",";STR$(c(i));
      NEXT i
   END IF
   PRINT "}"
END SUB
CALL card_display(m1,c1)
CALL card_display(m2,c2)
CALL card_display(m3,c3)
PRINT


SUB move(x(),a,y(),b) !XからYへ移動させる
   LET t=x(a)
   LET a=a-1
   LET b=b+1
   LET y(b)=t
END SUB

LET S=0 !ステップ
DO

   IF c1=N THEN !整列しているかどうか
      FOR i=c1 TO 1 STEP -1
         IF m1(i)<>N-i+1 THEN EXIT FOR
      NEXT i
      IF i<1 THEN EXIT DO !OK!
   END IF

   LET S=S+1
   PRINT S;": ";

   !ルール1
   IF (c1>0 AND m1(c1)=2) AND (c2>0 AND m2(c2)=1) AND (c3=0) THEN !(2,1,_)なら
      CALL move(m2,c2,m1,c1) !1を2の上にのせる
      PRINT "ルール1"
   ELSE

   !ルール2
      IF c1>0 AND c2>0 AND c3=0 THEN !3が空きなら
         CALL move(m2,c2,m3,c3) !左隣のカードで空きを埋める
         PRINT "ルール2"
      ELSEIF c2>0 AND c3>0 AND c1=0 THEN !1が空きなら
         CALL move(m3,c3,m1,c1)
         PRINT "ルール2"
      ELSEIF c3>0 AND c1>0 AND c2=0 THEN !2が空きなら
         CALL move(m1,c1,m2,c2)
         PRINT "ルール2"
      ELSE

      !ルール3
         IF (c1>0 AND c2>0 AND c3>0) AND (m1(c1)-1=m3(c3) AND m2(c2)<m1(c1)) THEN !(k,j,k-1)
            CALL move(m3,c3,m1,c1) !(k-1)のカードをkのカードの上にのせる
            PRINT "ルール3"
         ELSE

         !ルール4
            IF c1=N AND c2=0 AND c3=0 THEN !2,3が空きなら
               CALL move(m1,c1,m3,c3) !左隣へ移動する
               PRINT "ルール4"
            ELSEIF c2=N AND c3=0 AND c1=0  THEN !3,1が空きなら
               CALL move(m2,c2,m1,c1)
               PRINT "ルール4"
            ELSEIF c3=N AND c1=0 AND c3=0 THEN !1,2が空きなら
               CALL move(m3,c3,m2,c2)
               PRINT "ルール4"
            ELSE

            !ルール5
               IF (c1>0 AND c2>0 AND c3>0) THEN !3枚のカードが見えるなら
                  LET t1=m1(c1)
                  LET t2=m2(c2)
                  LET t3=m3(c3)
                  LET t=MAX(MAX(t1,t2),t3)
                  IF t1=t THEN !1が最大なら
                     CALL move(m2,c2,m3,c3) !右隣のカードを右隣へ移動させる
                  ELSEIF t2=t THEN !2が最大なら
                     CALL move(m3,c3,m1,c1)
                  ELSE !3が最大なら
                     CALL move(m1,c1,m2,c2)
                  END IF
                  PRINT "ルール5"

               END IF
            END IF
         END IF
      END IF
   END IF

   CALL card_display(m1,c1) !結果を表示する
   CALL card_display(m2,c2)
   CALL card_display(m3,c3)
   PRINT

LOOP

END

 

和が22および33にする

 投稿者:山中和義  投稿日:2013年 1月 7日(月)11時00分44秒
  問題
1から10までの10個の数を5個ずつ2組に分ける。それぞれの組で和が22および33になるようにする。
どのように分ければよいか。
例
{1,3,5,6,7}=22と{2,4,8,9,10}=33

答え
  1 +2 +3 +4 +5
+ 10 +9 +8 +7 +6
-------------------
  11+11+11+11+11 = 11*5 = 55
より、
和が11になる組の5通りから、その内の2組ずつを使って、22をつくる。
たとえば、
 {1,10, 2,9}=22
 {3, 8, 4,7}=22
とする。
残りの1組をどちらかに加える。
 {1,10, 2,9, 5,6}=33
 {3, 8, 4,7}=22
22と33ができるが、6個と4個で個数が合わないので、
交換して個数を±1にする1+6=7に着目して、
 {7,10, 2,9,   5}=33
 {3, 8, 4,1,6}=22
とすればよい。
(終り)


別解
小町算
 +1±2±3±4±5±6±7±8±9±10=±(33-22)=±11
の解で、左辺の+と-の個数が同じもの
(終り)


LET N=9 !左辺の+が5つ
LET R=4
CALL CombBit(N,R, 0) !2進法n桁、r個のビットが1
END

EXTERNAL SUB CombBit(N,R, Bit) !n個の中からr個を選ぶ組み合わせをビットで表す ※辞書式順序
IF N=R THEN
!!PRINT Bit+2^R-1 !ビットパターンを生成する
   CALL stub(Bit+2^R-1)
ELSEIF N>0 THEN
   CALL CombBit(N-1,R,Bit)
   CALL CombBit(N-1,R-1,Bit+2^(N-1))
END IF
END SUB

!小町算「+1±2±3±4±5±6±7±8±9±10=±11、左辺の+と-の個数が同じもの」を解く
EXTERNAL SUB stub(Bit)
LET t=Bit !左辺を計算する
LET S=1 !1の前は+のみ
FOR K=10 TO 2 STEP -1 !進数変換でパターンを得る
   IF MOD(t,2)=1 THEN LET S=S+K ELSE LET S=S-K !ビットが1なら和
   LET t=INT(t/2)
NEXT K
IF ABS(S)=11 THEN PRINT BSTR$(2^9+Bit,2) !±11なら、条件を満たす
END SUB



別解
 問題
 1≦a<b<c<d<e≦10とする整数の組(a,b,c,d,e)がある。
 a+b+c+d+e=22(または33)を満たすものはいくつあるか。
として、不定方程式を解く。
1≦a<b<c<d≦10なる整数として、a+b+c+d+e=22を考える。
 5a<a+b+c+d+e=22より、a<22/5
 4b<b+c+d+e=22-aより、b<(22-a)/4
 3c<c+d+e=22-(a+b)より、c<(22-(a+b))/3
 2d<d+e=22-(a+b+c)より、d<(22-(a+b+c))/2
なので、組(a,b,c,d)を求めると、
 (1,2,3,6,10) (1,2,3,7,9) (1,2,4,5,10) (1,2,4,6,9) (1,2,4,7,8)
 (1,2,5,6,8) (1,3,4,5,9) (1,3,4,6,8) (1,3,5,6,7) (2,3,4,5,8)
 (2,3,4,6,7)
の11通りとなる。


FOR a=1 TO 22/5
   FOR b=a+1 TO (22-a)/4
      FOR c=b+1 TO (22-(a+b))/3
         FOR d=c+1 TO (22-(a+b+c))/2
            LET e=22-(a+b+c+d)
            IF e>d AND e<=10 THEN PRINT a;b;c;d;e
         NEXT d
      NEXT c
   NEXT b
NEXT a
END

 

小町算でπを作る

 投稿者:山中和義  投稿日:2013年 1月10日(木)20時50分5秒
 
!小町算でπを作る

!π=ArcTan(1)+ArcTan(2)+ArcTan(3)より、

PRINT ATN(5-4)+ATN(3)+ATN(2*1) !1から5まで
PRINT ATN((5-4)*3)+ATN(2)+ATN(1) !1から5まで
PRINT ATN((5+4)/3)+ATN(2)+ATN(1) !1から5まで

PRINT ATN(7-6+5-4)+ATN(3)+ATN(2-1) !1から7まで
PRINT ATN(7-6)+ATN((5-4)*3)+ATN(2*1) !1から7まで
PRINT ATN(7-6)+ATN((5+4)/3)+ATN(2*1) !1から7まで
PRINT ATN((7+6-5)/4)+ATN(3)+ATN(2-1) !1から7まで

PRINT ATN(8+7+6-5*4)+ATN(3)+ATN(2*1) !1から8まで
PRINT ATN((8+7-6-5)/4)+ATN(3)+ATN(2*1) !1から8まで

PRINT ATN(9-8-7+6+5-4)+ATN(3)+ATN(2*1) !1から9まで
PRINT ATN(9-8+7-6-5+4)+ATN(3)+ATN(2*1) !1から9まで
PRINT ATN(-9-8-7+6+5*4)+ATN(3)+ATN(2-1) !1から9まで
PRINT ATN(-9-8-7+6*5-4)+ATN(3)+ATN(2-1) !1から9まで
PRINT ATN((9*8-7*6)/5-4)+ATN(3)+ATN(2-1) !1から9まで

PRINT ATN(10-9)+ATN(8-7+6-5)+ATN(4-3+2*1) !1から10まで
PRINT ATN(10+9-8-7+6-5-4)+ATN(3)+ATN(2*1) !1から10まで
PRINT ATN((10+9-8-7)*(6-5)/4)+ATN(3)+ATN(2*1) !1から10まで


!π/4=ArcTan(1)より

PRINT 4*(3-2)*ATN(1) !1から4まで
PRINT 4*ATN(3-2*1) !1から4まで

PRINT (5+4-3-2)*ATN(1) !1から5まで
PRINT (5-4+3)*ATN(2-1) !1から5まで
PRINT ATN(5-4)*(3+2-1) !1から5まで

PRINT (6+5-4-3)*ATN(2-1) !1から6まで
PRINT (6-5)*4*(3-2)*ATN(1) !1から6まで

PRINT (7+6-5-4)*(3-2)*ATN(1) !1から7まで
PRINT (7-6-5)*ATN((4-3-2)*1) !1から7まで

PRINT (8-7+6-5-4+3*2)*ATN(1) !1から8まで
PRINT (8-7-6+5+4)*ATN(3-2*1) !1から8まで
PRINT (8-7)*(6-5)*4*(3-2)*ATN(1) !1から8まで
PRINT (8+7-6-5)*ATN((-4+3+2)*1) !1から8まで

PRINT (9-8+7-6+5-4+3-2)*ATN(1) !1から9まで
PRINT (9+8-7-6+5-4-3+2)*ATN(1) !1から9まで

PRINT ((10-9+8-7)*(6-5)-4+3*2)*ATN(1) !1から10まで
PRINT ATN((10-9)*(8-7)*(6-5))*4*(3-2*1) !1から10まで
PRINT (10+9-8-7)*(6-5)*(-4+3+2)*ATN(1) !1から10まで
PRINT (10+9-8-7)*(6-5)*ATN(-4+3*2-1) !1から10まで


!α+β=π/4を求める。
! tan(α+β)=(tanα+tanβ)/(1-tanαtanβ)=1とすると、tanβ=(1-tanα)/(1+tanα)
! tanα=m/nのとき、tanβ=(n-m)/(n+m)
! (m,n)=(2,1)なら、(n-m)/(n+m)=(1-2)/(1+2)=-1/3
! (m,n)=(5,1)なら、(n-m)/(n+m)=(1-5)/(1+5)=-2/3
! (m,n)=(6,1)なら、(n-m)/(n+m)=(1-6)/(1+6)=-5/7
! から、(tanα,tanβ)=(2,-1/3)、(5,-2/3)、(6,-5/7)、…
!より、

PRINT 4*(ATN(2)-ATN(1/3)) !1,2,3,4
PRINT 4*(ATN(5)-ATN(2/3)) !2,3,4,5
PRINT 4*(ATN(6)-ATN(5/7)) !4,5,6,7


!その他

PRINT ATN(3-2)*4 !2,3,4
PRINT ATN(6-5)*4 !4,5,6
PRINT 4*ATN((7-5)*3/6) !3,4,5,6,7
PRINT ATN((8-7)*(6-5))*4 !4,5,6,7,8
PRINT (10+9-8-7)*ATN(6-5) !5,6,7,8,9,10
PRINT ATN((10-9)*(8-7)*(6-5))*4 !4,5,6,7,8,9,10


PRINT ATN(1)+ATN(4-2)+ATN(3) !1から4まで
PRINT ATN(5-4)+ATN(2*1)+ATN(6-3) !1から6まで
PRINT ATN(6-5)+ATN(4-2)+ATN(3*1) !1から6まで
PRINT ATN(6-5)+ATN(3)+ATN(4-2*1) !1から6まで

END

 

赤字補填ゲーム

 投稿者:GAI  投稿日:2013年 1月11日(金)18時16分9秒
  正5角形の各頂点に整数(負の数も含む)が割り当てられている。
これをラベルと呼ぶことにする。
各ラベルの和sは正の値とする。
今、ある頂点にあるラベルが負の値のとき、ここを符号を反転させて正の値に切り替える。
このとき全体の和sの値が変わらないように、両隣のラベルから、反転させた値を引くようにしておく。
どのラベルをひっくり返すかにかかわらず、この操作を有限回繰り返すと、すべてのラベルの値が非負になって必ず止まることが起こるという。


<このモデルは各支社の売り上げが黒字(プラスのラベル)や赤字(マイナスのラベル)であるとき(ただし総計での売り上げは黒字。)各支社は赤字を隠すために両隣の支社から、赤字補填の操作をしてもらうことを繰り返し行っていくと、遂には各支社赤字が出なかった帳簿を作り上げるよくニュースで聞くモデルを見せてくれそうです。>

例として5角形の頂点にあるラベルを
(1,-2,0,-1,3)を初期状態として(s=1)推移の様子を記述してみると
(-1,2,-2,-1,3)
(-1,0,2,-3,3)
(-1,0,-1,3,0)
(1,-1,-1,3,-1)
(0,1,-2,3,-1)
(0,-1,2,1,-1)
(-1,1,1,1,-1)
(1,0,1,1,-2)
(-1,0,1,-1,2)
(-1,0,0,1,1)
(1,-1,0,1,0)
(0,1,-1,1,0)
(0,0,1,0,0)
と13回目でストップする。

これは一般にn角形の頂点やさらに任意の連結グラフにまで一般化できるという。
そこでこのモデルがどの様に動くのかを、5角形や6角形、・・・
の支社を持つ会社として見てみたい。

分かり難い説明で申し訳ありませんが、趣旨を読み取ってそのモデルを作って頂きたい。



 

Re: 赤字補填ゲーム

 投稿者:山中和義  投稿日:2013年 1月12日(土)11時14分30秒
  > No.2953[元記事へ]

GAIさんへのお返事です。

> 例として5角形の頂点にあるラベルを
> (1,-2,0,-1,3)を初期状態として(s=1)推移の様子を記述してみると
> (-1,2,-2,-1,3)
> (-1,0,2,-3,3)
> (-1,0,-1,3,0)
> (1,-1,-1,3,-1)
> (0,1,-2,3,-1)
> (0,-1,2,1,-1)
> (-1,1,1,1,-1)
> (1,0,1,1,-2)
> (-1,0,1,-1,2)
> (-1,0,0,1,1)
> (1,-1,0,1,0)
> (0,1,-1,1,0)
> (0,0,1,0,0)
> と13回目でストップする。


!赤字補填ゲーム

DATA 5 !個数
DATA 1,-2,0,-1,3 !値

READ N
DIM B(0 TO N-1)
MAT READ B
MAT PRINT B; !debug

LET S=0
FOR i=0 TO N-1
   LET S=S+B(i)
NEXT i
PRINT "総和=";S


LET C=0 !回数
DO
   FOR i=0 TO N-1 !最初に見つかったもの
      IF B(i)<0 THEN EXIT FOR
   NEXT i
   IF i>N-1 THEN EXIT DO !すべてが非負なら、終了!

   LET T=-B(i) !反転
   LET B(i)=T
   LET B(MOD(i-1,N))=B(MOD(i-1,N))-T !両隣から反転させた値を引く
   LET B(MOD(i+1,N))=B(MOD(i+1,N))-T

   MAT PRINT B; !状態を表示する

   LET C=C+1
LOOP

PRINT C;"回"

END


実行結果

1 -2  0 -1  3

総和= 1
-1  2 -2 -1  3

1  1 -2 -1  2

1 -1  2 -3  2

0  1  1 -3  2

0  1 -2  3 -1

0 -1  2  1 -1

-1  1  1  1 -1

1  0  1  1 -2

-1  0  1 -1  2

1 -1  1 -1  1

0  1  0 -1  1

0  1 -1  1  0

0  0  1  0  0

13 回




 

Re: 赤字補填ゲーム

 投稿者:山中和義  投稿日:2013年 1月13日(日)11時08分35秒
  > No.2954[元記事へ]

> (0,0,1,0,0)
> と13回目でストップする。

操作の順番によらず結果と回数は同じになるようです。
 

バケツを空に

 投稿者:GAI  投稿日:2013年 1月14日(月)17時38分31秒
  大きなバケツが3つあり(これをA,B,Cで表す。)
それぞれにきっちり整数リットルの蒸発しない液体が入っているとする。
(容器には十分な余裕があるものとする。)
一度に出来る操作は、あるバケツにそれ以上多くの液体が入っている他のバケツから
液体の一部を移して2倍にすること。
言いかえれば、xリットル入っているバケツから、yリットル(ただしy≦x)入っている
バケツへyリットルだけ移し、バケツの中身をそれぞれ、(x-y)リットルと(2×y)リットル
にすることである。

今最初の3つのバケツの液体の量が次の時一つのバケツを空にする手順は?
例
(A,B,C)=( 6,11,14) であるとき、
      →(12,11, 8)
      →(12, 3,16)
      →( 9, 6,16)
      →( 3,12,16)
      →( 6,12,13)
      →(12,12, 7)
      →( 0,24, 7)

の7回で目的達成できる。



この操作をする限りどんな初期状態であれ、必ず一つのバケツを空にすることができるという。
このパズルを解かせる最も手数が掛かってしまう初期状態の容器にある液体の量の組合せ(100リットル以内で)を探してくれませんか。
 

Re: バケツを空に

 投稿者:山中和義  投稿日:2013年 1月15日(火)11時19分6秒
  > No.2956[元記事へ]

GAIさんへのお返事です。

> 例
> (A,B,C)=( 6,11,14) であるとき、
>       →(12,11, 8)
>       →(12, 3,16)
>       →( 9, 6,16)
>       →( 3,12,16)
>       →( 6,12,13)
>       →(12,12, 7)
>       →( 0,24, 7)
>
>  の7回で目的達成できる。

最後の3手
x<yとして、組(x,2x,y) → (2x,2x,y-x) → (0,4x,y-x) となる。
これより、x+2x+y=Nとして、3x=N-y
この式を満たす(x,y)に着目する。

この場合は、6+11+14=31なので、
(x,y)=(10,1)、(9,4)、(8,7)、(7,10)、(6,13)、(5,16)、(4,19)、(3,22)、(2,25)、(1,28)
が最後の3手である。

 0: (6,11,14)
 1: (6,22,3) ←(3,22)
 2: (6,19,6)
 3: (0,19,12)


>       →( 6,12,13)
>       →(12,12, 7)
>       →( 0,24, 7)

これは、(6,13)となります。


最適解は、試行錯誤するしかないようなので、深さ優先(バックトラック法)で探索してみました。


PUBLIC NUMERIC S !手数 ※上限
LET S=20
DIM A(0 TO S),B(0 TO S),C(0 TO S) !バケツの水量

LET A(0)=6
LET B(0)=11
LET C(0)=14

CALL try(0,A,B,C)
PRINT S;"回"

END

EXTERNAL SUB try(p,A(),B(),C()) !バックトラック法で検索する
IF A(p)=0 OR B(p)=0 OR C(p)=0 THEN
   IF p< S THEN
      LET S=p !更新
      FOR i=0 TO p !手順を表示する
         PRINT STR$(i);": (";STR$(A(i));",";STR$(B(i));",";STR$(C(i));")"
      NEXT i
      PRINT
   END IF
ELSE
   IF p< S THEN !手数の上限以内なら、次の6通りを試す
      IF A(p)>=B(p) THEN !A→Bとする
         LET A(p+1)=A(p)-B(p)
         LET B(p+1)=2*B(p)
         LET C(p+1)=C(p)
         CALL try(p+1,A,B,C)
      END IF
      IF A(p)>=C(p) THEN !A→Cとする
         LET A(p+1)=A(p)-C(p)
         LET C(p+1)=2*C(p)
         LET B(p+1)=B(p)
         CALL try(p+1,A,B,C)
      END IF
      IF B(p)>=C(p) THEN !B→Cとする
         LET B(p+1)=B(p)-C(p)
         LET C(p+1)=2*C(p)
         LET A(p+1)=A(p)
         CALL try(p+1,A,B,C)
      END IF
      IF B(p)>=A(p) THEN !B→Aとする
         LET B(p+1)=B(p)-A(p)
         LET A(p+1)=2*A(p)
         LET C(p+1)=C(p)
         CALL try(p+1,A,B,C)
      END IF
      IF C(p)>=A(p) THEN !C→Aとする
         LET C(p+1)=C(p)-A(p)
         LET A(p+1)=2*A(p)
         LET B(p+1)=B(p)
         CALL try(p+1,A,B,C)
      END IF
      IF C(p)>=B(p) THEN !C→Bとする
         LET C(p+1)=C(p)-B(p)
         LET B(p+1)=2*B(p)
         LET A(p+1)=A(p)
         CALL try(p+1,A,B,C)
      END IF
   END IF
END IF
END SUB

 

Re: バケツを空に

 投稿者:山中和義  投稿日:2013年 1月15日(火)12時41分8秒
  GAIさんへのお返事です。

> 最後の3手
> x<yとして、組(x,2x,y) → (2x,2x,y-x) → (0,4x,y-x) となる。
> これより、x+2x+y=Nとして、3x=N-y
> この式を満たす(x,y)に着目する。

x<yとして、組(x,3x,y) → (2x,3x-x,y)=(2x,2x,y) → (0,4x,y) となる。
これも条件をみたしますね。

50の範囲では、
(27,35,43) 9 回

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (30,32,43)
4: (60,2,43)
5: (60,4,41)
6: (56,8,41)
7: (48,16,41)
8: (32,32,41)
9: (0,64,41)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (30,32,43)
4: (60,2,43)
5: (60,4,41)
6: (56,8,41)
7: (48,16,41)
8: (32,32,41)
9: (64,0,41)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,13,86)
5: (6,26,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,13,86)
5: (6,26,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,10,83)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,10,83)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,4,77)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,4,77)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,16,65)
7: (48,16,41)
8: (32,32,41)
9: (0,64,41)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,16,65)
7: (48,16,41)
8: (32,32,41)
9: (64,0,41)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,13,86)
5: (6,26,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,13,86)
5: (6,26,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,10,83)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,10,83)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,4,77)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,4,77)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,16,65)
7: (48,16,41)
8: (32,32,41)
9: (0,64,41)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,16,65)
7: (48,16,41)
8: (32,32,41)
9: (64,0,41)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (22,8,75)
4: (14,16,75)
5: (28,2,75)
6: (28,4,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (22,8,75)
4: (14,16,75)
5: (28,2,75)
6: (28,4,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (11,16,78)
4: (22,5,78)
5: (22,10,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (11,16,78)
4: (22,5,78)
5: (22,10,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (76,3,26)
5: (73,6,26)
6: (73,12,20)
7: (73,24,8)
8: (73,16,16)
9: (73,0,32)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (76,3,26)
5: (73,6,26)
6: (73,12,20)
7: (73,24,8)
8: (73,16,16)
9: (73,32,0)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (76,3,26)
5: (50,3,52)
6: (100,3,2)
7: (97,6,2)
8: (97,4,4)
9: (97,0,8)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (76,3,26)
5: (50,3,52)
6: (100,3,2)
7: (97,6,2)
8: (97,4,4)
9: (97,8,0)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (38,6,61)
5: (38,12,55)
6: (38,24,43)
7: (38,48,19)
8: (38,29,38)
9: (0,29,76)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (38,6,61)
5: (38,12,55)
6: (38,24,43)
7: (38,48,19)
8: (38,29,38)
9: (76,29,0)

0: (27,35,43)
1: (54,35,16)
2: (54,19,32)
3: (54,38,13)
4: (41,38,26)
5: (41,12,52)
6: (41,24,40)
7: (41,48,16)
8: (41,32,32)
9: (41,0,64)

0: (27,35,43)
1: (54,35,16)
2: (54,19,32)
3: (54,38,13)
4: (41,38,26)
5: (41,12,52)
6: (41,24,40)
7: (41,48,16)
8: (41,32,32)
9: (41,64,0)

0: (27,35,43)
1: (54,35,16)
2: (54,19,32)
3: (54,38,13)
4: (54,25,26)
5: (54,50,1)
6: (4,100,1)
7: (4,99,2)
8: (4,97,4)
9: (0,97,8)

0: (27,35,43)
1: (54,35,16)
2: (54,19,32)
3: (54,38,13)
4: (54,25,26)
5: (54,50,1)
6: (4,100,1)
7: (4,99,2)
8: (4,97,4)
9: (8,97,0)


つづく

 

Re: バケツを空に

 投稿者:山中和義  投稿日:2013年 1月15日(火)12時44分47秒
  > No.2958[元記事へ]

GAIさんへのお返事です。

> 50の範囲では、
> (27,35,43) 9 回

つづき

(36,41,46) 9 回

0: (36,41,46)
1: (72,5,46)
2: (67,10,46)
3: (67,20,36)
4: (67,40,16)
5: (67,24,32)
6: (67,48,8)
7: (59,48,16)
8: (59,32,32)
9: (59,0,64)

0: (36,41,46)
1: (72,5,46)
2: (67,10,46)
3: (67,20,36)
4: (67,40,16)
5: (67,24,32)
6: (67,48,8)
7: (59,48,16)
8: (59,32,32)
9: (59,64,0)

0: (36,41,46)
1: (72,5,46)
2: (26,5,92)
3: (52,5,66)
4: (104,5,14)
5: (99,10,14)
6: (99,20,4)
7: (99,16,8)
8: (91,16,16)
9: (91,0,32)

0: (36,41,46)
1: (72,5,46)
2: (26,5,92)
3: (52,5,66)
4: (104,5,14)
5: (99,10,14)
6: (99,20,4)
7: (99,16,8)
8: (91,16,16)
9: (91,32,0)

0: (36,41,46)
1: (72,5,46)
2: (26,5,92)
3: (26,10,87)
4: (16,20,87)
5: (32,4,87)
6: (32,8,83)
7: (32,16,75)
8: (32,32,59)
9: (0,64,59)

0: (36,41,46)
1: (72,5,46)
2: (26,5,92)
3: (26,10,87)
4: (16,20,87)
5: (32,4,87)
6: (32,8,83)
7: (32,16,75)
8: (32,32,59)
9: (64,0,59)

0: (36,41,46)
1: (72,41,10)
2: (31,82,10)
3: (62,51,10)
4: (11,102,10)
5: (22,91,10)
6: (12,91,20)
7: (24,91,8)
8: (16,91,16)
9: (0,91,32)

0: (36,41,46)
1: (72,41,10)
2: (31,82,10)
3: (62,51,10)
4: (11,102,10)
5: (22,91,10)
6: (12,91,20)
7: (24,91,8)
8: (16,91,16)
9: (32,91,0)

0: (36,41,46)
1: (72,41,10)
2: (62,41,20)
3: (62,21,40)
4: (22,21,80)
5: (44,21,58)
6: (88,21,14)
7: (67,42,14)
8: (67,28,28)
9: (67,0,56)

0: (36,41,46)
1: (72,41,10)
2: (62,41,20)
3: (62,21,40)
4: (22,21,80)
5: (44,21,58)
6: (88,21,14)
7: (67,42,14)
8: (67,28,28)
9: (67,56,0)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (52,31,40)
4: (12,31,80)
5: (12,62,49)
6: (24,50,49)
7: (48,50,25)
8: (23,50,50)
9: (23,0,100)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (52,31,40)
4: (12,31,80)
5: (12,62,49)
6: (24,50,49)
7: (48,50,25)
8: (23,50,50)
9: (23,100,0)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (52,31,40)
4: (52,62,9)
5: (52,53,18)
6: (34,53,36)
7: (34,17,72)
8: (34,34,55)
9: (0,68,55)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (52,31,40)
4: (52,62,9)
5: (52,53,18)
6: (34,53,36)
7: (34,17,72)
8: (34,34,55)
9: (68,0,55)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (72,11,40)
4: (72,22,29)
5: (72,44,7)
6: (28,88,7)
7: (28,81,14)
8: (28,67,28)
9: (0,67,56)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (72,11,40)
4: (72,22,29)
5: (72,44,7)
6: (28,88,7)
7: (28,81,14)
8: (28,67,28)
9: (56,67,0)

0: (36,41,46)
1: (36,82,5)
2: (31,82,10)
3: (62,51,10)
4: (11,102,10)
5: (22,91,10)
6: (12,91,20)
7: (24,91,8)
8: (16,91,16)
9: (0,91,32)

0: (36,41,46)
1: (36,82,5)
2: (31,82,10)
3: (62,51,10)
4: (11,102,10)
5: (22,91,10)
6: (12,91,20)
7: (24,91,8)
8: (16,91,16)
9: (32,91,0)

0: (36,41,46)
1: (36,82,5)
2: (36,77,10)
3: (26,77,20)
4: (6,77,40)
5: (12,71,40)
6: (24,59,40)
7: (48,59,16)
8: (32,59,32)
9: (0,59,64)

0: (36,41,46)
1: (36,82,5)
2: (36,77,10)
3: (26,77,20)
4: (6,77,40)
5: (12,71,40)
6: (24,59,40)
7: (48,59,16)
8: (32,59,32)
9: (64,59,0)

0: (36,41,46)
1: (36,82,5)
2: (36,77,10)
3: (36,67,20)
4: (16,67,40)
5: (32,67,24)
6: (8,67,48)
7: (16,59,48)
8: (32,59,32)
9: (0,59,64)

0: (36,41,46)
1: (36,82,5)
2: (36,77,10)
3: (36,67,20)
4: (16,67,40)
5: (32,67,24)
6: (8,67,48)
7: (16,59,48)
8: (32,59,32)
9: (64,59,0)

 

Re: バケツを空に

 投稿者:山中和義  投稿日:2013年 1月16日(水)10時56分23秒
  > No.2959[元記事へ]

次の流れに早く持ち込めれば最少手数になるようです。

●最後の2手
組(x,x,y) → (0,2x,y) となる。(yを使わない)

●最後の3手
・x<yとして、組(x,2x,y) → (2x,2x,y-x) → (0,4x,y-x) となる。
・組(x,3x,y) → (2x,3x-x,y)=(2x,2x,y) → (0,4x,y) となる。(yを使わない)

●既約
(kx,ky,kz)は、(x,y,z)と同じ

●2のべき乗
a,bを正の整数とする。互いに素で、a+b=2^kを満たすとき、(ax,bx,y)はk回となる。
例 2^4=16のとき、4手
 (x,15x,y) → (2x,14x,y) → (4x,12x,y) → (8x,8x,y) → (0,16x,y)
 (3x,13x,y) → (6x,10x,y) → (12x,4x,y) → (8x,8x,y) → (0,16x,y)
 (5x,11x,y) → (10x,6x,y) → (4x,12x,y) → (8x,8x,y) → (0,16x,y)
 (7x,9x,y) → (14x,2x,y) → (12x,4x,y) → (8x,8x,y) → (0,16x,y)
(考察)
k=1のとき、
 a+b=2^1なので、a=1,b=1
 (x,x,y) → (0,2x,y)
 yを使わず、1(=k)回である。 ※最後の2手
k=2のとき、
 a+b=2^2なので、a=1,b=3
 (x,3x,y) → (2x,3x-x,y)=(2x,2x,y) → (0,4x,y)
 yを使わず、2(=k)回である。 ※最後の3手のひとつ
k≧3のとき、
 a<bとすると、(ax,bx,y)=(ax,(2^k-a)x,y) → (2ax,(2^k-a)x-ax,y)=(2ax,2(2^(k-1)-a)x,y)
 (ax,(2^(k-1)-a)x,y)は(k-1)回と仮定すると、k回となる。
 実際は、途中に現れるaxとbxの小さい方を2倍していくことになる。
(終り)
 

単位分数の和で1/2をつくる

 投稿者:山中和義  投稿日:2013年 1月17日(木)10時10分56秒
  問題
nを、2より大きい整数とする。
互いに素となる正の整数p,qが、p<q≦n かつ p+q>n を満たすとき、
Σ1/(pq)=1/2となる。

考察
n=2のとき
 1/(1*2)
n=3のとき
 1/(1*2) +1/(1*3)+1/(2*3)
n=4のとき
 1/(1*3) +1/(2*3) +1/(1*4)+1/(3*4)
n=5のとき
 1/(2*3)+1/(1*4) +1/(3*4) +1/(1*5)+1/(2*5)+1/(3*5)+1/(4*5)
n=6のとき
 1/(1*5) +1/(3*4)+1/(2*5)+1/(3*5)+1/(4*5) +1/(1*6)+1/(5*6)

一般に、
 a,bは正の整数のとき、1/(ab)=1/(a(a+b))+1/(b(a+b))

互いに素とする組(a,b)が、この問題にあてはまる。

a+b=7のとき、(a,b)=(1,6)、(2,5)、(3,4)なので、
1/(1*6)=1/(1*7)+1/(6*7)、1/(2*5)=1/(2*7)+1/(5*7)、1/(3*4)=1/(3*7)+1/(4*7)
これより、
 n=7のとき、
  n=6、すなわち、1/(3*4)+1/(2*5)+1/(3*5)+1/(4*5)+1/(1*6)+1/(5*6) をもとに、
  1/(3*4)+1/(2*5)+1/(1*6) +1/(3*5)+1/(4*5)+1/(5*6) +1/(1*7)+1/(2*7)+1/(3*7)+1/(4*7)+1/(5*7)+1/(6*7)
  とする。
とすることで、機械的に生成できる。
(終り)


OPTION ARITHMETIC RATIONAL !有理数モード
FOR n=2 TO 20
   LET s=0
   FOR p=1 TO n-1 !1≦p<q≦n
      FOR q=p+1 TO n
         IF gcd(p,q)=1 THEN !互いに素
            IF p+q>n THEN
               PRINT p;q; !debug
               IF p+q=n+1 THEN PRINT "*" ELSE PRINT !debug
               LET s=s+1/(p*q) !Σ1/(pq)
            END IF
         END IF
      NEXT q
   NEXT p
   PRINT "n=";n; s !=1/2
   PRINT
NEXT n
END

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=a
END FUNCTION

 

0と1からなるnの倍数

 投稿者:山中和義  投稿日:2013年 1月18日(金)12時56分27秒
  問題
全ての自然数n対して必ず0と1からなるnの倍数が存在する

考察
9,18,27,36,…,90,99,,… が大きい数となる
最小の数がすべて1となるのは、1,3,9,11,33,37,41,99,…


OPTION ARITHMETIC RATIONAL !多桁の整数

FOR N=1 TO 100

   LET C=0 !個数
   LET B=1
   DO WHILE C<3

      LET W=BIT2DEC(B) !2進法のビット列を10進法数値と解釈する
      IF MOD(W,N)=0 THEN
         LET C=C+1
         PRINT N;"×";W/N;"=";W
      END IF

      LET B=B+1
   LOOP
   PRINT

NEXT n

END

EXTERNAL FUNCTION BIT2DEC(N) !2進法のビット列を10進法数値と解釈する
OPTION ARITHMETIC RATIONAL !多桁の整数
LET BIT2DEC=0
IF N>0 THEN LET BIT2DEC=BIT2DEC(INT(N/2))*10+MOD(N,2)
END FUNCTION


実行結果

1 × 1 = 1
1 × 10 = 10
1 × 11 = 11

2 × 5 = 10
2 × 50 = 100
2 × 55 = 110

3 × 37 = 111
3 × 337 = 1011
3 × 367 = 1101

4 × 25 = 100
4 × 250 = 1000
4 × 275 = 1100

5 × 2 = 10
5 × 20 = 100
5 × 22 = 110

6 × 185 = 1110
6 × 1685 = 10110
6 × 1835 = 11010

7 × 143 = 1001
7 × 1430 = 10010
7 × 1443 = 10101

8 × 125 = 1000
8 × 1250 = 10000
8 × 1375 = 11000

9 × 12345679 = 111111111
9 × 112345679 = 1011111111
9 × 122345679 = 1101111111

10 × 1 = 10
10 × 10 = 100
10 × 11 = 110

11 × 1 = 11
11 × 10 = 110
11 × 91 = 1001

12 × 925 = 11100
12 × 8425 = 101100
12 × 9175 = 110100

13 × 77 = 1001
13 × 770 = 10010
13 × 777 = 10101

14 × 715 = 10010
14 × 7150 = 100100
14 × 7215 = 101010

15 × 74 = 1110
15 × 674 = 10110
15 × 734 = 11010

16 × 625 = 10000
16 × 6250 = 100000
16 × 6875 = 110000

17 × 653 = 11101
17 × 5883 = 100011
17 × 6530 = 111010

18 × 61728395 = 1111111110
18 × 561728395 = 10111111110
18 × 611728395 = 11011111110

19 × 579 = 11001
19 × 5269 = 100111
19 × 5790 = 110010

20 × 5 = 100
20 × 50 = 1000
20 × 55 = 1100

21 × 481 = 10101
21 × 4810 = 101010
21 × 5291 = 111111

22 × 5 = 110
22 × 50 = 1100
22 × 455 = 10010

23 × 4787 = 110101
23 × 43957 = 1011011
23 × 47870 = 1101010

24 × 4625 = 111000
24 × 42125 = 1011000
24 × 45875 = 1101000

25 × 4 = 100
25 × 40 = 1000
25 × 44 = 1100

26 × 385 = 10010
26 × 3850 = 100100
26 × 3885 = 101010

27 × 40781893 = 1101111111
27 × 41151893 = 1111101111
27 × 41152263 = 1111111101

28 × 3575 = 100100
28 × 35750 = 1001000
28 × 36075 = 1010100

29 × 37969 = 1101101
29 × 348659 = 10111111
29 × 379659 = 11010111

30 × 37 = 1110
30 × 337 = 10110
30 × 367 = 11010

31 × 3581 = 111011
31 × 32581 = 1010011
31 × 35810 = 1110110

32 × 3125 = 100000
32 × 31250 = 1000000
32 × 34375 = 1100000

33 × 3367 = 111111
33 × 33367 = 1101111
33 × 33667 = 1111011

34 × 3265 = 111010
34 × 29415 = 1000110
34 × 32650 = 1110100

35 × 286 = 10010
35 × 2860 = 100100
35 × 2886 = 101010

36 × 308641975 = 11111111100
36 × 2808641975 = 101111111100
36 × 3058641975 = 110111111100

37 × 3 = 111
37 × 30 = 1110
37 × 273 = 10101

38 × 2895 = 110010
38 × 26345 = 1001110
38 × 28950 = 1100100

39 × 259 = 10101
39 × 2590 = 101010
39 × 2849 = 111111

40 × 25 = 1000
40 × 250 = 10000
40 × 275 = 11000

41 × 271 = 11111
41 × 2710 = 111110
41 × 24661 = 1011101

42 × 2405 = 101010
42 × 24050 = 1010100
42 × 26455 = 1111110

43 × 25607 = 1101101
43 × 234907 = 10101001
43 × 256070 = 11011010

44 × 25 = 1100
44 × 250 = 11000
44 × 2275 = 100100

45 × 24691358 = 1111111110
45 × 224691358 = 10111111110
45 × 244691358 = 11011111110

46 × 23935 = 1101010
46 × 219785 = 10110110
46 × 239350 = 11010100

47 × 213 = 10011
47 × 2130 = 100110
47 × 21300 = 1001100

48 × 23125 = 1110000
48 × 210625 = 10110000
48 × 229375 = 11010000

49 × 22449 = 1100001
49 × 206349 = 10111101
49 × 224490 = 11000010

50 × 2 = 100
50 × 20 = 1000
50 × 22 = 1100

51 × 1961 = 100011
51 × 19610 = 1000110
51 × 196100 = 10001100

52 × 1925 = 100100
52 × 19250 = 1001000
52 × 19425 = 1010100

53 × 1887 = 100011
53 × 18870 = 1000110
53 × 18887 = 1001011

54 × 203909465 = 11011111110
54 × 205759465 = 11111011110
54 × 205761315 = 11111111010

55 × 2 = 110
55 × 20 = 1100
55 × 182 = 10010

56 × 17875 = 1001000
56 × 178750 = 10010000
56 × 180375 = 10101000

57 × 193 = 11001
57 × 1930 = 110010
57 × 19300 = 1100100

58 × 189845 = 11011010
58 × 1743295 = 101111110
58 × 1898295 = 110101110

59 × 186629 = 11011111
59 × 1696629 = 100101111
59 × 1713729 = 101110011

60 × 185 = 11100
60 × 1685 = 101100
60 × 1835 = 110100

61 × 1641 = 100101
61 × 16410 = 1001010
61 × 18051 = 1101111

62 × 17905 = 1110110
62 × 162905 = 10100110
62 × 179050 = 11101100

63 × 17635097 = 1111011111
63 × 160335097 = 10101111111
63 × 160493827 = 10111111101

64 × 15625 = 1000000
64 × 156250 = 10000000
64 × 171875 = 11000000

65 × 154 = 10010
65 × 1540 = 100100
65 × 1554 = 101010

66 × 16835 = 1111110
66 × 166835 = 11011110
66 × 168335 = 11110110

67 × 16433 = 1101011
67 × 149403 = 10010001
67 × 164330 = 11010110

68 × 16325 = 1110100
68 × 147075 = 10001100
68 × 163250 = 11101000

69 × 144929 = 10000101
69 × 161029 = 11111001
69 × 1449290 = 100001010

70 × 143 = 10010
70 × 1430 = 100100
70 × 1443 = 101010

71 × 141 = 10011
71 × 1410 = 100110
71 × 14100 = 1001100

72 × 1543209875 = 111111111000
72 × 14043209875 = 1011111111000
72 × 15293209875 = 1101111111000

73 × 137 = 10001
73 × 1370 = 100010
73 × 1507 = 110011

74 × 15 = 1110
74 × 150 = 11100
74 × 1365 = 101010

75 × 148 = 11100
75 × 1348 = 101100
75 × 1468 = 110100

76 × 14475 = 1100100
76 × 131725 = 10011100
76 × 144750 = 11001000

77 × 13 = 1001
77 × 130 = 10010
77 × 143 = 11011

78 × 1295 = 101010
78 × 12950 = 1010100
78 × 14245 = 1111110

79 × 126709 = 10010011
79 × 140519 = 11101001
79 × 1267090 = 100100110

80 × 125 = 10000
80 × 1250 = 100000
80 × 1375 = 110000

81 × 13717421 = 1111111101
81 × 124828531 = 10111111011
81 × 135939631 = 11011110111

82 × 1355 = 111110
82 × 13550 = 1111100
82 × 123305 = 10111010

83 × 1217 = 101011
83 × 12170 = 1010110
83 × 121700 = 10101100

84 × 12025 = 1010100
84 × 120250 = 10101000
84 × 132275 = 11111100

85 × 1306 = 111010
85 × 11766 = 1000110
85 × 13060 = 1110100

86 × 128035 = 11011010
86 × 1174535 = 101010010
86 × 1280350 = 110110100

87 × 126553 = 11010111
87 × 1149553 = 100011111
87 × 1265530 = 110101110

88 × 125 = 11000
88 × 1250 = 110000
88 × 11375 = 1001000

89 × 123709 = 11010101
89 × 1123709 = 100010101
89 × 1237090 = 110101010

90 × 12345679 = 1111111110
90 × 112345679 = 10111111110
90 × 122345679 = 11011111110

91 × 11 = 1001
91 × 110 = 10010
91 × 111 = 10101

92 × 119675 = 11010100
92 × 1098925 = 101101100
92 × 1196750 = 110101000

93 × 107527 = 10000011
93 × 1075270 = 100000110
93 × 1193657 = 111010101

94 × 1065 = 100110
94 × 10650 = 1001100
94 × 106500 = 10011000

95 × 1158 = 110010
95 × 10538 = 1001110
95 × 11580 = 1100100

96 × 115625 = 11100000
96 × 1053125 = 101100000
96 × 1146875 = 110100000

97 × 114433 = 11100001
97 × 1032063 = 100110111
97 × 1135063 = 110101111

98 × 112245 = 11000010
98 × 1031745 = 101111010
98 × 1122450 = 110000100

99 × 1122334455667789 = 111111111111111111
99 × 11122334455667789 = 1101111111111111111
99 × 11222334455667789 = 1111011111111111111

100 × 1 = 100
100 × 10 = 1000
100 × 11 = 1100

 

Re: 0と1からなるnの倍数

 投稿者:山中和義  投稿日:2013年 1月19日(土)11時21分45秒
  > No.2962[元記事へ]

> 問題
> 全ての自然数n対して必ず0と1からなるnの倍数が存在する

すべての桁が1(111…1という数)をベースに考えれば一般解になります。

考察
nが2や5の倍数でない場合、すべての桁が1(111…1という数)のnの倍数がある。
このとき、1/nは循環小数になるので、1/n={循環節}/(10^k-1)と表される。
よって、(10^k-1)/9={循環節}/9*N
・nが3で割り切れない場合
 左辺は、すべての桁が1の数で、{循環節}/9倍したものである。
 例 n=7のとき、1/7=0.{142857}=142857/999999なので、999999/9=(142857/9)*7

・nが3で割り切れる場合
 n=3^r*M(Mは3で割り切れない自然数)として、
 上記より、すべての桁が1の数をMの倍数にすることができる。
 この桁数を3^r倍に増やせば、nで割り切れる。
 例 n=33=3*11のとき、1/11=0.{09}=9/99なので、循環節の長さは2
   これより、2*3=6個として、111111

n=2^p*5^qのとき、10^MAX(p,q)とすればよい。

以上をまとめると、
n=2^p*5^q*3^r*M(Mは2,5,3で割り切れない自然数)のとき、
 1/Mの循環節の長さをkとすると、
 (10^(k*3^r)-1)/9 *10^MAX(p,q) がnの倍数となる。
n=2^p*5^q*3^rのとき、
 (10^(3^r)-1)/9 *10^MAX(p,q) がnの倍数となる。
(終り)


OPTION ARITHMETIC RATIONAL !多桁の整数

FOR N=1 TO 100

   LET M=N
   LET P=0
   DO WHILE MOD(M,2)=0 !2^p
      LET M=M/2
      LET P=P+1
   LOOP
   LET Q=0
   DO WHILE MOD(M,5)=0 !5^q
      LET M=M/5
      LET Q=Q+1
   LOOP

   LET R=0
   DO WHILE MOD(M,3)=0 !3^r
      LET M=M/3
      LET R=R+1
   LOOP
   !!!PRINT P;Q;R;M !debug

   FOR K=1 TO M-1 !1/Mの循環節の長さを求める 10^k≡1 mod mを満たす最小のk
      IF modpow(10,K,M)=1 THEN EXIT FOR
   NEXT K
   LET W=(10^(lcm(K,3^R))-1)/9 *10^MAX(P,Q)
   PRINT N; "×"; W/N; "="; W; "(";lcm(K,3^R);"個の1)";   "  k=";K; "r=";R

   !※
   !LET W=(10^(K*3^R)-1)/9 *10^MAX(P,Q)
   !PRINT N; "×"; W/N; "="; W; "(";K*3^R;"個の1)";   "  k=";K; "r=";R

   !※同値
   !IF M>1 THEN !n=2^p*5^q*3^r*Mの場合
   !   FOR K=1 TO M-1 !1/Mの循環節の長さを求める 10^k≡1 mod mを満たす最小のk
   !      IF modpow(10,K,M)=1 THEN EXIT FOR
   !   NEXT K
   !   LET W=(10^(K*3^R)-1)/9 *10^MAX(P,Q)
   !   PRINT N; "×"; W/N; "="; W; "(";K*3^R;"個の1)";   "  k=";K; "r=";R
   !ELSE !n=2^p*5^q*3^rの場合
   !   LET W=(10^(3^R)-1)/9 *10^MAX(P,Q)
   !   PRINT N; "×"; W/N; "="; W; "(";3^R;"個の1)";   "  r=";R
   !END IF

NEXT N

END

EXTERNAL FUNCTION modpow(a,n,b) !a^n≡x mod b のxを返す ※nは非負整数
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=MOD(1,b)
DO WHILE n>0 !べき乗nを2進展開する
   IF MOD(n,2)=1 THEN LET S=MOD(S*a,b) !ビットが1なら計算する
   LET a=MOD(a*a,b)
   LET n=INT(n/2)
LOOP
LET modpow=S
END FUNCTION

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=a
END FUNCTION

EXTERNAL FUNCTION lcm(a,b) !最小公倍数
OPTION ARITHMETIC RATIONAL !多桁の整数
IF a>b THEN !少しでも桁あふれを防止するために大きい方を先に割る
   LET lcm=(a/gcd(a,b))*b
ELSE
   LET lcm=a*(b/gcd(a,b))
END IF
END FUNCTION


実行結果

1 × 1 = 1 ( 1 個の1)  k= 1 r= 0
2 × 5 = 10 ( 1 個の1)  k= 1 r= 0
3 × 37 = 111 ( 3 個の1)  k= 1 r= 1
4 × 25 = 100 ( 1 個の1)  k= 1 r= 0
5 × 2 = 10 ( 1 個の1)  k= 1 r= 0
6 × 185 = 1110 ( 3 個の1)  k= 1 r= 1
7 × 15873 = 111111 ( 6 個の1)  k= 6 r= 0
8 × 125 = 1000 ( 1 個の1)  k= 1 r= 0
9 × 12345679 = 111111111 ( 9 個の1)  k= 1 r= 2
10 × 1 = 10 ( 1 個の1)  k= 1 r= 0
11 × 1 = 11 ( 2 個の1)  k= 2 r= 0
12 × 925 = 11100 ( 3 個の1)  k= 1 r= 1
13 × 8547 = 111111 ( 6 個の1)  k= 6 r= 0
14 × 79365 = 1111110 ( 6 個の1)  k= 6 r= 0
15 × 74 = 1110 ( 3 個の1)  k= 1 r= 1
16 × 625 = 10000 ( 1 個の1)  k= 1 r= 0
17 × 65359477124183 = 1111111111111111 ( 16 個の1)  k= 16 r= 0
18 × 61728395 = 1111111110 ( 9 個の1)  k= 1 r= 2
19 × 5847953216374269 = 111111111111111111 ( 18 個の1)  k= 18 r= 0
20 × 5 = 100 ( 1 個の1)  k= 1 r= 0
21 × 5291 = 111111 ( 6 個の1)  k= 6 r= 1
22 × 5 = 110 ( 2 個の1)  k= 2 r= 0
23 × 48309178743961352657 = 1111111111111111111111 ( 22 個の1)  k= 22 r= 0
24 × 4625 = 111000 ( 3 個の1)  k= 1 r= 1
25 × 4 = 100 ( 1 個の1)  k= 1 r= 0
26 × 42735 = 1111110 ( 6 個の1)  k= 6 r= 0
27 × 4115226337448559670781893 = 111111111111111111111111111 ( 27 個の1)  k= 1 r= 3
28 × 396825 = 11111100 ( 6 個の1)  k= 6 r= 0
29 × 38314176245210727969348659 = 1111111111111111111111111111 ( 28 個の1)  k= 28 r= 0
30 × 37 = 1110 ( 3 個の1)  k= 1 r= 1
31 × 3584229390681 = 111111111111111 ( 15 個の1)  k= 15 r= 0
32 × 3125 = 100000 ( 1 個の1)  k= 1 r= 0
33 × 3367 = 111111 ( 6 個の1)  k= 2 r= 1
34 × 326797385620915 = 11111111111111110 ( 16 個の1)  k= 16 r= 0
35 × 31746 = 1111110 ( 6 個の1)  k= 6 r= 0
36 × 308641975 = 11111111100 ( 9 個の1)  k= 1 r= 2
37 × 3 = 111 ( 3 個の1)  k= 3 r= 0
38 × 29239766081871345 = 1111111111111111110 ( 18 個の1)  k= 18 r= 0
39 × 2849 = 111111 ( 6 個の1)  k= 6 r= 1
40 × 25 = 1000 ( 1 個の1)  k= 1 r= 0
41 × 271 = 11111 ( 5 個の1)  k= 5 r= 0
42 × 26455 = 1111110 ( 6 個の1)  k= 6 r= 1
43 × 2583979328165374677 = 111111111111111111111 ( 21 個の1)  k= 21 r= 0
44 × 25 = 1100 ( 2 個の1)  k= 2 r= 0
45 × 24691358 = 1111111110 ( 9 個の1)  k= 1 r= 2
46 × 241545893719806763285 = 11111111111111111111110 ( 22 個の1)  k= 22 r= 0
47 × 23640661938534278959810874704491725768321513 = 1111111111111111111111111111111111111111111111 ( 46 個の1)  k= 46 r= 0
48 × 23125 = 1110000 ( 3 個の1)  k= 1 r= 1
49 × 2267573696145124716553287981859410430839 = 111111111111111111111111111111111111111111 ( 42 個の1)  k= 42 r= 0
50 × 2 = 100 ( 1 個の1)  k= 1 r= 0
51 × 2178649237472766884531590413943355119825708061 = 111111111111111111111111111111111111111111111111 ( 48 個の1)  k= 16 r= 1
52 × 213675 = 11111100 ( 6 個の1)  k= 6 r= 0
53 × 20964360587 = 1111111111111 ( 13 個の1)  k= 13 r= 0
54 × 20576131687242798353909465 = 1111111111111111111111111110 ( 27 個の1)  k= 1 r= 3
55 × 2 = 110 ( 2 個の1)  k= 2 r= 0
56 × 1984125 = 111111000 ( 6 個の1)  k= 6 r= 0
57 × 1949317738791423 = 111111111111111111 ( 18 個の1)  k= 18 r= 1
58 × 191570881226053639846743295 = 11111111111111111111111111110 ( 28 個の1)  k= 28 r= 0
59 × 18832391713747645951035781544256120527306967984934086629 = 1111111111111111111111111111111111111111111111111111111111 ( 58 個の1)  k= 58 r= 0
60 × 185 = 11100 ( 3 個の1)  k= 1 r= 1
61 × 1821493624772313296903460837887067395264116575591985428051 = 111111111111111111111111111111111111111111111111111111111111 ( 60 個の1)  k= 60 r= 0
62 × 17921146953405 = 1111111111111110 ( 15 個の1)  k= 15 r= 0
63 × 1763668430335097 = 111111111111111111 ( 18 個の1)  k= 6 r= 2
64 × 15625 = 1000000 ( 1 個の1)  k= 1 r= 0
65 × 17094 = 1111110 ( 6 個の1)  k= 6 r= 0
66 × 16835 = 1111110 ( 6 個の1)  k= 2 r= 1
67 × 1658374792703150912106135986733 = 111111111111111111111111111111111 ( 33 個の1)  k= 33 r= 0
68 × 1633986928104575 = 111111111111111100 ( 16 個の1)  k= 16 r= 0
69 × 1610305958132045088566827697262479871175523349436392914653784219 = 111111111111111111111111111111111111111111111111111111111111111111 ( 66 個の1)  k= 22 r= 1
70 × 15873 = 1111110 ( 6 個の1)  k= 6 r= 0
71 × 156494522691705790297339593114241 = 11111111111111111111111111111111111 ( 35 個の1)  k= 35 r= 0
72 × 1543209875 = 111111111000 ( 9 個の1)  k= 1 r= 2
73 × 152207 = 11111111 ( 8 個の1)  k= 8 r= 0
74 × 15 = 1110 ( 3 個の1)  k= 3 r= 0
75 × 148 = 11100 ( 3 個の1)  k= 1 r= 1
76 × 146198830409356725 = 11111111111111111100 ( 18 個の1)  k= 18 r= 0
77 × 1443 = 111111 ( 6 個の1)  k= 6 r= 0
78 × 14245 = 1111110 ( 6 個の1)  k= 6 r= 1
79 × 14064697609 = 1111111111111 ( 13 個の1)  k= 13 r= 0
80 × 125 = 10000 ( 1 個の1)  k= 1 r= 0
81 × 1371742112482853223593964334705075445816186556927297668038408779149519890260631 = 111111111111111111111111111111111111111111111111111111111111111111111111111111111 ( 81 個の1)  k= 1 r= 4
82 × 1355 = 111110 ( 5 個の1)  k= 5 r= 0
83 × 133868808567603748326639892904953145917 = 11111111111111111111111111111111111111111 ( 41 個の1)  k= 41 r= 0
84 × 132275 = 11111100 ( 6 個の1)  k= 6 r= 1
85 × 130718954248366 = 11111111111111110 ( 16 個の1)  k= 16 r= 0
86 × 12919896640826873385 = 1111111111111111111110 ( 21 個の1)  k= 21 r= 0
87 × 1277139208173690932311621966794380587484035759897828863346104725415070242656449553 = 111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ( 84 個の1)  k= 28 r= 1
88 × 125 = 11000 ( 2 個の1)  k= 2 r= 0
89 × 124843945068664169787765293383270911360799 = 11111111111111111111111111111111111111111111 ( 44 個の1)  k= 44 r= 0
90 × 12345679 = 1111111110 ( 9 個の1)  k= 1 r= 2
91 × 1221 = 111111 ( 6 個の1)  k= 6 r= 0
92 × 1207729468599033816425 = 111111111111111111111100 ( 22 個の1)  k= 22 r= 0
93 × 1194743130227 = 111111111111111 ( 15 個の1)  k= 15 r= 1
94 × 118203309692671394799054373522458628841607565 = 11111111111111111111111111111111111111111111110 ( 46 個の1)  k= 46 r= 0
95 × 11695906432748538 = 1111111111111111110 ( 18 個の1)  k= 18 r= 0
96 × 115625 = 11100000 ( 3 個の1)  k= 1 r= 1
97 × 1145475372279495990836197021764032073310423825887743413516609392898052691867124856815578465063 = 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ( 96 個の1)  k= 96 r= 0
98 × 11337868480725623582766439909297052154195 = 1111111111111111111111111111111111111111110 ( 42 個の1)  k= 42 r= 0
99 × 1122334455667789 = 111111111111111111 ( 18 個の1)  k= 2 r= 2
100 × 1 = 100 ( 1 個の1)  k= 1 r= 0

 

Re: 0と1からなるnの倍数

 投稿者:山中和義  投稿日:2013年 1月21日(月)12時41分40秒
  > No.2963[元記事へ]

> 問題
> 全ての自然数n対して必ず0と1からなるnの倍数が存在する

関連問題
nは2,5を約数にもたない自然数とする。
ある自然数mをかけると、n*m=11…1(1が並ぶ数)とすることができる。

類題
nは2,5を約数にもたない自然数とする。
ある自然数mをかけると、n*m=99…9(9が並ぶ数)とすることができる。

答え
a>bとして、10^a-10^bを考える。
これは、数字9が(a-b)個並び、その後数字0がb個並んだ数9…90…0となり、9の倍数である。
鳩ノ巣原理より、1,10,10^2,…,10^9nのうち、9nで割った余りが等しいものがある。
そこで、a,bを10^aと10^bが9nで割って同じ余りとなるものとすると、10^a-10^bは9nの倍数であり、
1が(a-b)個並ぶ数は、(10^a-10^b)/(2^b*5^b*3^2)と表されて、nの倍数となる。
よって、1をある個数並べてnの倍数を作ることができる。
(終り)


OPTION ARITHMETIC RATIONAL !多桁整数

FOR n=1 TO 100

   LET t=9*n !10^0,10^1,10^2,…,10^9nとして、
   FOR b=0 TO t-1 !9nで割った余りが等しいものを探す
      LET W=modpow(10,b,t)
      FOR a=b+1 TO t
         IF modpow(10,a,t)=W THEN EXIT FOR
      NEXT a
      IF a<=t THEN EXIT FOR
   NEXT b
   IF b<=t-1 THEN !条件を満たすa,bで

   !!PRINT 10^a-10^b !debug
      LET nm=(10^a-10^b)/3^2 !1が並ぶ数 + 0が並ぶ数
      PRINT n;"×"; nm/n; "="; nm

   END IF

NEXT n

END


EXTERNAL FUNCTION modpow(a,n,b) !a^n≡x mod b のxを返す ※nは非負整数
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=MOD(1,b)
DO WHILE n>0 !べき乗nを2進展開する
   IF MOD(n,2)=1 THEN LET S=MOD(S*a,b) !ビットが1なら計算する
   LET a=MOD(a*a,b)
   LET n=INT(n/2)
LOOP
LET modpow=S
END FUNCTION

 

1と2からなる2^nの倍数

 投稿者:GAI  投稿日:2013年 1月23日(水)08時32分48秒
  n=1→2^1=2→2*1=2
n=2→2^2=4→4*3=12
n=3→2^3=8→8*14=112
n=4→2^4=16→16*132=2112
n=5→2^5=32→32*691=22112
n=6→2^6=64→64*1908=122112
・・・

これらより一般に1と2から作られる2^nの倍数が必ず存在するが成立しそうです。
これらが具体的に存在しているのかを各nに対して倍数を見つけてください。
 

Re: 1と2からなる2^nの倍数

 投稿者:山中和義  投稿日:2013年 1月25日(金)09時49分58秒
  > No.2965[元記事へ]

GAIさんへのお返事です。

> n=1→2^1=2→2*1=2
> n=2→2^2=4→4*3=12
> n=3→2^3=8→8*14=112
> n=4→2^4=16→16*132=2112
> n=5→2^5=32→32*691=22112
> n=6→2^6=64→64*1908=122112
> ・・・
>
> これらより一般に1と2から作られる2^nの倍数が必ず存在するが成立しそうです。

考察
n=1のとき、2^1*1=2
n=kのとき、2^kの倍数で1,2からなるk桁の数が存在すると仮定する。
n=k+1のとき、
 最上位のさらに左の桁に1を付加した数 1{1,2からなるk桁の数}
 最上位のさらに左の桁に2を付加した数 2{1,2からなるk桁の数}
とする(k+1)桁の数を考える。
1{1,2からなるk桁の数}は、10^k=2^k*5^k増えたことなので、2^kの倍数である。
2{1,2からなるk桁の数}は、2*10^k=2^(k+1)*5^k増えたことなので、2^kの倍数である。
差 2{1,2からなるk桁の数} - 1{1,2からなるk桁の数} = 2*10^k-10^k = 2^k*5^k なので、
どちらかは2^(k+1)で割り切れる。
よって、どちらかは2^(k+1)の倍数で(k+1)桁の数となる。
(終り)
例 n=2
 n=1のとき、2より、
 12=3*2^2で2^2の倍数
 22=5*2^2+2で2^2の倍数でない
例 n=3
 n=2のとき、12より、
 112=14*2^3で2^3の倍数
 212=26*2^3+4で2^3の倍数でない
例 n=4
 n=3のとき、112より、
 1112=69*2^4+8で2^4の倍数でない
 2112=132*2^4で2^4の倍数

一般解が機械的に構成できます。
同様な議論で、奇数 1,3,5,7,9 と 0を除く偶数 2,4,6,8 で2^nの倍数が構成できます。


OPTION ARITHMETIC RATIONAL !多桁の整数

LET A=1 !奇数 1,3,5,7,9
LET B=2 !0を除く偶数 2,4,6,8

PRINT "2^1 ×";B/2;"=";B !n=1のとき
LET K=B !1,2からなるk桁の数

FOR N=2 TO 20 !nが2以上のとき

   LET M=K+A*10^(N-1) !1{1,2からなるk桁の数}
   IF MOD(M,2^N)=0 THEN
      LET K=M
   ELSE
      LET M=K+B*10^(N-1) !2{1,2からなるk桁の数}
      IF MOD(M,2^N)=0 THEN
         LET K=M
      ELSE
         PRINT "論理エラー"
         STOP
      END IF
   END IF
   PRINT "2^";STR$(N); " ×";M/2^N; "=";M

NEXT N

END

 

関数でお絵かき

 投稿者:山中和義  投稿日:2013年 1月25日(金)11時19分45秒
  > No.2018[元記事へ]

問題
同じ長さのマッチ棒12本を一辺に3本、4本、5本使って三角形を作りました。
これら12本のマッチ棒のうち、4本だけを動かして、
面積がもとの三角形の1/2である多角形になるようにしてください。

答え

SET WINDOW -3,3,-1,5 !表示領域
DRAW grid !座標を描く

CALL fvSEGMENT(-2,0,1,0) !AB
PLOT TEXT ,AT -2,0: "A"
CALL fvSEGMENT(1,0,1,4) !BC
PLOT TEXT ,AT 1,0: "B"
CALL fvSEGMENT(1,4,-2,0) !CA
PLOT TEXT ,AT 1,4: "C"

!折り返し
SET LINE COLOR 4
CALL fvSEGMENT(0,1,1,3) !P

CALL fvSYMMETRY2(1,1,2,1, xx,yy) !B'
PRINT xx;yy

SET LINE COLOR 2
CALL fvSEGMENT(0,0,0,1)
CALL fvSEGMENT(0,1,xx,yy)
CALL fvSEGMENT(xx,yy,1,3)

END

!●作図ルーチン

!直線
EXTERNAL SUB fvSEGMENT(x1,y1,x2,y2) !線分
PLOT LINES: x1,y1; x2,y2
END SUB

!●計算ルーチン

!点対称

!点(x,y)の原点に対称な点は、(-x,-y)より、点(a,b)に対しては、(-(x-a)+a,-(y-b)+b)=(2a-x,2b-y)
EXTERNAL SUB fvSYMMETRY(x,y,a,b, xx,yy) !点(a,b)に対称な点(点(a,b)を基準に180度回転した点)
LET xx=2*a-x
LET yy=2*b-y
END SUB

!線対称

EXTERNAL SUB fvSYMMETRY22(x,y,a, xx,yy) !直線Y=a*Xに対称な点
LET m1=1-a*a
LET m2=2*a
LET m3=1+a*a
LET xx=(m1*x+m2*y)/m3
LET yy=(m2*x-m1*y)/m3
END SUB

EXTERNAL SUB fvSYMMETRY2(x,y,a,b, xx,yy) !直線Y=a*X+bに対称な点
LET m1=1-a*a
LET m2=2*a
LET m3=1+a*a
LET xx=(m1*x+m2*y-2*b*a)/m3
LET yy=(m2*x-m1*y+2*b)/m3
END SUB

!点(x,y)のy軸に対称な点は、(-x,y)より、直線X=aについては、(-(x-a)+a,y)=(2a-x,y)
EXTERNAL SUB fvSYMMETRYh(x,y,a, xx,yy) !直線X=aに対称な点
LET xx=2*a-x
LET yy=y
END SUB

!点(x,y)のx軸に対称な点は、(x,-y)より、直線Y=bについては、(x,-(y-b)+b)=(x,2b-y)
EXTERNAL SUB fvSYMMETRYv(x,y,b, xx,yy) !直線Y=bに対称な点
LET xx=x
LET yy=2*b-y
END SUB

!回転

EXTERNAL SUB fvROTATE90(x,y,a,b, xx,yy) !点(a,b)を基準に90度回転した点
LET xx=-(y-b)+a
LET yy= (x-a)+b
END SUB

EXTERNAL SUB fvROTATEm90(x,y,a,b, xx,yy) !点(a,b)を基準に-90度回転した点
LET xx= (y-b)+a
LET yy=-(x-a)+b
END SUB



その他の解の例
 

入門言語について

 投稿者:kikiriri  投稿日:2013年 1月26日(土)13時25分42秒
  BASICが、最適である理由を、もう少し砕いてお教え願えませんか。よく使うコマンド数が少ないからですか。
あとプログラムを作る機会よりは、エクセルのVBAの方が、
機会が多いというか、とある通信教育で、一度、カリキュラ
ムを、こなしたぐらいです。今、思えば、BASICがいいなと思います。背伸びをして、C言語をやりたかったので、
basicの勉強ができませんでした。一度は家計簿ソフトを作ろうかとも思いましたが、今パソコン教室に通っていて、年賀状作成ソフトを作るのと同じぐらい、家計簿マムがプレインストールされたパソコンでは、家計簿ソフトを作るのは
無駄ではないが、もっと自分を啓蒙させなくては駄目だと思いました。

善きご助言をお願いします。
 

Re: 入門言語について

 投稿者:白石和夫  投稿日:2013年 1月27日(日)10時25分44秒
  > No.2968[元記事へ]

「〇〇ソフトを作る」という目的にFull BASICは適さないと思います。JavaのようにGUIが作れてイベント駆動ができるものがアプリケーション作成には適しているのではないでしょうか。
 Full BASICが適するのは問題解決のための計算です。コンピュータの能力を限界まで引き出さなければ解決できないような本格的な応用には適しませんが,計算は瞬時に終わってしまうのにプログラムを書くのに手間がかかってしまうような場合にFull BASICが勧められます。計算プログラムを作るのにプロトタイプをFull BASICで書いて,本番はPascalとかCに書き直すというのも有効な手段です。また,BASICAccを利用すれば,実用上,十分な速さが得られることが多いと思います。そんな場合は,他の言語はいりません。
 Full BASICでは書けない(あるいは書きにくい)アルゴリズムが存在するのも事実です。そういうアルゴリズムの記述の必要性を知れば他の言語を始めるきっかけになると思います。


 

数のピラミッド

 投稿者:山中和義  投稿日:2013年 1月27日(日)10時45分50秒
  数のピラミッド

1 * (1) = 1^2
121 * (1+2+1) = 22^2
12321 * (1+2+3+2+1) = 333^2
1234321 * (1+2+3+4+3+2+1) = 4444^2
123454321 * (1+2+3+4+5+4+3+2+1) = 55555^2
12345654321 * (1+2+3+4+5+6+5+4+3+2+1) = 666666^2
1234567654321 * (1+2+3+4+5+6+7+6+5+4+3+2+1) = 7777777^2
123456787654321 * (1+2+3+4+5+6+7+8+7+6+5+4+3+2+1) = 88888888^2
12345678987654321 * (1+2+3+4+5+6+7+8+9+8+7+6+5+4+3+2+1) = 999999999^2

考察
123…(n-1)n(n-1)…321について
 (1がn個並ぶ数)の2乗である。
例
 11*11=121
 111*111=12321

1+2+3+ … +(n-1)+n+(n-1)+ … +3+2+1について
  1+2+3+   … +n
 +  1+2+3+ … +(n-1)
 ---------------------------
  1+3+5+   … +(2n-1)=n^2 ∵奇数の和より
例
 1+2+1=4=2^2
 1+2+3+2+1=9=3^2
(終り)

OPTION ARITHMETIC RATIONAL !多桁の整数

FOR N=1 TO 9

   PRINT ( N*(10^N-1)/9 )^2 / N^2; "* (";

   FOR i=1 TO N-1 !分母 昇順
      PRINT STR$(i); "+";
   NEXT i
   PRINT STR$(N);
   FOR i=N-1 TO 1 STEP -1 !降順
      PRINT "+"; STR$(i);
   NEXT i
   PRINT ")";

   PRINT " = "; STR$(N*(10^N-1)/9); "^2"

NEXT N

END

 

Re: 入門言語について

 投稿者:白石和夫  投稿日:2013年 1月27日(日)10時59分35秒
  > No.2969[元記事へ]

補足です。

よく使うコマンド数が少ないから簡単だというのは幻想にすぎません。
たとえば,旧規格の基本BASICは,IF ・・・ THEN 行番号 とGOTO 行番号 を用いてプログラムの流れを書きますが,それでアルゴリズムの記述が楽だと思えるのは,手始めのほんの短期間だけです。
 

Re: 入門言語について

 投稿者:kikiriri  投稿日:2013年 1月27日(日)14時03分27秒
  白石和夫さんへのお返事です。


白石先生へ

  早速のご返信ありがとうございました。「レスを二つも!!」

 参考にさせていただきたいです。
> 補足です。
>
> よく使うコマンド数が少ないから簡単だというのは幻想にすぎません。
> たとえば,旧規格の基本BASICは,IF ・・・ THEN 行番号 とGOTO 行番号 を用いてプログラムの流れを書きますが,それでアルゴリズムの記述が楽だと思えるのは,手始めのほんの短期間だけです。
>
 

VBAについて

 投稿者:kikiriri  投稿日:2013年 1月27日(日)17時14分54秒
  VBAの可能性というか、実務で使用すると思うんですが、入門には不適ですか。
と、いうのも、プログラミングの面白さを知ったのは、日経PCの、エクセルVBA大会
と、とある通信教育で助言を受けながらの、エクセルVBAだったもので、また、今、パソ
コン教室に通っていて、今は、ワードですが、エクセルの勉強が始まったら、VBAか、
マクロ、の勉強で、VBAの存在が効いてくると、思うので、まだ、MOSの勉強で精いっぱ
いですが、そのうち、VBAの勉強か、BASICの勉強をしたいと思うのですが、本がありません。
おすすめのものがあれば、ぜひ、ご紹介いただけないでしょうか??
 

Re: VBAについて

 投稿者:白石和夫  投稿日:2013年 1月27日(日)17時26分9秒
  > No.2973[元記事へ]

VBAは実務には使えると思います。
ただし,私には難しいです。

十進BASICに慣れた人がVBAを始めるときに,
Microsoft BASICからのFull BASIC入門
http://www.geocities.jp/thinking_math_education/MS2Full.htm
が(逆方向の入門にも)役に立つと思います。
 

Re: VBAについて

 投稿者:kikiriri  投稿日:2013年 1月27日(日)18時10分24秒
  > No.2974[元記事へ]

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

白石先生へ

  早速のご返信ありがとうございました。
 >ただし,私には難しいです。
 僕も実は、丁度いいくらいに難しそうだったので。
 新聞の日曜版の問題を、(クロスワードや間違い探し)
 と、(同じではないですが)解くような面白さがありました。
 {VBAの問題を解くのは}なので、思い切って、通信教育を始めました。
 先生がわかっている人で、側{ネットの向こう側}に居てもらえることが、
 こんなに良い事とは思えない位に良い事でして、では、と、パソコン教室に通い
 先生が本当に存在する場所で、勉強をしています。マンツーマンでもなく、
 授業形式でもないのですが、運転免許と同じくらい、ウキウキ、ワクワクしました。
 でも、本当は、すごくビビりまくりで、中々ここに居ていいんだと思えなくて。
 授業が進んでいるのですが、オフィス系ならアクセスを習いたいんですけど。
 パワーポイントもアクセスも、2010年版が買えそうにないので、
 ワードとエクセル、が終わったらお話ししないとと、思っています。
 活き込んで、VBAや、アクセスの話をしたら、VBAは駄目だけど、
 パワーポイントと、アクセスは、できますよと言われています。

                                    以上
     長文失礼しました。

> VBAは実務には使えると思います。
> ただし,私には難しいです。
>
> 十進BASICに慣れた人がVBAを始めるときに,
> Microsoft BASICからのFull BASIC入門http://www.geocities.jp/thinking_math_education/MS2Full.htm
> が(逆方向の入門にも)役に立つと思います。
>
 

秤の問題

 投稿者:山中和義  投稿日:2013年 1月30日(水)12時57分9秒
  問題
金貨の入った袋が5袋ある。
4袋には10gの金貨が入っているが、1袋だけ9gの金貨が入っている。
グラム単位で量れる秤を1回だけ使って、どの袋が9gの金貨が入っているのか当てよ。

答え
それぞれの袋から、0,1,2,3,4枚とる。
全部10gなら、10x(0+1+2+3+4)=100gとなるが、9gのものがあるのでその分軽くなる。
100gよりAg軽かったら、A枚とった袋が9gである。
(終り)


LET N=5 !袋の個数
DATA 10,10,10,9,10 !A,B,C,D,Eの順に

DIM S(N)
MAT READ S
MAT PRINT S; !debug

LET T=0
FOR i=1 TO N
   LET T=T+S(i)*(i-1) !0,1,2,3,4
NEXT i
PRINT 10*(N-1)*N/2-T+1;"番目"



!その2 m進法

LET T=0
FOR i=1 TO N
   LET T=T+(S(i)-9)*2^(i-1) !1,2,4,8,16,…
NEXT i
PRINT T !debug

FOR i=1 TO N !A,B,C,D,Eの順に
   PRINT MOD(T,2); !0:9g、1:10gを表す
   LET T=INT(T/2)
NEXT i
PRINT



!その3 デジタル表示

LET T=0
FOR i=1 TO N
   LET T=T+S(i)*100^(N-i) !100^0,100^1,100^2,100^3,…
NEXT i
PRINT T;"番目"

END

 

天秤ばかりの問題

 投稿者:山中和義  投稿日:2013年 1月30日(水)17時18分48秒
  > No.2976[元記事へ]

問題
たくさんの塩があります。
ここに、天秤ばかりと、2gと7gの分銅がひとつずつあります。
天秤ばかりと分銅を使って、塩50gを量りなさい。

類題
140gの塩があります。
ここに、天秤ばかりと、2gと7gの分銅がひとつずつあります。
天秤ばかりと分銅を使って、塩を50gと90gに分割しなさい。

答え
不定方程式2x+7y=50の解のひとつは、(x,y)=(4,6)より、
2gの分銅で4回、7gの分銅で6回、計10回量ればよい。

量った塩を分銅として使う場合、
  左     右
  2+7+(0)   9  1回目
   7+(9)   16  2回目
+   (9+16) 25  3回目
-------------------
        50g
とすれば、3回となる。

回数は、max(x,y)<2^kを満たす最小のkとなる。
手順は、
 x=4=100[2]、y=6=110[2]なので、
  1 1
  0 1
  0 0
 と上位から順に並べる。(上記の表を参照のこと)
 これを元に、1のときに分銅を使い、量った塩の和と一緒に新しい塩を量っていく。
とすればよい。
(終り)


LET A=2 !ax+by=c
LET B=7
LET C=50

FOR X=0 TO INT(C/A) !非負の整数解
   LET Y=(C-A*X)/B
   IF Y=INT(Y) THEN
      PRINT "(x,y)=("; X; Y; ")"


      LET XX=X !手順を表示する
      LET YY=Y

      LET K=INT(LOG10(MAX(XX,YY))/LOG10(2))+1
      PRINT K;"回"

      LET S=0 !量った塩
      LET T=0
      LET R=2^(K-1) !2進法k桁へ ※上位から
      FOR J=K TO 1 STEP -1
         LET P=INT(XX/R) !k桁目
         LET Q=INT(YY/R)

         PRINT P;Q;"+"; S;T; "="; S+P;T+Q !表を表示する
         LET S=2*S+P
         LET T=2*T+Q

         LET XX=MOD(XX,R) !次へ
         LET YY=MOD(YY,R)
         LET R=R/2
      NEXT J
      PRINT
   END IF
NEXT X

END

 

フラクタルポップコーン

 投稿者:望月健一  投稿日:2013年 2月 2日(土)21時26分10秒
  ! フラクタルポップコーン
!  「コンピューターレクリエーション Ⅳ 遊びの展開」
!  日経サイエンス より

SET WINDOW -8,8,-8,8
SET POINT STYLE 1
LET h=0.05
RANDOMIZE
LET c = INT(MOD(RND*9999,225))+1

FOR j=1 TO 50           ! x方向
   FOR k=1 TO 50        ! y方向
      LET x=-6+0.24*j
      LET y=-6+0.24*k

      FOR n=1 TO 50
         LET xx=x-h*sin(y+TAN(3*y))
         LET yy=y-h*sin(x+TAN(3*x))

         PLOT POINTS :xx,yy

         IF MOD(I,10000)=0 THEN
            LET c=c+1
            LET i=0

            IF c>225 THEN
               LET c=c-225
            END if

            SET POINT COLOR c
         END IF

         LET i=i+1
         LET x=xx
         LET y=yy

      NEXT n
   NEXT k
NEXT j

END
 

Re: 秤の問題

 投稿者:山中和義  投稿日:2013年 2月 3日(日)14時07分44秒
  > No.2976[元記事へ]

問題
パチンコ玉が3個あります。外見では見分けはつきません。
そのうち2個は同じ重さで、1個だけ重さが少し違うことがわかっています。
ただし、重いか軽いかは不明です。
バネ秤を3回使って、この1個の玉を選び出してください。
また、2個の玉は何グラム、1個の玉は何グラムまで出してほしいのです。

答え
パチンコ玉をA,B,Cとして、その重さをa,b,cとする。
○は同じ重さ、●は少し違う重さを表すとして、
 a b c
 ○○●
 ○●○
 ●○○
以上の3通りである。

手法A:それまでの測定結果によって、次の回のはかり方を決める方法


LET a=1
LET b=2
LET c=2

LET w1=a
LET w2=b
PRINT "w1=";w1; "w2=";w2 !debug

IF w1=w2 THEN !cが偽
   LET w3=c
   PRINT "w3=";w3 !debug

   LET x=w1
   LET y=w3
   PRINT "x=";x; "y=";y; "偽C"
ELSE
   LET w3=c
   PRINT "w3=";w3 !debug

   IF w3=w1 THEN !bが偽
      LET x=w3
      LET y=w2
      PRINT "x=";x; "y=";y; "偽B"
   ELSEIF w3=w2 THEN !aが偽
      LET x=w2
      LET y=w1
      PRINT "x=";x; "y=";y; "偽A"
   ELSE
      PRINT "論理エラー"
   END IF
END IF

END



手法B:最初にすべての回のはかり方を決め、全結果から答えを出す方法


LET a=1
LET b=2
LET c=2

LET w1=a
LET w2=b
LET w3=c
PRINT "w1=";w1; "w2=";w2; "w3=";w3 !debug

IF w1=w2 THEN !cが偽
   LET x=w1
   LET y=w3
   PRINT "x=";x; "y=";y; "偽C"
ELSEIF w3=w1 THEN !aが偽
   LET x=w3
   LET y=w2
   PRINT "x=";x; "y=";y; "偽B"
ELSEIF w2=w3 THEN !bが偽
   LET x=w2
   LET y=w1
   PRINT "x=";x; "y=";y; "偽A"
ELSE
   PRINT "論理エラー"
END IF

END

 

Re: 秤の問題

 投稿者:山中和義  投稿日:2013年 2月 4日(月)10時21分58秒
  > No.2979[元記事へ]

> 問題
> パチンコ玉が3個あります。外見では見分けはつきません。
> そのうち2個は同じ重さで、1個だけ重さが少し違うことがわかっています。
> ただし、重いか軽いかは不明です。
> バネ秤を3回使って、この1個の玉を選び出してください。
> また、2個の玉は何グラム、1個の玉は何グラムまで出してほしいのです。

手法A:それまでの測定結果によって、次の回のはかり方を決める方法

●パチンコ玉が4個の場合

LET a=1
LET b=2
LET c=2
LET d=2

LET w1=a
LET w2=b+c
PRINT "w1=";w1; "w2=";w2 !debug

IF 2*w1=w2 THEN !dが偽 ※a=b=cより
   LET w3=d
   PRINT "w3=";w3 !debug

   LET x=w1 !a
   LET y=w3 !d
   PRINT "x=";x; "y=";y; "偽D"
ELSE
   LET w3=b
   PRINT "w3=";w3 !debug

   IF w3=w1 THEN !cが偽 ※a=bより
      LET x=w1 !a
      LET y=w2-w3 !(b+c)-b
      PRINT "x=";x; "y=";y; "偽C"
   ELSEIF 2*w3=w2 THEN !aが偽 ※b=cより、w3=w2-w3 ∴2*w3=w2
      LET x=w3 !b
      LET y=w1 !a
      PRINT "x=";x; "y=";y; "偽A"
   ELSEIF w1=w2-w3 THEN !bが偽 ※a=cより、w1=w2-w3
      LET x=w1 !a
      LET y=w3 !b
      PRINT "x=";x; "y=";y; "偽B"
   ELSE
      PRINT "論理エラー"
   END IF
END IF

END


●パチンコ玉が5個の場合

LET a=2
LET b=2
LET c=1
LET d=2
LET e=2

LET w1=a+b
LET w2=c+d
PRINT "w1=";w1; "w2=";w2 !debug

IF w1=w2 THEN !eが偽 ※a=b=c=dより
   LET w3=e
   PRINT "w3=";w3 !debug

   LET x=w1/2 !x=w2/2
   LET y=w3
   PRINT "x=";x; "y=";y; "偽E"
ELSE
   LET w3=a+c+e
   PRINT "w3=";w3 !debug

   IF 2*w3=3*w1 THEN !e=a=c=bより、w3=a+c+e=3e、w1=a+b=2e
      LET x=w1/2 !x=w3/3
      LET y=w2-x
      PRINT "x=";x; "y=";y; "偽D"
   ELSEIF 2*w3=3*w2 THEN !e=a=c=dより、w3=a+c+e=3e、w2=c+d=2e
      LET x=w2/2 !x=w3/3
      LET y=w1-x
      PRINT "x=";x; "y=";y; "偽B"
   ELSEIF 2*(w3-w2)=w1 THEN !e=b=d=aより、w3-w2=(a+c+e)-(c+d)=a+e-d=e、w1=a+b=2e
      LET x=w1/2 !x=w3-w2
      LET y=w2-x !y=w3-w1
      PRINT "x=";x; "y=";y; "偽C"
   ELSEIF 2*(w3-w1)=w2 THEN !e=b=d=cより、w3-w1=(a+c+e)-(a+b)=c+e-b=e、w2=c+d=2e
      LET x=w2/2 !x=w3-w1
      LET y=w1-x !y=w3-w2
      PRINT "x=";x; "y=";y; "偽A"
   ELSE
      PRINT "論理エラー"
   END IF
END IF

END


●パチンコ玉が6個の場合

LET a=2
LET b=2
LET c=2
LET d=2
LET e=3
LET f=2

LET w1=a+b+c+d
LET w2=a+b    +e
PRINT "w1=";w1; "w2=";w2 !debug

IF 3*w1=4*w2 THEN !eが偽 ※a=b=c=d=eより
   LET w3=f
   PRINT "w3=";w3 !debug

   LET x=w1/4 !x=w2/3
   LET y=w3
   PRINT "x=";x; "y=";y; "偽F"
ELSE
   LET w3=a+c
   PRINT "w3=";w3 !debug

   LET p=w1-w2 !w1-w2=(a+b+c+d)-(a+b+e)=c+d-e
   LET q=w2-w3 !w2-w3=(a+b+e)-(a+c)=b+e-c
   LET r=w1-w3 !w1-w3=(a+b+c+d)-(a+c)=b+d
   PRINT "p=";p; "q=";q; "r=";r !debug

   IF p=q THEN !f=b=c=d=eより、p=c+d-e=f+f-f=f、q=b+e-c=f+f-f=f
      LET x=p
      LET y=w3-x
      PRINT "x=";x; "y=";y; "偽A"
   ELSEIF 2*p=w3 THEN !f=a=c=d=eより、p=c+d-e=f+f-f=f、w3=a+c=f+f=2f
      LET x=p
      LET y=r-x
      PRINT "x=";x; "y=";y; "偽B"
   ELSEIF 3*r=2*w2 THEN !f=a=b=d=eより、r=b+d=f+f=2f、w2=a+b+e=f+f+f=3f
      LET x=r/2
      LET y=w3-x
      PRINT "x=";x; "y=";y; "偽C"
   ELSEIF 2*w2=3*w3 THEN !f=a=b=c=eより、w2=a+b+e=f+f+f=3f、w3=a+c=f+f=2f
      LET x=w3/2
      LET y=r-x
      PRINT "x=";x; "y=";y; "偽D"
   ELSEIF 2*w1=4*w3 THEN !f=a=b=c=dより、w1=a+b+c+d=f+f+f+f=4f、w3=a+c=f+f=2f
      LET x=w1/4
      LET y=w2-2*x
      PRINT "x=";x; "y=";y; "偽E"
   ELSE
      PRINT "論理エラー"
   END IF
END IF

END

 

Re: 秤の問題

 投稿者:山中和義  投稿日:2013年 2月 5日(火)11時15分29秒
  > No.2980[元記事へ]

> 問題
> パチンコ玉が6個あります。外見では見分けはつきません。
> そのうち5個は同じ重さで、1個だけ重さが少し違うことがわかっています。
> ただし、重いか軽いかは不明です。
> バネ秤を3回使って、この1個の玉を選び出してください。
> また、5個の玉は何グラム、1個の玉は何グラムまで出してほしいのです。>

> 手法A:それまでの測定結果によって、次の回のはかり方を決める方法

近似解 3組の計測

2個ずつ取り出して3組をつくり、それぞれを量る。
(a,b)、(c,d)、(e,f)として、W1=a+b, W2=c+d, W3=e+f
同じ値のものが存在するので、他と違う1組の中の1個が、重さが少し違うパチンコ玉である。
よって、その組の1つを取り出して量る。たとえば、(e,f)とすると、W4=e
2*W4=W1のとき、x=W4(=W1/2=W2/2), y=W3-W4
2*W4≠W1のとき、x=W3-W4(=W1/2=W2/2), y=W4
したがって、4回となる。


この手法を使うと、7個の場合は、
2個ずつ取り出して3組をつくり、それぞれを量る。
(a,b)、(c,d)、(e,f)として、W1=a+b, W2=c+d, W3=e+f
・すべて同じ値(W1=W2=W3)のとき、残った1個が重さが少し違うパチンコ玉である。
 W4=gとして、x=W1/2(=W2/2=W3/2), y=W4
・他と違う1組が存在したとき、その中の1個が、重さが少し違うパチンコ玉である。
 たとえば、W3とすると、W4=e
  2*W4=W1のとき、x=W4(=W1/2=W2/2), y=W3-W4
  2*W4≠W1のとき、x=W3-W4(=W1/2=W2/2), y=W4
したがって、4回となる。
 

数列 - 中学入試から

 投稿者:山中和義  投稿日:2013年 2月 7日(木)11時36分53秒
  問題
コインがたくさんあり、そこからA君とB君の2人が交互にコインを取っていきます。
1回目はA君が1枚、2回目はB君が3枚、3回目はA君が5枚、4回目はB君が7枚、5回目はA君が9枚、…
というように、2人は自分が前に取った枚数より4枚多くコインを取ります。
何回か取った後、2人の持っているコインの枚数を比べたところ、差が31枚でした。
コインを多く持っているのはどちらですか。
また、その人が最後に取ったコインは何枚ですか。

答え
具体的に見ていくと、
 1回目: Aが1枚なので、差=1
 2回目: Bが3枚なので、差=3-1=2
 3回目: Aが5枚なので、差=5-3+1=3
 4回目: Bが7枚なので、差=7-5+3-1=4
 5回目: Aが9枚なので、差=9-7+5-3+1=5
 6回目: Bが11枚なので、差=11-9+7-5+3-1=6
 7回目: Aが13枚なので、差=13-11+9-7+5-3+1=7
  :
から、差は回数と同じ値を示す。
これより、差が31となるのは、「奇数回はA 偶数回はB」より、31回目のAの番である。
取る枚数は、2*回数-1より、2*31-1=61枚である。
(終り)

考察
 1回目: Aが1枚なので、差=1
 2回目: Bが3枚なので、差=3-1=2
 3回目: Aが5枚なので、差=5-3+1=5-(3-1)=3
 4回目: Bが7枚なので、差=7-5+3-1=7-(5-3+1)=4
 5回目: Aが9枚なので、差=9-7+5-3+1=9-(7-5+3-1)=5
 6回目: Bが11枚なので、差=11-9+7-5+3-1=11-(9-7+5-3+1)=6
 7回目: Aが13枚なので、差=13-11+9-7+5-3+1=13-(11-9+7-5+3-1)=7
  :
と解釈すれば、差は、
 自分が取る枚数 - 1つ前の相手の差
として求まる。
また、
 1回目: Aが1枚なので、差=1
 2回目: Bが3枚なので、差=3-1=2
 3回目: Aが5枚なので、差=5-3+1=(5-3)+1=3
 4回目: Bが7枚なので、差=7-5+3-1=(7-5)+{3-1}=4
 5回目: Aが9枚なので、差=9-7+5-3+1=(9-7)+{5-3+1}=5
 6回目: Bが11枚なので、差=11-9+7-5+3-1=(11-9)+{7-5+3-1}=6
 7回目: Aが13枚なので、差=13-11+9-7+5-3+1=(13-11)+{9-7+5-3+1}=7
  :
と解釈すれば、差は、
 { 自分が取る枚数 - 相手が取った枚数 } + 1つ前の自分の差
として求まる。
(終り)

別解
具体的に見ていくと、
 Aの和 1     6    15    28    45    66    91    …
    ┌──┬──┬──┬──┬──┬──┬──┬
    1  3  5  7  9 11 13 15 17 19 21 23 25 …
     └──┴──┴──┴──┴──┴──┴
 Bの和   3    10    21    36    55    78    …
 差  1  2  3  4  5  6  7  8  9 10 11 12 13 …
となる。
これより、
 回数をkとすると、kが奇数のときA 偶数のときBである。
 取る枚数は2k-1、持っている枚数はk(k+1)/2で与えられる。
となる。
k回目のとき、その差はk(k+1)/2-(k-1)k/2=kなので、31になるのは、k=31
よって、奇数回なのでA、その取る枚数は2*31-1=61枚である。
(終り)

別解
コインを取った回数をmとする。
具体的に見ていくと、
  m  1  2  3  4  5  6 …
  A  1  5  9 13 17 21 …
  B  3  7 11 15 19 23 …

 和A  1  6 15 28 45 66 …
 和B  3 10 21 36 55 78 …
となる。
これより、
 A,Bがそれぞれ取る枚数は4(m-1)+1,4(m-1)+3、持っている枚数はm(2m-1),m(2m+1)となる。
となる。
コインを多く持っている人がAの場合(Aが取ったとき)
 Bが(m-1)回目、Aがm回目のときなので、その差は、m(2m-1)-(m-1){2(m-1)+1}=2m-1
 これは奇数になる。よって、取る枚数は、2m-1=31より、m=16 ∴4*(16-1)+1=61枚
コインを多く持っている人がBの場合(Bが取ったとき)
 A,B共にm回目のときなので、m(2m+1)-m(2m-1)=2m
 これは偶数になる。よって、奇数31には成り得ない。
(終り)


!その1 シミュレーション

!1回目 差は1
LET P=1 !取る枚数
LET A=1 !持っている枚数
PRINT "1回: Aが取る枚数=";P; " 持っている枚数=";A

!2回目 差は2
LET Q=3
LET B=3
PRINT "2回: Bが取る枚数=";Q; " 持っている枚数=";B

!3回目以降
LET K=2 !回数
DO
   LET K=K+1

   IF MOD(K,2)=1 THEN !奇数回はAの番
      LET P=P+4
      LET A=A+P
      PRINT STR$(K);"回: Aが取る枚数=";P; " 持っている枚数=";A
   ELSE !Bの番
      LET Q=Q+4
      LET B=B+Q
      PRINT STR$(K);"回: Bが取る枚数=";Q; " 持っている枚数=";B
   END IF
LOOP UNTIL ABS(A-B)=31 !条件を満たすまで

PRINT K;"回"
PRINT "A=";P; "枚数="; A
PRINT "B=";Q; "枚数="; B


PRINT


!その2 シミュレーション

LET A=0 !1つ前の結果
LET B=0

LET K=0 !回数
DO
   LET K=K+1

   LET T=2*K-1 !取る枚数

   IF MOD(K,2)=1 THEN !奇数回はAの番
      LET A=T-B
      PRINT STR$(K);"回: Aが取る枚数=";T; " 差=";A
   ELSE !Bの番
      LET B=T-A
      PRINT STR$(K);"回: Bが取る枚数=";T; " 差=";B
   END IF
LOOP UNTIL A=31 OR B=31 !条件を満たすまで

PRINT K;"回"
IF MOD(K,2)=1 THEN !奇数回はAの番
   PRINT "A=";2*K-1; "枚数="; K*(K+1)/2
   PRINT "B=";2*K-3; "枚数="; (K-1)*K/2
ELSE !Bの番
   PRINT "A=";2*K-3; "枚数="; (K-1)*K/2
   PRINT "B=";2*K-1; "枚数="; K*(K+1)/2
END IF

END


実行結果

1回: Aが取る枚数= 1  持っている枚数= 1
2回: Bが取る枚数= 3  持っている枚数= 3
3回: Aが取る枚数= 5  持っている枚数= 6
4回: Bが取る枚数= 7  持っている枚数= 10
5回: Aが取る枚数= 9  持っている枚数= 15
6回: Bが取る枚数= 11  持っている枚数= 21
7回: Aが取る枚数= 13  持っている枚数= 28
8回: Bが取る枚数= 15  持っている枚数= 36
9回: Aが取る枚数= 17  持っている枚数= 45
10回: Bが取る枚数= 19  持っている枚数= 55
11回: Aが取る枚数= 21  持っている枚数= 66
12回: Bが取る枚数= 23  持っている枚数= 78
13回: Aが取る枚数= 25  持っている枚数= 91
14回: Bが取る枚数= 27  持っている枚数= 105
15回: Aが取る枚数= 29  持っている枚数= 120
16回: Bが取る枚数= 31  持っている枚数= 136
17回: Aが取る枚数= 33  持っている枚数= 153
18回: Bが取る枚数= 35  持っている枚数= 171
19回: Aが取る枚数= 37  持っている枚数= 190
20回: Bが取る枚数= 39  持っている枚数= 210
21回: Aが取る枚数= 41  持っている枚数= 231
22回: Bが取る枚数= 43  持っている枚数= 253
23回: Aが取る枚数= 45  持っている枚数= 276
24回: Bが取る枚数= 47  持っている枚数= 300
25回: Aが取る枚数= 49  持っている枚数= 325
26回: Bが取る枚数= 51  持っている枚数= 351
27回: Aが取る枚数= 53  持っている枚数= 378
28回: Bが取る枚数= 55  持っている枚数= 406
29回: Aが取る枚数= 57  持っている枚数= 435
30回: Bが取る枚数= 59  持っている枚数= 465
31回: Aが取る枚数= 61  持っている枚数= 496
31 回
A= 61 枚数= 496
B= 59 枚数= 465

1回: Aが取る枚数= 1  差= 1
2回: Bが取る枚数= 3  差= 2
3回: Aが取る枚数= 5  差= 3
4回: Bが取る枚数= 7  差= 4
5回: Aが取る枚数= 9  差= 5
6回: Bが取る枚数= 11  差= 6
7回: Aが取る枚数= 13  差= 7
8回: Bが取る枚数= 15  差= 8
9回: Aが取る枚数= 17  差= 9
10回: Bが取る枚数= 19  差= 10
11回: Aが取る枚数= 21  差= 11
12回: Bが取る枚数= 23  差= 12
13回: Aが取る枚数= 25  差= 13
14回: Bが取る枚数= 27  差= 14
15回: Aが取る枚数= 29  差= 15
16回: Bが取る枚数= 31  差= 16
17回: Aが取る枚数= 33  差= 17
18回: Bが取る枚数= 35  差= 18
19回: Aが取る枚数= 37  差= 19
20回: Bが取る枚数= 39  差= 20
21回: Aが取る枚数= 41  差= 21
22回: Bが取る枚数= 43  差= 22
23回: Aが取る枚数= 45  差= 23
24回: Bが取る枚数= 47  差= 24
25回: Aが取る枚数= 49  差= 25
26回: Bが取る枚数= 51  差= 26
27回: Aが取る枚数= 53  差= 27
28回: Bが取る枚数= 55  差= 28
29回: Aが取る枚数= 57  差= 29
30回: Bが取る枚数= 59  差= 30
31回: Aが取る枚数= 61  差= 31
31 回
A= 61 枚数= 496
B= 59 枚数= 465

 

15パズルとあみだくじ

 投稿者:永野護  投稿日:2013年 2月 7日(木)15時05分57秒
  15パズルをあみだくじで解く方法があるそうですが、どのようにするのでしょうか。
よろしければ教えてください。
 

15パズルとあみだくじ

 投稿者:永野護  投稿日:2013年 2月 7日(木)15時21分12秒
  追伸
http://www.h6.dion.ne.jp/~ooya/Suugaku/Amida.html
参考までに上記に似た問題が出ています。
 

旅人算 - 中学入試から

 投稿者:山中和義  投稿日:2013年 2月12日(火)13時49分21秒
  > No.2982[元記事へ]

問題
A君とB君がX地点を同時に出発して、Y地点までそれぞれ一定の速さで歩き続けました。
C君は2人が出発してから5分後にX地点を出発し、一定の速さで走り続けて2人を追いかけました。
C君は出発して5分後にB君に追いつき、その10分後にA君に追いつきました。
(1)A君、B君、C君の速さの比をできるだけ簡単な整数の比で表しなさい。
C君はA君に追いついて、すぐに来た道を同じ速さで引き返しました。
(2)次に、C君がB君に出会うのは、C君がA君に追いついてから何分後ですか。分数で答えなさい。
C君はB君に出会って、すぐにまた同じ速さでY地点に向かったところ、A君と同時にY地点に到着しました。
(3)C君の走った道のりの合計が5kmのとき、X地点からY地点までの距離を求めなさい。

答え
(1) ※移動した距離は同じで1とする
B君がC君と出会うまでに移動した距離を1とすると、速度=距離÷時間なので
B君の速度:C君の速度=1/(5+5):1/5=1/10:1/5=1:2=2:4
同様に、A君の速度:C君の速度=1/(5+5+10):1/(5+10)=1/20:1/15=3:4
A君の速度:B君の速度:C君の速度=3:2:4

(2) ※B君の速度を1とする
C君がA君に追いついたとき、B君とC君のそれぞれが移動した(X地点からの)距離は、
B君の速度を1とすると、1×(5+5+10)=20、2×(5+10)=30となる。その差は、30-20=10である。
この距離をB君とC君が向い合って移動するので、
B君とC君の速度の和で移動する時間として、10÷(1+2)=10/3分である。

(3) ※A君の速度を1とする → C君の速度が分数になるので、A君の速度を3とする
C君がA君と同時にY地点に到着した時間について
 C君がB君に出会ったとき、A君とC君との距離は、反対方向に移動した距離なので、
 A君の速度を3とすると、(3+4)×(10/3)=70/3となる。
 この距離はC君がA君に再度追いついた距離なので、
 C君とA君の速度の差で移動する時間として、(70/3)÷(4-3)=70/3分である。
よって、C君の歩いた道のりは、4×(5+10+10/3+70/3)=500/3
X地点からY地点までの距離は、A君が歩いた距離なので、3×(5+5+10+10/3+70/3)=140
したがって、5:□=500/3:140より、□=5×140÷(500/3)=21/5=4.2km
(終り)

別解 ダイヤ図(運行図表)
(1)
C君の速度を1とする。これをもとにA君とB君の速度を表す。
横軸を時間、縦軸を距離とするグラフを考える。速度×時間=距離より、
C君について、
 傾き1、点(5,0)を通るので、Y-0=1*(X-5) ∴Y=X-5
B君について、
 原点と点P(5+5,(5+5)-5)を通るので、Y={(((5+5)-5)-0)/((5+5)-0)}X ∴Y=(1/2)X
A君について、
 原点と点Q(5+5+10,(5+5+10)-5)を通るので、Y={(((5+5+10-5)-0)/((5+5+10)-0)}X ∴Y=(3/4)X
したがって、3/4:1/2:1=3:2:4
(2)
傾き-1(Y=X-5に直交する)、点Qを通る直線を考える。
この直線は、Y-{(5+5+10)-5}=-(X-(5+5+10)) ∴Y=-X+35
この直線とY=(1/2)Xとの交点Rが、C君がB君に出会ったときを表す。
連立方程式を解いて、X=70/3
したがって、70/3-(5+5+10)=10/3[分]
(3)
傾き1(Y=X-5に平行である)、交点Rを通る直線を考える。
この直線は、Y-35/3=(X-70/3) ∴Y=X-35/3
この直線とY=(3/4)Xとの交点が、C君がA君と同時にY地点に到着したときを表す。
連立方程式を解いて、X=140/3、Y=35
C君の走った道のりは、ひたすらまっすぐに走った距離に相当するので、
X=140/3をY=X-5に代入して、140/3-5=125/3
したがって、125/3:35=5:□より、□=5*35/(125/3)=21/5=4.2[km]
(終り)


SET WINDOW -1,50,-1,50 !表示領域
DRAW grid(5,5) !座標を描く

!(1)
SET LINE COLOR 4
DEF f(x)=x-5 !直線C ∵傾き1、点(5,0)を通る
CALL fvLINE(1,-5, 0,50)

SET LINE COLOR 1
LET t=5+5 !点(0,0)、点P(5+5,(5+5)-5)を通る
CALL fvPOINT(t,f(t),"P")
LET b=(f(t)-0)/(t-0)
CALL fvLINE(b,0, 0,50) !直線B Y=(1/2)X

SET LINE COLOR 2
LET t=5+5+10 !点(0,0)、点Q(5+5+10,(5+5+10)-5)を通る
CALL fvPOINT(t,f(t),"Q")
LET a=(f(t)-0)/(t-0)
CALL fvLINE(a,0, 0,50) !直線A Y=(3/4)X

!(1)の答え 3/4:1/2:1=3:2:4


!(2)
SET LINE COLOR 4
LET t=5+5+10
CALL fvLINE(-1,t+f(t), 0,50) !直線D Y-f(t)=-(X-t) ∵傾き-1、点Qを通るより


CALL fvINTERSECTION(-1,t+f(t),b,0, x,y) !交点R
CALL fvPOINT(x,y,"R")
PRINT x; y !debug
PRINT x-t !(2)の答え


!(3)
CALL fvLINE(1,-x+y, 0,50) !直線E Y-y=(X-x) ∵傾き1、点Rを通るより

CALL fvINTERSECTION(1,-x+y,a,0, xx,yy) !交点Y
CALL fvPOINT(xx,yy,"Y")
PRINT xx; yy !debug

CALL fvPOINT(xx,f(xx),"S")
PRINT f(xx);":"; a*xx; "= 5 : □"
PRINT a*xx * 5 / f(xx) !(3)の答え

END

!関数でお絵かき
! http://6317.teacup.com/basic/bbs/2967
! http://6317.teacup.com/basic/bbs/2018
!を参照のこと

!●作図ルーチン

EXTERNAL SUB fvPOINT(x,y,S$) !点(x,y)
DRAW disk WITH SCALE(0.5)*SHIFT(x,y) !※大きさは調整が必要である
PLOT TEXT ,AT x+0.5,y+0.5: S$ !※位置は調整が必要である
END SUB

EXTERNAL SUB fvLINE(A,B, P,Q) !直線y=Ax+B, x∈[P,Q]
PLOT LINES: P,A*P+B; Q,A*Q+B
END SUB


!●計算ルーチン

EXTERNAL SUB fvINTERSECTION(A,B,C,D, x,y) !2直線y=Ax+Bとy=Cx+Dとの交点(x,y)を求める
IF A=C THEN
   PRINT "2直線は平行です。"; A;C
ELSE
   LET x=(D-B)/(A-C)
   LET y=A*x+B
END IF
END SUB


実行結果 ※有理数モードにて

70/3  35/3
10/3
140/3  35
125/3 : 35 = 5 : □
21/5



 

循環節の性質

 投稿者:山中和義  投稿日:2013年 2月15日(金)11時32分51秒
  既約分数m/n(0<m<nを満たす整数)の循環節の性質
例
循環節の長さが偶数のとき、半分で切って足し合わせると、9が並ぶ。
1/7=0.{142857}の場合、142+857=999

考察
●2分割
循環節の長さを2kとする。
循環節の前半部分のk桁をa、後半部分のk桁をbとする。
題意より、a+b=10^k-1
既約分数m/nは、m/n=(a*10^k+b)/(10^(2k)-1)と表される。
∴m{10^(2k)-1}=n(a*10^k+b)
∴m{10^(2k)-1}=n{a*10^k+(10^k-1-a)}
∴m(10^k+1)(10^k-1)=n(a+1)(10^k-1)
∴m(10^k+1)=n(a+1)
m,nは互いに素なので、nは(10^k+1)の約数となる。
例
1/7=142857/999999=(142*1000+857)/999999=0.{142857}の場合、142+857=999
循環節の長さが6なので、k=3 ∴10^3+1=1001=7*11*13

●3分割
循環節の長さを3kとする。
循環節の前1/3部分のk桁をa、真ん中1/3部分のk桁をb、後1/3部分のk桁をcとする。
題意より、a+b+c=10^k-1
既約分数m/nは、m/n=(a*10^(2k)+b*10^k+c)/(10^(3k)-1)と表される。
∴m{10^(3k)-1}=n(a*10^(2k)+b*10^k+c)
∴m{10^(3k)-1}=n{a*10^(2k)+b*10^k+(10^k-1-a-b)}
∴m(10^k-1){10^(2k)+10^k+1}=n(10^k-1){a*(10^k+1)+b+1}
∴m{10^(2k)+10^k+1}=n{a*(10^k+1)+b+1}
m,nは互いに素なので、nは(10^(2k)+10^k+1)の約数となる。
例
1/7=142857/999999=(14*10000+28*100+57)/999999=0.{142857}の場合、14+28+57=99
循環節の長さが6なので、k=2 ∴10^4+10^2+1=10101=3*7*13*37
(終り)


!!DATA 3 !個数
!!DATA 7,11,13 !素因数

DATA 4 !個数
DATA 3,7,13,37 !素因数

READ D
DIM F(D) !素因数
MAT READ F
MAT PRINT F; !debug


FOR i=1 TO D !素因数の組み合わせで分母の候補を得る
   FOR h=0 TO COMB(D,i)-1

      LET m=1 !分子

      LET n=1 !分母
      LET T=Num2CombBit(h,D,i)
      FOR J=1 TO D
         IF MOD(T,2)=1 THEN LET n=n*F(J)
         LET T=INT(T/2)
      NEXT J

      CALL cycle(m,n,k,L) !循環節の長さを得る

      PRINT m;"/";n;"="; !純循環小数として表示する ※k=0
      PRINT "0.{";right$(REPEAT$("0",L)&STR$(INT(10^(k+L)*m/n)),L);"} 循環節=";L

   NEXT h
NEXT i

END


EXTERNAL SUB cycle(m,n,k,L) !既約分数m/n(0<m<nを満たす整数)の有限小数の桁数kと循環節の長さLを求める
!n/m=0.ab…z{AB…Z} 有限小数0.ab…zはk桁 (k+1)桁からの循環節AB…Zの長さはL
LET x=n

LET p=0 !2^p
DO WHILE MOD(x,2)=0
   LET x=x/2
   LET p=p+1
LOOP
LET q=0 !5^q
DO WHILE MOD(x,5)=0
   LET x=x/5
   LET q=q+1
LOOP
LET k=MAX(p,q) !小数点以下k桁は循環しない

IF x=1 THEN !有限小数
   LET L=0
ELSE !10^L≡1 MOD n/(2^p*5^q)を満たす最小のLより
   LET L=1 !循環節の長さ
   LET a=MOD(10,x)
   DO WHILE a<>1
      LET a=MOD(a*10,x)
      LET L=L+1
   LOOP
END IF
END SUB


EXTERNAL FUNCTION Num2CombBit(h,N,R) !番号から組合せビットパターンを生成する ※辞書式順序
LET v=h+1
LET j=R
LET A=0
FOR i=N-1 TO 0 STEP -1 !組合せをビット位置とする
   LET t=COMB(i,j)
   IF v>t THEN
      LET A=A+2^i !ビット位置(N-i-1)を1とする
      LET j=j-1
      LET v=v-t
   END IF
NEXT i
LET Num2CombBit=A
END FUNCTION


実行結果

3  7  13  37

1 / 3 =0.{3} 循環節= 1
1 / 7 =0.{142857} 循環節= 6
1 / 13 =0.{076923} 循環節= 6
1 / 37 =0.{027} 循環節= 3
1 / 21 =0.{047619} 循環節= 6
1 / 39 =0.{025641} 循環節= 6
1 / 91 =0.{010989} 循環節= 6
1 / 111 =0.{009} 循環節= 3
1 / 259 =0.{003861} 循環節= 6
1 / 481 =0.{002079} 循環節= 6
1 / 273 =0.{003663} 循環節= 6
1 / 777 =0.{001287} 循環節= 6
1 / 1443 =0.{000693} 循環節= 6
1 / 3367 =0.{000297} 循環節= 6
1 / 10101 =0.{000099} 循環節= 6

 

文字の消去

 投稿者:安井 章  投稿日:2013年 2月18日(月)09時45分23秒
  PRINT文で表示した文字列や計算結果を訂正する方法を教えてください。
計算条件を変更し結果を表示する場合変更前の値に重複します。変更前の値は
消去したいのですが。
N88BASICではprint spc(10)等で処理していました。
 

Re: 文字の消去

 投稿者:白石和夫  投稿日:2013年 2月18日(月)17時24分36秒
  > No.2987[元記事へ]

PRINT文に既出力の訂正機能はありません。
どうしてもという場合は,出力ウインドウをRicheditコントロールとして扱ってWin32APIで操ればできるかもしれません。ただし,Windows版限定です。
汎用性を取るのであれば,グラフィックスウィンドウの利用が考えられます。


 

単位分数の和で1をつくる

 投稿者:山中和義  投稿日:2013年 2月20日(水)12時24分18秒
  > No.2961[元記事へ]

問題
分母がn以下の相異なる単位分数の和で1をつくる
 1=1/a+1/b+ … +1/c、a<b< … <c≦n
例
 1/1 項数= 1
 1/2+1/3+1/6 項数= 3
 1/2+1/3+1/7+1/42 項数= 4
 1/2+1/3+1/7+1/78+1/91 項数= 5
 1/2+1/3+1/8+1/24 項数= 4
 1/2+1/3+1/8+1/32+1/96 項数= 5
 1/2+1/3+1/8+1/33+1/88 項数= 5
 1/2+1/3+1/8+1/36+1/72 項数= 5
 1/2+1/3+1/8+1/40+1/60 項数= 5
 1/2+1/3+1/8+1/42+1/56 項数= 5
 1/2+1/3+1/8+1/56+1/78+1/91 項数= 6
 1/2+1/3+1/8+1/60+1/72+1/90 項数= 6
 1/2+1/3+1/8+1/63+1/72+1/84 項数= 6
 1/2+1/3+1/9+1/18 項数= 4
 1/2+1/3+1/9+1/22+1/99 項数= 5
 1/2+1/3+1/9+1/24+1/72 項数= 5
 1/2+1/3+1/9+1/27+1/54 項数= 5
 1/2+1/3+1/9+1/30+1/45 項数= 5
 1/2+1/3+1/9+1/32+1/72+1/96 項数= 6
 1/2+1/3+1/9+1/33+1/66+1/99 項数= 6
 1/2+1/3+1/9+1/33+1/72+1/88 項数= 6
 1/2+1/3+1/9+1/35+1/63+1/90 項数= 6
    :

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


OPTION ARITHMETIC RATIONAL !有理数モード
DIM F(100),A(100),B(100)
MAT F=ZER
LET A(100)=1/100 !iの値、i以降の和
LET B(100)=A(100)
FOR i=99 TO 1 STEP -1
   LET A(i)=1/i !減少列 1/1>1/2>1/3> … >1/100
   LET B(i)=A(i)+B(i+1)
NEXT i
LET N=1
CALL try(N,1,A,B,F)
END

EXTERNAL SUB try(N,p,A(),B(),F()) !バックトラック法で検索する
OPTION ARITHMETIC RATIONAL !有理数モード
FOR i=p TO 100 !※cの上限
   LET T=N-A(i) !残り
   IF T>0 THEN
      IF i<100 AND B(i+1)<T THEN EXIT FOR !全部を使って可能性があれば、その部分集合を考える
      LET F(i)=1 !使用中とする
      CALL try(T,i+1,A,B,F) !有理数tを(i+1)以降で表す
      LET F(i)=0 !元に戻す
   ELSEIF T=0 THEN !題意を満たすなら
      LET k=0
      FOR j=1 TO p-1 !式を表示する
         IF F(j)=1 THEN
            PRINT "1/";STR$(j);"+";
            LET k=k+1
         END IF
      NEXT j
      PRINT  "1/";STR$(i);" 項数=";k+1
   END IF
NEXT i
END SUB

 

小町算となる単位分数 - パズル

 投稿者:山中和義  投稿日:2013年 2月22日(金)10時28分51秒
  問題 小町覆面算
単位分数が1/nとなる1から9までの数を1回ずつ使った分数を求めよ。
ただし、nは2から20までの数とする。
たとえば、6729/13458は1/2なので、求める答えのひとつである。

考察
1/n=m/(mn)を考える。
1から9までの数を1回ずつ使うので、分子のmは4桁の数、分母のmnは5桁の数である。
n=2の場合、
m=1234として、1234/(1234*2)=1234/2468より、
1234と2468とで、1から9までの数を1回ずつ使っているかどうか確認する。
次に、m=1235として、1235/(1235*2)=1235/2470
次に、m=1236として、1236/(1236*2)=1236/2472
 :
(終り)

参考サイト http://antlers.cis.ibaraki.ac.jp/PROGRAM/CPROG/297.pdf


DIM F(0 TO 9) !1から9までの数
FOR N=2 TO 20
   PRINT "N=";N

   FOR M=1234 TO 9876 !4桁の数
      MAT F=ZER
      LET F(0)=1 !使用中とする

      LET t=M
      FOR i=1 TO 4 !10進法4桁
         LET w=MOD(t,10)
         IF F(w)=1 THEN EXIT FOR !既に使用済み
         LET F(w)=1 !使用中とする
         LET t=INT(t/10)
      NEXT i
      IF i>4 THEN !各桁が異なる4桁の数なら
      !!!PRINT M !debug

         LET t=M*N
         IF t>=12345 AND t<=98765 THEN !5桁の数なら
            FOR i=1 TO 5
               LET w=MOD(t,10)
               IF F(w)=1 THEN EXIT FOR
               LET F(w)=1
               LET t=INT(t/10)
            NEXT i
            IF i>5 THEN !各桁が異なる5桁の数なら

               PRINT M; "/"; M*N !題意を満たす

            END IF
         END IF
      END IF
   NEXT M
   PRINT

NEXT N

END

 

Page-2

 投稿者:SECOND  投稿日:2013年 2月26日(火)10時04分37秒
  !Page-2 の始め

!========================
! decorder
! J= huffman code table selection ( 0=YDC 1=YAC 2=CDC 3=CAC)
! V_= pickup RRRRssss <-- JPG.file

SUB DEC1_NS
   DO
      IF BC< BST THEN CALL DEC1_IN
      LET W=IP(Hx)           ! bits width BST
      !----
      LET W=A(NA+W,J)
      IF 32768<=W THEN EXIT DO
      LET NA=W               ! nest adr.  W=0 table end
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   LOOP
   LET NA=0                  ! DU0L LLLL VVVV VVVV
   LET L_=MOD(IP(W/256),128) !  U0L LLLL
   LET V_=MOD(W,256)         !           VVVV VVVV
   IF 16< L_ THEN PRINT "unused code" !BREAK  !unused code ! LET V_=BVAL("8000",16)
   !----
   LET W=MOD(L_,BST)
   IF 0< W THEN
      LET BC=BC-W
      LET Hx=MOD(Hx*2^W,SHb)
   ELSE
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   END IF
END SUB

SUB DEC1_IN
   CALL RED_D
   LET W=ORD(D$)
   IF W=255 THEN
      CALL RED_D
      LET M=ORD(D$)
      IF M<>0 THEN LET w=1/0 ! EXTYPE=3001, ffxx marker, abnormally break
   END IF
   LET Hx=Hx+W*2^(BST-8-BC)
   LET BC=BC+8
END SUB

!-------
SUB DEC1_EX
   LET V_=0
   DO
      IF L_< 1 THEN EXIT SUB
      IF BC< L_ THEN CALL DEC1_IN
      LET W=IP(Hx)
      !----
      IF BST>=L_ THEN EXIT DO
      LET V_=V_*SHb+W
      LET L_=L_-BST
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   LOOP
   LET V_=V_*2^L_+IP(W*2^(L_-BST))
   !----
   LET BC=BC-L_
   LET Hx=MOD(Hx*2^L_,SHb)
END SUB

!============
! B(,J)L(,J)<-- DH(,J) for decorder table A(,J)
!
SUB makeH0(J)
   LET i=0   ! コード生成 順番(短い順)
   LET Hx=0
   LET Tx=BVAL("8000",16)
   FOR L_=1 TO 16
      FOR P=1 TO DH(L_,J)
         LET L(i,J)=L_
         LET B(i,J)=Hx ! コード(生成順), 座標DV(頻度降順) と同順。
         LET i=i+1
         LET Hx=Hx+Tx
      NEXT P
      LET Tx=Tx/2
   NEXT L_
   LET B(256,J)=0
   FOR i=i TO 255
      LET L(i,J)=0
      LET B(i,J)=0
   NEXT i
END SUB

!============
!A(,J)=output decorder table<-- B(,J) L(,J) DH(,J) DV(,J)
!
SUB makeD0(J)
   FOR LH=16 TO 1 STEP -1
      IF DH(LH,J)<>0 THEN EXIT FOR
   NEXT LH                          !length max. in huffman table
   LET LM=CEIL(LH/BST)*BST          !length max. bound by BST
   !---
   LET I=0                          !start huffman table adr.
   LET LA=0                         !line adr.
   LET P=BST                        !start Decord code width
   LET U_=2^(16-BST)                !start Decord code step
   LET NC=0                         !next start Decord code
   DO
      LET D_=NC                                         !start Decord code
      LET NC=-1
      LET LB=LA+(65536-D_)/U_                           !1st nest adr.
      DO
         CALL SERCH
         IF 0< L_ THEN
            LET A(LA,J)= BVAL("8000",16)+L_*256+DV(I,J) !b15=end. +L.+V.
         ELSEIF P=LM THEN
            LET A(LA,J)= BVAL("C000",16)+LH*256         !b15=end. b14=Unused. +L.
         ELSE
            IF NC=-1 THEN LET NC=D_
            LET A(LA,J)=LB                              !nest adr.
            LET LB=LB+SHb                               !next nest adr.
         END IF
         LET D_=D_+U_
         LET LA=LA+1
      LOOP UNTIL IP(D_)=65536
      LET P=P+BST
      LET U_=U_/SHb                                     !shr(U_,BST)
   LOOP UNTIL P>LM
   !---
   FOR LA=LA TO 255
      LET A(LA,J)=0                                     !(0),table stop mark
   NEXT LA
END SUB

SUB SERCH
   FOR I=I TO DH(0,J)-1
      LET L_=L(I,J)
      IF L_<=P THEN LET w=IP(D_/2^(16-L_))*2^(16-L_) ELSE EXIT FOR
      IF w<=B(I,J) THEN
         IF w=B(I,J) THEN EXIT SUB ELSE EXIT FOR
      END IF
   NEXT I
   LET L_=-1
END SUB

!===========
! Inverse Fast Cosin Transform.( 8x8, iDCT-2 ) ← Inverse Quantization.DQ()
SUB IDDCT8X8
   FOR P=0 TO CMO                                             !(0=Y,1=Cb,2=Cr)
      FOR V0=0 TO DV_-1 STEP 8*MV(0)/MV(P)
         FOR U0=0 TO DU-1 STEP 8*MH(0)/MH(P)
         !----decord one of MCU( Minimum Coded Unit)
            FOR Y_=0 TO 7
               FOR X_=0 TO 7
                  LET x(X_)=D2(U0+X_,V0+Y_,P)*DQ(X_,Y_,QS(P)) !Inverse Quantization
               NEXT X_
               CALL IWANG                                     !inverse DCT horizontal_row_8
               FOR X_=0 TO 7
                  LET T(X_,Y_)=x(X_)
               NEXT X_
            NEXT Y_
            !---
            FOR X_=0 TO 7
               FOR Y_=0 TO 7
                  LET x(Y_)=T(X_,Y_)
               NEXT Y_
               CALL IWANG                                     !inverse DCT vertical_column_8
               LET i=X_*MH(0)                                 !expand pt.X
               FOR Y_=0 TO 7
                  IF P=0 THEN
                     LET D1(U0+X_,V0+Y_,P)=x(Y_)+128          !inverse level shift
                  ELSE
                     LET j=Y_*MV(0)                           !expand pt.Y
                     !----expand
                     FOR V_=j TO j+MV(0)-1
                        FOR U_=i TO i+MH(0)-1
                           LET D1(U0+U_,V0+V_,P)=x(Y_)        !CbCr to MCU scale
                        NEXT U_
                     NEXT V_
                     !----expand
                  END IF
               NEXT Y_
            NEXT X_
            !----
         NEXT U0
      NEXT V0
   NEXT P
END SUB

!----inverse Wang.( 8, iDCT-2 )
SUB IWANG
   LET xo(0)=SQR(2/8)*x(0)
   LET xo(1)=SQR(2/8)*x(4)
   LET xo(2)=SQR(2/8)*x(2)
   LET xo(3)=SQR(2/8)*x(6)
   LET xo(4)=SQR(1/8)*x(1)
   LET xo(5)=SQR(1/8)*x(5)
   LET xo(6)=SQR(1/8)*x(3)
   LET xo(7)=SQR(1/8)*x(7)
   !
   LET x(4)=(COS(PI  /16)*xo(4)+SIN(PI  /16)*xo(7))
   LET x(5)=(COS(PI*5/16)*xo(5)+SIN(PI*5/16)*xo(6))
   LET x(6)=(SIN(PI*5/16)*xo(5)-COS(PI*5/16)*xo(6))
   LET x(7)=(SIN(PI  /16)*xo(4)-COS(PI  /16)*xo(7))
   !
   LET xo(4)= x(4)+x(5)
   LET xo(5)= x(4)-x(5)
   LET xo(6)=-x(6)+x(7)
   LET xo(7)= x(6)+x(7)
   !
   LET x(0)=(COS(PI/4)*xo(0)+COS(PI  /4)*xo(1))
   LET x(1)=(COS(PI/4)*xo(0)-COS(PI  /4)*xo(1))
   LET x(2)=(SIN(PI/8)*xo(2)-SIN(PI*3/8)*xo(3))
   LET x(3)=(COS(PI/8)*xo(2)+COS(PI*3/8)*xo(3))
   LET x(4)=xo(4)
   LET x(5)=xo(6)
   LET x(6)=xo(5)
   LET x(7)=xo(7)
   !
   LET xo(0)=x(0)+x(3)
   LET xo(1)=x(1)+x(2)
   LET xo(2)=x(1)-x(2)
   LET xo(3)=x(0)-x(3)
   LET xo(4)=x(7)*SQR(2)
   LET xo(5)=x(6)-x(5)
   LET xo(6)=x(6)+x(5)
   LET xo(7)=x(4)*SQR(2)
   !
   LET x(0)=xo(0)+xo(7)
   LET x(1)=xo(1)+xo(6)
   LET x(2)=xo(2)+xo(5)
   LET x(3)=xo(3)+xo(4)
   LET x(4)=xo(3)-xo(4)
   LET x(5)=xo(2)-xo(5)
   LET x(6)=xo(1)-xo(6)
   LET x(7)=xo(0)-xo(7)
END SUB

!=============
SUB R_BIN31(M) ! decord(M) before new.search(M)
   DO
      IF M=BVAL("D8",16) THEN  ! SOI
         MAT DH=ZER   ! clear Huffman Table
         LET DRI=0    ! clear Restart Interval.value for RST0~7(restart marker)
         LET rct=-1   ! Interval.counter, valid (0<=rct), invalid (rct< 0)
         MAT M3=ZER   ! clear scan band sum
      ELSEIF M=BVAL("D9",16) THEN ! EOI
         EXIT DO      ! close & end_sub
      ELSEIF BVAL("D0",16)<=M AND M<=BVAL("D7",16) THEN ! RST0~7( restart marker)
         LET rct=DRI  ! set counter with Restart Interval
         EXIT SUB
      ELSEIF 0< M THEN     !M=0 is data"FF" in picture area
         CALL RED_D
         LET N=ORD(D$)*256
         CALL RED_D
         LET N=N+ORD(D$)-2 ! N=remain size
         !---
         IF BVAL("E0",16)<=M AND M<=BVAL("EF",16) THEN ! APP0~APP15
            CALL FFE0
         ELSEIF M=BVAL("DD",16) THEN
            CALL FFDD ! DRI  load DRI & rct=DRI
         ELSEIF M=BVAL("FE",16) THEN
            CALL FFFE ! COMMENT
         ELSEIF M=BVAL("C4",16) THEN
            CALL FFC4 ! DHT
         ELSEIF M=BVAL("DB",16) THEN
            CALL FFDB ! DQT
         ELSEIF M=BVAL("C0",16) OR M=BVAL("C2",16) THEN
            PRINT right$("000"& BSTR$(byt-4,16),4)
            !---
            CALL FFC0 ! SOF0 SOF2
            !---
            PRINT " SOF";STR$(MOD(M,16));" MCU_HV Ybr ";STR$(MH(0));STR$(MV(0));
            PRINT " ";STR$(MH(1));STR$(MV(1));" ";STR$(MH(2));STR$(MV(2))
         ELSEIF M=BVAL("DA",16) THEN
            CALL FFDA ! SOS
            EXIT SUB  ! without close
         ELSE
            BREAK     ! new marker
         END IF
      END IF
      !---
      DO
         LET M=BVAL("D9",16) ! EOI, 256 ! end of file
         CHARACTER INPUT #1,IF MISSING THEN EXIT DO :D$
         LET byt=byt+1 !!!
         LET M=ORD(D$)
      LOOP UNTIL M=255       ! 1st.mark
      IF M<>255 THEN EXIT DO ! close & end_sub
      CALL RED_D
      LET M=ORD(D$)
   LOOP
   CLOSE #1
END SUB

!DRI
SUB FFDD
   CALL RED_D
   LET DRI=ORD(D$)*256
   CALL RED_D
   LET DRI=DRI+ORD(D$)
   LET rct=DRI
END SUB

!APP0
SUB FFE0
   FOR W=1 TO N
      CALL RED_D
   NEXT W
END SUB

!COMMENT
SUB FFFE
   FOR W=1 TO N
      CALL RED_D
   NEXT W
END SUB

!DQT
SUB FFDB
   DO WHILE 0< N
      CALL RED_D
      LET w= IP(ORD(D$)/16) !p=0(byte) p=1(word)
      LET J=MOD(ORD(D$),16) !J=0~3 (QT.number)
      FOR i=0 TO 63
         CALL RED_D
         LET DQ(U(i),V(i),J)=ORD(D$)
         IF w=1 THEN
            CALL RED_D
            LET DQ(U(i),V(i),J)=DQ(U(i),V(i),J)*256+ORD(D$)
         END IF
      NEXT i
      LET N=N-65-64*w ! remain size
   LOOP
END SUB

!SOF0 SOF2
SUB FFC0
   CALL RED_D
   IF ORD(D$)<>8 THEN BREAK ! 8bit( 24bitColor ) at RGB.dimension
   CALL RED_D
   LET W=ORD(D$)*256
   CALL RED_D
   LET DY=W+ORD(D$) !V.pix.
   CALL RED_D
   LET W=ORD(D$)*256
   CALL RED_D
   LET DX=W+ORD(D$) !H.pix.
   CALL RED_D
   FOR i=0 TO ORD(D$)-1   !1~3 フレーム数、続くID 配置は、暗黙に Y,Cb,Cr の順
      CALL RED_D
      LET CoID(ORD(D$))=i ! CoID( ID=0~255) <--(Y=0, Cb=1, Cr=2)
      CALL RED_D
      LET MH(i)= IP(ORD(D$)/16) ! HV Y=11,12,21,22,41 Cb=11,11,11,11,11 Cr=11,11,11,11,11
      LET MV(i)=MOD(ORD(D$),16)
      CALL RED_D
      LET QS(i)=ORD(D$)   ! QT.number0~3 <-- QS( Y=0, Cb=1, Cr=2)
   NEXT i
   IF i=1 THEN LET CMO=0 ELSE LET CMO=2
END SUB

!DHT
SUB FFC4
   DO WHILE 0< N
      CALL RED_D
      LET J=ORD(D$)              ! (DC=0 AC=1 | ID0_0~3)
      LET J=2*MOD(J,16)+IP(J/16) ! 0~1=ID0.DC~AC  2~3=ID1.DC~AC  4~5=ID2.…
      LET DH(0,J)=0 !!!for 2nd.use for clear
      FOR i=1 TO 16
         CALL RED_D
         LET DH(i,J)=ORD(D$)
         LET DH(0,J)=DH(0,J)+DH(i,J)
      NEXT i
      FOR i=0 TO DH(0,J)-1
         CALL RED_D
         LET DV(i,J)=ORD(D$)
      NEXT i
      !---
      FOR i=i TO 255
         LET DV(i,J)=0
      NEXT i
      CALL makeH0(J) ! make Huffman Code table B() L()
      CALL makeD0(J) ! make Huffman Decorder table A()
      !---
      LET N=N-1-16-DH(0,J) ! remain size
   LOOP
END SUB

!SOS
SUB FFDA
   CALL RED_D
   LET M2=ORD(D$)
   MAT HDC=(-2)*CON
   MAT HAC=(-2)*CON
   FOR i=1 TO M2
      CALL RED_D    ! ID=0~255( defined by SOFx)
      LET w=ORD(D$)
      CALL RED_D    ! (DC_0~3|AC_0~3) huffman table selection
      LET HDC(CoID(w))= IP(ORD(D$)/16)*2   !DC 0~3-->0,2,4,6
      LET HAC(CoID(w))=MOD(ORD(D$),16)*2+1 !AC 0~3-->1,3,5,7
   NEXT i
   CALL RED_D
   LET Ss_=ORD(D$) ! low of spectral selection
   CALL RED_D
   LET Se_=ORD(D$) ! high of spectral selection
   CALL RED_D
   LET Al=MOD(ORD(D$),16) !successive approximation bit position low ( point transform )
   LET Ah=IP(ORD(D$)/16)  !successive approximation bit position high ( preceding "Al" )
   !--- balance monitor M30 M3() for display timing.
   LET w=Se_-Ss_+1
   IF Ah<>Al THEN LET w=w*(Ah-Al) ! prog.sa
   FOR i=0 TO 2
      IF 0<=HAC(i) THEN LET M3(i)=M3(i)+w ! M3()= scan band sum
   NEXT i
   IF CMO=0 OR M3(0)=M3(1) AND M3(1)=M3(2) THEN LET M30=M3(0) ELSE LET M30=99 ! Ybr.balance
   !--- next image data top
END SUB

!プログレッシブ・シーケンスでは、段階的に画像ができるため、
!カラー画像表示のタイミング適正のため、上の様に、モニター変数 M30 を設けた。
!
!      (Ah|Al)     (バンド幅*ビット幅)の積算
!Ss Se Y  Cb Cr   ベース・ライン・シーケンス例 baseline
!00 3F 00 00 00   M3()=  64  64  64  …M30=64     完成画。

!Ss Se Y  Cb Cr   プログレッシブ・シーケンス例 spectral selection
!00 00 00 00 00   M3()=   1   1   1  …M30= 1
!01 05 -- 00 --   M3()=   1   6   1       = 99   99 は、バンド幅(Se-Ss+1)の
!01 05 -- -- 00   M3()=   1   6   6       = 99    累積が、
!01 05 00 -- --   M3()=   6   6   6  …M30= 6     Y,Cb,Cr で揃っていない時。
!06 3F -- 00 --   M3()=   6  64   6       = 99
!06 3F -- -- 00   M3()=   6  64  64       = 99
!06 3F 00 -- --   M3()=  64  64  64  …M30= 64    完成画。

!Ss Se Y  Cb Cr   プログレッシブ・シーケンス例 successive approximation
!00 00 01 01 01   M3()=  -1  -1  -1  …M30= -1
!01 05 02 -- --   M3()= -11  -1  -1       = 99   99 は、バンド幅(Se-Ss+1)と、
!01 3F -- -- 01   M3()= -11  -1 -64       = 99    分割ビット長(Ah-Al)の積の
!01 3F -- 01 --   M3()= -11 -64 -64       = 99    累積が、
!06 3F 02 -- --   M3()=-127 -64 -64       = 99    Y,Cb,Cr で揃っていない時。
!01 3F 21 -- --   M3()= -64 -64 -64  …M30= -64
!00 00 10 10 10   M3()= -63 -63 -63  …M30= -63
!01 3F -- -- 10   M3()= -63 -63   0       = 99
!01 3F -- 10 --   M3()= -63   0   0       = 99
!01 3F 10 -- --   M3()=   0   0   0  …M30= 0     完成画。

SUB ROPEN
   OPEN #1 :NAME FL$ ,ACCESS INPUT
END SUB

SUB RED_D
   CHARACTER INPUT #1 :D$
   LET byt=byt+1 !!!
END SUB

END
 

訂正版

 投稿者:SECOND  投稿日:2013年 2月26日(火)10時05分56秒
  !------------------------------------------------------------
!先の投稿 http://6317.teacup.com/basic/bbs/t5/#1
! で、エンコーダー側DC処理 point transform は、
! "divide by 2^AL" でなく、"arithmetic-shift-right AL" である事を、考慮していない
! 誤りがあり、その訂正版です。
! 先投稿への編集は、出来なくなっているので、これと差し換えて下さい。
!
! 依存資料:http://www.w3.org/Graphics/JPEG/itu-t81.pdf
! itu-t81.pdf の Annex K ( K.9~K.10  P177~P178) 参照
!
!整数出力(負~0)での、"divide by 2^N" と "arithmetic shift right N" の違い。
!
!       out         (N=1 の時) ┏┛divide by 2   ┌┘arithmetic shift right 1
!       │
!       │+3 ………┏    (+4) 00000100→ 00000010(商=+2)  00000100→ 00000010(+2)
!       │+2 …┏━┛    ( ~)      ~ → 00000001(商=+1)       ~ → 00000001(+1)
!       │+1┏━┛        (+2) 00000010→ 00000001(商=+1)  00000010→ 00000001(+1)
! ────┏━┿━┛────in  ( ~)      ~ → 00000000(商= 0)       ~ → 00000000( 0)
!   ┏━╋─┤-1             ( 0) 00000000→ 00000000(商= 0)  00000000→ 00000000( 0)
! ┏━╋─┘…│-2              ( ~)      ~ → 00000000(商= 0)       ~ → 11111111(-1)
! ╋─┘………│-3            (-2) 11111110→ 11111111(商=-1)  11111110→ 11111111(-1)
! ┘     │                ( ~)      ~ → 11111111(商=-1)       ~ → 11111110(-2)
! │~│~│~│~│~│~│    (-4) 11111100→ 11111110(商=-2)  11111100→ 11111110(-2)
!-6 -4 -2 0 +2 +4 +6    ( ~)      ~ → 11111110(商=-2)       ~ → 11111101(-3)
!                        (-6) 11111010→ 11111101(商=-3)  11111010→ 11111101(-3)

!************************************************************
!訂正版:十進 BASIC による プログレッシブ JPG の展開と画像化。
!
!プログレッシブ JPG 再生過程の画像は、最初のDC成分1枚だけ と、最終完成画、全2枚とした。
!Baseline JPG は、全1枚なので、画数で両者を区別できる。( 描画倍率は、1又は、2倍拡大)
!(必要なら、再生過程 全ての画像も、表示できるよう、SUB IZZRL0 に注釈行がある)
!
!大きな再生画像でも、縮尺を止め、1倍又は、極小な場合の2倍拡大のみにした。
!色差成分 Cb Cr の間引き走査復元の塗潰しは、SUB IDDCT8X8 に組み込み。
!
!具体的、可視的なプログラムで、実行し画像化するので、詳細事項の追跡と御参考に。
!再生できるファイルは、1000x1000 までの JPG だけで、
! baseline , spectral selection , successive approximation の3種類( web 上の、ほぼ全種)
!
!
!1)successive approximation AC.subsequence(Y,Cb,Cr 別々、1bit づつの処理)
!    0 でない追加データ extend (1bit) が 1st.scan も 0 の初めてのデーターになるまで、
!    Zero-RUN を続ける。
!    その間の、上位桁<>0 の 1st.scan 値 追加データーは、その個数分が、
!    extend. に後続している。Zero-RUN 個数 の 0 の次の 0 の位置に、extend.を置く。
!    ここでの extend. は group 1 だけで、(0,1) → (-1,+1)
!
!      0      1      1      0      0      0      0      0      0     ?
!      0      0      0      0      0      1      0      0      0     ?
!      0      1      0      0      0      0      0      1      0     ?
!      0      1      1      0      0      1      0      1      0     ?
!      0      1      1      0      0      1      0      1      0     ?
! --------------------------------------------------------------------------
!    ±1      b1     b2     0      0      b3     0      b4   ±1     ?
! 前の終り                 RRRR   RRRR          RRRR        extend.  次の始め
!
!    huffman.
!    RRRRssss  extend.  b1 b2 b3 b4 …  bit_stream=?何個になるかは、
!      3   1  (0 or 1)   (0 or 1)       上位桁 =0 の係数が RRRR 個 になるまでに
!               ↓         ↓           通過した上位桁 <>0 の個数。上図では、4
!
!    新規(上位桁無)        エンコーダー側AC処理 point transform は、
!    の復号  0 → -1       "divide by 2^AL" なので
!            1 → +1       0 → 無変化。
!                          1 → ±符号は上位桁に合せて加算。(絶対値が+1)
!
!
!2)successive approximation DC.subsequence(Y,Cb,Cr 別々、1bit づつの処理)
!    ハフマン・コード RRRRssss 部は、存在せず、
!    頭からの bit_stream.で、1bit づつ、全てのblock の DC係数 に加える。
!
!                          エンコーダー側DC処理 point transform は、
!                          "arithmetic-shift-right AL" なので
!                          0 → 無変化。
!                          1 → 上位桁符号に関らず、+加算。(符号無し整数値が+1)
!
!
! ※AL・・・ 係数などの数値が、2^AL のステップ幅で 量子化された値 になっている意。
! ※AH・・・ preceding AL.  同じ BAND で直前の AL 値 (AH=0 は、最初の AL に添える)
!
!          (Ah|Al)
!   ←──┐ 0 0 全bits のデータ。復元は、(・・・111111.)*2^( point transform =0)
! ・・・111111
!
! 以下3つを加算すると、上と同じになる。
!          (Ah|Al)
!   ←─┐   0 2  上位bits のデータ。   復元は、(・・・1111  )*2^( point transform =2)
! ・・・1111xx
!        〟  2 1 1bitづつ、分けて追加。復元は、(       1 )*2^( point transform =1)
! ・・・xxxx1x
!         〟 1 0            復元は、(        1)*2^( point transform =0)
! ・・・xxxxx1
!
!------------------------
DEBUG ON
!------------------------
!JPG.decoder
! Baseline
! Progressive( spectral selection )( successive approximation )
!------------------------
OPTION ARITHMETIC NATIVE
OPTION BASE 0
OPTION CHARACTER byte
SET TEXT background "OPAQUE"
SET ECHO "OFF"
SET COLOR MODE "NATIVE"
!
DIM D8(1000,1000)   !MAIN65
DIM D2(1000,1000,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
DIM D1(1000,1000,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
DIM MH(2),MV(2)     !R_BIN31  SOF0 MCU.Ybr.H()V()
DIM HDC(2),HAC(2)   !R_BIN31 hT.table selection
DIM QS(2),CoID(255) !R_BIN31 qT.table selection
DIM M3(2)
!
DIM U(63),V(63)         !zigzag
DIM DQ(7,7,3)           !blk8x8 DQT
DIM DH(16,7),DV(255,7)  !DHT
DIM B(255+1,7),L(255,7) !encorder & decorder's pre_table, length, ( MAKE_H2,MAKE_H0)
DIM A(2000,7)           !decorder
DIM B2(2)               !Ybr D.C.成分 starting & back_level for difference
DIM T(7,7),x(7),xo(7)  !DDCT8X8, IDDCT8X8
!
LET BST=2      !huffman decorder's bit step 1=8.5s 2=6.5s 4=8.0s 8=50.0s
LET SHb=2^BST  !huffman decorder   n*SHb=(shl n,BST)  n/SHb=(shr n,BST)
!
!---zigzag table
FOR V_=0 TO 7
   FOR U_=0 TO 7
      READ i
      LET U(i)=U_
      LET V(i)=V_
   NEXT U_
NEXT V_
DATA  0, 1, 5, 6,14,15,27,28
DATA  2, 4, 7,13,16,26,29,42
DATA  3, 8,12,17,25,30,41,43
DATA  9,11,18,24,31,40,44,53
DATA 10,19,23,32,39,45,52,54
DATA 20,22,33,38,46,51,55,60
DATA 21,34,37,47,50,56,59,61
DATA 35,36,48,49,57,58,62,63
!
DO
   FILE GETNAME FL$, "jpg"
   IF FL$="" THEN
      PRINT "入力ファイル名無し"
      EXIT DO
   END IF
   PRINT "入力ファイル:"& FL$
   !---
   CLEAR
   CALL IZZRL0   ! D2()<-- decord JPG
   PRINT "次のファイル[ 左クリック ]"
   beep
   DO
      MOUSE POLL j,i,mlb,mrb !CHARACTER INPUT CLEAR: w$
      WAIT DELAY 0
   LOOP UNTIL 0< mlb OR 0< mrb
LOOP UNTIL 0< mrb
PRINT "終了。"

!-------- IZZRL0 call here for display D2()
SUB MAIN65
   LET tester=TIME
   PRINT "画像の準備中、";
   CALL IDDCT8X8 ! D1()<-- iDCT<-- iDQT<-- D2()
   !------ JPG 色空間 ----------------------------
   ! | Y |   | 0.2990   +0.5870   +0.1140  | | R |
   ! |B-Y| = |-0.1687   -0.3313   +0.5000  | | G |
   ! |R-Y|   | 0.5000   -0.4187   -0.0813  | | B |
   !
   ! | R |   | 1         0        +1.40200 | | Y |
   ! | G | = | 1        -0.34414  -0.71414 | |B-Y|
   ! | B |   | 1        +1.77200   0       | |R-Y|
   !----------------------------------------------
   FOR V0=0 TO DY-1
      FOR U0=0 TO DX-1
      !--- RGB<-- Ybr
         LET w1=IP(D1(U0,V0,0)                      +1.40200*D1(U0,V0,2)) !R
         LET w2=IP(D1(U0,V0,0) -0.34414*D1(U0,V0,1) -0.71414*D1(U0,V0,2)) !G
         LET w3=IP(D1(U0,V0,0) +1.77200*D1(U0,V0,1))                      !B
         IF w1< 0 THEN
            LET w1=0
         ELSEIF 255< w1 THEN
            LET w1=255
         END IF
         IF w2< 0 THEN
            LET w2=0
         ELSEIF 255< w2 THEN
            LET w2=255
         END IF
         IF w3< 0 THEN
            LET w3=0
         ELSEIF 255< w3 THEN
            LET w3=255
         END IF
         LET D8(U0,V0)=w3*65536+w2*256+w1 !(逆)BGR
      NEXT U0
   NEXT V0
   PRINT TRUNCATE(TIME-tester,2);"秒"
   !!! LET w=1                                !等倍で描画、画素数どうり。
   LET w=IP( MIN( 500/DX, 500/DY))        !整数倍拡大、1~2の何れかで描画。
   IF 2< w THEN LET w=2
   IF w< 1 THEN LET w=1
   PRINT "描画の倍率=";w
   CALL scrns(DX*w, DY*w)
   MAT PLOT CELLS,IN 1,1; DX*w, DY*w :D8
END SUB

SUB scrns(px,py)
   SET bitmap SIZE px+50,py+50
   SET WINDOW 1-20,px+30, py+27,1-23
   SET LINE COLOR "cyan"
   SET LINE width 3
   PLOT LINES:1-3,1-3;px+3,1-3;px+3,py+3;1-3,py+3;1-3,1-3
   PLOT TEXT,AT -3,-4: "原画 "& STR$(px/w)& "x"& STR$(py/w)& " 倍率= "& STR$(w)
END SUB

!========================
!inverse haffman Transform.
SUB IZZRL0
   LET byt=0 !!!
   CALL ROPEN ! FL$
   !---
   CALL R_BIN31(0) !A() B(i,J)L(i,J)<-- DH(), return at img.top
   PRINT right$("000"& BSTR$(byt,16),4) !!!
   PRINT "(";STR$(DX);"x";STR$(DY);
   !---
   MAT D8=ZER(DX-1,DY-1)     !MAIN65
   LET i=8*MH(0)             !MCU Y.Hsize
   LET j=8*MV(0)             !MCU Y.Vsize
   LET DUM=CEIL(DX/i)*i      !Uwidth=bound by MCU Y.Hsize
   LET DVM=CEIL(DY/j)*j      !Vwidth=bound by MCU Y.Vsize
   MAT D1=ZER(DUM-1,DVM-1,2) !Y=D1(,,0)  Cb=D1(,,1)  Cr=D1(,,2)
   MAT D2=ZER(DUM-1,DVM-1,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
   LET MH_=MH(0)
   LET MV_=MV(0)
   LET DU =DUM               !Uwidth=bound by MCU Y.Hsize
   LET DV_=DVM               !Vwidth=bound by MCU Y.Vsize
   LET DU8=CEIL(DX/8)*8      !Uwidth=bound by block Y.Hsize
   LET DV8=CEIL(DY/8)*8      !Vwidth=bound by block Y.Vsize
   !---
   PRINT "/ ";STR$(DU8);",";STR$(DV8);"/ ";STR$(DUM);",";STR$(DVM);")"
   CALL frame
   !---
   PRINT "M3()=";M3(0);M3(1);M3(2)
   CALL MAIN65 ! Baseline.最終、Progressive.1st.
   !---
   IF 0< M THEN PRINT " (";STR$(DX);"x";STR$(DY);"/";STR$(U0);",";STR$(V0);") ";debug$;" abort by ";BSTR$(M,16) !!!
   PRINT right$("000"& BSTR$(byt-2*SGN(M),16),4) !!!
   CALL R_BIN31(M) ! return at img.top, or EOI
   !---
   DO WHILE M=BVAL("DA",16) !SOS
      IF 0<=HAC(0) THEN
         LET MV(0)=1
         LET MH(0)=1
         LET DU=DU8
         LET DV_=DV8
      END IF
      CALL frame
      LET MV(0)=MV_
      LET MH(0)=MH_
      LET DU=DUM
      LET DV_=DVM
      !---
      PRINT "M3()=";M3(0);M3(1);M3(2)     !文末参照:M30<>99(balance), M30=99(un-balance)
      IF M30=0 OR M30=64 THEN CALL MAIN65 !Progressive.最終スキャン後の画像
      !IF M30<>99 THEN CALL MAIN65         !Progressive.各スキャン毎、Ybr 揃った画像のみ
      !CALL MAIN65                         !Progressive.各スキャン毎、全画像
      !---
      IF 0< M THEN PRINT " (";STR$(DX);"x";STR$(DY);"/";STR$(U0);",";STR$(V0);") ";debug$;" abort by ";BSTR$(M,16) !!!
      PRINT right$("000"& BSTR$(byt-2*SGN(M),16),4)
      CALL R_BIN31(M) ! return at img.top
   LOOP
   CLOSE #1 ! FL$
END SUB

SUB reset0
   LET B2(0)=0 !ROUND( YDC0/DQ(0,0,QS(0)) ) !prediction YDC.( 1st.reference level)
   LET B2(1)=0 !prediction CbDC.
   LET B2(2)=0 !prediction CrDC.
   LET Hx=0  !bits stream input buffer 0~(7+8)bits, use fraction
   LET BC=0  !stored bits in Hx
   LET NA=0  !nest adr. in A()
   LET EOB=0 !counter( end_of_band)
   LET M=0
   LET ext=0
END SUB

SUB frame
   PRINT "  Ss Se AhAl: ";Ss_;Se_;STR$(Ah);STR$(Al)
   PRINT "  Y  HDC HAC: ";IP(HDC(0)/2);IP(HAC(0)/2)
   PRINT "  Cb        : ";IP(HDC(1)/2);IP(HAC(1)/2)
   PRINT "  Cr        : ";IP(HDC(2)/2);IP(HAC(2)/2)
   CALL reset0
   !---
   FOR V09=0 TO DV_-1 STEP 8*MV(0)
      FOR U09=0 TO DU-1 STEP 8*MH(0)
         IF rct=0 THEN
            CALL R_BIN31(0)        ! read marker
            IF rct<>DRI THEN BREAK ! not RST0~7
            CALL reset0 ! Restart
         END IF
         CALL MCUxx11 ! read picture data
         LET rct=rct-1
         !---
         IF 0< ext THEN
            IF ext=103001 THEN
               PRINT "abort marker ";BSTR$(M,16)
               IF BVAL("D0",16)<=M AND M<=BVAL("D7",16) THEN ! RST0~7( restart marker)
                  LET rct=DRI ! set counter
                  CALL reset0 ! Restart
               ELSE
                  EXIT SUB ! others marker
               END IF
            ELSE
               PRINT "file error. display fragment"
               LET M=BVAL("D9",16) ! EOI
               EXIT SUB
            END IF
         END IF
      NEXT U09
   NEXT V09
   IF 0< EOB THEN PRINT "EOBn over frame";EOB  !!!
END SUB

SUB MCUxx11
!---read MCU
   FOR P=0 TO CMO
      IF 0<=HDC(P) OR 0<=HAC(P) THEN
         FOR V0=V09 TO V09+8*MV(P)-1 STEP 8
            FOR U0=U09 TO U09+8*MH(P)-1 STEP 8
               WHEN EXCEPTION IN
                  IF EOB=0 THEN CALL R_BLK0 ELSE LET EOB=EOB-1
               USE
                  LET ext=EXTYPE
                  EXIT SUB
               END WHEN
               !---extend bitmap
               IF 0< Ah AND 0< Se_ THEN
                  FOR i=A_ TO Se_
                     IF D2(U0+U(i),V0+V(i),P)<>0 THEN
                        LET L_=1
                        WHEN EXCEPTION IN
                           CALL DEC1_EX
                        USE
                           LET ext=EXTYPE
                           EXIT SUB
                        END WHEN
                        LET V_=SGN(D2(U0+U(i),V0+V(i),P))*V_
                        LET D2(U0+U(i),V0+V(i),P)=D2(U0+U(i),V0+V(i),P) +V_*2^Al
                     END IF
                  NEXT i
                  LET A_=Ss_
               END IF
               !---
            NEXT U0
         NEXT V0
      END IF
   NEXT P
END SUB

!------
SUB R_BLK0
   IF Ss_=0 THEN
   !===D.C.part
      LET debug$="DC.huffman" !!!
      IF Ah=0 THEN
      !-----baseline.progSS.progSA(1st.scan).
         LET J=HDC(P)                     !huffman D.C.table selection P( 0=Y 1=Cb 2=Cr)
         CALL DEC1_NS
         LET EL=V_                        !extent length
         !---D.C.extent
         LET debug$="DC.huffman extend" !!!
         IF 0< EL THEN
            LET L_=EL
            CALL DEC1_EX                  !keep EL, V_=extent value( length EL bits)
            LET W=2^(EL-1)                !minimum in EL bits length
            IF V_< W THEN LET V_=V_-W*2+1 !restore signed value
            LET B2(P)=B2(P)+V_*2^Al       !point transform, integrate to D.C.
         END IF
         LET D2(U0+U(0),V0+V(0),P)=B2(P)
      ELSE
      !-----progSA(2st.scan).
         LET L_=1
         CALL DEC1_EX
         !!! LET V_=SGN(D2(U0+U(0),V0+V(0),P))*V_
         LET D2(U0+U(0),V0+V(0),P)=D2(U0+U(0),V0+V(0),P) +V_*2^Al
      END IF
      !===A.C.parts
      LET Sa_=1
   ELSE
   !===A.C.parts
      LET Sa_=Ss_
   END IF
   IF Se_=0 THEN EXIT SUB                 !band Ss_~Se_
   LET J=HAC(P)                           !huffman A.C.table selection P( 0=Y 1=Cb 2=Cr)
   LET debug$="AC.huffman" !!!
   FOR A_=Sa_ TO Se_
      CALL DEC1_NS
      LET EL=MOD(V_,16)                   !extent length
      LET RL= IP(V_/16)                   !run length
      !---
      IF RL<=14 AND EL=0 THEN             !End Of Block(00). End Of Band n(10,20,,E0)
      !---EOBn extend
         LET debug$="EOBn extend"& STR$(RL) !!!
         IF 0< RL THEN
            LET L_=RL                     !RL= 1,2,,E (EOB1, EOB2, ・・・, EOB14)
            CALL DEC1_EX                  !keep RL, run_length= V_+2^RL
            LET EOB=V_+2^RL -1            !※-1 (1st.count)
         END IF
         EXIT SUB
         !---
      END IF
      !---RL=(0~15)EL=(1~10), RL=(15)EL=(0)
      LET debug$="AC.huffman extend" !!!
      IF Ah=0 THEN
      !-----baseline.progSS.progSA(1st.scan).
         LET A_=A_+RL                     !skip zero_run_length 0~15
         !---A.C.extent
         IF 0< EL THEN                    !ZRL(16) only skip
            LET L_=EL
            CALL DEC1_EX                  !keep EL, V_=extent value( length EL bits)
            LET w=2^(EL-1)                !minimum in EL bits length
            IF V_< w THEN LET V_=V_-w*2+1       !restore signed value
            LET D2(U0+U(A_),V0+V(A_),P)=V_*2^Al !point transform
         END IF
      ELSE
      !-----progSA(2st.scan).
         IF 0< EL THEN                    !ZRL(16) only skip
            LET L_=EL
            CALL DEC1_EX                  !keep EL, V_=extent value( length EL bits)
            IF EL<>1 THEN PRINT "AC.2nd.=";EL;V_ !!!
            LET V01=V_
         END IF
         FOR i=A_ TO Se_
            IF D2(U0+U(i),V0+V(i),P)<>0 THEN  !zz(k)=xxx_1?/0?
               LET L_=1
               CALL DEC1_EX
               LET V_=SGN(D2(U0+U(i),V0+V(i),P))*V_
               LET D2(U0+U(i),V0+V(i),P)=D2(U0+U(i),V0+V(i),P) +V_*2^Al
            ELSEIF RL=0 THEN              !zz(k)=000_V01
               EXIT FOR
            ELSE                          !zz(k)=000_0  ,zero run
               LET RL=RL-1
            END IF
         NEXT i
         IF 0< EL THEN                    !ZRL(16) skip
            IF V01=0 THEN LET V01=-1      !group1( -1, 1)
            LET D2(U0+U(i),V0+V(i),P)=V01*2^Al
         END IF
         LET A_=i
      END IF
   NEXT A_
END SUB

!
Page-2 へ続く
 

整数の組による積の和

 投稿者:山中和義  投稿日:2013年 3月 2日(土)10時21分14秒
  問題
nを任意の正の整数とする。
a≧b≧0、a+2b=n
を満たす整数の組(a,b)のそれぞれに対して、積abを考える。
その積のすべての和をf(n)とすると、f(n)をnの式で表せ。

答え
a≧bなので、n=a+2b≧(1+2)bより、1≦b≦[n/3]である。
Σab
=Σ[B=1,[N/3]](N-2B)B
=NΣ[B=1,[N/3]]B - 2Σ[B=1,[N/3]]B^2
=N{x(x+1)/2} - 2{x(x+1)(2x+1)/6} ただし、x=[N/3]
=x(x+1)(3N-2-4x)/6
または
=( -4x^3+3(N-2)x^2+(3N-2)x )/6
(終り)


FOR N=1 TO 50
   PRINT "N="; N

   LET S=0 !a≧b≧1として考える
   FOR B=1 TO INT( N/(1+2) ) !n=a+2b≧(1+2)bより
      LET A=N-2*B
      IF A< B THEN STOP !論理エラー

      PRINT A;B !題意を満たす
      LET S=S+A*B

   NEXT B
   PRINT "積="; S


   LET X=INT(N/3) !f(n)
   !!PRINT X*(X+1)*(3*N-2-4*X)/6
   PRINT ( -4*X^3+3*(N-2)*X^2+(3*N-2)*X )/6
NEXT N

END



問題
nを任意の正の整数とする。
a≧b≧c≧0、a+2b+3c=n
を満たす整数の組(a,b,c)のそれぞれに対して、積abcを考える。
その積のすべての和をf(n)とすると、f(n)をnの式で表せ。

考察
類題として問題文が展開ができるので、いくつか先を見ていくと、

漸化式を用いて、

FOR n=1 TO 60
   PRINT n;":"; F2(n,INT(n/3)); F3(n,INT(n/6)); F4(n,INT(n/10)); F5(n,INT(n/15))
NEXT n
END

!a+2b=n、a≧b≧0、Σab=Σ[b=1,[n/3]]b*(n-2b)
EXTERNAL FUNCTION F2(n,k) !Σ[i=1,k]i(n-2i)
LET S=0
FOR i=1 TO k
   LET S=S+i*(n-2*i)
NEXT i
LET F2=S
END FUNCTION

!a+2b+3c=n、a≧b≧c≧0、Σabc=Σ[c=1,[n/6]] c*{ Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) }
EXTERNAL FUNCTION F3(n,k)
LET S=0
FOR i=1 TO k
   LET x=n-3*i
   LET S=S+i*(F2(x,INT(x/3)) - F2(x,i-1))
NEXT i
LET F3=S
END FUNCTION

EXTERNAL FUNCTION F4(n,k)
LET S=0
FOR i=1 TO k
   LET x=n-4*i
   LET S=S+i*(F3(x,INT(x/6)) - F3(x,i-1))
NEXT i
LET F4=S
END FUNCTION

EXTERNAL FUNCTION F5(n,k)
LET S=0
FOR i=1 TO k
   LET x=n-5*i
   LET S=S+i*(F4(x,INT(x/10)) - F4(x,i-1))
NEXT i
LET F5=S
END FUNCTION

(終り)


Σabc=Σ[c=1,[n/6]] c*{ Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) } なので、
Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) の部分を、
 a+2b=n の式 f(N)=( -4x^3+3(N-2)x^2+(3N-2)x )/6
のxに、[n/3]-c と c-1 を代入して求めると、


FOR N=1 TO 60
   PRINT "N="; N

   LET S=0 !a≧b≧c≧1として考える
   FOR C=1 TO INT( N/(1+2+3) ) !n=a+2b+3c≧(1+2+3)cより
      FOR B=C TO INT( (N-3*C)/(1+2) ) !n-3c=a+2b≧(1+2)bより
         LET A=N-3*C-2*B
         IF A< B THEN STOP !論理エラー

         PRINT A;B;C !題意を満たす
         LET S=S+A*B*C

      NEXT B
   NEXT C
   PRINT "積="; S


   LET y=INT(N/6) !f(n)
   LET x=INT(N/3)
   PRINT y*(y+1)* ( 16*y^3  +3*(5*x-2)*y^2  +(10*x^2 +5*(5-4*N)*x -14)*y  -5*x*(4*x^2 +(5-3*N)*x -N+1) +4 )/60


NEXT N

END


a+2b+3c+4d=n、a≧b≧c≧d≧0 となると、手計算では難しい。。。

 

Re: 整数の組による積の和

 投稿者:山中和義  投稿日:2013年 3月 4日(月)13時15分20秒
  > No.2993[元記事へ]

> 問題
> nを任意の正の整数とする。
> a≧b≧0、a+2b=n
> を満たす整数の組(a,b)のそれぞれに対して、積abを考える。
> その積のすべての和をf(n)とすると、f(n)をnの式で表せ。

答え
A=a-bとする。a≧bより、A≧0
また、A=(n-2b)-b=n-3b ∴A+3b=n
Σ[a+2b=n,a≧b≧0]ab
=Σ[A+3b=n,A≧0,b≧0](A+b)b
3b=n-A≦nより、b≦n/3なので、
=Σ[1≦b≦[n/3]](A+b)b ただし、A=n-3b
(終り)


FOR N=1 TO 50
   PRINT "N="; N

   LET S=0
   FOR b=1 TO INT(N/3) !b≧1として考える
      LET A=N-3*b
      IF A<0 THEN STOP !論理エラー

      PRINT A;b !題意を満たす
      LET S=S+(A+b)*b

   NEXT b
   PRINT "積=";S
NEXT N

END



別解 母関数
(A+b)b=Ab+b^2なので、項Abと項b^2について考える。
項Abのf(n)に対する寄与をf(n:Ab)と表す。
f(n:Ab)の母関数Σ[k=0,∞]f(k:Ab)*x^kについて
 f(n:Ab)は、
  p[x]=0*1+1*x+2*x^2+3*x^3+4*x^4+5*x^5+6*x^6+7*x^7+ …  =x/(1-x)^2
  q[x]=0*1+1*x^3+2*x^6+3*x^9+4*x^12+5*x^15+6*x^18+7*x^21+ …  =x^3/(1-x^3)^2
 として、積pqを展開したときのx^nの係数になる。
 よって、x/(1-x)^2 * x^3/(1-x^3)^2 をマクローリン展開したときのx^nの係数になる。

同様に
 f(n:b^2)は、
  p[x]=1+x+x^2+x^3+x^4+x^5+x^6+x^7+ … =1/(1-x)
  q[x]=0^2*1+1^2*x^3+2^2*x^6+3^2*x^9+4^2*x^12+5^2*x^15+6^2*x^18+7^2*x^21+ …  =(x^6+x^3)/(1-x^3)^3
 として、積pqを展開したときのx^nの係数になる。
 よって、1/(1-x) * (x^6+x^3)/(1-x^3)^3 をマクローリン展開したときのx^nの係数になる。

したがって、f(n)の母関数は、
Σ[k=0,∞]f(k)*x^k
=x^4/{(1-x)^2(1-x^3)^2} + (x^6+x^3)/{(1-x)(1-x^3)^3}
=x^3(2x^3+x^2+x+1)/{(1-x)(1-x^3)^3}
これをマクローリン展開したときのx^nの係数になる。、
(終り)


!マクローリン展開
! P(x)=P(0)+{P'(0)/1!}x+{P''(0)/2!}x^2+{P'''(0)/3!}x^3+ …
!例
!P(x)=1/(1-x)=1+x+x^2+x^3+x^4+ …
!
!考察
!P(0)は、x=0を代入して、1/(1-0)=1
!P'(0)は、
! P(x)=f(x)/g(x)より、P'=(f'g-fg')/g^2なので、
! 1'(1-x)-1(1-x)'/(1-x)^2=1/(1-x)^2
! x=0を代入して、1
!P''(0)は、
! P''(x)=(P'(x))'なので、
! 上記の結果をあらためて、f(x)=f'g-fg'、g(x)=g^2と考える。上記と同じ議論を繰り返す。
!(終り)

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC N !次数
LET N=50

!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
!「dim a(0 to n) !係数」で定義する
DIM P(0 TO N)
DIM F(0 TO N),G(0 TO N) !p=f/g
MAT F=ZER
MAT G=ZER

DATA 6 !次数 f=x^3(2x^3+x^2+x+1)=2*x^6+x^5+x^4+x^3 ※
DATA 0,0,0,1,1,1,2 !係数 ※展開して次数が小さい方から
READ R
FOR i=0 TO R
   READ F(i)
NEXT i
!!!MAT PRINT F; !debug
CALL poly_disp(F) !多項式を表示する
PRINT

DATA 10 !次数 g=(1-x)(1-x^3)^3=x^10-x^9-3x^7+3x^6+3x^4-3x^3-x+1 ※
DATA 1,-1,0,-3,3,0,3,-3,0,-1,1 !係数 ※展開して次数が小さい方から
READ R
FOR i=0 TO R
   READ G(i)
NEXT i
!!!MAT PRINT G; !debug
CALL poly_disp(G) !多項式を表示する
PRINT


LET P(0)=F(0)/G(0)/FACT(0) !定数項
PRINT 0; P(0) !debug

DIM F1(0 TO N),G1(0 TO N), W1(0 TO N),W2(0 TO N),W3(0 TO N) !作業用
FOR i=1 TO N !i階微分

   CALL poly_diff(F,W3) !f'g
   CALL poly_mul(W3,G, W1)
   !!!MAT PRINT W1; !debug

   CALL poly_diff(G,W3) !fg'
   CALL poly_mul(F,W3, W2)
   !!!MAT PRINT W2; !debug

   CALL poly_sub(W1,W2, F1) !分子 f'g-fg'
   !!!MAT PRINT F1; !debug


   CALL poly_mul(G,G, G1) !分母 g^2
   !!!MAT PRINT G1; !debug


   LET P(i)=F1(0)/G1(0)/FACT(i) !x^iの係数
   PRINT i; P(i) !debug


   MAT F=F1 !次へ
   MAT G=G1
NEXT i

CALL poly_disp(P) !多項式を表示する
PRINT

END


!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
!「dim a(0 to n) !係数」で定義する

!演算関連

EXTERNAL SUB poly_add(v1(),v2(), v()) !加算 v=v1+v2
OPTION ARITHMETIC RATIONAL !有理数モード
MAT v=v1+v2
END SUB

EXTERNAL SUB poly_sub(v1(),v2(), v()) !減算 v=v1-v2
OPTION ARITHMETIC RATIONAL !有理数モード
MAT v=v1-v2
END SUB

EXTERNAL SUB poly_mul(v1(),v2(), v()) !乗算 v=v1*v2
OPTION ARITHMETIC RATIONAL !有理数モード
DIM w(0 TO 2*N) !桁数は2倍になる
MAT w=ZER
FOR i=0 TO N !係数
   FOR j=0 TO N
      LET w(i+j)=w(i+j)+v1(i)*v2(j) !畳み込み
   NEXT j
NEXT i
FOR i=0 TO N !※下n桁をコピーする ※オーバーフローは考慮していない
   LET v(i)=w(i)
NEXT i
END SUB

EXTERNAL SUB poly_diff(v1(), v()) !微分 v=v1'
OPTION ARITHMETIC RATIONAL !有理数モード
FOR i=1 TO N
   LET v(i-1)=v1(i)*i
NEXT i
LET v(N)=0
END SUB


!表示関連

EXTERNAL SUB poly_disp(A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
OPTION ARITHMETIC RATIONAL !有理数モード
CALL mono_disp(A(N),N)
FOR i=N-1 TO 0 STEP -1 !次項
   LET w=A(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 OR N=0 THEN CALL mono_disp(w,i)
NEXT i
END SUB

EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
OPTION ARITHMETIC RATIONAL !有理数モード
IF k<>0 THEN !x^nで
   IF ak=0 OR ak=1 THEN !係数が0,1なら
   ELSEIF ak=-1 THEN !係数が-1なら
      PRINT "-"; !符号
   ELSE
      PRINT STR$(ak);"*";
   END IF
END IF
IF k=0 THEN !次数が0なら
   PRINT STR$(ak);
ELSEIF k=1 THEN !次数が1なら
   PRINT "X";
ELSE
   IF ak<>0 THEN PRINT "X^";STR$(k); !係数が0以外なら
END IF
END SUB

 

Re: 整数の組による積の和

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

> 問題
> nを任意の正の整数とする。
> a≧b≧c≧0、a+2b+3c=n
> を満たす整数の組(a,b,c)のそれぞれに対して、積abcを考える。
> その積のすべての和をf(n)とすると、f(n)をnの式で表せ。

答え
A=a-b、B=b-cとする。a≧b≧cより、A≧0、B≧0
また、A=(n-3c-2b)-b=n-3c-3b=n-3(b-c)-6c=n-3B-6c ∴A+3B+6c=n
Σ[a+2b+3c=n,a≧b≧c≧0]abc
=Σ[A+3B+6c=n,A≧0,B≧0,c≧0](A+B+c)(B+c)c
(終り)


FOR N=1 TO 50
   PRINT "N="; N

   LET S=0
   FOR c=1 TO INT(N/6) !c≧1として考える
      FOR B=0 TO INT((N-6*c)/3) !B≧0として考える
         LET A=N-6*c-3*B
         IF A<0 THEN STOP !論理エラー

         PRINT A;B;c !題意を満たす
         LET S=S+(A+B+c)*(B+c)*c

      NEXT B
   NEXT c
   PRINT "積=";S
NEXT N

END


別解 母関数
(A+B+c)(B+c)c=(AB+B^2)c+(A+2B)c^2+c^3である。
項ABcのf(n)に対する寄与をf(n:ABc)と表す。
変数1a,A,1b,B,B^2,c,c^2,c^3に相当するxの多項式は、
  1a =1+x+x^2+x^3+x^4+x^5+x^6+x^7+ … =1/(1-x)
  A =0*1+1x+2x^2+3x^3+4x^4+5x^5+6x^6+7x^7+ …  =x/(1-x)^2
  1b =1+x^3+x^6+x^9+x^12+x^15+x^18+x^21+ … =1/(1-x^3)
  B =0*1+1x^3+2x^6+3x^9+4x^12+5x^15+6x^18+7x^21+ …  =x^3/(1-x^3)^2
  B^2 =0^2*1+1^2x^3+2^2x^6+3^2x^9+4^2x^12+5^2x^15+6^2x^18+7^2x^21+ …  =(x^6+x^3)/(1-x^3)^3
  c =0*1+1x^6+2x^12+3x^18+4x^24+5x^30+6x^36+7x^42+ …  =x^6/(1-x^6)^2
  c^2 =0^2*1+1^2x^6+2^2x^12+3^2x^18+4^2x^24+5^2x^30+6^2x^36+7^2x^42+ …  =(x^12+x^6)/(1-x^6)^3
  c^3 =0^3*1+1^3x^6+2^3x^12+3^3x^18+4^3x^24+5^3x^30+6^3x^36+7^3x^42+ …  =(x^18+4x^12+x^6)/(1-x^6)^4
である。
f(n:ABc)の母関数Σ[k=0,∞]f(k:ABc)*x^kについて
 f(n:ABc)は、積A*B*cをマクローリン展開したときのx^nの係数になる。
同様に
 f(n:B^2c)は、積1a*B^2*c
 f(n:Ac^2)は、積A*1b*c^2
 f(n:Bc^2)は、積1a*B*c^2
 f(n:c^3)は、積1a*1b*c^3

したがって、f(n)の母関数は、
Σ[k=0,∞]f(k)*x^k
=f(n:ABc) + f(n:B^2c) + f(n:Ac^2) + 2*f(n:Bc^2) + f(n:c^3)
= x/(1-x)^2 * x^3/(1-x^3)^2 * x^6/(1-x^6)^2
 + 1/(1-x) * (x^6+x^3)/(1-x^3)^3 * x^6/(1-x^6)^2
 + x/(1-x)^2 * 1/(1-x^3) * (x^12+x^6)/(1-x^6)^3
 + 2 * { 1/(1-x) * x^3/(1-x^3)^2 * (x^12+x^6)/(1-x^6)^3 }
 + 1/(1-x) * 1/(1-x^3) * (x^18+4x^12+x^6)/(1-x^6)^4
= (6x^20+8x^19+10x^18+12x^17+13x^16+14x^15+17x^14+16x^13+15x^12+8x^11+7x^10+6x^9+3x^8+2x^7+x^6 )
 / { (1-x^3)^2 * (1-x^6)^4 }
これをマクローリン展開したときのx^nの係数になる。、
(終り)

先のマクローリン展開のプログラムでは、DATA文の箇所を、

DATA 20 !次数 f=6x^20+8x^19+10x^18+12x^17+13x^16+14x^15+17x^14+16x^13+15x^12+8x^11+7x^10+6x^9+3x^8+2x^7+x^6
DATA 0,0,0,0,0,0,1,2,3,6,7,8,15,16,17,14,13,12,10,8,6 !係数 ※展開して次数が小さい方から


DATA 30 !次数 g=x^30-2x^27-3x^24+8x^21+2x^18-12x^15+2x^12+8x^9-3x^6-2x^3+1
DATA 1,0,0,-2,0,0,-3,0,0,8,0,0,2,0,0,-12,0,0,2,0,0,8,0,0,-3,0,0,-2,0,0,1 !係数 ※展開して次数が小さい方から

とする。
 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月10日(日)09時40分8秒
  > No.3009[元記事へ]

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

山中さんが作成された下記「マクローリン展開」プログラムを、任意関数P(x)のマクローリン展開に利用したのですが、任意関数を

DEF F(x)=....
DEF G(x)=....
DEF P(x)=F(x)/G(x)

と設定して簡単に使える様にできないでしょうか?

> !マクローリン展開
> ! P(x)=P(0)+{P'(0)/1!}x+{P''(0)/2!}x^2+{P'''(0)/3!}x^3+ …
> !例
> !P(x)=1/(1-x)=1+x+x^2+x^3+x^4+ …
> !
> !考察
> !P(0)は、x=0を代入して、1/(1-0)=1
> !P'(0)は、
> ! P(x)=f(x)/g(x)より、P'=(f'g-fg')/g^2なので、
> ! 1'(1-x)-1(1-x)'/(1-x)^2=1/(1-x)^2
> ! x=0を代入して、1
> !P''(0)は、
> ! P''(x)=(P'(x))'なので、
> ! 上記の結果をあらためて、f(x)=f'g-fg'、g(x)=g^2と考える。上記と同じ議論を繰り返す。
> !(終り)
>
> OPTION ARITHMETIC RATIONAL !有理数モード
>
> PUBLIC NUMERIC N !次数
> LET N=50
>
> !変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
> !「dim a(0 to n) !係数」で定義する
> DIM P(0 TO N)
> DIM F(0 TO N),G(0 TO N) !p=f/g
> MAT F=ZER
> MAT G=ZER
>
> DATA 6 !次数 f=x^3(2x^3+x^2+x+1)=2*x^6+x^5+x^4+x^3 ※
> DATA 0,0,0,1,1,1,2 !係数 ※展開して次数が小さい方から
> READ R
> FOR i=0 TO R
>    READ F(i)
> NEXT i
> !!!MAT PRINT F; !debug
> CALL poly_disp(F) !多項式を表示する
> PRINT
>
> DATA 10 !次数 g=(1-x)(1-x^3)^3=x^10-x^9-3x^7+3x^6+3x^4-3x^3-x+1 ※
> DATA 1,-1,0,-3,3,0,3,-3,0,-1,1 !係数 ※展開して次数が小さい方から
> READ R
> FOR i=0 TO R
>    READ G(i)
> NEXT i
> !!!MAT PRINT G; !debug
> CALL poly_disp(G) !多項式を表示する
> PRINT
>
>
> LET P(0)=F(0)/G(0)/FACT(0) !定数項
> PRINT 0; P(0) !debug
>
> DIM F1(0 TO N),G1(0 TO N), W1(0 TO N),W2(0 TO N),W3(0 TO N) !作業用
> FOR i=1 TO N !i階微分
>
>    CALL poly_diff(F,W3) !f'g
>    CALL poly_mul(W3,G, W1)
>    !!!MAT PRINT W1; !debug
>
>    CALL poly_diff(G,W3) !fg'
>    CALL poly_mul(F,W3, W2)
>    !!!MAT PRINT W2; !debug
>
>    CALL poly_sub(W1,W2, F1) !分子 f'g-fg'
>    !!!MAT PRINT F1; !debug
>
>
>    CALL poly_mul(G,G, G1) !分母 g^2
>    !!!MAT PRINT G1; !debug
>
>
>    LET P(i)=F1(0)/G1(0)/FACT(i) !x^iの係数
>    PRINT i; P(i) !debug
>
>
>    MAT F=F1 !次へ
>    MAT G=G1
> NEXT i
>
> CALL poly_disp(P) !多項式を表示する
> PRINT
>
> END
>
>
> !変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
> !「dim a(0 to n) !係数」で定義する
>
> !演算関連
>
> EXTERNAL SUB poly_add(v1(),v2(), v()) !加算 v=v1+v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> MAT v=v1+v2
> END SUB
>
> EXTERNAL SUB poly_sub(v1(),v2(), v()) !減算 v=v1-v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> MAT v=v1-v2
> END SUB
>
> EXTERNAL SUB poly_mul(v1(),v2(), v()) !乗算 v=v1*v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> DIM w(0 TO 2*N) !桁数は2倍になる
> MAT w=ZER
> FOR i=0 TO N !係数
>    FOR j=0 TO N
>       LET w(i+j)=w(i+j)+v1(i)*v2(j) !畳み込み
>    NEXT j
> NEXT i
> FOR i=0 TO N !※下n桁をコピーする ※オーバーフローは考慮していない
>    LET v(i)=w(i)
> NEXT i
> END SUB
>
> EXTERNAL SUB poly_diff(v1(), v()) !微分 v=v1'
> OPTION ARITHMETIC RATIONAL !有理数モード
> FOR i=1 TO N
>    LET v(i-1)=v1(i)*i
> NEXT i
> LET v(N)=0
> END SUB
>
>
> !表示関連
>
> EXTERNAL SUB poly_disp(A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
> OPTION ARITHMETIC RATIONAL !有理数モード
> CALL mono_disp(A(N),N)
> FOR i=N-1 TO 0 STEP -1 !次項
>    LET w=A(i)
>    IF w>0 THEN PRINT "+";
>    IF w<>0 OR N=0 THEN CALL mono_disp(w,i)
> NEXT i
> END SUB
>
> EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
> OPTION ARITHMETIC RATIONAL !有理数モード
> IF k<>0 THEN !x^nで
>    IF ak=0 OR ak=1 THEN !係数が0,1なら
>    ELSEIF ak=-1 THEN !係数が-1なら
>       PRINT "-"; !符号
>    ELSE
>       PRINT STR$(ak);"*";
>    END IF
> END IF
> IF k=0 THEN !次数が0なら
>    PRINT STR$(ak);
> ELSEIF k=1 THEN !次数が1なら
>    PRINT "X";
> ELSE
>    IF ak<>0 THEN PRINT "X^";STR$(k); !係数が0以外なら
> END IF
> END SUB
>
>
 

Re: 整数の組による積の和

 投稿者:山中和義  投稿日:2013年 3月10日(日)12時28分33秒
  > No.3012[元記事へ]

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

> DEF F(x)=....
> DEF G(x)=....
> DEF P(x)=F(x)/G(x)
> と設定して簡単に使える様にできないでしょうか?

提示したプログラムは、有理式に特化した手法です。
途中で算出される分数は、既約分数ではありませんが、厳密に微分した式になります。
よって、x=0を代入した値は誤差はありません。

一般の関数では、個々の関数に応じて微分しないといけませんので、プログラムは複雑になります。
汎用的な計算では、微分係数などで微分を近似します。したがって、誤差が累積していきます。
中点法、前進法、後退法の1,2,3次などを使えばある程度の精度は保証されますが、期待通りにはなりません。

F(X)=X/(1-X)^2の場合、係数 0,1,2,3,4,5,…

!マクローリン展開にみる数値微分の誤差と計算量 - 再帰呼び出しによるn階微分

LET A=0 !X=0 ※マクローリン展開
LET N=9 !N次近似

DIM c(0 TO N) !係数
LET c(0)=DF(A,0) !f(a)
PRINT c(0)

FOR i=1 TO N
   LET c(i)=DF(A,i)/FACT(i)
   PRINT c(i);"X^";STR$(i)
NEXT i

END


EXTERNAL FUNCTION F(X) !関数
!LET F=SIN(X)
!LET F=COS(X)
!LET F=EXP(X)
LET F=X/(1-X)^2 !0,1,2,3,4,5,…
!LET F=1/(1-X) !1,1,1,1,…
!LET F=(1-X)^4 !1,-4,6,-4,1,0,0,…
END FUNCTION

EXTERNAL FUNCTION DF(x,n) !f(x)のn階微分
IF n>0 THEN !微分係数から求める
   LET h=1/1024
   LET DF=(DF(x+h,n-1)-DF(x,n-1))/h
ELSE
   LET DF=F(x)
END IF
END FUNCTION


実行結果

0
1.00195598975279 X^1
2.00881583539961 X^2
3.02355721412682 X^3
4.04920235221334 X^4
5.08883308900731 X^5
6.14561086632151 X^6
7.22195861264053 X^7
8.4220216127928 X^8
7.07402933721543 X^9



初等関数のように、n階微分がnの一般式で定義できる場合は、精度はかなり保証されます。

F(X)=SIN(X)の場合

!マクローリン展開にみる数値微分の誤差と計算量 - 再帰呼び出しによるn階微分

LET A=0 !X=0 ※マクローリン展開
LET N=9 !N次近似

DIM c(0 TO N) !係数
LET c(0)=DF(A,0) !f(a)
PRINT c(0)

FOR i=1 TO N
   LET c(i)=DF(A,i)/FACT(i)
   PRINT c(i);"X^";STR$(i)
NEXT i

END


EXTERNAL FUNCTION F(X) !関数
LET F=SIN(X)
!LET F=COS(X)
!LET F=EXP(X)
END FUNCTION

EXTERNAL FUNCTION DF(x,n) !f(x)のn階微分
LET DF=SIN(x+n*PI/2) !f(x)=SIN(x)
!LET DF=COS(x+n*PI/2) !f(x)=COS(x)
!LET DF=EXP(x) !f(x)=EXP(x)
END FUNCTION


実行結果

0
1 X^1
2.31321691639751E-19 X^2
-.166666666666667 X^3
-3.85536152732919E-20 X^4
8.33333333333333E-3 X^5
1.9276807636646E-21 X^6
-1.98412698412698E-4 X^7
-4.58971610396332E-23 X^8
2.75573192239859E-6 X^9

 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月10日(日)13時14分8秒
  山中和義さんへのお返事です。

山中さん、早速のご教示有難う御座いました。

山中さんがご教示くださった
「汎用的な計算では、微分係数などで微分を近似する」方法のプログラムにF(x)=sin(x)と設定し出力したマクローリン係数と

「初等関数のように、n階微分がnの一般式で定義できる場合」の方法で出力されたF(x)=sin(x)のマクローリン係数

とを見比べると、x^5までの係数は概ね一致ですが、x^6以上の項では大きな差が出ており、任意関数を数値計算でマクローリン展開する場合は誤差の累積に注意が必要とのことが良く分かりました。
 

Re: 整数の組による積の和

 投稿者:しばっち  投稿日:2013年 3月12日(火)21時50分7秒
  > No.3013[元記事へ]

再帰を使った方法より、下記の方が若干精度がいいようです

EXTERNAL  FUNCTION DF(X,K)
LET H=1/1024
FOR J=0 TO K
   LET  S=S+(-1)^J*COMB(K,J)*F(X+(K/2-J)*H)
NEXT J
LET  DF=S/(H^K)
END FUNCTION

また1000桁モードを使用して、下記のようにすればある程度は使えそうです

OPTION ARITHMETIC DECIMAL_HIGH
PUBLIC NUMERIC H
LET X=0
LET N=9
LET EPS=1E-10 !'計算精度
FOR I=0 TO N
   LET H=1/128
   DO
      LET H=H/2
      LET A=DF1(X,I)
      LET B=DF2(X,I)
   LOOP UNTIL ABS(A - B) < EPS
   LET DF=(A+B)/2
   PRINT DF/FACT(I)
NEXT I
END

EXTERNAL FUNCTION F(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET F=X/(1-X)^2
END FUNCTION

EXTERNAL FUNCTION DF1(X,N)
OPTION ARITHMETIC DECIMAL_HIGH
IF N>0 THEN
   LET DF1=(DF1(X-2*H,N-1)-4*DF1(X-H,N-1)+3*DF1(X,N-1))/(2*H) !'3点前進法
   !'LET DF1=(3*DF1(X-4*H,N-1)-16*DF1(X-3*H,N-1)+36*DF1(X-2*H,N-1)-48*DF1(X-H,N-1)+25*DF1(X,N-1))/(12*H) !'5点前進法
ELSE
   LET DF1=F(X)
END IF
END FUNCTION

EXTERNAL FUNCTION DF2(X,N)
OPTION ARITHMETIC DECIMAL_HIGH
IF N>0 THEN
   LET DF2=(-3*DF2(X,N-1)+4*DF2(X+H,N-1)-DF2(X+2*H,N-1))/(2*H) !'3点後退法
   !'LET DF2=(-25*DF2(X,N-1)+48*DF2(X+H,N-1)-36*DF2(X+2*H,N-1)+16*DF2(X+3*H,N-1)-3*DF2(X+4*H,N-1))/(12*H) !'5点後退法
ELSE
   LET DF2=F(X)
END IF
END FUNCTION
 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月13日(水)09時25分4秒
  > No.3015[元記事へ]

しばっちさんへのお返事です。

しばっちさん、ご教示有難う御座いました。
関数 F(X)=X/(1-X)^2
についてご提示のあった二つのプロ(理屈は理解不能)を実行してみました。
---------------------------------------------------------
> 再帰を使った方法より、下記の方が若干精度がいいようです
---------------------------------------------------------
このプロの場合は結果が
0
1.00000071525602 X^1
2.00000381470259 X^2
3.00001192084544 X^3
4.00002806202375 X^4
5.00015669041249 X^5
6.01465745988539 X^6
24.1746473103899 X^7
-2263.61524295701 X^8
303480.118194826 X^9
となり、X^6の係数までは精度が高かったですが、X^7以降の係数は当てにならない結果でした。演算時間は速いので6次(必ずそう言えるか不明な点が気になるが)以下の係数には使えるようです。

----------------------------------------------------------------------
> また1000桁モードを使用して、下記のようにすればある程度は使えそうです
----------------------------------------------------------------------
上記2番目のプロは、9次までの係数が極めて高い精度で得られたので、幾らの次数まで正しい値かということを意識せず?に使えそうです。
ただし、私のコンピュータは遅い(AMD-AthlonXP2200+ 2.2GHz相当)ので8次以上の結果が出るまで5~6分必要としました。
 

Re: 整数の組による積の和

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

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

5次程度なら、次の連立方程式を解けば求まります。


!マクローリン展開
!f(x)=f(0)+{f'(0)/1!}x+{f''(0)/2!}x^2+{f'''(0)/3!}x^3+ …
!    =f(0)+a[1]x+a[2]x^2+a[3]x^3+a[4]x^4+ …

!DEF F(X)=SIN(X)
!DEF F(X)=COS(X)
!DEF F(X)=EXP(X)
DEF F(X)=X/(1-X)^2 !0,1,2,3,4,5,…
!DEF F(X)=1/(1-X) !1,1,1,1,1,…
!DEF F(x)=(1-X)^4 !1,-4,6,-4,1,0,0,…


LET N=9 !次数

!A=
!  x   x^2   x^3    x^4 …
! 2x  4x^2  8x^3  16x^4 …
! 3x  9x^2 27x^3  81x^4 …
! 4x 16x^2 64x^3 256x^4 …
!   :

LET x=1E-3 !x≒0

DIM A(N,N)
FOR i=1 TO N
   FOR J=1 TO N
      LET A(i,J)=(i*x)^J
   NEXT J
NEXT i
!!!MAT PRINT A; !debug

!b=
! f( x)-f(0)
! f(2x)-f(0)
! f(3x)-f(0)
! f(4x)-f(0)
!   :
DIM b(N)
LET F0=F(0)
FOR i=1 TO N
   LET b(i)=F(i*x)-F0
NEXT i

DIM p(N),iA(N,N) !連立方程式Ap=bを解く
MAT iA=INV(A)
MAT p=iA*b

PRINT F(0) !各係数 定数項
MAT PRINT p; !x,x^2,x^3,…の項

END


実行結果

0
1.00000000000017  1.99999999953607  3.00000058623451  3.999024242  5.03640518 -18.75867688  1689.07931105014 -130559.084358461  2609878


 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月14日(木)13時16分45秒
  山中和義さんへのお返事です。

山中さん、度重なるご教示有難う御座いました。

> 5次程度なら、次の連立方程式を解けば求まります。

上記プログラムの考え方も記載して頂き、私の頭でも「なるほどな~」と良く分かる計算法で感心するばかりでした。

コード中に「x=1E-3 !x≒0」の箇所が有りましたが、x=1E-2、x=1E-4、等と変えてみましたが、xを小さくすれば精度が上がると言う事でもない様ですね。
(この「x=1E-3 !x≒0」は「行列Aの高次係数が大きくなり過ぎない様にする為」という理由でしょうか?)

さてこのプログラムで「F(X)=X/(1-X)^2」を、x=1E-3のまま1000桁モードで計算させたら瞬時に9次までの高精度結果が得られました。難解な数値計算理論を使っていないのに、この方法は凄いですね。





 

Re: 整数の組による積の和

 投稿者:山中和義  投稿日:2013年 3月14日(木)14時20分0秒
  > No.3018[元記事へ]

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

> コード中に「x=1E-3 !x≒0」の箇所が有りましたが、x=1E-2、x=1E-4、等と変えてみましたが、xを小さくすれば精度が上がると言う事でもない様ですね。

1E-3あたりが実用値でしょう。


> (この「x=1E-3 !x≒0」は「行列Aの高次係数が大きくなり過ぎない様にする為」という理由でしょか?)

提示したプログラムは、X=x,2x,3x,…を代入して、これを満たす補間多項式を得ます。
x=0は、0を代入するのですが、x^kがすべて0になって、行列Aが成り立ちません。

Xは、テイラー展開におけるX=aと考えることもできます。
このことは、プログラムの最後に、

!F(x)の値
LET S=F(0)
FOR i=1 TO N
   LET S=S+p(i)*x^i
NEXT i
PRINT S; F(x)

を追加して、
先頭部分の関数定義とXの値を(別の関数と値でよいのですが)、

 DEF F(X)=SIN(X)

 LET x=PI/3

と変更して、確認できます。

 

Re: 整数の組による積の和

 投稿者:しばっち  投稿日:2013年 3月14日(木)21時36分13秒
  高階微分の計算に時間がかかるのは、再帰ルーチン内で多重呼び出しを行っているためです
これを直接(10階微分まで)求めるようにすれば速くなります
(精度については注意を払う必要がある)

OPTION ARITHMETIC DECIMAL_HIGH
PUBLIC NUMERIC H
LET X=0
LET EPS=1E-20 !'精度
FOR I=1 TO 10
   LET H=1/2^10
   DO
      LET H=H/2
      SELECT CASE I
      CASE 1
         LET A=(-25*F(X)+48*F(X+H)-36*F(X+2*H)+16*F(X+3*H)-3*F(X+4*H))/(12*H)
         LET B=(3*F(X-4*H)-16*F(X-3*H)+36*F(X-2*H)-48*F(X-H)+25*F(X))/(12*H)
      CASE 2
         LET A=(F(X)-2*F(X+H)+F(X+2*H))/(H^2)
         LET B=(F(X-2*H)-2*F(X-H)+F(X))/(H^2)
      CASE 3
         LET A=(-49*F(X)+232*F(X+H)-461*F(X+2*H)+496*F(X+3*H)-307*F(X+4*H)+104*F(X+5*H)-15*F(X+6*H))/(8*H^3)
         LET B=(15*F(X-6*H)-104*F(X-5*H)+307*F(X-4*H)-496*F(X-3*H)+461*F(X-2*H)-232*F(X-H)+49*F(X))/(8*H^3)
      CASE 4
         LET A=(F(X)-4*F(X+H)+6*F(X+2*H)-4*F(X+3*H)+F(X+4*H))/(H^4)
         LET B=(F(X-4*H)-4*F(X-3*H)+6*F(X-2*H)-4*F(X-H)+F(X))/(H^4)
      CASE 5
         LET A=(-81*F(X)+575*F(X+H)-1790*F(X+2*H)+3195*F(X+3*H)-3580*F(X+4*H)+2581*F(X+5*H)-1170*F(X+6*H)+305*F(X+7*H)-35*F(X+8*H))/(6*H^5)
         LET B=(35*F(X-8*H)-305*F(X-7*H)+1170*F(X-6*H)-2581*F(X-5*H)+3580*F(X-4*H)-3195*F(X-3*H)+1790*F(X-2*H)-575*F(X-H)+81*F(X))/(6*H^5)
      CASE 6
         LET A=(F(X)-6*F(X+H)+15*F(X+2*H)-20*F(X+3*H)+15*F(X+4*H)-6*F(X+5*H)+F(X+6*H))/(H^6)
         LET B=(F(X-6*H)-6*F(X-5*H)+15*F(X-4*H)-20*F(X-3*H)+15*F(X-2*H)-6*F(X-H)+F(X))/(H^6)
      CASE 7
         LET A=(-605*F(X)+5628*F(X+H)-23583*F(X+2*H)+58632*F(X+3*H)-95802*F(X+4*H)+107520*F(X+5*H)-83958*F(X+6*H)+45048*F(X+7*H)-15897*F(X+8*H)+3332*F(X+9*H)-315*F(X+10*H))/(24*H^7)
         LET B=(315*F(X-10*H)-3332*F(X-9*H)+15897*F(X-8*H)-45048*F(X-7*H)+83958*F(X-6*H)-107520*F(X-5*H)+95802*F(X-4*H)-58632*F(X-3*H)+23583*F(X-2*H)-5628*F(X-H)+605*F(X))/(24*H^7)
      CASE 8
         LET A=(F(X)-8*F(X+H)+28*F(X+2*H)-56*F(X+3*H)+70*F(X+4*H)-56*F(X+5*H)+28*F(X+6*H)-8*F(X+7*H)+F(X+8*H))/(H^8)
         LET B=(F(X-8*H)-8*F(X-7*H)+28*F(X-6*H)-56*F(X-5*H)+70*F(X-4*H)-56*F(X-3*H)+28*F(X-2*H)-8*F(X-H)+F(X))/(H^8)
      CASE 9
         LET A=(-169*F(X)+1932*F(X+H)-10128*F(X+2*H)+32196*F(X+3*H)-69129*F(X+4*H)+105624*F(X+5*H)-117768*F(X+6*H)+96552*F(X+7*H)-57771*F(X+8*H)+24604*F(X+9*H)-7080*F(X+10*H)+1236*F(X+11*H)-99*F(X+12*H))/(4*H^9)
         LET B=(99*F(X-12*H)-1236*F(X-11*H)+7080*F(X-10*H)-24604*F(X-9*H)+57771*F(X-8*H)-96552*F(X-7*H)+117768*F(X-6*H)-105624*F(X-5*H)+69129*F(X-4*H)-32196*F(X-3*H)+10128*F(X-2*H)-1932*F(X-H)+169*F(X))/(4*H^9)
      CASE 10
         LET A=(F(X)-10*F(X+H)+45*F(X+2*H)-120*F(X+3*H)+210*F(X+4*H)-252*F(X+5*H)+210*F(X+6*H)-120*F(X+7*H)+45*F(X+8*H)-10*F(X+9*H)+F(X+10*H))/(H^10)
         LET B=(F(X-10*H)-10*F(X-9*H)+45*F(X-8*H)-120*F(X-7*H)+210*F(X-6*H)-252*F(X-5*H)+210*F(X-4*H)-120*F(X-3*H)+45*F(X-2*H)-10*F(X-H)+F(X))/(H^10)
      END SELECT
   LOOP UNTIL ABS(A - B) < EPS
   LET DF=(A+B)/2
   PRINT DF/FACT(I)
NEXT I
END

EXTERNAL FUNCTION F(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET F=X/(1-X)^2
END FUNCTION
 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月15日(金)16時25分44秒
  > No.3019[元記事へ]

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

山中さん、ご教示有難うございます。

> Xは、テイラー展開におけるX=aと考えることもできます。

ご指示頂いた様に、x=1E-3ではなく、x=pi/3と設定しF(x)=sin(x)について確認しましたら、ご教示のとおりになりました。
上記「Xはテーラー展開における・・・」の意味は下記で解釈すると納得出来たのですが誤りでしょうか?

X=aの近傍X=a+hに於けるF(a+h)はテイラー展開によって
  F(a+h)=F(a)+F'(a)*h+F''(a)*h^2/2!+・・・
だから、これを
  F(a+h)-F(a)=F'(a)*h+F''(a)*h^2/2!+・・・
と変形して「a=0,h=pi/3」と置けば、「多元連立式[A][p]=[b]を[p]について解きマクローリン係数を求めるプログラム」を利用してF(pi/3)が得られる。
 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月16日(土)14時48分27秒
  > No.3020[元記事へ]

しばっちさんへのお返事です。

> 高階微分の計算に時間がかかるのは、再帰ルーチン内で多重呼び出しを行っているためです
> これを直接(10階微分まで)求めるようにすれば速くなります
> (精度については注意を払う必要がある)

ご教示頂いたコードを走らせて、瞬時に結果が得られることを確認しました。
どうも有難うございました。
 

マクローリン展開(テイラー展開)

 投稿者:山中和義  投稿日:2013年 3月16日(土)15時40分51秒
  > No.3021[元記事へ]

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

> Xは、テイラー展開におけるX=aと考えることもできます。

申し訳ありません。誤解を招く言い方になりました。
べき級数(x^kの和、多項式)で補間(近似)しているので、f(a)は求まるのは当然ですね。
これについての記述は取り下げます。


テイラー展開を考えると、プログラムは次のようになりますね。


!テイラー展開
!f(x)=c0 + c1(x-a) + c2(x-a)^2 + c3(x-a)^3 + c4(x-a)^4 + …

!参考サイト http://www.ice.tohtech.ac.jp/~nakagawa/taylorexp/taylor5.htm

!f(x)=1/(x+9)をx=1の周りでテイラー展開しなさい。
DEF F(X)=1/(X+9)

LET N=10 !次数
LET A=1 !3 !x=aの周り

LET x=1E-3 !⊿x≒0 ※1E-2、1E-4

!P=
!  x   x^2   x^3    x^4 …
! 2x  4x^2  8x^3  16x^4 …
! 3x  9x^2 27x^3  81x^4 …
! 4x 16x^2 64x^3 256x^4 …
!   :

DIM P(N,N)
FOR i=1 TO N
   FOR J=1 TO N
      LET P(i,J)=(i*x)^J
   NEXT J
NEXT i
!!!MAT PRINT P; !debug

!q=
! f(a+ x)-f(a)
! f(a+2x)-f(a)
! f(a+3x)-f(a)
! f(a+4x)-f(a)
!   :

DIM q(N)
LET FA=F(A)
FOR i=1 TO N
   LET q(i)=F(A+i*x)-FA
NEXT i
!!!MAT PRINT q; !debug


DIM c(N),W(N,N) !連立方程式Pc=qを解く
MAT W=INV(P)
MAT c=W*q


PRINT FA !各係数 定数項
MAT PRINT c; !(x-a),(x-a)^2,(x-a)^3,…の項

END

 

Re: マクローリン展開(テイラー展開)

 投稿者:島村1243  投稿日:2013年 3月16日(土)20時18分46秒
  山中和義さんへのお返事です。

> > Xは、テイラー展開におけるX=aと考えることもできます。
>
> べき級数(x^kの和、多項式)で補間(近似)しているので、f(a)は求まるのは当然ですね。
> これについての記述は取り下げます。
> テイラー展開を考えると、プログラムは次のようになりますね。

山中さん、大変良く分かりました。
マクローリン級数やテイラー展開の係数を、「多元一次連立方程式で求める」と言う発想が素晴らしいと思いました。
ご教示有難うございました。(完)
 

合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月24日(日)18時54分0秒
  電気回路の問題というより、数学の問題です。

問題
抵抗値が1Ωの抵抗がたくさんある。
この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

考察
合成抵抗の公式
 直列 R1+R2+R3+ … +Rn
 並列 1/(1/R1+1/R2+1/R3+ … +1/Rn)

仮分数A/Bを考える。それを帯分数にして、真分数の部分を単位分数で表す。
A/B=K+a/B=K+(1/b1+1/b2+1/b3+ … +1/bm)
※K個の直列、b1個の並列、b2個の並列、b3個の並列、…、bm個の並列
個数は、(K+b1+b2+b3+ … +bm)個

単位分数は、エジプト分数を使う。 参考プログラム Mathフォルダ内 EGYPT.BAS

例 3/2の場合
 3/2=1+1/2より、
  ─R┬R┬
    └R┘
のように接続する。

例 2/3の場合
 2/3=1/3+1/3=1/2+1/6 のように一通りではない。

また、2/3=1/(1/1+1/2)なので、上記の3/2の並びを縦に見て、
  ├┐
  R R
  ││
  │ R
  ├┘
がその逆数の値の接続となる。

2/3のように個数を減らすには、仮分数で考えた方がよい。
(終り)

●n個のときの接続パターン(場合の数)
分割数(自然数を1以上の自然数の和で表すことを考える。ただし、順序は問わない)を利用する。

例 4個の場合
 4
 3+1
 2+2
 2+1+1
 1+1+1+1
なので、
 ─R─R─R─R─

 ┬R┬R┬R┬
 └R─

 ┬R┬R┬
 └R┬R─

 ┬R┬R┬
 ├R┬
 └R─

 ┬R┬
 ├R┬
 ├R┬
 └R─
を得る。

┬ の解釈

     ↑上の段の縦線(┬)への接続
  ┬ ┘
  ↑下の段の横線(─、┬)からの接続

 結線が交差しない(包含する)ように、さらに上の段へ接続できる。(※1を参照のこと)
 自分の位置より左側の位置とは、接続できない。(※2を参照のこと)

に注意して、

─R─R─R─R─ の解釈は、─R─R─R─R─

┬R┬R┬R┬ の解釈は、
└R─

 ┬R ─┬R┬R┬
 │    ↑   ×3
 └R─ ┘

┬R┬R┬ の解釈は、
└R┬R─

 ┬R┬R ─┬      ┬R┬R ─┬
 │       ↑ ※2    │ ↑    ↑
 └R┬R─ ┘      └R┴R─ ┘

┬R┬R┬ の解釈は、
├R┬
└R─

 ┬R ──┬R┬     ┬R ─┬R┬
 │      ↑  ×2   │    ↑ ↑
 ├R─ ┬┘       ├R─ ┘ ↑ ※1
 │    ↑        │       ↑
 └R─ ┘        └R ── ┘

┬R┬ の解釈は、
├R┬
├R┬
└R─

 ┬R─── ┬
 │        ↑
 ├R── ┬┘
 │      ↑
 ├R─ ┬┘
 │    ↑
 └R─ ┘

以上、10通り
具体的な値は、4,  5/2, 5/3, 3/4,  1, 1,  4/3, 2/5, 3/5,  1/4

1,2,3,4,5,…個で 1,2,4,10,24,…通り  参考サイト http://oeis.org/A000084
(終り)


LET N=4 !非負の整数

PUBLIC NUMERIC A(50) !※50は、Nの最大値
MAT A=ZER

PUBLIC NUMERIC HEIGHT !段数
FOR HEIGHT=1 TO N
   CALL print_young(HEIGHT,N,N)
NEXT HEIGHT

END


EXTERNAL SUB print_young(d,n,c) !ヤング図形を表示する
IF d>0 THEN
   LET upper=n-d+1
   LET lower=INT((n-1)/d)+1
   FOR i=MIN(c,upper) TO lower STEP -1
      LET A(HEIGHT-d+1)=i
      CALL print_young(d-1,n-i,i) !次へ
   NEXT i
ELSE !揃ったら
   MAT PRINT A; !debug
   CALL connect(1,A)
END IF
END SUB


EXTERNAL SUB connect(P,A()) !p段目を表示する
!左端の分岐
LET W=A(P+1) !次の段の有無
IF P=1 THEN !1段目なら
   IF W>0 THEN PRINT "┬"; ELSE PRINT "─";
ELSE !2段目以降
   IF W>0 THEN PRINT "├"; ELSE PRINT "└";
END IF

FOR i=1 TO A(P) !各抵抗への接続位置
   IF W=0 AND (P=1 OR i=A(P)) THEN PRINT "R─"; ELSE PRINT "R┬";
NEXT i
PRINT

IF W>0 THEN CALL connect(P+1,A) !次の段へ
END SUB

 

LOGでエラー

 投稿者:島村1243  投稿日:2013年 3月25日(月)13時55分24秒
  取り消します。  

Re: 合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月25日(月)19時15分4秒
  > No.3025[元記事へ]

> 問題
> 抵抗値が1Ωの抵抗がたくさんある。
> この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

特別な場合は、簡単に生成できるようです。

n=5の場合
分割数を考える。
 5
 4+1
 3+2
 3+1+1
 2+2+1
 2+1+1+1
 1+1+1+1+1
より、

5から、
 No. 1
 ─R─R─R─R─

4+1から、
 No. 1
 ┬R┬R┬R┬R┬
 └R┘

 No. 2
 ┬R─R┬R┬R┬
 └   R┘

 No. 3
 ┬R─R─R┬R┬
 └      R┘

 No. 4
 ┬R─R─R─R┬
 └         R┘

3+2から、
 No. 1       No. 3
 ┬R┳R┬R┬   ┬R┳R┬R┬
 │    │     │ ┃ │
 └R┻R┘     └R┻R┘

 No. 2       No. 4
 ┬R┳R┬R┬   ┬R┳R┬R┬
 │       │   │ ┃    │
 └R┻R   ┘   └R┻R   ┘


3+1+1から、
 No. 1
 ┬R┬R┬R┬
 ├R┤
 └R┘

 No. 2
 ┬R┬R┬R┬
 ├R┘
 └   R┘

 No. 3
 ┬R┬R┬R┬
 ├R┘
 └      R┘

 No. 4
 ┬R─R┬R┬
 ├   R┤
 └   R┘

 No. 5
 ┬R─R┬R┬
 ├   R┘
 └      R┘

 No. 6
 ┬R─R─R┬
 ├      R┤
 └      R┘

2+2+1から、
 2+1として、
  No. 1
  ┬R┬R┬
  └R┘

  No. 2
  ┬R─R┬
  └   R┘
 を得る。
 1段目の前に、┬R┳R┬ を追加して、これへの接続の有無を考える。
 No. 1    No. 3
 ┬R┳R┬  ┬R┳R┬
 │    │  │ ┃ │
 ├R╋R┤  ├R╋R┤
 └R┘     └R┘

 No. 2    No. 4
 ┬R┳R┬  ┬R┳R┬
 │    │  │ ┃ │
 ├R╋R┤  ├R╋R┤
 └   R┘  └   R┘


2+1+1+1から、
 No. 1
 ┬R┬R┬
 ├R┤
 ├R┤
 └R┘

 No. 2
 ┬R┬R┬
 ├R┤
 ├R┘
 └   R┘

 No. 3
 ┬R┬R┬
 ├R┘
 ├   R┤
 └   R┘

 No. 4
 ┬R─R┬
 ├   R┤
 ├   R┤
 └   R┘

1+1+1+1+1から、
 No. 1
 ┬R┬
 ├R┤
 ├R┤
 ├R┤
 └R┘

以上より、1+4+4+6+4+4+1=24通り


●n,1,1,…,1形式
 └  m個  ┘


LET M=3 !段数m ※2以上
LET N=3 !n

DIM B(M+1) !各段の配置位置
MAT B=(N+1)*CON

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(2,M,B,1,N)

END


EXTERNAL SUB try(P,M,B(),R,L)
FOR i=R TO L !配置位置の候補 ※ひとつ上の段の右側へ
   LET B(P)=i

   IF P<M THEN !次の段があれば
      CALL try(P+1,M,B,i,L)
   ELSE !結果を表示する
      LET C=C+1
      PRINT "No."; C

      PRINT "┬"; !1段目
      FOR J=1 TO L
         IF B(2)>J THEN PRINT "R─"; ELSE PRINT "R┬";
      NEXT J
      PRINT

      !!!MAT PRINT B; !debug
      FOR J=2 TO M !2段目以降
         IF J=M THEN PRINT "└"; ELSE PRINT "├"; !左端
         PRINT REPEAT$(" ",3*(B(J)-1));
         IF B(J+1)>B(J) THEN PRINT "R┘" ELSE PRINT "R┤"
      NEXT J
      PRINT
   END IF
NEXT i
END SUB


●n,n,…,n,1,1,…,1形式
 └ p個 ┘

n,1,1,…,1形式をs通りとすると、2^{(p-1)(n-1)}×s通り

 

Re: 合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月26日(火)11時26分45秒
  > No.3027[元記事へ]

> 問題
> 抵抗値が1Ωの抵抗がたくさんある。
> この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

式で接続形態を表すことにする。 + は直列、/ は並列 を表すとする。

 ─R┬R┬  式 R+R/R
   └R┘


OPTION ARITHMETIC RATIONAL !有理数

DEF s(a,b)=a+b !直列
DEF p(a,b)=a*b/(a+b) !並列 ∵1/(1/a+1/b)より
LET R=1 !1Ω

!●5より
!式 R+R+R+R
! ─R─R─R─
PRINT s(s(s(R,R),R),R)


!●4+1より
!式 R/R+R+R
! ┬R┬R┬R┬
! └R┘
PRINT s(s(p(R,R),R),R)

!(R+R)/R+R
! ┬R─R ┬R┬
! └R──┘
PRINT s(p(s(R,R),R),R)

!式 (R+R+R)/R
! ┬R─R─R┬
! └R───┘
PRINT p(s(s(R,R),R),R)


!●2+2より
!式 (R+R)/(R+R)
! ┬R─R┬
! └R─R┘
PRINT p(s(R,R),s(R,R))

!式 R/R+R/R
! ┬R┬R┬
! └R┴R┘
PRINT s(p(R,R),p(R,R))


!●2+1+1より
!式 R/R/R+R
! ┬R┬R┬
! ├R┤
! └R┘
PRINT s(p(p(R,R),R),R)

!式 (R/R+R)/R
! ┬R┬R┬
! ├R┘
! └   R┘
PRINT p(s(p(R,R),R),R)

!式 (R+R)/R/R
! ┬R┬R┬
! ├   R┘
! └   R┘
PRINT p(p(s(R,R),R),R)


!●1+1+1+1より
!式 R/R/R/R
! ┬R┬
! ├R┤
! ├R┤
! └R┘
PRINT p(p(p(R,R),R),R)

END


実行結果 4個の場合(10通り)

4
5/2
5/3
3/4
1
1
4/3
3/5
2/5
1/4


逆数どうしの組が現れる。

 

Re: 合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月27日(水)12時47分26秒
  > No.3028[元記事へ]

> 問題
> 抵抗値が1Ωの抵抗がたくさんある。
> この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

今までみてきた「分割数と右スライド」方式から展開してみました。

考察
分割数から左端を固定した並列を列挙する。
例 6の場合
 6, 5+1, 4+2, 4+1+1, …

例 4+2の場合
 ┬R┬R┬R┬R┬
 └R┴R┘
なので、各抵抗どうしの接続の組み合わせを考える。

1段目を並べる。
 ┬R┬R┬R┬R┬

2段目以降は、ひとつ上の段と左端を揃えるように、
隙間がない状態で並べる。
 ┬R┬R┬R┬R┬    (R+R)/(R+R)+R+R  R/R+R/R+R+R
 └R┻R┘    ×2

末尾を右へずらす。
 ┬R┬R┬R┬R┬    (R+R+R)/(R+R)+R  R/R+(R+R)/R+R
 └R┻   R┘   ×2

 ┬R┬R┬R┬R┬    (R+R+R+R)/(R+R)  R/R+(R+R+R)/R
 └R┻      R┘ ×2

次に、1個分の隙間にした状態で並べる。
ただし、上の段への接続は「接続」の状態とする。
 ┬R┬R┬R┬R┬    (R+R)/R+(R+R)/R
 └   R┴   R┘
    ↑

末尾を右へずらす。(この場合はない!)

次に、2個分の隙間にした状態で並べる。(この場合はない!)
末尾を右へずらす。
  :
  :
なければ、次の段へ進む。

以上を(再帰的に)繰り返す。
(終り)

6個の場合、66通り

OPTION ARITHMETIC RATIONAL !有理数

DEF s(a,b)=a+b !直列
DEF p(a,b)=a*b/(a+b) !並列 ∵1/(1/a+1/b)より
LET R=1 !1Ω


!●6
!No. 1
!─R─R─R─R─R─R─  R+R+R+R+R+R
PRINT s(s(s(s(s(R,R),R),R),R),R)

PRINT


!●5+1
!No. 1
!┬R┬R┬R┬R┬R┬  R/R+R+R+R+R
!└R┘
PRINT s(s(s(s(p(R,R),R),R),R),R)

!No. 2
!┬R─R┬R┬R┬R┬  (R+R)/R+R+R+R
!└   R┘
PRINT s(s(s(p(s(R,R),R),R),R),R)

!No. 3
!┬R─R─R┬R┬R┬  (R+R+R)/R+R+R
!└      R┘
PRINT s(s(p(s(s(R,R),R),R),R),R)

!No. 4
!┬R─R─R─R┬R┬  (R+R+R+R)/R+R
!└         R┘
PRINT s(p(s(s(s(R,R),R),R),R),R)

!No. 5
!┬R─R─R─R─R┬  (R+R+R+R+R)/R
!└            R┘
PRINT p(s(s(s(s(R,R),R),R),R),R)

PRINT


!●4+2
!No. 1
!┬R┬R┬R┬R┬    (R+R)/(R+R)+R+R  R/R+R/R+R+R
!└R┻R┘    ×2
PRINT s(s(p(s(R,R),s(R,R)),R),R)
PRINT s(s(s(p(R,R),p(R,R)),R),R)

!No. 2
!┬R┬R─R┬R┬    (R+R+R)/(R+R)+R  R/R+(R+R)/R+R
!└R┻   R┘   ×2
PRINT s(p(s(s(R,R),R),s(R,R)),R)
PRINT s(s(p(R,R),p(s(R,R),R)),R)

!No. 3
!┬R┬R─R─R┬    (R+R+R+R)/(R+R)  R/R+(R+R+R)/R
!└R┻      R┘ ×2
PRINT p(s(s(s(R,R),R),R),s(R,R))
PRINT s(p(R,R),p(s(s(R,R),R),R))

!No. 7
!┬R─R┬R┬R┬  (R+R)/R+(R+R)/R
!│    ┃    │
!└   R┻   R┘

PRINT s(p(s(R,R),R),p(s(R,R),R))

PRINT


!●3+3+3
!No. 1
!┬R┬R┬R┬  (R+R+R)/(R+R+R)
!│     │
!└R┻R┻R┘
PRINT p(s(s(R,R),R),s(s(R,R),R))

!No. 2
!┬R┬R┬R┬  R/R+(R+R)/(R+R)
!│ ┃  │
!└R┻R┻R┘
PRINT s(p(R,R),p(s(R,R),s(R,R)))

!No. 3
!┬R┬R┬R┬  R/R+R/R+R/R
!│ ┃ ┃ │
!└R┻R┻R┘
PRINT s(s(p(R,R),p(R,R)),p(R,R))

PRINT


!●4+1+1
!No. 1
!┬R┬R┬R┬R┬  R/R/R+R+R+R
!├R┤
!└R┘
PRINT s(s(s(p(p(R,R),R),R),R),R)

!No. 2
!┬R┬R┬R┬R┬  (R/R+R)/R+R+R
!├R┘
!└   R┘
PRINT s(s(p(s(p(R,R),R),R),R),R)

!No. 3
!┬R┬R┬R┬R┬  (R/R+R+R)/R+R
!├R┘
!└      R┘
PRINT s(p(s(s(p(R,R),R),R),R),R)

!No. 4
!┬R┬R┬R┬R┬  (R/R+R+R+R)/R
!├R┘
!└         R┘
PRINT p(s(s(s(p(R,R),R),R),R),R)

!No. 5
!┬R─R┬R┬R┬  (R+R)/R/R+R+R
!├   R┤
!└   R┘
PRINT s(s(p(p(s(R,R),R),R),R),R)

!No. 6
!┬R─R┬R┬R┬  ((R+R)/R+R)/R+R
!├   R┘
!└      R┘
PRINT s(p(s(p(s(R,R),R),R),R),R)

!No. 7
!┬R─R┬R┬R┬  ((R+R)/R+R+R)/R
!├   R┘
!└         R┘
PRINT p(s(s(p(s(R,R),R),R),R),R)

!No. 8
!┬R─R─R┬R┬  (R+R+R)/R/R+R
!├      R┤
!└      R┘
PRINT s(p(p(s(s(R,R),R),R),R),R)

!No. 9
!┬R─R─R┬R┬  ((R+R+R)/R+R)/R
!├      R┘
!└         R┘
PRINT p(s(p(s(s(R,R),R),R),R),R)

!No. 10
!┬R─R─R─R┬  (R+R+R+R)/R/R
!├         R┤
!└         R┘
PRINT p(p(s(s(s(R,R),R),R),R),R)

PRINT


!●3+2+1
!No. 1
!┬R┬R┬R┬    (R+R)/(R/R+R)+R  R/R/R+R/R+R
!├R┻R┘  ×2
!└R┘
PRINT s(p(s(R,R),s(p(R,R),R)),R)
PRINT s(s(p(p(R,R),R),p(R,R)),R)

!No. 2
!┬R┬R┬R┬    (R+R)/(R+R)/R+R  (R/R+R/R)/R+R
!├R┻R┤  ×2
!└   R┘
PRINT s(p(p(s(R,R),s(R,R)),R),R)
PRINT s(p(s(p(R,R),p(R,R)),R),R)

!No. 3
!┬R┬R┬R┬    ((R+R)/(R+R)+R)/R  (R/R+R/R+R)/R
!├R┻R┘  ×2
!└      R┘
PRINT p(s(p(s(R,R),s(R,R)),R),R)
PRINT p(s(s(p(R,R),p(R,R)),R),R)

!No. 4
!┬R┬R─R┬    (R+R+R)/(R/R+R)  R/R/R+(R+R)/R
!├R┻   R┤ ×2
!└R┘
PRINT p(s(s(R,R),R),s(p(R,R),R))
PRINT s(p(p(R,R),R),p(s(R,R),R))

!No. 5
!┬R┬R─R┬    (R+R+R)/(R+R)/R  (R/R+(R+R)/R)/R
!├R┻   R┘ ×2
!└      R┘
PRINT p(p(s(s(R,R),R),s(R,R)),R)
PRINT p(s(p(R,R),p(s(R,R),R)),R)

!No. 7
!┬R┬R┬R┬    (R/R+R+R)/(R+R)  (R/R+R)/R+R/R
!├R┘
!└   R┻R┘   ×2

PRINT p(s(s(p(R,R),R),R),s(R,R))
PRINT s(p(s(p(R,R),R),R),p(R,R))

!No. 8
!┬R┬R┬R┬    ((R+R)/R+R)/(R+R)  (R+R)/R/R+R/R
!├   R┘
!└   R┻R┘   ×2

PRINT p(s(p(s(R,R),R),R),s(R,R))
PRINT s(p(p(s(R,R),R),R),p(R,R))

PRINT


!●2+2+2
!No. 1
!┬R┬R┬  (R+R)/(R+R)/(R+R)
!│    │
!├R┻R┤
!│    │
!└R┻R┘
PRINT p(p(s(R,R),s(R,R)),s(R,R))

!No. 2
!┬R┬R┬  (R/R+R/R)/(R+R)
!│ ┃ │
!├R┻R┤
!│    │
!└R┻R┘
PRINT p(s(p(R,R),p(R,R)),s(R,R))

!No. 3
!┬R┬R┬  (R/R/R)+(R/R/R)
!│ ┃ │
!├R╋R┤
!│ ┃ │
!└R┻R┘
PRINT s(p(p(R,R),R),p(p(R,R),R))

PRINT


!●3+1+1+1
!No. 1
!┬R┬R┬R┬  R/R/R/R+R+R
!├R┤
!├R┤
!└R┘
PRINT s(s(p(p(p(R,R),R),R),R),R)

!No. 2
!┬R┬R┬R┬  (R/R/R+R)/R+R
!├R┤
!├R┘
!└   R┘
PRINT s(p(s(p(p(R,R),R),R),R),R)

!No. 3
!┬R┬R┬R┬  (R/R/R+R+R)/R
!├R┤
!├R┘
!└      R┘
PRINT p(s(s(p(p(R,R),R),R),R),R)

!No. 4
!┬R┬R┬R┬  (R/R+R)/R/R+R
!├R┘
!├   R┤
!└   R┘
PRINT s(p(p(s(p(R,R),R),R),R),R)

!No. 5
!┬R┬R┬R┬  ((R/R+R)/R+R)/R
!├R┘
!├   R┘
!└      R┘
PRINT p(s(p(s(p(R,R),R),R),R),R)

!No. 6
!┬R┬R┬R┬  (R/R+R+R)/R/R
!├R┘
!├      R┤
!└      R┘
PRINT p(p(s(s(p(R,R),R),R),R),R)

!No. 7
!┬R─R┬R┬  ((R+R)/R/R/R+R
!├   R┤
!├   R┤
!└   R┘
PRINT s(p(p(p(s(R,R),R),R),R),R)

!No. 8
!┬R─R┬R┬  ((R+R)/R/R+R)/R
!├   R┤
!├   R┘
!└      R┘
PRINT p(s(p(p(s(R,R),R),R),R),R)

!No. 9
!┬R─R┬R┬  ((R+R)/R+R)/R/R
!├   R┘
!├      R┤
!└      R┘
PRINT p(p(s(p(s(R,R),R),R),R),R)

!No. 10
!┬R─R─R┬  (R+R+R)/R/R/R
!├      R┤
!├      R┤
!└      R┘
PRINT p(p(p(s(s(R,R),R),R),R),R)

PRINT


!●2+2+1+1
!No. 1
!┬R┬R┬    (R+R)/(R/R/R+R)  R/R/R/R+R/R
!├R┻R┘ ×2
!├R┤
!└R┘
PRINT p(s(R,R),s(p(p(R,R),R),R))
PRINT s(p(p(p(R,R),R),R),p(R,R))

!No. 2
!┬R┬R┬    (R+R)/(R/R+R)/R  (R/R/R+R/R)/R
!├R┻R┘ ×2
!├R┘
!└   R┘
PRINT p(p(s(R,R),s(p(R,R),R)),R)
PRINT p(s(p(p(R,R),R),p(R,R)),R)

!No. 3
!┬R┬R┬    (R+R)/(R+R)/R/R  (R/R+R/R)/R/R
!├R┻R┤ ×2
!├   R┤
!└   R┘
PRINT p(p(p(s(R,R),s(R,R)),R),R)
PRINT p(p(s(p(R,R),p(R,R)),R),R)

!No. 7
!┬R┬R┬    (R/R+R)/(R/R+R)
!├R┘
!├R┬R┘
!└R┘

PRINT p(s(p(R,R),R),s(p(R,R),R))

PRINT


!●2+1+1+1+1
!No. 1
!┬R┬R┬  R/R/R/R/R+R
!├R┤
!├R┤
!├R┤
!└R┘
PRINT s(p(p(p(p(R,R),R),R),R),R)

!No. 2
!┬R┬R┬  (R/R/R/R+R)/R
!├R┤
!├R┤
!├R┘
!└   R┘
PRINT p(s(p(p(p(R,R),R),R),R),R)

!No. 3
!┬R┬R┬  (R/R/R+R)/R/R
!├R┤
!├R┘
!├   R┤
!└   R┘
PRINT p(p(s(p(p(R,R),R),R),R),R)

!No. 4
!┬R┬R┬  (R/R+R)/R/R/R
!├R┘
!├   R┤
!├   R┤
!└   R┘
PRINT p(p(p(s(p(R,R),R),R),R),R)

!No. 5
!┬R─R┬  (R+R)/R/R/R/R
!├   R┤
!├   R┤
!├   R┤
!└   R┘
PRINT p(p(p(p(s(R,R),R),R),R),R)

PRINT


!●1+1+1+1+1+1
!No. 1
!┬R┬  R/R/R/R/R/R
!├R┤
!├R┤
!├R┤
!├R┤
!└R┘
PRINT p(p(p(p(p(R,R),R),R),R),R)

END


つづく
 

Re: 合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月27日(水)12時49分15秒
  > No.3029[元記事へ]

つづき

実行結果

6

9/2
11/3
11/4
9/5
5/6

3
3
11/5
13/6
4/3
5/4
4/3

3/2
3/2
3/2

10/3
13/5
12/7
7/9
12/5
13/8
8/11
10/7
7/11
4/9

13/7
11/6
3/2
3/2
2/3
2/3
1
1
6/11
7/13
10/9
11/10
10/11
9/10

2/3
2/3
2/3

9/4
11/7
7/10
11/8
8/13
5/12
9/7
7/12
5/13
3/10

4/5
3/4
6/13
5/11
1/3
1/3
3/4

6/5
5/9
4/11
3/11
2/9

1/6


逆数どうしの組が現れる。対称性がある。
 6と1+1+1+1+1+1
 5+1と2+1+1+1+1
 4+2と3+1+1+1
 など

ふたつの式の関係は、
たとえば、
 ┬R─R┬R┬R┬R┬  式 (R+R)/R+R+R+R
 └   R┘
と
 ┬R┬R┬  式 (R/R+R)/R/R/R
 ├R┘
 ├   R┤
 ├   R┤
 └   R┘
のように、+,/ の入れ替えることになる。(必要に応じて括弧がいる)

 

Re: 素数多発関数の考察

 投稿者:山中和義  投稿日:2013年 1月 1日(火)11時50分8秒
  > No.2868[元記事へ]

GAIさんへのお返事です。

> f(n)=2*n^2-199
> の関数で素数を発生させるnの値の表(*は合成数の結果となるもの。)
> これより効率よい関数を探せないか?

●1次
素数は2と奇素数より、2n+3、n=0,1,2,3,…  ← 式1
素数判定法のひとつ試し割り法(提示した関数PrimeQ(n)を参照)より、6n+{1,5} ← 式2
発展させて、2,3,5と30n+{1,7,11,13,17,19,23,29}とすることもできる。

ひとつの式のみ採用すれば、式1が優位だが、式2は2つ採用すれば精度は上がる。

●2次
2n^2-199では、11項が負の数と1になるので、nをn+11として、2n^2+44n+43
オイラーが発見したn^2+n+41
n^2+999n+61



!素数を生成する変数nの整数係数多項式
!http://www.saoyagi2.net/integer/primegensearch.html

LET M=10000 !上限
LET C=0 !素数になる回数
FOR N=0 TO M
   !!LET P=2*N+3
   LET P=6*N+1
   !!LET P=6*N-1

   !!LET P=2*N^2+44*N+43 !2n^2-199より
   !!LET P=N^2+N+41 !オイラーが発見
   !!LET P=N^2+999*N+61

   LET W=PrimeQ(P)
   LET C=C+W
   !PRINT N; P; W !debg
NEXT N
PRINT C/(M+1)*100;"%"
END


!試行割算法

EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !2の倍数
   IF n=2 THEN LET PrimeQ=1 !2は素数
ELSEIF MOD(n,3)=0 THEN !3の倍数
   IF n=3 THEN LET PrimeQ=1 !3は素数
ELSE
   LET k=5
   DO WHILE k*k<=n !√nまで検証する
      IF MOD(n,k)=0 THEN !5,11,17,23,29,…
         EXIT FUNCTION
      ELSEIF MOD(n,k+2)=0 THEN !7,13,19,25,31,…
         EXIT FUNCTION
      END IF !+1,+3,+5は2の倍数(偶数)、+1,+4は3の倍数、+5は5の倍数
      LET k=k+6
   LOOP
   LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION

 

Re: 素数多発関数の考察

 投稿者:山中和義  投稿日:2013年 1月 2日(水)12時57分33秒
  > No.2920[元記事へ]

ウラムの螺旋

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

右斜めの数 1,3,7,13,21,…は、n^2+n+1、n=0,1,2,3,…
中央1を41に置き換えて、n^2+n+41


!ウラムの螺旋

LET M=25 !45

!!SET TEXT HEIGHT 0.0075
SET TEXT JUSTIFY "CENTER","HALF"
SET bitmap SIZE 600,600
SET WINDOW -M/2,M/2,-M/2,M/2

LET D=41 !中央の値
LET X=0
LET Y=0
SET TEXT COLOR 1+3*PrimeQ(D)
PLOT TEXT, AT X,Y: STR$(D)

LET DX=1 !移動方向
LET DY=1
FOR S=1 TO M !ステップ数
   FOR L=1 TO S !x軸方向
      LET D=D+1
      LET X=X+DX
      SET TEXT COLOR 1+3*PrimeQ(D)
      PLOT TEXT, AT X,Y: STR$(D)
   NEXT L
   LET DX=-DX

   FOR L=1 TO S !y軸方向
      LET D=D+1
      LET Y=Y+DY
      SET TEXT COLOR 1+3*PrimeQ(D)
      PLOT TEXT, AT X,Y: STR$(D)
   NEXT L
   LET DY=-DY
NEXT S

END


!試行割算法

EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !2の倍数
   IF n=2 THEN LET PrimeQ=1 !2は素数
ELSEIF MOD(n,3)=0 THEN !3の倍数
   IF n=3 THEN LET PrimeQ=1 !3は素数
ELSE
   LET k=5
   DO WHILE k*k<=n !√nまで検証する
      IF MOD(n,k)=0 THEN !5,11,17,23,29,…
         EXIT FUNCTION
      ELSEIF MOD(n,k+2)=0 THEN !7,13,19,25,31,…
         EXIT FUNCTION
      END IF !+1,+3,+5は2の倍数(偶数)、+1,+4は3の倍数、+5は5の倍数
      LET k=k+6
   LOOP
   LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION

 

カステラを切り分ける

 投稿者:山中和義  投稿日:2013年 1月 5日(土)10時11分26秒
  問題
9本のカステラを10人で切り分けたい。
包丁を使う回数を、できるだけ減らすには、どのように切り分けたらよいだろうか。
ただし、いくつかのカステラをまとめて、一気に切るということはしないものとする。

答え
エジプト分数より、9/10=1/2+1/3+1/15なので、両辺に10をかけて、9=5+10/3+2/3

1本目 ┌───────┬──────┐ 5 本をそれぞれ 2 等分して、1/2 ずつ分ける
   └───────┴──────┘ これは、5回
2本目 ┌───────┬──────┐
   └───────┴──────┘
3本目 ┌───────┬──────┐
   └───────┴──────┘
4本目 ┌───────┬──────┐
   └───────┴──────┘
5本目 ┌───────┬──────┐
   └───────┴──────┘
6本目 ┌────┬────┬────┐ 10/3 本をそれぞれ 3 等分して、1/3 ずつ分ける
   └────┴────┴────┘ これは、7回
7本目 ┌────┬────┬────┐
   └────┴────┴────┘
8本目 ┌────┬────┬────┐
   └────┴────┴────┘
9本目 ┌┬┬┬┬┬┬┬┬┬┬────┐ 2/3 本を 10 等分して、1/15 ずつ分ける
   └┴┴┴┴┴┴┴┴┴┴────┘ これは、9回
よって、5+7+9=21回

同じ大きさのものを同じ個数ずつ分けることになる。
(終り)

別解
9/10=1/2+1/5+1/5 9=5+2+2なので、1*5+4*2+4*2=21回
(終り)

参考 http://homepage1.nifty.com/haniu/cake.html


OPTION ARITHMETIC RATIONAL !有理数モード

LET m=9 !6 !7 !4 !2 !本数
LET n=10 !10 !8 !9 !5 !人数

LET s=0 !回数

LET x=n !save it
DO UNTIL m=0
   LET q=CEIL(n/m)
   IF x>q THEN
      LET s=s+(x-INT(x/q))
      PRINT x/q;"本をそれぞれ";q;"等分して、";
   ELSE
      LET s=s+(x-1)
      PRINT x/q;"本を";x;"等分して、";
   END IF
   PRINT "1/";STR$(q);" ずつ分ける"

   LET m=m*q-n !次へ
   LET n=n*q
LOOP

PRINT s;"回"

END

 

狭い場所でカード揃え

 投稿者:GAI  投稿日:2013年 1月 5日(土)17時59分16秒
  1~nの番号のカードを十分シャッフルしてから
表向きにしてテーブルの左の位置に重ねて置いておく。
そして、
テーブルの3カ所(左,中,右)にカードを動かしていく。
ただし、下のルールだけを頼りに操作する。
つまり、下にあるカードの数字は見えなく、また何枚が下にあるのかも
わからない。
以前の状態は一切関係なく、今見えているカードの数のみに依存して
操作を進めるものとする。


_は空枠であることを示す。

<ルール>
①(2,1,_)→1を2の上にのせる。
②2枚のカードが見えていたら、空き枠の左隣のカードで空きを埋める。
(右と左は繋がっていると考える。)
③j<kとし、(k,j,k-1)の配置が見えたら、k-1をkの上にのせる。
(両端が連続する数で左端の方が大きいものであり、中の数がより小さい場合)
④1枚しかカードが見えてないなら、そのカードを左隣へ動かす。
(右と左は繋がっていると考える。)
⑤3枚のカードが見えていたら、その3枚のうち最大の数の右隣に
 あるカードを右隣へ移動する。
(右と左は繋がっていると考える。)

*(左,中,右)にあるカード(重なっている場合は左端の数字が見える。)
 を示す。
<例1>
番号1~4の4枚のカードをシャッフルして
上から[2,1,3,4]であった場合の推移の様子

([2,1,3,4],_,_)
↓④
([1,3,4],_,2)
↓②
([3,4],1,2)
↓③
([2,3,4],1,_)
↓①
([1,2,3,4],_,_)

<例2>
同じく[4,3,2,1]であった場合の推移の様子

([4,3,2,1],_,_)
↓④
([3,2,1],_,4)
↓②
([2,1],3,4)
↓⑤
(1,[2,3],4)
↓⑤
(_,[1,2,3],4)
↓②
(4,[1,2,3],_)
↓②
(4,[2,3],1)
↓⑤
(4,3,[2,1])
↓⑤
(4,_,[3,2,1])
↓②
(_,4,[3,2,1])
↓②
(3,4,[2,1])
↓⑤
([2,3],4,1)
↓⑤
([1,2,3],4,_)
↓②
([1,2,3],_,4)
↓②
([2,3],1,4)
↓⑤
(3,[2,1],4)
↓⑤
(_,[3,2,1],4)
↓②
(4,[3,2,1],_)
↓②
(4,[2,1],3)
↓③
([3,4],[2,1],_)
↓②
([3,4],1,2)
↓③
([2,3,4],1,_)
↓①
([1,2,3,4],_,_)

このルールを守って操作する限り、必ず左の位置に上から1~nの順番に揃ったカードが
重なって終わる。

これが本当に52枚あるトランプでも達成できるのか確かめたいので
この操作をプログラム化して頂きたいです。


 

Re: 狭い場所でカード揃え

 投稿者:山中和義  投稿日:2013年 1月 6日(日)12時13分9秒
  > No.2949[元記事へ]

GAIさんへのお返事です。

> 1~nの番号のカードを十分シャッフルしてから

> <ルール>
> ①(2,1,_)→1を2の上にのせる。
> ②2枚のカードが見えていたら、空き枠の左隣のカードで空きを埋める。
> (右と左は繋がっていると考える。)
> ③j<kとし、(k,j,k-1)の配置が見えたら、k-1をkの上にのせる。
> (両端が連続する数で左端の方が大きいものであり、中の数がより小さい場合)
> ④1枚しかカードが見えてないなら、そのカードを左隣へ動かす。
> (右と左は繋がっていると考える。)
> ⑤3枚のカードが見えていたら、その3枚のうち最大の数の右隣に
>  あるカードを右隣へ移動する。
> (右と左は繋がっていると考える。)

52枚の場合、かなりの作業となります。


LET N=4 !カードの枚数

DIM m1(N),m2(N),m3(N) !カードの並び

SUB card_initialize(c(),N) !カードを整列する
   FOR i=1 TO N
      LET c(i)=i
   NEXT i
END SUB
RANDOMIZE
CALL card_initialize(m1,N)


SUB shuffle_randomize(c(),N) !ランダムにシャッフルする
   FOR i=N TO 2 STEP -1
      LET j=INT(RND*(i-1))+1 !1~i-1
      swap c(i),c(j)
   NEXT i
END SUB
CALL shuffle_randomize(m1,N)
!DATA 1,2,3,4
!!DATA 4,3,1,2
!MAT READ m1
!!!MAT PRINT m1; !debug

MAT m2=ZER
MAT m3=ZER

LET c1=N
LET c2=0
LET c3=0


SUB card_display(c(),N)
   PRINT "{";
   IF N>0 THEN
      PRINT STR$(c(N));
      FOR i=N-1 TO 1 STEP -1
         PRINT ",";STR$(c(i));
      NEXT i
   END IF
   PRINT "}"
END SUB
CALL card_display(m1,c1)
CALL card_display(m2,c2)
CALL card_display(m3,c3)
PRINT


SUB move(x(),a,y(),b) !XからYへ移動させる
   LET t=x(a)
   LET a=a-1
   LET b=b+1
   LET y(b)=t
END SUB

LET S=0 !ステップ
DO

   IF c1=N THEN !整列しているかどうか
      FOR i=c1 TO 1 STEP -1
         IF m1(i)<>N-i+1 THEN EXIT FOR
      NEXT i
      IF i<1 THEN EXIT DO !OK!
   END IF

   LET S=S+1
   PRINT S;": ";

   !ルール1
   IF (c1>0 AND m1(c1)=2) AND (c2>0 AND m2(c2)=1) AND (c3=0) THEN !(2,1,_)なら
      CALL move(m2,c2,m1,c1) !1を2の上にのせる
      PRINT "ルール1"
   ELSE

   !ルール2
      IF c1>0 AND c2>0 AND c3=0 THEN !3が空きなら
         CALL move(m2,c2,m3,c3) !左隣のカードで空きを埋める
         PRINT "ルール2"
      ELSEIF c2>0 AND c3>0 AND c1=0 THEN !1が空きなら
         CALL move(m3,c3,m1,c1)
         PRINT "ルール2"
      ELSEIF c3>0 AND c1>0 AND c2=0 THEN !2が空きなら
         CALL move(m1,c1,m2,c2)
         PRINT "ルール2"
      ELSE

      !ルール3
         IF (c1>0 AND c2>0 AND c3>0) AND (m1(c1)-1=m3(c3) AND m2(c2)<m1(c1)) THEN !(k,j,k-1)
            CALL move(m3,c3,m1,c1) !(k-1)のカードをkのカードの上にのせる
            PRINT "ルール3"
         ELSE

         !ルール4
            IF c1=N AND c2=0 AND c3=0 THEN !2,3が空きなら
               CALL move(m1,c1,m3,c3) !左隣へ移動する
               PRINT "ルール4"
            ELSEIF c2=N AND c3=0 AND c1=0  THEN !3,1が空きなら
               CALL move(m2,c2,m1,c1)
               PRINT "ルール4"
            ELSEIF c3=N AND c1=0 AND c3=0 THEN !1,2が空きなら
               CALL move(m3,c3,m2,c2)
               PRINT "ルール4"
            ELSE

            !ルール5
               IF (c1>0 AND c2>0 AND c3>0) THEN !3枚のカードが見えるなら
                  LET t1=m1(c1)
                  LET t2=m2(c2)
                  LET t3=m3(c3)
                  LET t=MAX(MAX(t1,t2),t3)
                  IF t1=t THEN !1が最大なら
                     CALL move(m2,c2,m3,c3) !右隣のカードを右隣へ移動させる
                  ELSEIF t2=t THEN !2が最大なら
                     CALL move(m3,c3,m1,c1)
                  ELSE !3が最大なら
                     CALL move(m1,c1,m2,c2)
                  END IF
                  PRINT "ルール5"

               END IF
            END IF
         END IF
      END IF
   END IF

   CALL card_display(m1,c1) !結果を表示する
   CALL card_display(m2,c2)
   CALL card_display(m3,c3)
   PRINT

LOOP

END

 

和が22および33にする

 投稿者:山中和義  投稿日:2013年 1月 7日(月)11時00分44秒
  問題
1から10までの10個の数を5個ずつ2組に分ける。それぞれの組で和が22および33になるようにする。
どのように分ければよいか。
例
{1,3,5,6,7}=22と{2,4,8,9,10}=33

答え
  1 +2 +3 +4 +5
+ 10 +9 +8 +7 +6
-------------------
  11+11+11+11+11 = 11*5 = 55
より、
和が11になる組の5通りから、その内の2組ずつを使って、22をつくる。
たとえば、
 {1,10, 2,9}=22
 {3, 8, 4,7}=22
とする。
残りの1組をどちらかに加える。
 {1,10, 2,9, 5,6}=33
 {3, 8, 4,7}=22
22と33ができるが、6個と4個で個数が合わないので、
交換して個数を±1にする1+6=7に着目して、
 {7,10, 2,9,   5}=33
 {3, 8, 4,1,6}=22
とすればよい。
(終り)


別解
小町算
 +1±2±3±4±5±6±7±8±9±10=±(33-22)=±11
の解で、左辺の+と-の個数が同じもの
(終り)


LET N=9 !左辺の+が5つ
LET R=4
CALL CombBit(N,R, 0) !2進法n桁、r個のビットが1
END

EXTERNAL SUB CombBit(N,R, Bit) !n個の中からr個を選ぶ組み合わせをビットで表す ※辞書式順序
IF N=R THEN
!!PRINT Bit+2^R-1 !ビットパターンを生成する
   CALL stub(Bit+2^R-1)
ELSEIF N>0 THEN
   CALL CombBit(N-1,R,Bit)
   CALL CombBit(N-1,R-1,Bit+2^(N-1))
END IF
END SUB

!小町算「+1±2±3±4±5±6±7±8±9±10=±11、左辺の+と-の個数が同じもの」を解く
EXTERNAL SUB stub(Bit)
LET t=Bit !左辺を計算する
LET S=1 !1の前は+のみ
FOR K=10 TO 2 STEP -1 !進数変換でパターンを得る
   IF MOD(t,2)=1 THEN LET S=S+K ELSE LET S=S-K !ビットが1なら和
   LET t=INT(t/2)
NEXT K
IF ABS(S)=11 THEN PRINT BSTR$(2^9+Bit,2) !±11なら、条件を満たす
END SUB



別解
 問題
 1≦a<b<c<d<e≦10とする整数の組(a,b,c,d,e)がある。
 a+b+c+d+e=22(または33)を満たすものはいくつあるか。
として、不定方程式を解く。
1≦a<b<c<d≦10なる整数として、a+b+c+d+e=22を考える。
 5a<a+b+c+d+e=22より、a<22/5
 4b<b+c+d+e=22-aより、b<(22-a)/4
 3c<c+d+e=22-(a+b)より、c<(22-(a+b))/3
 2d<d+e=22-(a+b+c)より、d<(22-(a+b+c))/2
なので、組(a,b,c,d)を求めると、
 (1,2,3,6,10) (1,2,3,7,9) (1,2,4,5,10) (1,2,4,6,9) (1,2,4,7,8)
 (1,2,5,6,8) (1,3,4,5,9) (1,3,4,6,8) (1,3,5,6,7) (2,3,4,5,8)
 (2,3,4,6,7)
の11通りとなる。


FOR a=1 TO 22/5
   FOR b=a+1 TO (22-a)/4
      FOR c=b+1 TO (22-(a+b))/3
         FOR d=c+1 TO (22-(a+b+c))/2
            LET e=22-(a+b+c+d)
            IF e>d AND e<=10 THEN PRINT a;b;c;d;e
         NEXT d
      NEXT c
   NEXT b
NEXT a
END

 

小町算でπを作る

 投稿者:山中和義  投稿日:2013年 1月10日(木)20時50分5秒
 
!小町算でπを作る

!π=ArcTan(1)+ArcTan(2)+ArcTan(3)より、

PRINT ATN(5-4)+ATN(3)+ATN(2*1) !1から5まで
PRINT ATN((5-4)*3)+ATN(2)+ATN(1) !1から5まで
PRINT ATN((5+4)/3)+ATN(2)+ATN(1) !1から5まで

PRINT ATN(7-6+5-4)+ATN(3)+ATN(2-1) !1から7まで
PRINT ATN(7-6)+ATN((5-4)*3)+ATN(2*1) !1から7まで
PRINT ATN(7-6)+ATN((5+4)/3)+ATN(2*1) !1から7まで
PRINT ATN((7+6-5)/4)+ATN(3)+ATN(2-1) !1から7まで

PRINT ATN(8+7+6-5*4)+ATN(3)+ATN(2*1) !1から8まで
PRINT ATN((8+7-6-5)/4)+ATN(3)+ATN(2*1) !1から8まで

PRINT ATN(9-8-7+6+5-4)+ATN(3)+ATN(2*1) !1から9まで
PRINT ATN(9-8+7-6-5+4)+ATN(3)+ATN(2*1) !1から9まで
PRINT ATN(-9-8-7+6+5*4)+ATN(3)+ATN(2-1) !1から9まで
PRINT ATN(-9-8-7+6*5-4)+ATN(3)+ATN(2-1) !1から9まで
PRINT ATN((9*8-7*6)/5-4)+ATN(3)+ATN(2-1) !1から9まで

PRINT ATN(10-9)+ATN(8-7+6-5)+ATN(4-3+2*1) !1から10まで
PRINT ATN(10+9-8-7+6-5-4)+ATN(3)+ATN(2*1) !1から10まで
PRINT ATN((10+9-8-7)*(6-5)/4)+ATN(3)+ATN(2*1) !1から10まで


!π/4=ArcTan(1)より

PRINT 4*(3-2)*ATN(1) !1から4まで
PRINT 4*ATN(3-2*1) !1から4まで

PRINT (5+4-3-2)*ATN(1) !1から5まで
PRINT (5-4+3)*ATN(2-1) !1から5まで
PRINT ATN(5-4)*(3+2-1) !1から5まで

PRINT (6+5-4-3)*ATN(2-1) !1から6まで
PRINT (6-5)*4*(3-2)*ATN(1) !1から6まで

PRINT (7+6-5-4)*(3-2)*ATN(1) !1から7まで
PRINT (7-6-5)*ATN((4-3-2)*1) !1から7まで

PRINT (8-7+6-5-4+3*2)*ATN(1) !1から8まで
PRINT (8-7-6+5+4)*ATN(3-2*1) !1から8まで
PRINT (8-7)*(6-5)*4*(3-2)*ATN(1) !1から8まで
PRINT (8+7-6-5)*ATN((-4+3+2)*1) !1から8まで

PRINT (9-8+7-6+5-4+3-2)*ATN(1) !1から9まで
PRINT (9+8-7-6+5-4-3+2)*ATN(1) !1から9まで

PRINT ((10-9+8-7)*(6-5)-4+3*2)*ATN(1) !1から10まで
PRINT ATN((10-9)*(8-7)*(6-5))*4*(3-2*1) !1から10まで
PRINT (10+9-8-7)*(6-5)*(-4+3+2)*ATN(1) !1から10まで
PRINT (10+9-8-7)*(6-5)*ATN(-4+3*2-1) !1から10まで


!α+β=π/4を求める。
! tan(α+β)=(tanα+tanβ)/(1-tanαtanβ)=1とすると、tanβ=(1-tanα)/(1+tanα)
! tanα=m/nのとき、tanβ=(n-m)/(n+m)
! (m,n)=(2,1)なら、(n-m)/(n+m)=(1-2)/(1+2)=-1/3
! (m,n)=(5,1)なら、(n-m)/(n+m)=(1-5)/(1+5)=-2/3
! (m,n)=(6,1)なら、(n-m)/(n+m)=(1-6)/(1+6)=-5/7
! から、(tanα,tanβ)=(2,-1/3)、(5,-2/3)、(6,-5/7)、…
!より、

PRINT 4*(ATN(2)-ATN(1/3)) !1,2,3,4
PRINT 4*(ATN(5)-ATN(2/3)) !2,3,4,5
PRINT 4*(ATN(6)-ATN(5/7)) !4,5,6,7


!その他

PRINT ATN(3-2)*4 !2,3,4
PRINT ATN(6-5)*4 !4,5,6
PRINT 4*ATN((7-5)*3/6) !3,4,5,6,7
PRINT ATN((8-7)*(6-5))*4 !4,5,6,7,8
PRINT (10+9-8-7)*ATN(6-5) !5,6,7,8,9,10
PRINT ATN((10-9)*(8-7)*(6-5))*4 !4,5,6,7,8,9,10


PRINT ATN(1)+ATN(4-2)+ATN(3) !1から4まで
PRINT ATN(5-4)+ATN(2*1)+ATN(6-3) !1から6まで
PRINT ATN(6-5)+ATN(4-2)+ATN(3*1) !1から6まで
PRINT ATN(6-5)+ATN(3)+ATN(4-2*1) !1から6まで

END

 

赤字補填ゲーム

 投稿者:GAI  投稿日:2013年 1月11日(金)18時16分9秒
  正5角形の各頂点に整数(負の数も含む)が割り当てられている。
これをラベルと呼ぶことにする。
各ラベルの和sは正の値とする。
今、ある頂点にあるラベルが負の値のとき、ここを符号を反転させて正の値に切り替える。
このとき全体の和sの値が変わらないように、両隣のラベルから、反転させた値を引くようにしておく。
どのラベルをひっくり返すかにかかわらず、この操作を有限回繰り返すと、すべてのラベルの値が非負になって必ず止まることが起こるという。


<このモデルは各支社の売り上げが黒字(プラスのラベル)や赤字(マイナスのラベル)であるとき(ただし総計での売り上げは黒字。)各支社は赤字を隠すために両隣の支社から、赤字補填の操作をしてもらうことを繰り返し行っていくと、遂には各支社赤字が出なかった帳簿を作り上げるよくニュースで聞くモデルを見せてくれそうです。>

例として5角形の頂点にあるラベルを
(1,-2,0,-1,3)を初期状態として(s=1)推移の様子を記述してみると
(-1,2,-2,-1,3)
(-1,0,2,-3,3)
(-1,0,-1,3,0)
(1,-1,-1,3,-1)
(0,1,-2,3,-1)
(0,-1,2,1,-1)
(-1,1,1,1,-1)
(1,0,1,1,-2)
(-1,0,1,-1,2)
(-1,0,0,1,1)
(1,-1,0,1,0)
(0,1,-1,1,0)
(0,0,1,0,0)
と13回目でストップする。

これは一般にn角形の頂点やさらに任意の連結グラフにまで一般化できるという。
そこでこのモデルがどの様に動くのかを、5角形や6角形、・・・
の支社を持つ会社として見てみたい。

分かり難い説明で申し訳ありませんが、趣旨を読み取ってそのモデルを作って頂きたい。



 

Re: 赤字補填ゲーム

 投稿者:山中和義  投稿日:2013年 1月12日(土)11時14分30秒
  > No.2953[元記事へ]

GAIさんへのお返事です。

> 例として5角形の頂点にあるラベルを
> (1,-2,0,-1,3)を初期状態として(s=1)推移の様子を記述してみると
> (-1,2,-2,-1,3)
> (-1,0,2,-3,3)
> (-1,0,-1,3,0)
> (1,-1,-1,3,-1)
> (0,1,-2,3,-1)
> (0,-1,2,1,-1)
> (-1,1,1,1,-1)
> (1,0,1,1,-2)
> (-1,0,1,-1,2)
> (-1,0,0,1,1)
> (1,-1,0,1,0)
> (0,1,-1,1,0)
> (0,0,1,0,0)
> と13回目でストップする。


!赤字補填ゲーム

DATA 5 !個数
DATA 1,-2,0,-1,3 !値

READ N
DIM B(0 TO N-1)
MAT READ B
MAT PRINT B; !debug

LET S=0
FOR i=0 TO N-1
   LET S=S+B(i)
NEXT i
PRINT "総和=";S


LET C=0 !回数
DO
   FOR i=0 TO N-1 !最初に見つかったもの
      IF B(i)<0 THEN EXIT FOR
   NEXT i
   IF i>N-1 THEN EXIT DO !すべてが非負なら、終了!

   LET T=-B(i) !反転
   LET B(i)=T
   LET B(MOD(i-1,N))=B(MOD(i-1,N))-T !両隣から反転させた値を引く
   LET B(MOD(i+1,N))=B(MOD(i+1,N))-T

   MAT PRINT B; !状態を表示する

   LET C=C+1
LOOP

PRINT C;"回"

END


実行結果

1 -2  0 -1  3

総和= 1
-1  2 -2 -1  3

1  1 -2 -1  2

1 -1  2 -3  2

0  1  1 -3  2

0  1 -2  3 -1

0 -1  2  1 -1

-1  1  1  1 -1

1  0  1  1 -2

-1  0  1 -1  2

1 -1  1 -1  1

0  1  0 -1  1

0  1 -1  1  0

0  0  1  0  0

13 回




 

Re: 赤字補填ゲーム

 投稿者:山中和義  投稿日:2013年 1月13日(日)11時08分35秒
  > No.2954[元記事へ]

> (0,0,1,0,0)
> と13回目でストップする。

操作の順番によらず結果と回数は同じになるようです。
 

バケツを空に

 投稿者:GAI  投稿日:2013年 1月14日(月)17時38分31秒
  大きなバケツが3つあり(これをA,B,Cで表す。)
それぞれにきっちり整数リットルの蒸発しない液体が入っているとする。
(容器には十分な余裕があるものとする。)
一度に出来る操作は、あるバケツにそれ以上多くの液体が入っている他のバケツから
液体の一部を移して2倍にすること。
言いかえれば、xリットル入っているバケツから、yリットル(ただしy≦x)入っている
バケツへyリットルだけ移し、バケツの中身をそれぞれ、(x-y)リットルと(2×y)リットル
にすることである。

今最初の3つのバケツの液体の量が次の時一つのバケツを空にする手順は?
例
(A,B,C)=( 6,11,14) であるとき、
      →(12,11, 8)
      →(12, 3,16)
      →( 9, 6,16)
      →( 3,12,16)
      →( 6,12,13)
      →(12,12, 7)
      →( 0,24, 7)

の7回で目的達成できる。



この操作をする限りどんな初期状態であれ、必ず一つのバケツを空にすることができるという。
このパズルを解かせる最も手数が掛かってしまう初期状態の容器にある液体の量の組合せ(100リットル以内で)を探してくれませんか。
 

Re: バケツを空に

 投稿者:山中和義  投稿日:2013年 1月15日(火)11時19分6秒
  > No.2956[元記事へ]

GAIさんへのお返事です。

> 例
> (A,B,C)=( 6,11,14) であるとき、
>       →(12,11, 8)
>       →(12, 3,16)
>       →( 9, 6,16)
>       →( 3,12,16)
>       →( 6,12,13)
>       →(12,12, 7)
>       →( 0,24, 7)
>
>  の7回で目的達成できる。

最後の3手
x<yとして、組(x,2x,y) → (2x,2x,y-x) → (0,4x,y-x) となる。
これより、x+2x+y=Nとして、3x=N-y
この式を満たす(x,y)に着目する。

この場合は、6+11+14=31なので、
(x,y)=(10,1)、(9,4)、(8,7)、(7,10)、(6,13)、(5,16)、(4,19)、(3,22)、(2,25)、(1,28)
が最後の3手である。

 0: (6,11,14)
 1: (6,22,3) ←(3,22)
 2: (6,19,6)
 3: (0,19,12)


>       →( 6,12,13)
>       →(12,12, 7)
>       →( 0,24, 7)

これは、(6,13)となります。


最適解は、試行錯誤するしかないようなので、深さ優先(バックトラック法)で探索してみました。


PUBLIC NUMERIC S !手数 ※上限
LET S=20
DIM A(0 TO S),B(0 TO S),C(0 TO S) !バケツの水量

LET A(0)=6
LET B(0)=11
LET C(0)=14

CALL try(0,A,B,C)
PRINT S;"回"

END

EXTERNAL SUB try(p,A(),B(),C()) !バックトラック法で検索する
IF A(p)=0 OR B(p)=0 OR C(p)=0 THEN
   IF p< S THEN
      LET S=p !更新
      FOR i=0 TO p !手順を表示する
         PRINT STR$(i);": (";STR$(A(i));",";STR$(B(i));",";STR$(C(i));")"
      NEXT i
      PRINT
   END IF
ELSE
   IF p< S THEN !手数の上限以内なら、次の6通りを試す
      IF A(p)>=B(p) THEN !A→Bとする
         LET A(p+1)=A(p)-B(p)
         LET B(p+1)=2*B(p)
         LET C(p+1)=C(p)
         CALL try(p+1,A,B,C)
      END IF
      IF A(p)>=C(p) THEN !A→Cとする
         LET A(p+1)=A(p)-C(p)
         LET C(p+1)=2*C(p)
         LET B(p+1)=B(p)
         CALL try(p+1,A,B,C)
      END IF
      IF B(p)>=C(p) THEN !B→Cとする
         LET B(p+1)=B(p)-C(p)
         LET C(p+1)=2*C(p)
         LET A(p+1)=A(p)
         CALL try(p+1,A,B,C)
      END IF
      IF B(p)>=A(p) THEN !B→Aとする
         LET B(p+1)=B(p)-A(p)
         LET A(p+1)=2*A(p)
         LET C(p+1)=C(p)
         CALL try(p+1,A,B,C)
      END IF
      IF C(p)>=A(p) THEN !C→Aとする
         LET C(p+1)=C(p)-A(p)
         LET A(p+1)=2*A(p)
         LET B(p+1)=B(p)
         CALL try(p+1,A,B,C)
      END IF
      IF C(p)>=B(p) THEN !C→Bとする
         LET C(p+1)=C(p)-B(p)
         LET B(p+1)=2*B(p)
         LET A(p+1)=A(p)
         CALL try(p+1,A,B,C)
      END IF
   END IF
END IF
END SUB

 

Re: バケツを空に

 投稿者:山中和義  投稿日:2013年 1月15日(火)12時41分8秒
  GAIさんへのお返事です。

> 最後の3手
> x<yとして、組(x,2x,y) → (2x,2x,y-x) → (0,4x,y-x) となる。
> これより、x+2x+y=Nとして、3x=N-y
> この式を満たす(x,y)に着目する。

x<yとして、組(x,3x,y) → (2x,3x-x,y)=(2x,2x,y) → (0,4x,y) となる。
これも条件をみたしますね。

50の範囲では、
(27,35,43) 9 回

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (30,32,43)
4: (60,2,43)
5: (60,4,41)
6: (56,8,41)
7: (48,16,41)
8: (32,32,41)
9: (0,64,41)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (30,32,43)
4: (60,2,43)
5: (60,4,41)
6: (56,8,41)
7: (48,16,41)
8: (32,32,41)
9: (64,0,41)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,13,86)
5: (6,26,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,13,86)
5: (6,26,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,10,83)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,10,83)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,4,77)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,4,77)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,16,65)
7: (48,16,41)
8: (32,32,41)
9: (0,64,41)

0: (27,35,43)
1: (54,8,43)
2: (46,16,43)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,16,65)
7: (48,16,41)
8: (32,32,41)
9: (64,0,41)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,13,86)
5: (6,26,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,13,86)
5: (6,26,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,10,83)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,10,83)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,4,77)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,4,77)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,16,65)
7: (48,16,41)
8: (32,32,41)
9: (0,64,41)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (3,16,86)
4: (6,16,83)
5: (12,16,77)
6: (24,16,65)
7: (48,16,41)
8: (32,32,41)
9: (64,0,41)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (22,8,75)
4: (14,16,75)
5: (28,2,75)
6: (28,4,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (22,8,75)
4: (14,16,75)
5: (28,2,75)
6: (28,4,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (11,16,78)
4: (22,5,78)
5: (22,10,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (0,32,73)

0: (27,35,43)
1: (54,8,43)
2: (11,8,86)
3: (11,16,78)
4: (22,5,78)
5: (22,10,73)
6: (12,20,73)
7: (24,8,73)
8: (16,16,73)
9: (32,0,73)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (76,3,26)
5: (73,6,26)
6: (73,12,20)
7: (73,24,8)
8: (73,16,16)
9: (73,0,32)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (76,3,26)
5: (73,6,26)
6: (73,12,20)
7: (73,24,8)
8: (73,16,16)
9: (73,32,0)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (76,3,26)
5: (50,3,52)
6: (100,3,2)
7: (97,6,2)
8: (97,4,4)
9: (97,0,8)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (76,3,26)
5: (50,3,52)
6: (100,3,2)
7: (97,6,2)
8: (97,4,4)
9: (97,8,0)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (38,6,61)
5: (38,12,55)
6: (38,24,43)
7: (38,48,19)
8: (38,29,38)
9: (0,29,76)

0: (27,35,43)
1: (54,35,16)
2: (38,35,32)
3: (38,3,64)
4: (38,6,61)
5: (38,12,55)
6: (38,24,43)
7: (38,48,19)
8: (38,29,38)
9: (76,29,0)

0: (27,35,43)
1: (54,35,16)
2: (54,19,32)
3: (54,38,13)
4: (41,38,26)
5: (41,12,52)
6: (41,24,40)
7: (41,48,16)
8: (41,32,32)
9: (41,0,64)

0: (27,35,43)
1: (54,35,16)
2: (54,19,32)
3: (54,38,13)
4: (41,38,26)
5: (41,12,52)
6: (41,24,40)
7: (41,48,16)
8: (41,32,32)
9: (41,64,0)

0: (27,35,43)
1: (54,35,16)
2: (54,19,32)
3: (54,38,13)
4: (54,25,26)
5: (54,50,1)
6: (4,100,1)
7: (4,99,2)
8: (4,97,4)
9: (0,97,8)

0: (27,35,43)
1: (54,35,16)
2: (54,19,32)
3: (54,38,13)
4: (54,25,26)
5: (54,50,1)
6: (4,100,1)
7: (4,99,2)
8: (4,97,4)
9: (8,97,0)


つづく

 

Re: バケツを空に

 投稿者:山中和義  投稿日:2013年 1月15日(火)12時44分47秒
  > No.2958[元記事へ]

GAIさんへのお返事です。

> 50の範囲では、
> (27,35,43) 9 回

つづき

(36,41,46) 9 回

0: (36,41,46)
1: (72,5,46)
2: (67,10,46)
3: (67,20,36)
4: (67,40,16)
5: (67,24,32)
6: (67,48,8)
7: (59,48,16)
8: (59,32,32)
9: (59,0,64)

0: (36,41,46)
1: (72,5,46)
2: (67,10,46)
3: (67,20,36)
4: (67,40,16)
5: (67,24,32)
6: (67,48,8)
7: (59,48,16)
8: (59,32,32)
9: (59,64,0)

0: (36,41,46)
1: (72,5,46)
2: (26,5,92)
3: (52,5,66)
4: (104,5,14)
5: (99,10,14)
6: (99,20,4)
7: (99,16,8)
8: (91,16,16)
9: (91,0,32)

0: (36,41,46)
1: (72,5,46)
2: (26,5,92)
3: (52,5,66)
4: (104,5,14)
5: (99,10,14)
6: (99,20,4)
7: (99,16,8)
8: (91,16,16)
9: (91,32,0)

0: (36,41,46)
1: (72,5,46)
2: (26,5,92)
3: (26,10,87)
4: (16,20,87)
5: (32,4,87)
6: (32,8,83)
7: (32,16,75)
8: (32,32,59)
9: (0,64,59)

0: (36,41,46)
1: (72,5,46)
2: (26,5,92)
3: (26,10,87)
4: (16,20,87)
5: (32,4,87)
6: (32,8,83)
7: (32,16,75)
8: (32,32,59)
9: (64,0,59)

0: (36,41,46)
1: (72,41,10)
2: (31,82,10)
3: (62,51,10)
4: (11,102,10)
5: (22,91,10)
6: (12,91,20)
7: (24,91,8)
8: (16,91,16)
9: (0,91,32)

0: (36,41,46)
1: (72,41,10)
2: (31,82,10)
3: (62,51,10)
4: (11,102,10)
5: (22,91,10)
6: (12,91,20)
7: (24,91,8)
8: (16,91,16)
9: (32,91,0)

0: (36,41,46)
1: (72,41,10)
2: (62,41,20)
3: (62,21,40)
4: (22,21,80)
5: (44,21,58)
6: (88,21,14)
7: (67,42,14)
8: (67,28,28)
9: (67,0,56)

0: (36,41,46)
1: (72,41,10)
2: (62,41,20)
3: (62,21,40)
4: (22,21,80)
5: (44,21,58)
6: (88,21,14)
7: (67,42,14)
8: (67,28,28)
9: (67,56,0)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (52,31,40)
4: (12,31,80)
5: (12,62,49)
6: (24,50,49)
7: (48,50,25)
8: (23,50,50)
9: (23,0,100)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (52,31,40)
4: (12,31,80)
5: (12,62,49)
6: (24,50,49)
7: (48,50,25)
8: (23,50,50)
9: (23,100,0)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (52,31,40)
4: (52,62,9)
5: (52,53,18)
6: (34,53,36)
7: (34,17,72)
8: (34,34,55)
9: (0,68,55)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (52,31,40)
4: (52,62,9)
5: (52,53,18)
6: (34,53,36)
7: (34,17,72)
8: (34,34,55)
9: (68,0,55)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (72,11,40)
4: (72,22,29)
5: (72,44,7)
6: (28,88,7)
7: (28,81,14)
8: (28,67,28)
9: (0,67,56)

0: (36,41,46)
1: (72,41,10)
2: (72,31,20)
3: (72,11,40)
4: (72,22,29)
5: (72,44,7)
6: (28,88,7)
7: (28,81,14)
8: (28,67,28)
9: (56,67,0)

0: (36,41,46)
1: (36,82,5)
2: (31,82,10)
3: (62,51,10)
4: (11,102,10)
5: (22,91,10)
6: (12,91,20)
7: (24,91,8)
8: (16,91,16)
9: (0,91,32)

0: (36,41,46)
1: (36,82,5)
2: (31,82,10)
3: (62,51,10)
4: (11,102,10)
5: (22,91,10)
6: (12,91,20)
7: (24,91,8)
8: (16,91,16)
9: (32,91,0)

0: (36,41,46)
1: (36,82,5)
2: (36,77,10)
3: (26,77,20)
4: (6,77,40)
5: (12,71,40)
6: (24,59,40)
7: (48,59,16)
8: (32,59,32)
9: (0,59,64)

0: (36,41,46)
1: (36,82,5)
2: (36,77,10)
3: (26,77,20)
4: (6,77,40)
5: (12,71,40)
6: (24,59,40)
7: (48,59,16)
8: (32,59,32)
9: (64,59,0)

0: (36,41,46)
1: (36,82,5)
2: (36,77,10)
3: (36,67,20)
4: (16,67,40)
5: (32,67,24)
6: (8,67,48)
7: (16,59,48)
8: (32,59,32)
9: (0,59,64)

0: (36,41,46)
1: (36,82,5)
2: (36,77,10)
3: (36,67,20)
4: (16,67,40)
5: (32,67,24)
6: (8,67,48)
7: (16,59,48)
8: (32,59,32)
9: (64,59,0)

 

Re: バケツを空に

 投稿者:山中和義  投稿日:2013年 1月16日(水)10時56分23秒
  > No.2959[元記事へ]

次の流れに早く持ち込めれば最少手数になるようです。

●最後の2手
組(x,x,y) → (0,2x,y) となる。(yを使わない)

●最後の3手
・x<yとして、組(x,2x,y) → (2x,2x,y-x) → (0,4x,y-x) となる。
・組(x,3x,y) → (2x,3x-x,y)=(2x,2x,y) → (0,4x,y) となる。(yを使わない)

●既約
(kx,ky,kz)は、(x,y,z)と同じ

●2のべき乗
a,bを正の整数とする。互いに素で、a+b=2^kを満たすとき、(ax,bx,y)はk回となる。
例 2^4=16のとき、4手
 (x,15x,y) → (2x,14x,y) → (4x,12x,y) → (8x,8x,y) → (0,16x,y)
 (3x,13x,y) → (6x,10x,y) → (12x,4x,y) → (8x,8x,y) → (0,16x,y)
 (5x,11x,y) → (10x,6x,y) → (4x,12x,y) → (8x,8x,y) → (0,16x,y)
 (7x,9x,y) → (14x,2x,y) → (12x,4x,y) → (8x,8x,y) → (0,16x,y)
(考察)
k=1のとき、
 a+b=2^1なので、a=1,b=1
 (x,x,y) → (0,2x,y)
 yを使わず、1(=k)回である。 ※最後の2手
k=2のとき、
 a+b=2^2なので、a=1,b=3
 (x,3x,y) → (2x,3x-x,y)=(2x,2x,y) → (0,4x,y)
 yを使わず、2(=k)回である。 ※最後の3手のひとつ
k≧3のとき、
 a<bとすると、(ax,bx,y)=(ax,(2^k-a)x,y) → (2ax,(2^k-a)x-ax,y)=(2ax,2(2^(k-1)-a)x,y)
 (ax,(2^(k-1)-a)x,y)は(k-1)回と仮定すると、k回となる。
 実際は、途中に現れるaxとbxの小さい方を2倍していくことになる。
(終り)
 

単位分数の和で1/2をつくる

 投稿者:山中和義  投稿日:2013年 1月17日(木)10時10分56秒
  問題
nを、2より大きい整数とする。
互いに素となる正の整数p,qが、p<q≦n かつ p+q>n を満たすとき、
Σ1/(pq)=1/2となる。

考察
n=2のとき
 1/(1*2)
n=3のとき
 1/(1*2) +1/(1*3)+1/(2*3)
n=4のとき
 1/(1*3) +1/(2*3) +1/(1*4)+1/(3*4)
n=5のとき
 1/(2*3)+1/(1*4) +1/(3*4) +1/(1*5)+1/(2*5)+1/(3*5)+1/(4*5)
n=6のとき
 1/(1*5) +1/(3*4)+1/(2*5)+1/(3*5)+1/(4*5) +1/(1*6)+1/(5*6)

一般に、
 a,bは正の整数のとき、1/(ab)=1/(a(a+b))+1/(b(a+b))

互いに素とする組(a,b)が、この問題にあてはまる。

a+b=7のとき、(a,b)=(1,6)、(2,5)、(3,4)なので、
1/(1*6)=1/(1*7)+1/(6*7)、1/(2*5)=1/(2*7)+1/(5*7)、1/(3*4)=1/(3*7)+1/(4*7)
これより、
 n=7のとき、
  n=6、すなわち、1/(3*4)+1/(2*5)+1/(3*5)+1/(4*5)+1/(1*6)+1/(5*6) をもとに、
  1/(3*4)+1/(2*5)+1/(1*6) +1/(3*5)+1/(4*5)+1/(5*6) +1/(1*7)+1/(2*7)+1/(3*7)+1/(4*7)+1/(5*7)+1/(6*7)
  とする。
とすることで、機械的に生成できる。
(終り)


OPTION ARITHMETIC RATIONAL !有理数モード
FOR n=2 TO 20
   LET s=0
   FOR p=1 TO n-1 !1≦p<q≦n
      FOR q=p+1 TO n
         IF gcd(p,q)=1 THEN !互いに素
            IF p+q>n THEN
               PRINT p;q; !debug
               IF p+q=n+1 THEN PRINT "*" ELSE PRINT !debug
               LET s=s+1/(p*q) !Σ1/(pq)
            END IF
         END IF
      NEXT q
   NEXT p
   PRINT "n=";n; s !=1/2
   PRINT
NEXT n
END

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=a
END FUNCTION

 

0と1からなるnの倍数

 投稿者:山中和義  投稿日:2013年 1月18日(金)12時56分27秒
  問題
全ての自然数n対して必ず0と1からなるnの倍数が存在する

考察
9,18,27,36,…,90,99,,… が大きい数となる
最小の数がすべて1となるのは、1,3,9,11,33,37,41,99,…


OPTION ARITHMETIC RATIONAL !多桁の整数

FOR N=1 TO 100

   LET C=0 !個数
   LET B=1
   DO WHILE C<3

      LET W=BIT2DEC(B) !2進法のビット列を10進法数値と解釈する
      IF MOD(W,N)=0 THEN
         LET C=C+1
         PRINT N;"×";W/N;"=";W
      END IF

      LET B=B+1
   LOOP
   PRINT

NEXT n

END

EXTERNAL FUNCTION BIT2DEC(N) !2進法のビット列を10進法数値と解釈する
OPTION ARITHMETIC RATIONAL !多桁の整数
LET BIT2DEC=0
IF N>0 THEN LET BIT2DEC=BIT2DEC(INT(N/2))*10+MOD(N,2)
END FUNCTION


実行結果

1 × 1 = 1
1 × 10 = 10
1 × 11 = 11

2 × 5 = 10
2 × 50 = 100
2 × 55 = 110

3 × 37 = 111
3 × 337 = 1011
3 × 367 = 1101

4 × 25 = 100
4 × 250 = 1000
4 × 275 = 1100

5 × 2 = 10
5 × 20 = 100
5 × 22 = 110

6 × 185 = 1110
6 × 1685 = 10110
6 × 1835 = 11010

7 × 143 = 1001
7 × 1430 = 10010
7 × 1443 = 10101

8 × 125 = 1000
8 × 1250 = 10000
8 × 1375 = 11000

9 × 12345679 = 111111111
9 × 112345679 = 1011111111
9 × 122345679 = 1101111111

10 × 1 = 10
10 × 10 = 100
10 × 11 = 110

11 × 1 = 11
11 × 10 = 110
11 × 91 = 1001

12 × 925 = 11100
12 × 8425 = 101100
12 × 9175 = 110100

13 × 77 = 1001
13 × 770 = 10010
13 × 777 = 10101

14 × 715 = 10010
14 × 7150 = 100100
14 × 7215 = 101010

15 × 74 = 1110
15 × 674 = 10110
15 × 734 = 11010

16 × 625 = 10000
16 × 6250 = 100000
16 × 6875 = 110000

17 × 653 = 11101
17 × 5883 = 100011
17 × 6530 = 111010

18 × 61728395 = 1111111110
18 × 561728395 = 10111111110
18 × 611728395 = 11011111110

19 × 579 = 11001
19 × 5269 = 100111
19 × 5790 = 110010

20 × 5 = 100
20 × 50 = 1000
20 × 55 = 1100

21 × 481 = 10101
21 × 4810 = 101010
21 × 5291 = 111111

22 × 5 = 110
22 × 50 = 1100
22 × 455 = 10010

23 × 4787 = 110101
23 × 43957 = 1011011
23 × 47870 = 1101010

24 × 4625 = 111000
24 × 42125 = 1011000
24 × 45875 = 1101000

25 × 4 = 100
25 × 40 = 1000
25 × 44 = 1100

26 × 385 = 10010
26 × 3850 = 100100
26 × 3885 = 101010

27 × 40781893 = 1101111111
27 × 41151893 = 1111101111
27 × 41152263 = 1111111101

28 × 3575 = 100100
28 × 35750 = 1001000
28 × 36075 = 1010100

29 × 37969 = 1101101
29 × 348659 = 10111111
29 × 379659 = 11010111

30 × 37 = 1110
30 × 337 = 10110
30 × 367 = 11010

31 × 3581 = 111011
31 × 32581 = 1010011
31 × 35810 = 1110110

32 × 3125 = 100000
32 × 31250 = 1000000
32 × 34375 = 1100000

33 × 3367 = 111111
33 × 33367 = 1101111
33 × 33667 = 1111011

34 × 3265 = 111010
34 × 29415 = 1000110
34 × 32650 = 1110100

35 × 286 = 10010
35 × 2860 = 100100
35 × 2886 = 101010

36 × 308641975 = 11111111100
36 × 2808641975 = 101111111100
36 × 3058641975 = 110111111100

37 × 3 = 111
37 × 30 = 1110
37 × 273 = 10101

38 × 2895 = 110010
38 × 26345 = 1001110
38 × 28950 = 1100100

39 × 259 = 10101
39 × 2590 = 101010
39 × 2849 = 111111

40 × 25 = 1000
40 × 250 = 10000
40 × 275 = 11000

41 × 271 = 11111
41 × 2710 = 111110
41 × 24661 = 1011101

42 × 2405 = 101010
42 × 24050 = 1010100
42 × 26455 = 1111110

43 × 25607 = 1101101
43 × 234907 = 10101001
43 × 256070 = 11011010

44 × 25 = 1100
44 × 250 = 11000
44 × 2275 = 100100

45 × 24691358 = 1111111110
45 × 224691358 = 10111111110
45 × 244691358 = 11011111110

46 × 23935 = 1101010
46 × 219785 = 10110110
46 × 239350 = 11010100

47 × 213 = 10011
47 × 2130 = 100110
47 × 21300 = 1001100

48 × 23125 = 1110000
48 × 210625 = 10110000
48 × 229375 = 11010000

49 × 22449 = 1100001
49 × 206349 = 10111101
49 × 224490 = 11000010

50 × 2 = 100
50 × 20 = 1000
50 × 22 = 1100

51 × 1961 = 100011
51 × 19610 = 1000110
51 × 196100 = 10001100

52 × 1925 = 100100
52 × 19250 = 1001000
52 × 19425 = 1010100

53 × 1887 = 100011
53 × 18870 = 1000110
53 × 18887 = 1001011

54 × 203909465 = 11011111110
54 × 205759465 = 11111011110
54 × 205761315 = 11111111010

55 × 2 = 110
55 × 20 = 1100
55 × 182 = 10010

56 × 17875 = 1001000
56 × 178750 = 10010000
56 × 180375 = 10101000

57 × 193 = 11001
57 × 1930 = 110010
57 × 19300 = 1100100

58 × 189845 = 11011010
58 × 1743295 = 101111110
58 × 1898295 = 110101110

59 × 186629 = 11011111
59 × 1696629 = 100101111
59 × 1713729 = 101110011

60 × 185 = 11100
60 × 1685 = 101100
60 × 1835 = 110100

61 × 1641 = 100101
61 × 16410 = 1001010
61 × 18051 = 1101111

62 × 17905 = 1110110
62 × 162905 = 10100110
62 × 179050 = 11101100

63 × 17635097 = 1111011111
63 × 160335097 = 10101111111
63 × 160493827 = 10111111101

64 × 15625 = 1000000
64 × 156250 = 10000000
64 × 171875 = 11000000

65 × 154 = 10010
65 × 1540 = 100100
65 × 1554 = 101010

66 × 16835 = 1111110
66 × 166835 = 11011110
66 × 168335 = 11110110

67 × 16433 = 1101011
67 × 149403 = 10010001
67 × 164330 = 11010110

68 × 16325 = 1110100
68 × 147075 = 10001100
68 × 163250 = 11101000

69 × 144929 = 10000101
69 × 161029 = 11111001
69 × 1449290 = 100001010

70 × 143 = 10010
70 × 1430 = 100100
70 × 1443 = 101010

71 × 141 = 10011
71 × 1410 = 100110
71 × 14100 = 1001100

72 × 1543209875 = 111111111000
72 × 14043209875 = 1011111111000
72 × 15293209875 = 1101111111000

73 × 137 = 10001
73 × 1370 = 100010
73 × 1507 = 110011

74 × 15 = 1110
74 × 150 = 11100
74 × 1365 = 101010

75 × 148 = 11100
75 × 1348 = 101100
75 × 1468 = 110100

76 × 14475 = 1100100
76 × 131725 = 10011100
76 × 144750 = 11001000

77 × 13 = 1001
77 × 130 = 10010
77 × 143 = 11011

78 × 1295 = 101010
78 × 12950 = 1010100
78 × 14245 = 1111110

79 × 126709 = 10010011
79 × 140519 = 11101001
79 × 1267090 = 100100110

80 × 125 = 10000
80 × 1250 = 100000
80 × 1375 = 110000

81 × 13717421 = 1111111101
81 × 124828531 = 10111111011
81 × 135939631 = 11011110111

82 × 1355 = 111110
82 × 13550 = 1111100
82 × 123305 = 10111010

83 × 1217 = 101011
83 × 12170 = 1010110
83 × 121700 = 10101100

84 × 12025 = 1010100
84 × 120250 = 10101000
84 × 132275 = 11111100

85 × 1306 = 111010
85 × 11766 = 1000110
85 × 13060 = 1110100

86 × 128035 = 11011010
86 × 1174535 = 101010010
86 × 1280350 = 110110100

87 × 126553 = 11010111
87 × 1149553 = 100011111
87 × 1265530 = 110101110

88 × 125 = 11000
88 × 1250 = 110000
88 × 11375 = 1001000

89 × 123709 = 11010101
89 × 1123709 = 100010101
89 × 1237090 = 110101010

90 × 12345679 = 1111111110
90 × 112345679 = 10111111110
90 × 122345679 = 11011111110

91 × 11 = 1001
91 × 110 = 10010
91 × 111 = 10101

92 × 119675 = 11010100
92 × 1098925 = 101101100
92 × 1196750 = 110101000

93 × 107527 = 10000011
93 × 1075270 = 100000110
93 × 1193657 = 111010101

94 × 1065 = 100110
94 × 10650 = 1001100
94 × 106500 = 10011000

95 × 1158 = 110010
95 × 10538 = 1001110
95 × 11580 = 1100100

96 × 115625 = 11100000
96 × 1053125 = 101100000
96 × 1146875 = 110100000

97 × 114433 = 11100001
97 × 1032063 = 100110111
97 × 1135063 = 110101111

98 × 112245 = 11000010
98 × 1031745 = 101111010
98 × 1122450 = 110000100

99 × 1122334455667789 = 111111111111111111
99 × 11122334455667789 = 1101111111111111111
99 × 11222334455667789 = 1111011111111111111

100 × 1 = 100
100 × 10 = 1000
100 × 11 = 1100

 

Re: 0と1からなるnの倍数

 投稿者:山中和義  投稿日:2013年 1月19日(土)11時21分45秒
  > No.2962[元記事へ]

> 問題
> 全ての自然数n対して必ず0と1からなるnの倍数が存在する

すべての桁が1(111…1という数)をベースに考えれば一般解になります。

考察
nが2や5の倍数でない場合、すべての桁が1(111…1という数)のnの倍数がある。
このとき、1/nは循環小数になるので、1/n={循環節}/(10^k-1)と表される。
よって、(10^k-1)/9={循環節}/9*N
・nが3で割り切れない場合
 左辺は、すべての桁が1の数で、{循環節}/9倍したものである。
 例 n=7のとき、1/7=0.{142857}=142857/999999なので、999999/9=(142857/9)*7

・nが3で割り切れる場合
 n=3^r*M(Mは3で割り切れない自然数)として、
 上記より、すべての桁が1の数をMの倍数にすることができる。
 この桁数を3^r倍に増やせば、nで割り切れる。
 例 n=33=3*11のとき、1/11=0.{09}=9/99なので、循環節の長さは2
   これより、2*3=6個として、111111

n=2^p*5^qのとき、10^MAX(p,q)とすればよい。

以上をまとめると、
n=2^p*5^q*3^r*M(Mは2,5,3で割り切れない自然数)のとき、
 1/Mの循環節の長さをkとすると、
 (10^(k*3^r)-1)/9 *10^MAX(p,q) がnの倍数となる。
n=2^p*5^q*3^rのとき、
 (10^(3^r)-1)/9 *10^MAX(p,q) がnの倍数となる。
(終り)


OPTION ARITHMETIC RATIONAL !多桁の整数

FOR N=1 TO 100

   LET M=N
   LET P=0
   DO WHILE MOD(M,2)=0 !2^p
      LET M=M/2
      LET P=P+1
   LOOP
   LET Q=0
   DO WHILE MOD(M,5)=0 !5^q
      LET M=M/5
      LET Q=Q+1
   LOOP

   LET R=0
   DO WHILE MOD(M,3)=0 !3^r
      LET M=M/3
      LET R=R+1
   LOOP
   !!!PRINT P;Q;R;M !debug

   FOR K=1 TO M-1 !1/Mの循環節の長さを求める 10^k≡1 mod mを満たす最小のk
      IF modpow(10,K,M)=1 THEN EXIT FOR
   NEXT K
   LET W=(10^(lcm(K,3^R))-1)/9 *10^MAX(P,Q)
   PRINT N; "×"; W/N; "="; W; "(";lcm(K,3^R);"個の1)";   "  k=";K; "r=";R

   !※
   !LET W=(10^(K*3^R)-1)/9 *10^MAX(P,Q)
   !PRINT N; "×"; W/N; "="; W; "(";K*3^R;"個の1)";   "  k=";K; "r=";R

   !※同値
   !IF M>1 THEN !n=2^p*5^q*3^r*Mの場合
   !   FOR K=1 TO M-1 !1/Mの循環節の長さを求める 10^k≡1 mod mを満たす最小のk
   !      IF modpow(10,K,M)=1 THEN EXIT FOR
   !   NEXT K
   !   LET W=(10^(K*3^R)-1)/9 *10^MAX(P,Q)
   !   PRINT N; "×"; W/N; "="; W; "(";K*3^R;"個の1)";   "  k=";K; "r=";R
   !ELSE !n=2^p*5^q*3^rの場合
   !   LET W=(10^(3^R)-1)/9 *10^MAX(P,Q)
   !   PRINT N; "×"; W/N; "="; W; "(";3^R;"個の1)";   "  r=";R
   !END IF

NEXT N

END

EXTERNAL FUNCTION modpow(a,n,b) !a^n≡x mod b のxを返す ※nは非負整数
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=MOD(1,b)
DO WHILE n>0 !べき乗nを2進展開する
   IF MOD(n,2)=1 THEN LET S=MOD(S*a,b) !ビットが1なら計算する
   LET a=MOD(a*a,b)
   LET n=INT(n/2)
LOOP
LET modpow=S
END FUNCTION

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=a
END FUNCTION

EXTERNAL FUNCTION lcm(a,b) !最小公倍数
OPTION ARITHMETIC RATIONAL !多桁の整数
IF a>b THEN !少しでも桁あふれを防止するために大きい方を先に割る
   LET lcm=(a/gcd(a,b))*b
ELSE
   LET lcm=a*(b/gcd(a,b))
END IF
END FUNCTION


実行結果

1 × 1 = 1 ( 1 個の1)  k= 1 r= 0
2 × 5 = 10 ( 1 個の1)  k= 1 r= 0
3 × 37 = 111 ( 3 個の1)  k= 1 r= 1
4 × 25 = 100 ( 1 個の1)  k= 1 r= 0
5 × 2 = 10 ( 1 個の1)  k= 1 r= 0
6 × 185 = 1110 ( 3 個の1)  k= 1 r= 1
7 × 15873 = 111111 ( 6 個の1)  k= 6 r= 0
8 × 125 = 1000 ( 1 個の1)  k= 1 r= 0
9 × 12345679 = 111111111 ( 9 個の1)  k= 1 r= 2
10 × 1 = 10 ( 1 個の1)  k= 1 r= 0
11 × 1 = 11 ( 2 個の1)  k= 2 r= 0
12 × 925 = 11100 ( 3 個の1)  k= 1 r= 1
13 × 8547 = 111111 ( 6 個の1)  k= 6 r= 0
14 × 79365 = 1111110 ( 6 個の1)  k= 6 r= 0
15 × 74 = 1110 ( 3 個の1)  k= 1 r= 1
16 × 625 = 10000 ( 1 個の1)  k= 1 r= 0
17 × 65359477124183 = 1111111111111111 ( 16 個の1)  k= 16 r= 0
18 × 61728395 = 1111111110 ( 9 個の1)  k= 1 r= 2
19 × 5847953216374269 = 111111111111111111 ( 18 個の1)  k= 18 r= 0
20 × 5 = 100 ( 1 個の1)  k= 1 r= 0
21 × 5291 = 111111 ( 6 個の1)  k= 6 r= 1
22 × 5 = 110 ( 2 個の1)  k= 2 r= 0
23 × 48309178743961352657 = 1111111111111111111111 ( 22 個の1)  k= 22 r= 0
24 × 4625 = 111000 ( 3 個の1)  k= 1 r= 1
25 × 4 = 100 ( 1 個の1)  k= 1 r= 0
26 × 42735 = 1111110 ( 6 個の1)  k= 6 r= 0
27 × 4115226337448559670781893 = 111111111111111111111111111 ( 27 個の1)  k= 1 r= 3
28 × 396825 = 11111100 ( 6 個の1)  k= 6 r= 0
29 × 38314176245210727969348659 = 1111111111111111111111111111 ( 28 個の1)  k= 28 r= 0
30 × 37 = 1110 ( 3 個の1)  k= 1 r= 1
31 × 3584229390681 = 111111111111111 ( 15 個の1)  k= 15 r= 0
32 × 3125 = 100000 ( 1 個の1)  k= 1 r= 0
33 × 3367 = 111111 ( 6 個の1)  k= 2 r= 1
34 × 326797385620915 = 11111111111111110 ( 16 個の1)  k= 16 r= 0
35 × 31746 = 1111110 ( 6 個の1)  k= 6 r= 0
36 × 308641975 = 11111111100 ( 9 個の1)  k= 1 r= 2
37 × 3 = 111 ( 3 個の1)  k= 3 r= 0
38 × 29239766081871345 = 1111111111111111110 ( 18 個の1)  k= 18 r= 0
39 × 2849 = 111111 ( 6 個の1)  k= 6 r= 1
40 × 25 = 1000 ( 1 個の1)  k= 1 r= 0
41 × 271 = 11111 ( 5 個の1)  k= 5 r= 0
42 × 26455 = 1111110 ( 6 個の1)  k= 6 r= 1
43 × 2583979328165374677 = 111111111111111111111 ( 21 個の1)  k= 21 r= 0
44 × 25 = 1100 ( 2 個の1)  k= 2 r= 0
45 × 24691358 = 1111111110 ( 9 個の1)  k= 1 r= 2
46 × 241545893719806763285 = 11111111111111111111110 ( 22 個の1)  k= 22 r= 0
47 × 23640661938534278959810874704491725768321513 = 1111111111111111111111111111111111111111111111 ( 46 個の1)  k= 46 r= 0
48 × 23125 = 1110000 ( 3 個の1)  k= 1 r= 1
49 × 2267573696145124716553287981859410430839 = 111111111111111111111111111111111111111111 ( 42 個の1)  k= 42 r= 0
50 × 2 = 100 ( 1 個の1)  k= 1 r= 0
51 × 2178649237472766884531590413943355119825708061 = 111111111111111111111111111111111111111111111111 ( 48 個の1)  k= 16 r= 1
52 × 213675 = 11111100 ( 6 個の1)  k= 6 r= 0
53 × 20964360587 = 1111111111111 ( 13 個の1)  k= 13 r= 0
54 × 20576131687242798353909465 = 1111111111111111111111111110 ( 27 個の1)  k= 1 r= 3
55 × 2 = 110 ( 2 個の1)  k= 2 r= 0
56 × 1984125 = 111111000 ( 6 個の1)  k= 6 r= 0
57 × 1949317738791423 = 111111111111111111 ( 18 個の1)  k= 18 r= 1
58 × 191570881226053639846743295 = 11111111111111111111111111110 ( 28 個の1)  k= 28 r= 0
59 × 18832391713747645951035781544256120527306967984934086629 = 1111111111111111111111111111111111111111111111111111111111 ( 58 個の1)  k= 58 r= 0
60 × 185 = 11100 ( 3 個の1)  k= 1 r= 1
61 × 1821493624772313296903460837887067395264116575591985428051 = 111111111111111111111111111111111111111111111111111111111111 ( 60 個の1)  k= 60 r= 0
62 × 17921146953405 = 1111111111111110 ( 15 個の1)  k= 15 r= 0
63 × 1763668430335097 = 111111111111111111 ( 18 個の1)  k= 6 r= 2
64 × 15625 = 1000000 ( 1 個の1)  k= 1 r= 0
65 × 17094 = 1111110 ( 6 個の1)  k= 6 r= 0
66 × 16835 = 1111110 ( 6 個の1)  k= 2 r= 1
67 × 1658374792703150912106135986733 = 111111111111111111111111111111111 ( 33 個の1)  k= 33 r= 0
68 × 1633986928104575 = 111111111111111100 ( 16 個の1)  k= 16 r= 0
69 × 1610305958132045088566827697262479871175523349436392914653784219 = 111111111111111111111111111111111111111111111111111111111111111111 ( 66 個の1)  k= 22 r= 1
70 × 15873 = 1111110 ( 6 個の1)  k= 6 r= 0
71 × 156494522691705790297339593114241 = 11111111111111111111111111111111111 ( 35 個の1)  k= 35 r= 0
72 × 1543209875 = 111111111000 ( 9 個の1)  k= 1 r= 2
73 × 152207 = 11111111 ( 8 個の1)  k= 8 r= 0
74 × 15 = 1110 ( 3 個の1)  k= 3 r= 0
75 × 148 = 11100 ( 3 個の1)  k= 1 r= 1
76 × 146198830409356725 = 11111111111111111100 ( 18 個の1)  k= 18 r= 0
77 × 1443 = 111111 ( 6 個の1)  k= 6 r= 0
78 × 14245 = 1111110 ( 6 個の1)  k= 6 r= 1
79 × 14064697609 = 1111111111111 ( 13 個の1)  k= 13 r= 0
80 × 125 = 10000 ( 1 個の1)  k= 1 r= 0
81 × 1371742112482853223593964334705075445816186556927297668038408779149519890260631 = 111111111111111111111111111111111111111111111111111111111111111111111111111111111 ( 81 個の1)  k= 1 r= 4
82 × 1355 = 111110 ( 5 個の1)  k= 5 r= 0
83 × 133868808567603748326639892904953145917 = 11111111111111111111111111111111111111111 ( 41 個の1)  k= 41 r= 0
84 × 132275 = 11111100 ( 6 個の1)  k= 6 r= 1
85 × 130718954248366 = 11111111111111110 ( 16 個の1)  k= 16 r= 0
86 × 12919896640826873385 = 1111111111111111111110 ( 21 個の1)  k= 21 r= 0
87 × 1277139208173690932311621966794380587484035759897828863346104725415070242656449553 = 111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ( 84 個の1)  k= 28 r= 1
88 × 125 = 11000 ( 2 個の1)  k= 2 r= 0
89 × 124843945068664169787765293383270911360799 = 11111111111111111111111111111111111111111111 ( 44 個の1)  k= 44 r= 0
90 × 12345679 = 1111111110 ( 9 個の1)  k= 1 r= 2
91 × 1221 = 111111 ( 6 個の1)  k= 6 r= 0
92 × 1207729468599033816425 = 111111111111111111111100 ( 22 個の1)  k= 22 r= 0
93 × 1194743130227 = 111111111111111 ( 15 個の1)  k= 15 r= 1
94 × 118203309692671394799054373522458628841607565 = 11111111111111111111111111111111111111111111110 ( 46 個の1)  k= 46 r= 0
95 × 11695906432748538 = 1111111111111111110 ( 18 個の1)  k= 18 r= 0
96 × 115625 = 11100000 ( 3 個の1)  k= 1 r= 1
97 × 1145475372279495990836197021764032073310423825887743413516609392898052691867124856815578465063 = 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ( 96 個の1)  k= 96 r= 0
98 × 11337868480725623582766439909297052154195 = 1111111111111111111111111111111111111111110 ( 42 個の1)  k= 42 r= 0
99 × 1122334455667789 = 111111111111111111 ( 18 個の1)  k= 2 r= 2
100 × 1 = 100 ( 1 個の1)  k= 1 r= 0

 

Re: 0と1からなるnの倍数

 投稿者:山中和義  投稿日:2013年 1月21日(月)12時41分40秒
  > No.2963[元記事へ]

> 問題
> 全ての自然数n対して必ず0と1からなるnの倍数が存在する

関連問題
nは2,5を約数にもたない自然数とする。
ある自然数mをかけると、n*m=11…1(1が並ぶ数)とすることができる。

類題
nは2,5を約数にもたない自然数とする。
ある自然数mをかけると、n*m=99…9(9が並ぶ数)とすることができる。

答え
a>bとして、10^a-10^bを考える。
これは、数字9が(a-b)個並び、その後数字0がb個並んだ数9…90…0となり、9の倍数である。
鳩ノ巣原理より、1,10,10^2,…,10^9nのうち、9nで割った余りが等しいものがある。
そこで、a,bを10^aと10^bが9nで割って同じ余りとなるものとすると、10^a-10^bは9nの倍数であり、
1が(a-b)個並ぶ数は、(10^a-10^b)/(2^b*5^b*3^2)と表されて、nの倍数となる。
よって、1をある個数並べてnの倍数を作ることができる。
(終り)


OPTION ARITHMETIC RATIONAL !多桁整数

FOR n=1 TO 100

   LET t=9*n !10^0,10^1,10^2,…,10^9nとして、
   FOR b=0 TO t-1 !9nで割った余りが等しいものを探す
      LET W=modpow(10,b,t)
      FOR a=b+1 TO t
         IF modpow(10,a,t)=W THEN EXIT FOR
      NEXT a
      IF a<=t THEN EXIT FOR
   NEXT b
   IF b<=t-1 THEN !条件を満たすa,bで

   !!PRINT 10^a-10^b !debug
      LET nm=(10^a-10^b)/3^2 !1が並ぶ数 + 0が並ぶ数
      PRINT n;"×"; nm/n; "="; nm

   END IF

NEXT n

END


EXTERNAL FUNCTION modpow(a,n,b) !a^n≡x mod b のxを返す ※nは非負整数
OPTION ARITHMETIC RATIONAL !多桁の整数
LET S=MOD(1,b)
DO WHILE n>0 !べき乗nを2進展開する
   IF MOD(n,2)=1 THEN LET S=MOD(S*a,b) !ビットが1なら計算する
   LET a=MOD(a*a,b)
   LET n=INT(n/2)
LOOP
LET modpow=S
END FUNCTION

 

1と2からなる2^nの倍数

 投稿者:GAI  投稿日:2013年 1月23日(水)08時32分48秒
  n=1→2^1=2→2*1=2
n=2→2^2=4→4*3=12
n=3→2^3=8→8*14=112
n=4→2^4=16→16*132=2112
n=5→2^5=32→32*691=22112
n=6→2^6=64→64*1908=122112
・・・

これらより一般に1と2から作られる2^nの倍数が必ず存在するが成立しそうです。
これらが具体的に存在しているのかを各nに対して倍数を見つけてください。
 

Re: 1と2からなる2^nの倍数

 投稿者:山中和義  投稿日:2013年 1月25日(金)09時49分58秒
  > No.2965[元記事へ]

GAIさんへのお返事です。

> n=1→2^1=2→2*1=2
> n=2→2^2=4→4*3=12
> n=3→2^3=8→8*14=112
> n=4→2^4=16→16*132=2112
> n=5→2^5=32→32*691=22112
> n=6→2^6=64→64*1908=122112
> ・・・
>
> これらより一般に1と2から作られる2^nの倍数が必ず存在するが成立しそうです。

考察
n=1のとき、2^1*1=2
n=kのとき、2^kの倍数で1,2からなるk桁の数が存在すると仮定する。
n=k+1のとき、
 最上位のさらに左の桁に1を付加した数 1{1,2からなるk桁の数}
 最上位のさらに左の桁に2を付加した数 2{1,2からなるk桁の数}
とする(k+1)桁の数を考える。
1{1,2からなるk桁の数}は、10^k=2^k*5^k増えたことなので、2^kの倍数である。
2{1,2からなるk桁の数}は、2*10^k=2^(k+1)*5^k増えたことなので、2^kの倍数である。
差 2{1,2からなるk桁の数} - 1{1,2からなるk桁の数} = 2*10^k-10^k = 2^k*5^k なので、
どちらかは2^(k+1)で割り切れる。
よって、どちらかは2^(k+1)の倍数で(k+1)桁の数となる。
(終り)
例 n=2
 n=1のとき、2より、
 12=3*2^2で2^2の倍数
 22=5*2^2+2で2^2の倍数でない
例 n=3
 n=2のとき、12より、
 112=14*2^3で2^3の倍数
 212=26*2^3+4で2^3の倍数でない
例 n=4
 n=3のとき、112より、
 1112=69*2^4+8で2^4の倍数でない
 2112=132*2^4で2^4の倍数

一般解が機械的に構成できます。
同様な議論で、奇数 1,3,5,7,9 と 0を除く偶数 2,4,6,8 で2^nの倍数が構成できます。


OPTION ARITHMETIC RATIONAL !多桁の整数

LET A=1 !奇数 1,3,5,7,9
LET B=2 !0を除く偶数 2,4,6,8

PRINT "2^1 ×";B/2;"=";B !n=1のとき
LET K=B !1,2からなるk桁の数

FOR N=2 TO 20 !nが2以上のとき

   LET M=K+A*10^(N-1) !1{1,2からなるk桁の数}
   IF MOD(M,2^N)=0 THEN
      LET K=M
   ELSE
      LET M=K+B*10^(N-1) !2{1,2からなるk桁の数}
      IF MOD(M,2^N)=0 THEN
         LET K=M
      ELSE
         PRINT "論理エラー"
         STOP
      END IF
   END IF
   PRINT "2^";STR$(N); " ×";M/2^N; "=";M

NEXT N

END

 

関数でお絵かき

 投稿者:山中和義  投稿日:2013年 1月25日(金)11時19分45秒
  > No.2018[元記事へ]

問題
同じ長さのマッチ棒12本を一辺に3本、4本、5本使って三角形を作りました。
これら12本のマッチ棒のうち、4本だけを動かして、
面積がもとの三角形の1/2である多角形になるようにしてください。

答え

SET WINDOW -3,3,-1,5 !表示領域
DRAW grid !座標を描く

CALL fvSEGMENT(-2,0,1,0) !AB
PLOT TEXT ,AT -2,0: "A"
CALL fvSEGMENT(1,0,1,4) !BC
PLOT TEXT ,AT 1,0: "B"
CALL fvSEGMENT(1,4,-2,0) !CA
PLOT TEXT ,AT 1,4: "C"

!折り返し
SET LINE COLOR 4
CALL fvSEGMENT(0,1,1,3) !P

CALL fvSYMMETRY2(1,1,2,1, xx,yy) !B'
PRINT xx;yy

SET LINE COLOR 2
CALL fvSEGMENT(0,0,0,1)
CALL fvSEGMENT(0,1,xx,yy)
CALL fvSEGMENT(xx,yy,1,3)

END

!●作図ルーチン

!直線
EXTERNAL SUB fvSEGMENT(x1,y1,x2,y2) !線分
PLOT LINES: x1,y1; x2,y2
END SUB

!●計算ルーチン

!点対称

!点(x,y)の原点に対称な点は、(-x,-y)より、点(a,b)に対しては、(-(x-a)+a,-(y-b)+b)=(2a-x,2b-y)
EXTERNAL SUB fvSYMMETRY(x,y,a,b, xx,yy) !点(a,b)に対称な点(点(a,b)を基準に180度回転した点)
LET xx=2*a-x
LET yy=2*b-y
END SUB

!線対称

EXTERNAL SUB fvSYMMETRY22(x,y,a, xx,yy) !直線Y=a*Xに対称な点
LET m1=1-a*a
LET m2=2*a
LET m3=1+a*a
LET xx=(m1*x+m2*y)/m3
LET yy=(m2*x-m1*y)/m3
END SUB

EXTERNAL SUB fvSYMMETRY2(x,y,a,b, xx,yy) !直線Y=a*X+bに対称な点
LET m1=1-a*a
LET m2=2*a
LET m3=1+a*a
LET xx=(m1*x+m2*y-2*b*a)/m3
LET yy=(m2*x-m1*y+2*b)/m3
END SUB

!点(x,y)のy軸に対称な点は、(-x,y)より、直線X=aについては、(-(x-a)+a,y)=(2a-x,y)
EXTERNAL SUB fvSYMMETRYh(x,y,a, xx,yy) !直線X=aに対称な点
LET xx=2*a-x
LET yy=y
END SUB

!点(x,y)のx軸に対称な点は、(x,-y)より、直線Y=bについては、(x,-(y-b)+b)=(x,2b-y)
EXTERNAL SUB fvSYMMETRYv(x,y,b, xx,yy) !直線Y=bに対称な点
LET xx=x
LET yy=2*b-y
END SUB

!回転

EXTERNAL SUB fvROTATE90(x,y,a,b, xx,yy) !点(a,b)を基準に90度回転した点
LET xx=-(y-b)+a
LET yy= (x-a)+b
END SUB

EXTERNAL SUB fvROTATEm90(x,y,a,b, xx,yy) !点(a,b)を基準に-90度回転した点
LET xx= (y-b)+a
LET yy=-(x-a)+b
END SUB



その他の解の例
 

入門言語について

 投稿者:kikiriri  投稿日:2013年 1月26日(土)13時25分42秒
  BASICが、最適である理由を、もう少し砕いてお教え願えませんか。よく使うコマンド数が少ないからですか。
あとプログラムを作る機会よりは、エクセルのVBAの方が、
機会が多いというか、とある通信教育で、一度、カリキュラ
ムを、こなしたぐらいです。今、思えば、BASICがいいなと思います。背伸びをして、C言語をやりたかったので、
basicの勉強ができませんでした。一度は家計簿ソフトを作ろうかとも思いましたが、今パソコン教室に通っていて、年賀状作成ソフトを作るのと同じぐらい、家計簿マムがプレインストールされたパソコンでは、家計簿ソフトを作るのは
無駄ではないが、もっと自分を啓蒙させなくては駄目だと思いました。

善きご助言をお願いします。
 

Re: 入門言語について

 投稿者:白石和夫  投稿日:2013年 1月27日(日)10時25分44秒
  > No.2968[元記事へ]

「〇〇ソフトを作る」という目的にFull BASICは適さないと思います。JavaのようにGUIが作れてイベント駆動ができるものがアプリケーション作成には適しているのではないでしょうか。
 Full BASICが適するのは問題解決のための計算です。コンピュータの能力を限界まで引き出さなければ解決できないような本格的な応用には適しませんが,計算は瞬時に終わってしまうのにプログラムを書くのに手間がかかってしまうような場合にFull BASICが勧められます。計算プログラムを作るのにプロトタイプをFull BASICで書いて,本番はPascalとかCに書き直すというのも有効な手段です。また,BASICAccを利用すれば,実用上,十分な速さが得られることが多いと思います。そんな場合は,他の言語はいりません。
 Full BASICでは書けない(あるいは書きにくい)アルゴリズムが存在するのも事実です。そういうアルゴリズムの記述の必要性を知れば他の言語を始めるきっかけになると思います。


 

数のピラミッド

 投稿者:山中和義  投稿日:2013年 1月27日(日)10時45分50秒
  数のピラミッド

1 * (1) = 1^2
121 * (1+2+1) = 22^2
12321 * (1+2+3+2+1) = 333^2
1234321 * (1+2+3+4+3+2+1) = 4444^2
123454321 * (1+2+3+4+5+4+3+2+1) = 55555^2
12345654321 * (1+2+3+4+5+6+5+4+3+2+1) = 666666^2
1234567654321 * (1+2+3+4+5+6+7+6+5+4+3+2+1) = 7777777^2
123456787654321 * (1+2+3+4+5+6+7+8+7+6+5+4+3+2+1) = 88888888^2
12345678987654321 * (1+2+3+4+5+6+7+8+9+8+7+6+5+4+3+2+1) = 999999999^2

考察
123…(n-1)n(n-1)…321について
 (1がn個並ぶ数)の2乗である。
例
 11*11=121
 111*111=12321

1+2+3+ … +(n-1)+n+(n-1)+ … +3+2+1について
  1+2+3+   … +n
 +  1+2+3+ … +(n-1)
 ---------------------------
  1+3+5+   … +(2n-1)=n^2 ∵奇数の和より
例
 1+2+1=4=2^2
 1+2+3+2+1=9=3^2
(終り)

OPTION ARITHMETIC RATIONAL !多桁の整数

FOR N=1 TO 9

   PRINT ( N*(10^N-1)/9 )^2 / N^2; "* (";

   FOR i=1 TO N-1 !分母 昇順
      PRINT STR$(i); "+";
   NEXT i
   PRINT STR$(N);
   FOR i=N-1 TO 1 STEP -1 !降順
      PRINT "+"; STR$(i);
   NEXT i
   PRINT ")";

   PRINT " = "; STR$(N*(10^N-1)/9); "^2"

NEXT N

END

 

Re: 入門言語について

 投稿者:白石和夫  投稿日:2013年 1月27日(日)10時59分35秒
  > No.2969[元記事へ]

補足です。

よく使うコマンド数が少ないから簡単だというのは幻想にすぎません。
たとえば,旧規格の基本BASICは,IF ・・・ THEN 行番号 とGOTO 行番号 を用いてプログラムの流れを書きますが,それでアルゴリズムの記述が楽だと思えるのは,手始めのほんの短期間だけです。
 

Re: 入門言語について

 投稿者:kikiriri  投稿日:2013年 1月27日(日)14時03分27秒
  白石和夫さんへのお返事です。


白石先生へ

  早速のご返信ありがとうございました。「レスを二つも!!」

 参考にさせていただきたいです。
> 補足です。
>
> よく使うコマンド数が少ないから簡単だというのは幻想にすぎません。
> たとえば,旧規格の基本BASICは,IF ・・・ THEN 行番号 とGOTO 行番号 を用いてプログラムの流れを書きますが,それでアルゴリズムの記述が楽だと思えるのは,手始めのほんの短期間だけです。
>
 

VBAについて

 投稿者:kikiriri  投稿日:2013年 1月27日(日)17時14分54秒
  VBAの可能性というか、実務で使用すると思うんですが、入門には不適ですか。
と、いうのも、プログラミングの面白さを知ったのは、日経PCの、エクセルVBA大会
と、とある通信教育で助言を受けながらの、エクセルVBAだったもので、また、今、パソ
コン教室に通っていて、今は、ワードですが、エクセルの勉強が始まったら、VBAか、
マクロ、の勉強で、VBAの存在が効いてくると、思うので、まだ、MOSの勉強で精いっぱ
いですが、そのうち、VBAの勉強か、BASICの勉強をしたいと思うのですが、本がありません。
おすすめのものがあれば、ぜひ、ご紹介いただけないでしょうか??
 

Re: VBAについて

 投稿者:白石和夫  投稿日:2013年 1月27日(日)17時26分9秒
  > No.2973[元記事へ]

VBAは実務には使えると思います。
ただし,私には難しいです。

十進BASICに慣れた人がVBAを始めるときに,
Microsoft BASICからのFull BASIC入門
http://www.geocities.jp/thinking_math_education/MS2Full.htm
が(逆方向の入門にも)役に立つと思います。
 

Re: VBAについて

 投稿者:kikiriri  投稿日:2013年 1月27日(日)18時10分24秒
  > No.2974[元記事へ]

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

白石先生へ

  早速のご返信ありがとうございました。
 >ただし,私には難しいです。
 僕も実は、丁度いいくらいに難しそうだったので。
 新聞の日曜版の問題を、(クロスワードや間違い探し)
 と、(同じではないですが)解くような面白さがありました。
 {VBAの問題を解くのは}なので、思い切って、通信教育を始めました。
 先生がわかっている人で、側{ネットの向こう側}に居てもらえることが、
 こんなに良い事とは思えない位に良い事でして、では、と、パソコン教室に通い
 先生が本当に存在する場所で、勉強をしています。マンツーマンでもなく、
 授業形式でもないのですが、運転免許と同じくらい、ウキウキ、ワクワクしました。
 でも、本当は、すごくビビりまくりで、中々ここに居ていいんだと思えなくて。
 授業が進んでいるのですが、オフィス系ならアクセスを習いたいんですけど。
 パワーポイントもアクセスも、2010年版が買えそうにないので、
 ワードとエクセル、が終わったらお話ししないとと、思っています。
 活き込んで、VBAや、アクセスの話をしたら、VBAは駄目だけど、
 パワーポイントと、アクセスは、できますよと言われています。

                                    以上
     長文失礼しました。

> VBAは実務には使えると思います。
> ただし,私には難しいです。
>
> 十進BASICに慣れた人がVBAを始めるときに,
> Microsoft BASICからのFull BASIC入門http://www.geocities.jp/thinking_math_education/MS2Full.htm
> が(逆方向の入門にも)役に立つと思います。
>
 

秤の問題

 投稿者:山中和義  投稿日:2013年 1月30日(水)12時57分9秒
  問題
金貨の入った袋が5袋ある。
4袋には10gの金貨が入っているが、1袋だけ9gの金貨が入っている。
グラム単位で量れる秤を1回だけ使って、どの袋が9gの金貨が入っているのか当てよ。

答え
それぞれの袋から、0,1,2,3,4枚とる。
全部10gなら、10x(0+1+2+3+4)=100gとなるが、9gのものがあるのでその分軽くなる。
100gよりAg軽かったら、A枚とった袋が9gである。
(終り)


LET N=5 !袋の個数
DATA 10,10,10,9,10 !A,B,C,D,Eの順に

DIM S(N)
MAT READ S
MAT PRINT S; !debug

LET T=0
FOR i=1 TO N
   LET T=T+S(i)*(i-1) !0,1,2,3,4
NEXT i
PRINT 10*(N-1)*N/2-T+1;"番目"



!その2 m進法

LET T=0
FOR i=1 TO N
   LET T=T+(S(i)-9)*2^(i-1) !1,2,4,8,16,…
NEXT i
PRINT T !debug

FOR i=1 TO N !A,B,C,D,Eの順に
   PRINT MOD(T,2); !0:9g、1:10gを表す
   LET T=INT(T/2)
NEXT i
PRINT



!その3 デジタル表示

LET T=0
FOR i=1 TO N
   LET T=T+S(i)*100^(N-i) !100^0,100^1,100^2,100^3,…
NEXT i
PRINT T;"番目"

END

 

天秤ばかりの問題

 投稿者:山中和義  投稿日:2013年 1月30日(水)17時18分48秒
  > No.2976[元記事へ]

問題
たくさんの塩があります。
ここに、天秤ばかりと、2gと7gの分銅がひとつずつあります。
天秤ばかりと分銅を使って、塩50gを量りなさい。

類題
140gの塩があります。
ここに、天秤ばかりと、2gと7gの分銅がひとつずつあります。
天秤ばかりと分銅を使って、塩を50gと90gに分割しなさい。

答え
不定方程式2x+7y=50の解のひとつは、(x,y)=(4,6)より、
2gの分銅で4回、7gの分銅で6回、計10回量ればよい。

量った塩を分銅として使う場合、
  左     右
  2+7+(0)   9  1回目
   7+(9)   16  2回目
+   (9+16) 25  3回目
-------------------
        50g
とすれば、3回となる。

回数は、max(x,y)<2^kを満たす最小のkとなる。
手順は、
 x=4=100[2]、y=6=110[2]なので、
  1 1
  0 1
  0 0
 と上位から順に並べる。(上記の表を参照のこと)
 これを元に、1のときに分銅を使い、量った塩の和と一緒に新しい塩を量っていく。
とすればよい。
(終り)


LET A=2 !ax+by=c
LET B=7
LET C=50

FOR X=0 TO INT(C/A) !非負の整数解
   LET Y=(C-A*X)/B
   IF Y=INT(Y) THEN
      PRINT "(x,y)=("; X; Y; ")"


      LET XX=X !手順を表示する
      LET YY=Y

      LET K=INT(LOG10(MAX(XX,YY))/LOG10(2))+1
      PRINT K;"回"

      LET S=0 !量った塩
      LET T=0
      LET R=2^(K-1) !2進法k桁へ ※上位から
      FOR J=K TO 1 STEP -1
         LET P=INT(XX/R) !k桁目
         LET Q=INT(YY/R)

         PRINT P;Q;"+"; S;T; "="; S+P;T+Q !表を表示する
         LET S=2*S+P
         LET T=2*T+Q

         LET XX=MOD(XX,R) !次へ
         LET YY=MOD(YY,R)
         LET R=R/2
      NEXT J
      PRINT
   END IF
NEXT X

END

 

フラクタルポップコーン

 投稿者:望月健一  投稿日:2013年 2月 2日(土)21時26分10秒
  ! フラクタルポップコーン
!  「コンピューターレクリエーション Ⅳ 遊びの展開」
!  日経サイエンス より

SET WINDOW -8,8,-8,8
SET POINT STYLE 1
LET h=0.05
RANDOMIZE
LET c = INT(MOD(RND*9999,225))+1

FOR j=1 TO 50           ! x方向
   FOR k=1 TO 50        ! y方向
      LET x=-6+0.24*j
      LET y=-6+0.24*k

      FOR n=1 TO 50
         LET xx=x-h*sin(y+TAN(3*y))
         LET yy=y-h*sin(x+TAN(3*x))

         PLOT POINTS :xx,yy

         IF MOD(I,10000)=0 THEN
            LET c=c+1
            LET i=0

            IF c>225 THEN
               LET c=c-225
            END if

            SET POINT COLOR c
         END IF

         LET i=i+1
         LET x=xx
         LET y=yy

      NEXT n
   NEXT k
NEXT j

END
 

Re: 秤の問題

 投稿者:山中和義  投稿日:2013年 2月 3日(日)14時07分44秒
  > No.2976[元記事へ]

問題
パチンコ玉が3個あります。外見では見分けはつきません。
そのうち2個は同じ重さで、1個だけ重さが少し違うことがわかっています。
ただし、重いか軽いかは不明です。
バネ秤を3回使って、この1個の玉を選び出してください。
また、2個の玉は何グラム、1個の玉は何グラムまで出してほしいのです。

答え
パチンコ玉をA,B,Cとして、その重さをa,b,cとする。
○は同じ重さ、●は少し違う重さを表すとして、
 a b c
 ○○●
 ○●○
 ●○○
以上の3通りである。

手法A:それまでの測定結果によって、次の回のはかり方を決める方法


LET a=1
LET b=2
LET c=2

LET w1=a
LET w2=b
PRINT "w1=";w1; "w2=";w2 !debug

IF w1=w2 THEN !cが偽
   LET w3=c
   PRINT "w3=";w3 !debug

   LET x=w1
   LET y=w3
   PRINT "x=";x; "y=";y; "偽C"
ELSE
   LET w3=c
   PRINT "w3=";w3 !debug

   IF w3=w1 THEN !bが偽
      LET x=w3
      LET y=w2
      PRINT "x=";x; "y=";y; "偽B"
   ELSEIF w3=w2 THEN !aが偽
      LET x=w2
      LET y=w1
      PRINT "x=";x; "y=";y; "偽A"
   ELSE
      PRINT "論理エラー"
   END IF
END IF

END



手法B:最初にすべての回のはかり方を決め、全結果から答えを出す方法


LET a=1
LET b=2
LET c=2

LET w1=a
LET w2=b
LET w3=c
PRINT "w1=";w1; "w2=";w2; "w3=";w3 !debug

IF w1=w2 THEN !cが偽
   LET x=w1
   LET y=w3
   PRINT "x=";x; "y=";y; "偽C"
ELSEIF w3=w1 THEN !aが偽
   LET x=w3
   LET y=w2
   PRINT "x=";x; "y=";y; "偽B"
ELSEIF w2=w3 THEN !bが偽
   LET x=w2
   LET y=w1
   PRINT "x=";x; "y=";y; "偽A"
ELSE
   PRINT "論理エラー"
END IF

END

 

Re: 秤の問題

 投稿者:山中和義  投稿日:2013年 2月 4日(月)10時21分58秒
  > No.2979[元記事へ]

> 問題
> パチンコ玉が3個あります。外見では見分けはつきません。
> そのうち2個は同じ重さで、1個だけ重さが少し違うことがわかっています。
> ただし、重いか軽いかは不明です。
> バネ秤を3回使って、この1個の玉を選び出してください。
> また、2個の玉は何グラム、1個の玉は何グラムまで出してほしいのです。

手法A:それまでの測定結果によって、次の回のはかり方を決める方法

●パチンコ玉が4個の場合

LET a=1
LET b=2
LET c=2
LET d=2

LET w1=a
LET w2=b+c
PRINT "w1=";w1; "w2=";w2 !debug

IF 2*w1=w2 THEN !dが偽 ※a=b=cより
   LET w3=d
   PRINT "w3=";w3 !debug

   LET x=w1 !a
   LET y=w3 !d
   PRINT "x=";x; "y=";y; "偽D"
ELSE
   LET w3=b
   PRINT "w3=";w3 !debug

   IF w3=w1 THEN !cが偽 ※a=bより
      LET x=w1 !a
      LET y=w2-w3 !(b+c)-b
      PRINT "x=";x; "y=";y; "偽C"
   ELSEIF 2*w3=w2 THEN !aが偽 ※b=cより、w3=w2-w3 ∴2*w3=w2
      LET x=w3 !b
      LET y=w1 !a
      PRINT "x=";x; "y=";y; "偽A"
   ELSEIF w1=w2-w3 THEN !bが偽 ※a=cより、w1=w2-w3
      LET x=w1 !a
      LET y=w3 !b
      PRINT "x=";x; "y=";y; "偽B"
   ELSE
      PRINT "論理エラー"
   END IF
END IF

END


●パチンコ玉が5個の場合

LET a=2
LET b=2
LET c=1
LET d=2
LET e=2

LET w1=a+b
LET w2=c+d
PRINT "w1=";w1; "w2=";w2 !debug

IF w1=w2 THEN !eが偽 ※a=b=c=dより
   LET w3=e
   PRINT "w3=";w3 !debug

   LET x=w1/2 !x=w2/2
   LET y=w3
   PRINT "x=";x; "y=";y; "偽E"
ELSE
   LET w3=a+c+e
   PRINT "w3=";w3 !debug

   IF 2*w3=3*w1 THEN !e=a=c=bより、w3=a+c+e=3e、w1=a+b=2e
      LET x=w1/2 !x=w3/3
      LET y=w2-x
      PRINT "x=";x; "y=";y; "偽D"
   ELSEIF 2*w3=3*w2 THEN !e=a=c=dより、w3=a+c+e=3e、w2=c+d=2e
      LET x=w2/2 !x=w3/3
      LET y=w1-x
      PRINT "x=";x; "y=";y; "偽B"
   ELSEIF 2*(w3-w2)=w1 THEN !e=b=d=aより、w3-w2=(a+c+e)-(c+d)=a+e-d=e、w1=a+b=2e
      LET x=w1/2 !x=w3-w2
      LET y=w2-x !y=w3-w1
      PRINT "x=";x; "y=";y; "偽C"
   ELSEIF 2*(w3-w1)=w2 THEN !e=b=d=cより、w3-w1=(a+c+e)-(a+b)=c+e-b=e、w2=c+d=2e
      LET x=w2/2 !x=w3-w1
      LET y=w1-x !y=w3-w2
      PRINT "x=";x; "y=";y; "偽A"
   ELSE
      PRINT "論理エラー"
   END IF
END IF

END


●パチンコ玉が6個の場合

LET a=2
LET b=2
LET c=2
LET d=2
LET e=3
LET f=2

LET w1=a+b+c+d
LET w2=a+b    +e
PRINT "w1=";w1; "w2=";w2 !debug

IF 3*w1=4*w2 THEN !eが偽 ※a=b=c=d=eより
   LET w3=f
   PRINT "w3=";w3 !debug

   LET x=w1/4 !x=w2/3
   LET y=w3
   PRINT "x=";x; "y=";y; "偽F"
ELSE
   LET w3=a+c
   PRINT "w3=";w3 !debug

   LET p=w1-w2 !w1-w2=(a+b+c+d)-(a+b+e)=c+d-e
   LET q=w2-w3 !w2-w3=(a+b+e)-(a+c)=b+e-c
   LET r=w1-w3 !w1-w3=(a+b+c+d)-(a+c)=b+d
   PRINT "p=";p; "q=";q; "r=";r !debug

   IF p=q THEN !f=b=c=d=eより、p=c+d-e=f+f-f=f、q=b+e-c=f+f-f=f
      LET x=p
      LET y=w3-x
      PRINT "x=";x; "y=";y; "偽A"
   ELSEIF 2*p=w3 THEN !f=a=c=d=eより、p=c+d-e=f+f-f=f、w3=a+c=f+f=2f
      LET x=p
      LET y=r-x
      PRINT "x=";x; "y=";y; "偽B"
   ELSEIF 3*r=2*w2 THEN !f=a=b=d=eより、r=b+d=f+f=2f、w2=a+b+e=f+f+f=3f
      LET x=r/2
      LET y=w3-x
      PRINT "x=";x; "y=";y; "偽C"
   ELSEIF 2*w2=3*w3 THEN !f=a=b=c=eより、w2=a+b+e=f+f+f=3f、w3=a+c=f+f=2f
      LET x=w3/2
      LET y=r-x
      PRINT "x=";x; "y=";y; "偽D"
   ELSEIF 2*w1=4*w3 THEN !f=a=b=c=dより、w1=a+b+c+d=f+f+f+f=4f、w3=a+c=f+f=2f
      LET x=w1/4
      LET y=w2-2*x
      PRINT "x=";x; "y=";y; "偽E"
   ELSE
      PRINT "論理エラー"
   END IF
END IF

END

 

Re: 秤の問題

 投稿者:山中和義  投稿日:2013年 2月 5日(火)11時15分29秒
  > No.2980[元記事へ]

> 問題
> パチンコ玉が6個あります。外見では見分けはつきません。
> そのうち5個は同じ重さで、1個だけ重さが少し違うことがわかっています。
> ただし、重いか軽いかは不明です。
> バネ秤を3回使って、この1個の玉を選び出してください。
> また、5個の玉は何グラム、1個の玉は何グラムまで出してほしいのです。>

> 手法A:それまでの測定結果によって、次の回のはかり方を決める方法

近似解 3組の計測

2個ずつ取り出して3組をつくり、それぞれを量る。
(a,b)、(c,d)、(e,f)として、W1=a+b, W2=c+d, W3=e+f
同じ値のものが存在するので、他と違う1組の中の1個が、重さが少し違うパチンコ玉である。
よって、その組の1つを取り出して量る。たとえば、(e,f)とすると、W4=e
2*W4=W1のとき、x=W4(=W1/2=W2/2), y=W3-W4
2*W4≠W1のとき、x=W3-W4(=W1/2=W2/2), y=W4
したがって、4回となる。


この手法を使うと、7個の場合は、
2個ずつ取り出して3組をつくり、それぞれを量る。
(a,b)、(c,d)、(e,f)として、W1=a+b, W2=c+d, W3=e+f
・すべて同じ値(W1=W2=W3)のとき、残った1個が重さが少し違うパチンコ玉である。
 W4=gとして、x=W1/2(=W2/2=W3/2), y=W4
・他と違う1組が存在したとき、その中の1個が、重さが少し違うパチンコ玉である。
 たとえば、W3とすると、W4=e
  2*W4=W1のとき、x=W4(=W1/2=W2/2), y=W3-W4
  2*W4≠W1のとき、x=W3-W4(=W1/2=W2/2), y=W4
したがって、4回となる。
 

数列 - 中学入試から

 投稿者:山中和義  投稿日:2013年 2月 7日(木)11時36分53秒
  問題
コインがたくさんあり、そこからA君とB君の2人が交互にコインを取っていきます。
1回目はA君が1枚、2回目はB君が3枚、3回目はA君が5枚、4回目はB君が7枚、5回目はA君が9枚、…
というように、2人は自分が前に取った枚数より4枚多くコインを取ります。
何回か取った後、2人の持っているコインの枚数を比べたところ、差が31枚でした。
コインを多く持っているのはどちらですか。
また、その人が最後に取ったコインは何枚ですか。

答え
具体的に見ていくと、
 1回目: Aが1枚なので、差=1
 2回目: Bが3枚なので、差=3-1=2
 3回目: Aが5枚なので、差=5-3+1=3
 4回目: Bが7枚なので、差=7-5+3-1=4
 5回目: Aが9枚なので、差=9-7+5-3+1=5
 6回目: Bが11枚なので、差=11-9+7-5+3-1=6
 7回目: Aが13枚なので、差=13-11+9-7+5-3+1=7
  :
から、差は回数と同じ値を示す。
これより、差が31となるのは、「奇数回はA 偶数回はB」より、31回目のAの番である。
取る枚数は、2*回数-1より、2*31-1=61枚である。
(終り)

考察
 1回目: Aが1枚なので、差=1
 2回目: Bが3枚なので、差=3-1=2
 3回目: Aが5枚なので、差=5-3+1=5-(3-1)=3
 4回目: Bが7枚なので、差=7-5+3-1=7-(5-3+1)=4
 5回目: Aが9枚なので、差=9-7+5-3+1=9-(7-5+3-1)=5
 6回目: Bが11枚なので、差=11-9+7-5+3-1=11-(9-7+5-3+1)=6
 7回目: Aが13枚なので、差=13-11+9-7+5-3+1=13-(11-9+7-5+3-1)=7
  :
と解釈すれば、差は、
 自分が取る枚数 - 1つ前の相手の差
として求まる。
また、
 1回目: Aが1枚なので、差=1
 2回目: Bが3枚なので、差=3-1=2
 3回目: Aが5枚なので、差=5-3+1=(5-3)+1=3
 4回目: Bが7枚なので、差=7-5+3-1=(7-5)+{3-1}=4
 5回目: Aが9枚なので、差=9-7+5-3+1=(9-7)+{5-3+1}=5
 6回目: Bが11枚なので、差=11-9+7-5+3-1=(11-9)+{7-5+3-1}=6
 7回目: Aが13枚なので、差=13-11+9-7+5-3+1=(13-11)+{9-7+5-3+1}=7
  :
と解釈すれば、差は、
 { 自分が取る枚数 - 相手が取った枚数 } + 1つ前の自分の差
として求まる。
(終り)

別解
具体的に見ていくと、
 Aの和 1     6    15    28    45    66    91    …
    ┌──┬──┬──┬──┬──┬──┬──┬
    1  3  5  7  9 11 13 15 17 19 21 23 25 …
     └──┴──┴──┴──┴──┴──┴
 Bの和   3    10    21    36    55    78    …
 差  1  2  3  4  5  6  7  8  9 10 11 12 13 …
となる。
これより、
 回数をkとすると、kが奇数のときA 偶数のときBである。
 取る枚数は2k-1、持っている枚数はk(k+1)/2で与えられる。
となる。
k回目のとき、その差はk(k+1)/2-(k-1)k/2=kなので、31になるのは、k=31
よって、奇数回なのでA、その取る枚数は2*31-1=61枚である。
(終り)

別解
コインを取った回数をmとする。
具体的に見ていくと、
  m  1  2  3  4  5  6 …
  A  1  5  9 13 17 21 …
  B  3  7 11 15 19 23 …

 和A  1  6 15 28 45 66 …
 和B  3 10 21 36 55 78 …
となる。
これより、
 A,Bがそれぞれ取る枚数は4(m-1)+1,4(m-1)+3、持っている枚数はm(2m-1),m(2m+1)となる。
となる。
コインを多く持っている人がAの場合(Aが取ったとき)
 Bが(m-1)回目、Aがm回目のときなので、その差は、m(2m-1)-(m-1){2(m-1)+1}=2m-1
 これは奇数になる。よって、取る枚数は、2m-1=31より、m=16 ∴4*(16-1)+1=61枚
コインを多く持っている人がBの場合(Bが取ったとき)
 A,B共にm回目のときなので、m(2m+1)-m(2m-1)=2m
 これは偶数になる。よって、奇数31には成り得ない。
(終り)


!その1 シミュレーション

!1回目 差は1
LET P=1 !取る枚数
LET A=1 !持っている枚数
PRINT "1回: Aが取る枚数=";P; " 持っている枚数=";A

!2回目 差は2
LET Q=3
LET B=3
PRINT "2回: Bが取る枚数=";Q; " 持っている枚数=";B

!3回目以降
LET K=2 !回数
DO
   LET K=K+1

   IF MOD(K,2)=1 THEN !奇数回はAの番
      LET P=P+4
      LET A=A+P
      PRINT STR$(K);"回: Aが取る枚数=";P; " 持っている枚数=";A
   ELSE !Bの番
      LET Q=Q+4
      LET B=B+Q
      PRINT STR$(K);"回: Bが取る枚数=";Q; " 持っている枚数=";B
   END IF
LOOP UNTIL ABS(A-B)=31 !条件を満たすまで

PRINT K;"回"
PRINT "A=";P; "枚数="; A
PRINT "B=";Q; "枚数="; B


PRINT


!その2 シミュレーション

LET A=0 !1つ前の結果
LET B=0

LET K=0 !回数
DO
   LET K=K+1

   LET T=2*K-1 !取る枚数

   IF MOD(K,2)=1 THEN !奇数回はAの番
      LET A=T-B
      PRINT STR$(K);"回: Aが取る枚数=";T; " 差=";A
   ELSE !Bの番
      LET B=T-A
      PRINT STR$(K);"回: Bが取る枚数=";T; " 差=";B
   END IF
LOOP UNTIL A=31 OR B=31 !条件を満たすまで

PRINT K;"回"
IF MOD(K,2)=1 THEN !奇数回はAの番
   PRINT "A=";2*K-1; "枚数="; K*(K+1)/2
   PRINT "B=";2*K-3; "枚数="; (K-1)*K/2
ELSE !Bの番
   PRINT "A=";2*K-3; "枚数="; (K-1)*K/2
   PRINT "B=";2*K-1; "枚数="; K*(K+1)/2
END IF

END


実行結果

1回: Aが取る枚数= 1  持っている枚数= 1
2回: Bが取る枚数= 3  持っている枚数= 3
3回: Aが取る枚数= 5  持っている枚数= 6
4回: Bが取る枚数= 7  持っている枚数= 10
5回: Aが取る枚数= 9  持っている枚数= 15
6回: Bが取る枚数= 11  持っている枚数= 21
7回: Aが取る枚数= 13  持っている枚数= 28
8回: Bが取る枚数= 15  持っている枚数= 36
9回: Aが取る枚数= 17  持っている枚数= 45
10回: Bが取る枚数= 19  持っている枚数= 55
11回: Aが取る枚数= 21  持っている枚数= 66
12回: Bが取る枚数= 23  持っている枚数= 78
13回: Aが取る枚数= 25  持っている枚数= 91
14回: Bが取る枚数= 27  持っている枚数= 105
15回: Aが取る枚数= 29  持っている枚数= 120
16回: Bが取る枚数= 31  持っている枚数= 136
17回: Aが取る枚数= 33  持っている枚数= 153
18回: Bが取る枚数= 35  持っている枚数= 171
19回: Aが取る枚数= 37  持っている枚数= 190
20回: Bが取る枚数= 39  持っている枚数= 210
21回: Aが取る枚数= 41  持っている枚数= 231
22回: Bが取る枚数= 43  持っている枚数= 253
23回: Aが取る枚数= 45  持っている枚数= 276
24回: Bが取る枚数= 47  持っている枚数= 300
25回: Aが取る枚数= 49  持っている枚数= 325
26回: Bが取る枚数= 51  持っている枚数= 351
27回: Aが取る枚数= 53  持っている枚数= 378
28回: Bが取る枚数= 55  持っている枚数= 406
29回: Aが取る枚数= 57  持っている枚数= 435
30回: Bが取る枚数= 59  持っている枚数= 465
31回: Aが取る枚数= 61  持っている枚数= 496
31 回
A= 61 枚数= 496
B= 59 枚数= 465

1回: Aが取る枚数= 1  差= 1
2回: Bが取る枚数= 3  差= 2
3回: Aが取る枚数= 5  差= 3
4回: Bが取る枚数= 7  差= 4
5回: Aが取る枚数= 9  差= 5
6回: Bが取る枚数= 11  差= 6
7回: Aが取る枚数= 13  差= 7
8回: Bが取る枚数= 15  差= 8
9回: Aが取る枚数= 17  差= 9
10回: Bが取る枚数= 19  差= 10
11回: Aが取る枚数= 21  差= 11
12回: Bが取る枚数= 23  差= 12
13回: Aが取る枚数= 25  差= 13
14回: Bが取る枚数= 27  差= 14
15回: Aが取る枚数= 29  差= 15
16回: Bが取る枚数= 31  差= 16
17回: Aが取る枚数= 33  差= 17
18回: Bが取る枚数= 35  差= 18
19回: Aが取る枚数= 37  差= 19
20回: Bが取る枚数= 39  差= 20
21回: Aが取る枚数= 41  差= 21
22回: Bが取る枚数= 43  差= 22
23回: Aが取る枚数= 45  差= 23
24回: Bが取る枚数= 47  差= 24
25回: Aが取る枚数= 49  差= 25
26回: Bが取る枚数= 51  差= 26
27回: Aが取る枚数= 53  差= 27
28回: Bが取る枚数= 55  差= 28
29回: Aが取る枚数= 57  差= 29
30回: Bが取る枚数= 59  差= 30
31回: Aが取る枚数= 61  差= 31
31 回
A= 61 枚数= 496
B= 59 枚数= 465

 

15パズルとあみだくじ

 投稿者:永野護  投稿日:2013年 2月 7日(木)15時05分57秒
  15パズルをあみだくじで解く方法があるそうですが、どのようにするのでしょうか。
よろしければ教えてください。
 

15パズルとあみだくじ

 投稿者:永野護  投稿日:2013年 2月 7日(木)15時21分12秒
  追伸
http://www.h6.dion.ne.jp/~ooya/Suugaku/Amida.html
参考までに上記に似た問題が出ています。
 

旅人算 - 中学入試から

 投稿者:山中和義  投稿日:2013年 2月12日(火)13時49分21秒
  > No.2982[元記事へ]

問題
A君とB君がX地点を同時に出発して、Y地点までそれぞれ一定の速さで歩き続けました。
C君は2人が出発してから5分後にX地点を出発し、一定の速さで走り続けて2人を追いかけました。
C君は出発して5分後にB君に追いつき、その10分後にA君に追いつきました。
(1)A君、B君、C君の速さの比をできるだけ簡単な整数の比で表しなさい。
C君はA君に追いついて、すぐに来た道を同じ速さで引き返しました。
(2)次に、C君がB君に出会うのは、C君がA君に追いついてから何分後ですか。分数で答えなさい。
C君はB君に出会って、すぐにまた同じ速さでY地点に向かったところ、A君と同時にY地点に到着しました。
(3)C君の走った道のりの合計が5kmのとき、X地点からY地点までの距離を求めなさい。

答え
(1) ※移動した距離は同じで1とする
B君がC君と出会うまでに移動した距離を1とすると、速度=距離÷時間なので
B君の速度:C君の速度=1/(5+5):1/5=1/10:1/5=1:2=2:4
同様に、A君の速度:C君の速度=1/(5+5+10):1/(5+10)=1/20:1/15=3:4
A君の速度:B君の速度:C君の速度=3:2:4

(2) ※B君の速度を1とする
C君がA君に追いついたとき、B君とC君のそれぞれが移動した(X地点からの)距離は、
B君の速度を1とすると、1×(5+5+10)=20、2×(5+10)=30となる。その差は、30-20=10である。
この距離をB君とC君が向い合って移動するので、
B君とC君の速度の和で移動する時間として、10÷(1+2)=10/3分である。

(3) ※A君の速度を1とする → C君の速度が分数になるので、A君の速度を3とする
C君がA君と同時にY地点に到着した時間について
 C君がB君に出会ったとき、A君とC君との距離は、反対方向に移動した距離なので、
 A君の速度を3とすると、(3+4)×(10/3)=70/3となる。
 この距離はC君がA君に再度追いついた距離なので、
 C君とA君の速度の差で移動する時間として、(70/3)÷(4-3)=70/3分である。
よって、C君の歩いた道のりは、4×(5+10+10/3+70/3)=500/3
X地点からY地点までの距離は、A君が歩いた距離なので、3×(5+5+10+10/3+70/3)=140
したがって、5:□=500/3:140より、□=5×140÷(500/3)=21/5=4.2km
(終り)

別解 ダイヤ図(運行図表)
(1)
C君の速度を1とする。これをもとにA君とB君の速度を表す。
横軸を時間、縦軸を距離とするグラフを考える。速度×時間=距離より、
C君について、
 傾き1、点(5,0)を通るので、Y-0=1*(X-5) ∴Y=X-5
B君について、
 原点と点P(5+5,(5+5)-5)を通るので、Y={(((5+5)-5)-0)/((5+5)-0)}X ∴Y=(1/2)X
A君について、
 原点と点Q(5+5+10,(5+5+10)-5)を通るので、Y={(((5+5+10-5)-0)/((5+5+10)-0)}X ∴Y=(3/4)X
したがって、3/4:1/2:1=3:2:4
(2)
傾き-1(Y=X-5に直交する)、点Qを通る直線を考える。
この直線は、Y-{(5+5+10)-5}=-(X-(5+5+10)) ∴Y=-X+35
この直線とY=(1/2)Xとの交点Rが、C君がB君に出会ったときを表す。
連立方程式を解いて、X=70/3
したがって、70/3-(5+5+10)=10/3[分]
(3)
傾き1(Y=X-5に平行である)、交点Rを通る直線を考える。
この直線は、Y-35/3=(X-70/3) ∴Y=X-35/3
この直線とY=(3/4)Xとの交点が、C君がA君と同時にY地点に到着したときを表す。
連立方程式を解いて、X=140/3、Y=35
C君の走った道のりは、ひたすらまっすぐに走った距離に相当するので、
X=140/3をY=X-5に代入して、140/3-5=125/3
したがって、125/3:35=5:□より、□=5*35/(125/3)=21/5=4.2[km]
(終り)


SET WINDOW -1,50,-1,50 !表示領域
DRAW grid(5,5) !座標を描く

!(1)
SET LINE COLOR 4
DEF f(x)=x-5 !直線C ∵傾き1、点(5,0)を通る
CALL fvLINE(1,-5, 0,50)

SET LINE COLOR 1
LET t=5+5 !点(0,0)、点P(5+5,(5+5)-5)を通る
CALL fvPOINT(t,f(t),"P")
LET b=(f(t)-0)/(t-0)
CALL fvLINE(b,0, 0,50) !直線B Y=(1/2)X

SET LINE COLOR 2
LET t=5+5+10 !点(0,0)、点Q(5+5+10,(5+5+10)-5)を通る
CALL fvPOINT(t,f(t),"Q")
LET a=(f(t)-0)/(t-0)
CALL fvLINE(a,0, 0,50) !直線A Y=(3/4)X

!(1)の答え 3/4:1/2:1=3:2:4


!(2)
SET LINE COLOR 4
LET t=5+5+10
CALL fvLINE(-1,t+f(t), 0,50) !直線D Y-f(t)=-(X-t) ∵傾き-1、点Qを通るより


CALL fvINTERSECTION(-1,t+f(t),b,0, x,y) !交点R
CALL fvPOINT(x,y,"R")
PRINT x; y !debug
PRINT x-t !(2)の答え


!(3)
CALL fvLINE(1,-x+y, 0,50) !直線E Y-y=(X-x) ∵傾き1、点Rを通るより

CALL fvINTERSECTION(1,-x+y,a,0, xx,yy) !交点Y
CALL fvPOINT(xx,yy,"Y")
PRINT xx; yy !debug

CALL fvPOINT(xx,f(xx),"S")
PRINT f(xx);":"; a*xx; "= 5 : □"
PRINT a*xx * 5 / f(xx) !(3)の答え

END

!関数でお絵かき
! http://6317.teacup.com/basic/bbs/2967
! http://6317.teacup.com/basic/bbs/2018
!を参照のこと

!●作図ルーチン

EXTERNAL SUB fvPOINT(x,y,S$) !点(x,y)
DRAW disk WITH SCALE(0.5)*SHIFT(x,y) !※大きさは調整が必要である
PLOT TEXT ,AT x+0.5,y+0.5: S$ !※位置は調整が必要である
END SUB

EXTERNAL SUB fvLINE(A,B, P,Q) !直線y=Ax+B, x∈[P,Q]
PLOT LINES: P,A*P+B; Q,A*Q+B
END SUB


!●計算ルーチン

EXTERNAL SUB fvINTERSECTION(A,B,C,D, x,y) !2直線y=Ax+Bとy=Cx+Dとの交点(x,y)を求める
IF A=C THEN
   PRINT "2直線は平行です。"; A;C
ELSE
   LET x=(D-B)/(A-C)
   LET y=A*x+B
END IF
END SUB


実行結果 ※有理数モードにて

70/3  35/3
10/3
140/3  35
125/3 : 35 = 5 : □
21/5



 

循環節の性質

 投稿者:山中和義  投稿日:2013年 2月15日(金)11時32分51秒
  既約分数m/n(0<m<nを満たす整数)の循環節の性質
例
循環節の長さが偶数のとき、半分で切って足し合わせると、9が並ぶ。
1/7=0.{142857}の場合、142+857=999

考察
●2分割
循環節の長さを2kとする。
循環節の前半部分のk桁をa、後半部分のk桁をbとする。
題意より、a+b=10^k-1
既約分数m/nは、m/n=(a*10^k+b)/(10^(2k)-1)と表される。
∴m{10^(2k)-1}=n(a*10^k+b)
∴m{10^(2k)-1}=n{a*10^k+(10^k-1-a)}
∴m(10^k+1)(10^k-1)=n(a+1)(10^k-1)
∴m(10^k+1)=n(a+1)
m,nは互いに素なので、nは(10^k+1)の約数となる。
例
1/7=142857/999999=(142*1000+857)/999999=0.{142857}の場合、142+857=999
循環節の長さが6なので、k=3 ∴10^3+1=1001=7*11*13

●3分割
循環節の長さを3kとする。
循環節の前1/3部分のk桁をa、真ん中1/3部分のk桁をb、後1/3部分のk桁をcとする。
題意より、a+b+c=10^k-1
既約分数m/nは、m/n=(a*10^(2k)+b*10^k+c)/(10^(3k)-1)と表される。
∴m{10^(3k)-1}=n(a*10^(2k)+b*10^k+c)
∴m{10^(3k)-1}=n{a*10^(2k)+b*10^k+(10^k-1-a-b)}
∴m(10^k-1){10^(2k)+10^k+1}=n(10^k-1){a*(10^k+1)+b+1}
∴m{10^(2k)+10^k+1}=n{a*(10^k+1)+b+1}
m,nは互いに素なので、nは(10^(2k)+10^k+1)の約数となる。
例
1/7=142857/999999=(14*10000+28*100+57)/999999=0.{142857}の場合、14+28+57=99
循環節の長さが6なので、k=2 ∴10^4+10^2+1=10101=3*7*13*37
(終り)


!!DATA 3 !個数
!!DATA 7,11,13 !素因数

DATA 4 !個数
DATA 3,7,13,37 !素因数

READ D
DIM F(D) !素因数
MAT READ F
MAT PRINT F; !debug


FOR i=1 TO D !素因数の組み合わせで分母の候補を得る
   FOR h=0 TO COMB(D,i)-1

      LET m=1 !分子

      LET n=1 !分母
      LET T=Num2CombBit(h,D,i)
      FOR J=1 TO D
         IF MOD(T,2)=1 THEN LET n=n*F(J)
         LET T=INT(T/2)
      NEXT J

      CALL cycle(m,n,k,L) !循環節の長さを得る

      PRINT m;"/";n;"="; !純循環小数として表示する ※k=0
      PRINT "0.{";right$(REPEAT$("0",L)&STR$(INT(10^(k+L)*m/n)),L);"} 循環節=";L

   NEXT h
NEXT i

END


EXTERNAL SUB cycle(m,n,k,L) !既約分数m/n(0<m<nを満たす整数)の有限小数の桁数kと循環節の長さLを求める
!n/m=0.ab…z{AB…Z} 有限小数0.ab…zはk桁 (k+1)桁からの循環節AB…Zの長さはL
LET x=n

LET p=0 !2^p
DO WHILE MOD(x,2)=0
   LET x=x/2
   LET p=p+1
LOOP
LET q=0 !5^q
DO WHILE MOD(x,5)=0
   LET x=x/5
   LET q=q+1
LOOP
LET k=MAX(p,q) !小数点以下k桁は循環しない

IF x=1 THEN !有限小数
   LET L=0
ELSE !10^L≡1 MOD n/(2^p*5^q)を満たす最小のLより
   LET L=1 !循環節の長さ
   LET a=MOD(10,x)
   DO WHILE a<>1
      LET a=MOD(a*10,x)
      LET L=L+1
   LOOP
END IF
END SUB


EXTERNAL FUNCTION Num2CombBit(h,N,R) !番号から組合せビットパターンを生成する ※辞書式順序
LET v=h+1
LET j=R
LET A=0
FOR i=N-1 TO 0 STEP -1 !組合せをビット位置とする
   LET t=COMB(i,j)
   IF v>t THEN
      LET A=A+2^i !ビット位置(N-i-1)を1とする
      LET j=j-1
      LET v=v-t
   END IF
NEXT i
LET Num2CombBit=A
END FUNCTION


実行結果

3  7  13  37

1 / 3 =0.{3} 循環節= 1
1 / 7 =0.{142857} 循環節= 6
1 / 13 =0.{076923} 循環節= 6
1 / 37 =0.{027} 循環節= 3
1 / 21 =0.{047619} 循環節= 6
1 / 39 =0.{025641} 循環節= 6
1 / 91 =0.{010989} 循環節= 6
1 / 111 =0.{009} 循環節= 3
1 / 259 =0.{003861} 循環節= 6
1 / 481 =0.{002079} 循環節= 6
1 / 273 =0.{003663} 循環節= 6
1 / 777 =0.{001287} 循環節= 6
1 / 1443 =0.{000693} 循環節= 6
1 / 3367 =0.{000297} 循環節= 6
1 / 10101 =0.{000099} 循環節= 6

 

文字の消去

 投稿者:安井 章  投稿日:2013年 2月18日(月)09時45分23秒
  PRINT文で表示した文字列や計算結果を訂正する方法を教えてください。
計算条件を変更し結果を表示する場合変更前の値に重複します。変更前の値は
消去したいのですが。
N88BASICではprint spc(10)等で処理していました。
 

Re: 文字の消去

 投稿者:白石和夫  投稿日:2013年 2月18日(月)17時24分36秒
  > No.2987[元記事へ]

PRINT文に既出力の訂正機能はありません。
どうしてもという場合は,出力ウインドウをRicheditコントロールとして扱ってWin32APIで操ればできるかもしれません。ただし,Windows版限定です。
汎用性を取るのであれば,グラフィックスウィンドウの利用が考えられます。


 

単位分数の和で1をつくる

 投稿者:山中和義  投稿日:2013年 2月20日(水)12時24分18秒
  > No.2961[元記事へ]

問題
分母がn以下の相異なる単位分数の和で1をつくる
 1=1/a+1/b+ … +1/c、a<b< … <c≦n
例
 1/1 項数= 1
 1/2+1/3+1/6 項数= 3
 1/2+1/3+1/7+1/42 項数= 4
 1/2+1/3+1/7+1/78+1/91 項数= 5
 1/2+1/3+1/8+1/24 項数= 4
 1/2+1/3+1/8+1/32+1/96 項数= 5
 1/2+1/3+1/8+1/33+1/88 項数= 5
 1/2+1/3+1/8+1/36+1/72 項数= 5
 1/2+1/3+1/8+1/40+1/60 項数= 5
 1/2+1/3+1/8+1/42+1/56 項数= 5
 1/2+1/3+1/8+1/56+1/78+1/91 項数= 6
 1/2+1/3+1/8+1/60+1/72+1/90 項数= 6
 1/2+1/3+1/8+1/63+1/72+1/84 項数= 6
 1/2+1/3+1/9+1/18 項数= 4
 1/2+1/3+1/9+1/22+1/99 項数= 5
 1/2+1/3+1/9+1/24+1/72 項数= 5
 1/2+1/3+1/9+1/27+1/54 項数= 5
 1/2+1/3+1/9+1/30+1/45 項数= 5
 1/2+1/3+1/9+1/32+1/72+1/96 項数= 6
 1/2+1/3+1/9+1/33+1/66+1/99 項数= 6
 1/2+1/3+1/9+1/33+1/72+1/88 項数= 6
 1/2+1/3+1/9+1/35+1/63+1/90 項数= 6
    :

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


OPTION ARITHMETIC RATIONAL !有理数モード
DIM F(100),A(100),B(100)
MAT F=ZER
LET A(100)=1/100 !iの値、i以降の和
LET B(100)=A(100)
FOR i=99 TO 1 STEP -1
   LET A(i)=1/i !減少列 1/1>1/2>1/3> … >1/100
   LET B(i)=A(i)+B(i+1)
NEXT i
LET N=1
CALL try(N,1,A,B,F)
END

EXTERNAL SUB try(N,p,A(),B(),F()) !バックトラック法で検索する
OPTION ARITHMETIC RATIONAL !有理数モード
FOR i=p TO 100 !※cの上限
   LET T=N-A(i) !残り
   IF T>0 THEN
      IF i<100 AND B(i+1)<T THEN EXIT FOR !全部を使って可能性があれば、その部分集合を考える
      LET F(i)=1 !使用中とする
      CALL try(T,i+1,A,B,F) !有理数tを(i+1)以降で表す
      LET F(i)=0 !元に戻す
   ELSEIF T=0 THEN !題意を満たすなら
      LET k=0
      FOR j=1 TO p-1 !式を表示する
         IF F(j)=1 THEN
            PRINT "1/";STR$(j);"+";
            LET k=k+1
         END IF
      NEXT j
      PRINT  "1/";STR$(i);" 項数=";k+1
   END IF
NEXT i
END SUB

 

小町算となる単位分数 - パズル

 投稿者:山中和義  投稿日:2013年 2月22日(金)10時28分51秒
  問題 小町覆面算
単位分数が1/nとなる1から9までの数を1回ずつ使った分数を求めよ。
ただし、nは2から20までの数とする。
たとえば、6729/13458は1/2なので、求める答えのひとつである。

考察
1/n=m/(mn)を考える。
1から9までの数を1回ずつ使うので、分子のmは4桁の数、分母のmnは5桁の数である。
n=2の場合、
m=1234として、1234/(1234*2)=1234/2468より、
1234と2468とで、1から9までの数を1回ずつ使っているかどうか確認する。
次に、m=1235として、1235/(1235*2)=1235/2470
次に、m=1236として、1236/(1236*2)=1236/2472
 :
(終り)

参考サイト http://antlers.cis.ibaraki.ac.jp/PROGRAM/CPROG/297.pdf


DIM F(0 TO 9) !1から9までの数
FOR N=2 TO 20
   PRINT "N=";N

   FOR M=1234 TO 9876 !4桁の数
      MAT F=ZER
      LET F(0)=1 !使用中とする

      LET t=M
      FOR i=1 TO 4 !10進法4桁
         LET w=MOD(t,10)
         IF F(w)=1 THEN EXIT FOR !既に使用済み
         LET F(w)=1 !使用中とする
         LET t=INT(t/10)
      NEXT i
      IF i>4 THEN !各桁が異なる4桁の数なら
      !!!PRINT M !debug

         LET t=M*N
         IF t>=12345 AND t<=98765 THEN !5桁の数なら
            FOR i=1 TO 5
               LET w=MOD(t,10)
               IF F(w)=1 THEN EXIT FOR
               LET F(w)=1
               LET t=INT(t/10)
            NEXT i
            IF i>5 THEN !各桁が異なる5桁の数なら

               PRINT M; "/"; M*N !題意を満たす

            END IF
         END IF
      END IF
   NEXT M
   PRINT

NEXT N

END

 

Page-2

 投稿者:SECOND  投稿日:2013年 2月26日(火)10時04分37秒
  !Page-2 の始め

!========================
! decorder
! J= huffman code table selection ( 0=YDC 1=YAC 2=CDC 3=CAC)
! V_= pickup RRRRssss <-- JPG.file

SUB DEC1_NS
   DO
      IF BC< BST THEN CALL DEC1_IN
      LET W=IP(Hx)           ! bits width BST
      !----
      LET W=A(NA+W,J)
      IF 32768<=W THEN EXIT DO
      LET NA=W               ! nest adr.  W=0 table end
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   LOOP
   LET NA=0                  ! DU0L LLLL VVVV VVVV
   LET L_=MOD(IP(W/256),128) !  U0L LLLL
   LET V_=MOD(W,256)         !           VVVV VVVV
   IF 16< L_ THEN PRINT "unused code" !BREAK  !unused code ! LET V_=BVAL("8000",16)
   !----
   LET W=MOD(L_,BST)
   IF 0< W THEN
      LET BC=BC-W
      LET Hx=MOD(Hx*2^W,SHb)
   ELSE
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   END IF
END SUB

SUB DEC1_IN
   CALL RED_D
   LET W=ORD(D$)
   IF W=255 THEN
      CALL RED_D
      LET M=ORD(D$)
      IF M<>0 THEN LET w=1/0 ! EXTYPE=3001, ffxx marker, abnormally break
   END IF
   LET Hx=Hx+W*2^(BST-8-BC)
   LET BC=BC+8
END SUB

!-------
SUB DEC1_EX
   LET V_=0
   DO
      IF L_< 1 THEN EXIT SUB
      IF BC< L_ THEN CALL DEC1_IN
      LET W=IP(Hx)
      !----
      IF BST>=L_ THEN EXIT DO
      LET V_=V_*SHb+W
      LET L_=L_-BST
      LET BC=BC-BST
      LET Hx=MOD(Hx*SHb,SHb)
   LOOP
   LET V_=V_*2^L_+IP(W*2^(L_-BST))
   !----
   LET BC=BC-L_
   LET Hx=MOD(Hx*2^L_,SHb)
END SUB

!============
! B(,J)L(,J)<-- DH(,J) for decorder table A(,J)
!
SUB makeH0(J)
   LET i=0   ! コード生成 順番(短い順)
   LET Hx=0
   LET Tx=BVAL("8000",16)
   FOR L_=1 TO 16
      FOR P=1 TO DH(L_,J)
         LET L(i,J)=L_
         LET B(i,J)=Hx ! コード(生成順), 座標DV(頻度降順) と同順。
         LET i=i+1
         LET Hx=Hx+Tx
      NEXT P
      LET Tx=Tx/2
   NEXT L_
   LET B(256,J)=0
   FOR i=i TO 255
      LET L(i,J)=0
      LET B(i,J)=0
   NEXT i
END SUB

!============
!A(,J)=output decorder table<-- B(,J) L(,J) DH(,J) DV(,J)
!
SUB makeD0(J)
   FOR LH=16 TO 1 STEP -1
      IF DH(LH,J)<>0 THEN EXIT FOR
   NEXT LH                          !length max. in huffman table
   LET LM=CEIL(LH/BST)*BST          !length max. bound by BST
   !---
   LET I=0                          !start huffman table adr.
   LET LA=0                         !line adr.
   LET P=BST                        !start Decord code width
   LET U_=2^(16-BST)                !start Decord code step
   LET NC=0                         !next start Decord code
   DO
      LET D_=NC                                         !start Decord code
      LET NC=-1
      LET LB=LA+(65536-D_)/U_                           !1st nest adr.
      DO
         CALL SERCH
         IF 0< L_ THEN
            LET A(LA,J)= BVAL("8000",16)+L_*256+DV(I,J) !b15=end. +L.+V.
         ELSEIF P=LM THEN
            LET A(LA,J)= BVAL("C000",16)+LH*256         !b15=end. b14=Unused. +L.
         ELSE
            IF NC=-1 THEN LET NC=D_
            LET A(LA,J)=LB                              !nest adr.
            LET LB=LB+SHb                               !next nest adr.
         END IF
         LET D_=D_+U_
         LET LA=LA+1
      LOOP UNTIL IP(D_)=65536
      LET P=P+BST
      LET U_=U_/SHb                                     !shr(U_,BST)
   LOOP UNTIL P>LM
   !---
   FOR LA=LA TO 255
      LET A(LA,J)=0                                     !(0),table stop mark
   NEXT LA
END SUB

SUB SERCH
   FOR I=I TO DH(0,J)-1
      LET L_=L(I,J)
      IF L_<=P THEN LET w=IP(D_/2^(16-L_))*2^(16-L_) ELSE EXIT FOR
      IF w<=B(I,J) THEN
         IF w=B(I,J) THEN EXIT SUB ELSE EXIT FOR
      END IF
   NEXT I
   LET L_=-1
END SUB

!===========
! Inverse Fast Cosin Transform.( 8x8, iDCT-2 ) ← Inverse Quantization.DQ()
SUB IDDCT8X8
   FOR P=0 TO CMO                                             !(0=Y,1=Cb,2=Cr)
      FOR V0=0 TO DV_-1 STEP 8*MV(0)/MV(P)
         FOR U0=0 TO DU-1 STEP 8*MH(0)/MH(P)
         !----decord one of MCU( Minimum Coded Unit)
            FOR Y_=0 TO 7
               FOR X_=0 TO 7
                  LET x(X_)=D2(U0+X_,V0+Y_,P)*DQ(X_,Y_,QS(P)) !Inverse Quantization
               NEXT X_
               CALL IWANG                                     !inverse DCT horizontal_row_8
               FOR X_=0 TO 7
                  LET T(X_,Y_)=x(X_)
               NEXT X_
            NEXT Y_
            !---
            FOR X_=0 TO 7
               FOR Y_=0 TO 7
                  LET x(Y_)=T(X_,Y_)
               NEXT Y_
               CALL IWANG                                     !inverse DCT vertical_column_8
               LET i=X_*MH(0)                                 !expand pt.X
               FOR Y_=0 TO 7
                  IF P=0 THEN
                     LET D1(U0+X_,V0+Y_,P)=x(Y_)+128          !inverse level shift
                  ELSE
                     LET j=Y_*MV(0)                           !expand pt.Y
                     !----expand
                     FOR V_=j TO j+MV(0)-1
                        FOR U_=i TO i+MH(0)-1
                           LET D1(U0+U_,V0+V_,P)=x(Y_)        !CbCr to MCU scale
                        NEXT U_
                     NEXT V_
                     !----expand
                  END IF
               NEXT Y_
            NEXT X_
            !----
         NEXT U0
      NEXT V0
   NEXT P
END SUB

!----inverse Wang.( 8, iDCT-2 )
SUB IWANG
   LET xo(0)=SQR(2/8)*x(0)
   LET xo(1)=SQR(2/8)*x(4)
   LET xo(2)=SQR(2/8)*x(2)
   LET xo(3)=SQR(2/8)*x(6)
   LET xo(4)=SQR(1/8)*x(1)
   LET xo(5)=SQR(1/8)*x(5)
   LET xo(6)=SQR(1/8)*x(3)
   LET xo(7)=SQR(1/8)*x(7)
   !
   LET x(4)=(COS(PI  /16)*xo(4)+SIN(PI  /16)*xo(7))
   LET x(5)=(COS(PI*5/16)*xo(5)+SIN(PI*5/16)*xo(6))
   LET x(6)=(SIN(PI*5/16)*xo(5)-COS(PI*5/16)*xo(6))
   LET x(7)=(SIN(PI  /16)*xo(4)-COS(PI  /16)*xo(7))
   !
   LET xo(4)= x(4)+x(5)
   LET xo(5)= x(4)-x(5)
   LET xo(6)=-x(6)+x(7)
   LET xo(7)= x(6)+x(7)
   !
   LET x(0)=(COS(PI/4)*xo(0)+COS(PI  /4)*xo(1))
   LET x(1)=(COS(PI/4)*xo(0)-COS(PI  /4)*xo(1))
   LET x(2)=(SIN(PI/8)*xo(2)-SIN(PI*3/8)*xo(3))
   LET x(3)=(COS(PI/8)*xo(2)+COS(PI*3/8)*xo(3))
   LET x(4)=xo(4)
   LET x(5)=xo(6)
   LET x(6)=xo(5)
   LET x(7)=xo(7)
   !
   LET xo(0)=x(0)+x(3)
   LET xo(1)=x(1)+x(2)
   LET xo(2)=x(1)-x(2)
   LET xo(3)=x(0)-x(3)
   LET xo(4)=x(7)*SQR(2)
   LET xo(5)=x(6)-x(5)
   LET xo(6)=x(6)+x(5)
   LET xo(7)=x(4)*SQR(2)
   !
   LET x(0)=xo(0)+xo(7)
   LET x(1)=xo(1)+xo(6)
   LET x(2)=xo(2)+xo(5)
   LET x(3)=xo(3)+xo(4)
   LET x(4)=xo(3)-xo(4)
   LET x(5)=xo(2)-xo(5)
   LET x(6)=xo(1)-xo(6)
   LET x(7)=xo(0)-xo(7)
END SUB

!=============
SUB R_BIN31(M) ! decord(M) before new.search(M)
   DO
      IF M=BVAL("D8",16) THEN  ! SOI
         MAT DH=ZER   ! clear Huffman Table
         LET DRI=0    ! clear Restart Interval.value for RST0~7(restart marker)
         LET rct=-1   ! Interval.counter, valid (0<=rct), invalid (rct< 0)
         MAT M3=ZER   ! clear scan band sum
      ELSEIF M=BVAL("D9",16) THEN ! EOI
         EXIT DO      ! close & end_sub
      ELSEIF BVAL("D0",16)<=M AND M<=BVAL("D7",16) THEN ! RST0~7( restart marker)
         LET rct=DRI  ! set counter with Restart Interval
         EXIT SUB
      ELSEIF 0< M THEN     !M=0 is data"FF" in picture area
         CALL RED_D
         LET N=ORD(D$)*256
         CALL RED_D
         LET N=N+ORD(D$)-2 ! N=remain size
         !---
         IF BVAL("E0",16)<=M AND M<=BVAL("EF",16) THEN ! APP0~APP15
            CALL FFE0
         ELSEIF M=BVAL("DD",16) THEN
            CALL FFDD ! DRI  load DRI & rct=DRI
         ELSEIF M=BVAL("FE",16) THEN
            CALL FFFE ! COMMENT
         ELSEIF M=BVAL("C4",16) THEN
            CALL FFC4 ! DHT
         ELSEIF M=BVAL("DB",16) THEN
            CALL FFDB ! DQT
         ELSEIF M=BVAL("C0",16) OR M=BVAL("C2",16) THEN
            PRINT right$("000"& BSTR$(byt-4,16),4)
            !---
            CALL FFC0 ! SOF0 SOF2
            !---
            PRINT " SOF";STR$(MOD(M,16));" MCU_HV Ybr ";STR$(MH(0));STR$(MV(0));
            PRINT " ";STR$(MH(1));STR$(MV(1));" ";STR$(MH(2));STR$(MV(2))
         ELSEIF M=BVAL("DA",16) THEN
            CALL FFDA ! SOS
            EXIT SUB  ! without close
         ELSE
            BREAK     ! new marker
         END IF
      END IF
      !---
      DO
         LET M=BVAL("D9",16) ! EOI, 256 ! end of file
         CHARACTER INPUT #1,IF MISSING THEN EXIT DO :D$
         LET byt=byt+1 !!!
         LET M=ORD(D$)
      LOOP UNTIL M=255       ! 1st.mark
      IF M<>255 THEN EXIT DO ! close & end_sub
      CALL RED_D
      LET M=ORD(D$)
   LOOP
   CLOSE #1
END SUB

!DRI
SUB FFDD
   CALL RED_D
   LET DRI=ORD(D$)*256
   CALL RED_D
   LET DRI=DRI+ORD(D$)
   LET rct=DRI
END SUB

!APP0
SUB FFE0
   FOR W=1 TO N
      CALL RED_D
   NEXT W
END SUB

!COMMENT
SUB FFFE
   FOR W=1 TO N
      CALL RED_D
   NEXT W
END SUB

!DQT
SUB FFDB
   DO WHILE 0< N
      CALL RED_D
      LET w= IP(ORD(D$)/16) !p=0(byte) p=1(word)
      LET J=MOD(ORD(D$),16) !J=0~3 (QT.number)
      FOR i=0 TO 63
         CALL RED_D
         LET DQ(U(i),V(i),J)=ORD(D$)
         IF w=1 THEN
            CALL RED_D
            LET DQ(U(i),V(i),J)=DQ(U(i),V(i),J)*256+ORD(D$)
         END IF
      NEXT i
      LET N=N-65-64*w ! remain size
   LOOP
END SUB

!SOF0 SOF2
SUB FFC0
   CALL RED_D
   IF ORD(D$)<>8 THEN BREAK ! 8bit( 24bitColor ) at RGB.dimension
   CALL RED_D
   LET W=ORD(D$)*256
   CALL RED_D
   LET DY=W+ORD(D$) !V.pix.
   CALL RED_D
   LET W=ORD(D$)*256
   CALL RED_D
   LET DX=W+ORD(D$) !H.pix.
   CALL RED_D
   FOR i=0 TO ORD(D$)-1   !1~3 フレーム数、続くID 配置は、暗黙に Y,Cb,Cr の順
      CALL RED_D
      LET CoID(ORD(D$))=i ! CoID( ID=0~255) <--(Y=0, Cb=1, Cr=2)
      CALL RED_D
      LET MH(i)= IP(ORD(D$)/16) ! HV Y=11,12,21,22,41 Cb=11,11,11,11,11 Cr=11,11,11,11,11
      LET MV(i)=MOD(ORD(D$),16)
      CALL RED_D
      LET QS(i)=ORD(D$)   ! QT.number0~3 <-- QS( Y=0, Cb=1, Cr=2)
   NEXT i
   IF i=1 THEN LET CMO=0 ELSE LET CMO=2
END SUB

!DHT
SUB FFC4
   DO WHILE 0< N
      CALL RED_D
      LET J=ORD(D$)              ! (DC=0 AC=1 | ID0_0~3)
      LET J=2*MOD(J,16)+IP(J/16) ! 0~1=ID0.DC~AC  2~3=ID1.DC~AC  4~5=ID2.…
      LET DH(0,J)=0 !!!for 2nd.use for clear
      FOR i=1 TO 16
         CALL RED_D
         LET DH(i,J)=ORD(D$)
         LET DH(0,J)=DH(0,J)+DH(i,J)
      NEXT i
      FOR i=0 TO DH(0,J)-1
         CALL RED_D
         LET DV(i,J)=ORD(D$)
      NEXT i
      !---
      FOR i=i TO 255
         LET DV(i,J)=0
      NEXT i
      CALL makeH0(J) ! make Huffman Code table B() L()
      CALL makeD0(J) ! make Huffman Decorder table A()
      !---
      LET N=N-1-16-DH(0,J) ! remain size
   LOOP
END SUB

!SOS
SUB FFDA
   CALL RED_D
   LET M2=ORD(D$)
   MAT HDC=(-2)*CON
   MAT HAC=(-2)*CON
   FOR i=1 TO M2
      CALL RED_D    ! ID=0~255( defined by SOFx)
      LET w=ORD(D$)
      CALL RED_D    ! (DC_0~3|AC_0~3) huffman table selection
      LET HDC(CoID(w))= IP(ORD(D$)/16)*2   !DC 0~3-->0,2,4,6
      LET HAC(CoID(w))=MOD(ORD(D$),16)*2+1 !AC 0~3-->1,3,5,7
   NEXT i
   CALL RED_D
   LET Ss_=ORD(D$) ! low of spectral selection
   CALL RED_D
   LET Se_=ORD(D$) ! high of spectral selection
   CALL RED_D
   LET Al=MOD(ORD(D$),16) !successive approximation bit position low ( point transform )
   LET Ah=IP(ORD(D$)/16)  !successive approximation bit position high ( preceding "Al" )
   !--- balance monitor M30 M3() for display timing.
   LET w=Se_-Ss_+1
   IF Ah<>Al THEN LET w=w*(Ah-Al) ! prog.sa
   FOR i=0 TO 2
      IF 0<=HAC(i) THEN LET M3(i)=M3(i)+w ! M3()= scan band sum
   NEXT i
   IF CMO=0 OR M3(0)=M3(1) AND M3(1)=M3(2) THEN LET M30=M3(0) ELSE LET M30=99 ! Ybr.balance
   !--- next image data top
END SUB

!プログレッシブ・シーケンスでは、段階的に画像ができるため、
!カラー画像表示のタイミング適正のため、上の様に、モニター変数 M30 を設けた。
!
!      (Ah|Al)     (バンド幅*ビット幅)の積算
!Ss Se Y  Cb Cr   ベース・ライン・シーケンス例 baseline
!00 3F 00 00 00   M3()=  64  64  64  …M30=64     完成画。

!Ss Se Y  Cb Cr   プログレッシブ・シーケンス例 spectral selection
!00 00 00 00 00   M3()=   1   1   1  …M30= 1
!01 05 -- 00 --   M3()=   1   6   1       = 99   99 は、バンド幅(Se-Ss+1)の
!01 05 -- -- 00   M3()=   1   6   6       = 99    累積が、
!01 05 00 -- --   M3()=   6   6   6  …M30= 6     Y,Cb,Cr で揃っていない時。
!06 3F -- 00 --   M3()=   6  64   6       = 99
!06 3F -- -- 00   M3()=   6  64  64       = 99
!06 3F 00 -- --   M3()=  64  64  64  …M30= 64    完成画。

!Ss Se Y  Cb Cr   プログレッシブ・シーケンス例 successive approximation
!00 00 01 01 01   M3()=  -1  -1  -1  …M30= -1
!01 05 02 -- --   M3()= -11  -1  -1       = 99   99 は、バンド幅(Se-Ss+1)と、
!01 3F -- -- 01   M3()= -11  -1 -64       = 99    分割ビット長(Ah-Al)の積の
!01 3F -- 01 --   M3()= -11 -64 -64       = 99    累積が、
!06 3F 02 -- --   M3()=-127 -64 -64       = 99    Y,Cb,Cr で揃っていない時。
!01 3F 21 -- --   M3()= -64 -64 -64  …M30= -64
!00 00 10 10 10   M3()= -63 -63 -63  …M30= -63
!01 3F -- -- 10   M3()= -63 -63   0       = 99
!01 3F -- 10 --   M3()= -63   0   0       = 99
!01 3F 10 -- --   M3()=   0   0   0  …M30= 0     完成画。

SUB ROPEN
   OPEN #1 :NAME FL$ ,ACCESS INPUT
END SUB

SUB RED_D
   CHARACTER INPUT #1 :D$
   LET byt=byt+1 !!!
END SUB

END
 

訂正版

 投稿者:SECOND  投稿日:2013年 2月26日(火)10時05分56秒
  !------------------------------------------------------------
!先の投稿 http://6317.teacup.com/basic/bbs/t5/#1
! で、エンコーダー側DC処理 point transform は、
! "divide by 2^AL" でなく、"arithmetic-shift-right AL" である事を、考慮していない
! 誤りがあり、その訂正版です。
! 先投稿への編集は、出来なくなっているので、これと差し換えて下さい。
!
! 依存資料:http://www.w3.org/Graphics/JPEG/itu-t81.pdf
! itu-t81.pdf の Annex K ( K.9~K.10  P177~P178) 参照
!
!整数出力(負~0)での、"divide by 2^N" と "arithmetic shift right N" の違い。
!
!       out         (N=1 の時) ┏┛divide by 2   ┌┘arithmetic shift right 1
!       │
!       │+3 ………┏    (+4) 00000100→ 00000010(商=+2)  00000100→ 00000010(+2)
!       │+2 …┏━┛    ( ~)      ~ → 00000001(商=+1)       ~ → 00000001(+1)
!       │+1┏━┛        (+2) 00000010→ 00000001(商=+1)  00000010→ 00000001(+1)
! ────┏━┿━┛────in  ( ~)      ~ → 00000000(商= 0)       ~ → 00000000( 0)
!   ┏━╋─┤-1             ( 0) 00000000→ 00000000(商= 0)  00000000→ 00000000( 0)
! ┏━╋─┘…│-2              ( ~)      ~ → 00000000(商= 0)       ~ → 11111111(-1)
! ╋─┘………│-3            (-2) 11111110→ 11111111(商=-1)  11111110→ 11111111(-1)
! ┘     │                ( ~)      ~ → 11111111(商=-1)       ~ → 11111110(-2)
! │~│~│~│~│~│~│    (-4) 11111100→ 11111110(商=-2)  11111100→ 11111110(-2)
!-6 -4 -2 0 +2 +4 +6    ( ~)      ~ → 11111110(商=-2)       ~ → 11111101(-3)
!                        (-6) 11111010→ 11111101(商=-3)  11111010→ 11111101(-3)

!************************************************************
!訂正版:十進 BASIC による プログレッシブ JPG の展開と画像化。
!
!プログレッシブ JPG 再生過程の画像は、最初のDC成分1枚だけ と、最終完成画、全2枚とした。
!Baseline JPG は、全1枚なので、画数で両者を区別できる。( 描画倍率は、1又は、2倍拡大)
!(必要なら、再生過程 全ての画像も、表示できるよう、SUB IZZRL0 に注釈行がある)
!
!大きな再生画像でも、縮尺を止め、1倍又は、極小な場合の2倍拡大のみにした。
!色差成分 Cb Cr の間引き走査復元の塗潰しは、SUB IDDCT8X8 に組み込み。
!
!具体的、可視的なプログラムで、実行し画像化するので、詳細事項の追跡と御参考に。
!再生できるファイルは、1000x1000 までの JPG だけで、
! baseline , spectral selection , successive approximation の3種類( web 上の、ほぼ全種)
!
!
!1)successive approximation AC.subsequence(Y,Cb,Cr 別々、1bit づつの処理)
!    0 でない追加データ extend (1bit) が 1st.scan も 0 の初めてのデーターになるまで、
!    Zero-RUN を続ける。
!    その間の、上位桁<>0 の 1st.scan 値 追加データーは、その個数分が、
!    extend. に後続している。Zero-RUN 個数 の 0 の次の 0 の位置に、extend.を置く。
!    ここでの extend. は group 1 だけで、(0,1) → (-1,+1)
!
!      0      1      1      0      0      0      0      0      0     ?
!      0      0      0      0      0      1      0      0      0     ?
!      0      1      0      0      0      0      0      1      0     ?
!      0      1      1      0      0      1      0      1      0     ?
!      0      1      1      0      0      1      0      1      0     ?
! --------------------------------------------------------------------------
!    ±1      b1     b2     0      0      b3     0      b4   ±1     ?
! 前の終り                 RRRR   RRRR          RRRR        extend.  次の始め
!
!    huffman.
!    RRRRssss  extend.  b1 b2 b3 b4 …  bit_stream=?何個になるかは、
!      3   1  (0 or 1)   (0 or 1)       上位桁 =0 の係数が RRRR 個 になるまでに
!               ↓         ↓           通過した上位桁 <>0 の個数。上図では、4
!
!    新規(上位桁無)        エンコーダー側AC処理 point transform は、
!    の復号  0 → -1       "divide by 2^AL" なので
!            1 → +1       0 → 無変化。
!                          1 → ±符号は上位桁に合せて加算。(絶対値が+1)
!
!
!2)successive approximation DC.subsequence(Y,Cb,Cr 別々、1bit づつの処理)
!    ハフマン・コード RRRRssss 部は、存在せず、
!    頭からの bit_stream.で、1bit づつ、全てのblock の DC係数 に加える。
!
!                          エンコーダー側DC処理 point transform は、
!                          "arithmetic-shift-right AL" なので
!                          0 → 無変化。
!                          1 → 上位桁符号に関らず、+加算。(符号無し整数値が+1)
!
!
! ※AL・・・ 係数などの数値が、2^AL のステップ幅で 量子化された値 になっている意。
! ※AH・・・ preceding AL.  同じ BAND で直前の AL 値 (AH=0 は、最初の AL に添える)
!
!          (Ah|Al)
!   ←──┐ 0 0 全bits のデータ。復元は、(・・・111111.)*2^( point transform =0)
! ・・・111111
!
! 以下3つを加算すると、上と同じになる。
!          (Ah|Al)
!   ←─┐   0 2  上位bits のデータ。   復元は、(・・・1111  )*2^( point transform =2)
! ・・・1111xx
!        〟  2 1 1bitづつ、分けて追加。復元は、(       1 )*2^( point transform =1)
! ・・・xxxx1x
!         〟 1 0            復元は、(        1)*2^( point transform =0)
! ・・・xxxxx1
!
!------------------------
DEBUG ON
!------------------------
!JPG.decoder
! Baseline
! Progressive( spectral selection )( successive approximation )
!------------------------
OPTION ARITHMETIC NATIVE
OPTION BASE 0
OPTION CHARACTER byte
SET TEXT background "OPAQUE"
SET ECHO "OFF"
SET COLOR MODE "NATIVE"
!
DIM D8(1000,1000)   !MAIN65
DIM D2(1000,1000,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
DIM D1(1000,1000,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
DIM MH(2),MV(2)     !R_BIN31  SOF0 MCU.Ybr.H()V()
DIM HDC(2),HAC(2)   !R_BIN31 hT.table selection
DIM QS(2),CoID(255) !R_BIN31 qT.table selection
DIM M3(2)
!
DIM U(63),V(63)         !zigzag
DIM DQ(7,7,3)           !blk8x8 DQT
DIM DH(16,7),DV(255,7)  !DHT
DIM B(255+1,7),L(255,7) !encorder & decorder's pre_table, length, ( MAKE_H2,MAKE_H0)
DIM A(2000,7)           !decorder
DIM B2(2)               !Ybr D.C.成分 starting & back_level for difference
DIM T(7,7),x(7),xo(7)  !DDCT8X8, IDDCT8X8
!
LET BST=2      !huffman decorder's bit step 1=8.5s 2=6.5s 4=8.0s 8=50.0s
LET SHb=2^BST  !huffman decorder   n*SHb=(shl n,BST)  n/SHb=(shr n,BST)
!
!---zigzag table
FOR V_=0 TO 7
   FOR U_=0 TO 7
      READ i
      LET U(i)=U_
      LET V(i)=V_
   NEXT U_
NEXT V_
DATA  0, 1, 5, 6,14,15,27,28
DATA  2, 4, 7,13,16,26,29,42
DATA  3, 8,12,17,25,30,41,43
DATA  9,11,18,24,31,40,44,53
DATA 10,19,23,32,39,45,52,54
DATA 20,22,33,38,46,51,55,60
DATA 21,34,37,47,50,56,59,61
DATA 35,36,48,49,57,58,62,63
!
DO
   FILE GETNAME FL$, "jpg"
   IF FL$="" THEN
      PRINT "入力ファイル名無し"
      EXIT DO
   END IF
   PRINT "入力ファイル:"& FL$
   !---
   CLEAR
   CALL IZZRL0   ! D2()<-- decord JPG
   PRINT "次のファイル[ 左クリック ]"
   beep
   DO
      MOUSE POLL j,i,mlb,mrb !CHARACTER INPUT CLEAR: w$
      WAIT DELAY 0
   LOOP UNTIL 0< mlb OR 0< mrb
LOOP UNTIL 0< mrb
PRINT "終了。"

!-------- IZZRL0 call here for display D2()
SUB MAIN65
   LET tester=TIME
   PRINT "画像の準備中、";
   CALL IDDCT8X8 ! D1()<-- iDCT<-- iDQT<-- D2()
   !------ JPG 色空間 ----------------------------
   ! | Y |   | 0.2990   +0.5870   +0.1140  | | R |
   ! |B-Y| = |-0.1687   -0.3313   +0.5000  | | G |
   ! |R-Y|   | 0.5000   -0.4187   -0.0813  | | B |
   !
   ! | R |   | 1         0        +1.40200 | | Y |
   ! | G | = | 1        -0.34414  -0.71414 | |B-Y|
   ! | B |   | 1        +1.77200   0       | |R-Y|
   !----------------------------------------------
   FOR V0=0 TO DY-1
      FOR U0=0 TO DX-1
      !--- RGB<-- Ybr
         LET w1=IP(D1(U0,V0,0)                      +1.40200*D1(U0,V0,2)) !R
         LET w2=IP(D1(U0,V0,0) -0.34414*D1(U0,V0,1) -0.71414*D1(U0,V0,2)) !G
         LET w3=IP(D1(U0,V0,0) +1.77200*D1(U0,V0,1))                      !B
         IF w1< 0 THEN
            LET w1=0
         ELSEIF 255< w1 THEN
            LET w1=255
         END IF
         IF w2< 0 THEN
            LET w2=0
         ELSEIF 255< w2 THEN
            LET w2=255
         END IF
         IF w3< 0 THEN
            LET w3=0
         ELSEIF 255< w3 THEN
            LET w3=255
         END IF
         LET D8(U0,V0)=w3*65536+w2*256+w1 !(逆)BGR
      NEXT U0
   NEXT V0
   PRINT TRUNCATE(TIME-tester,2);"秒"
   !!! LET w=1                                !等倍で描画、画素数どうり。
   LET w=IP( MIN( 500/DX, 500/DY))        !整数倍拡大、1~2の何れかで描画。
   IF 2< w THEN LET w=2
   IF w< 1 THEN LET w=1
   PRINT "描画の倍率=";w
   CALL scrns(DX*w, DY*w)
   MAT PLOT CELLS,IN 1,1; DX*w, DY*w :D8
END SUB

SUB scrns(px,py)
   SET bitmap SIZE px+50,py+50
   SET WINDOW 1-20,px+30, py+27,1-23
   SET LINE COLOR "cyan"
   SET LINE width 3
   PLOT LINES:1-3,1-3;px+3,1-3;px+3,py+3;1-3,py+3;1-3,1-3
   PLOT TEXT,AT -3,-4: "原画 "& STR$(px/w)& "x"& STR$(py/w)& " 倍率= "& STR$(w)
END SUB

!========================
!inverse haffman Transform.
SUB IZZRL0
   LET byt=0 !!!
   CALL ROPEN ! FL$
   !---
   CALL R_BIN31(0) !A() B(i,J)L(i,J)<-- DH(), return at img.top
   PRINT right$("000"& BSTR$(byt,16),4) !!!
   PRINT "(";STR$(DX);"x";STR$(DY);
   !---
   MAT D8=ZER(DX-1,DY-1)     !MAIN65
   LET i=8*MH(0)             !MCU Y.Hsize
   LET j=8*MV(0)             !MCU Y.Vsize
   LET DUM=CEIL(DX/i)*i      !Uwidth=bound by MCU Y.Hsize
   LET DVM=CEIL(DY/j)*j      !Vwidth=bound by MCU Y.Vsize
   MAT D1=ZER(DUM-1,DVM-1,2) !Y=D1(,,0)  Cb=D1(,,1)  Cr=D1(,,2)
   MAT D2=ZER(DUM-1,DVM-1,2) !Y=D2(,,0)  Cb=D2(,,1)  Cr=D2(,,2)
   LET MH_=MH(0)
   LET MV_=MV(0)
   LET DU =DUM               !Uwidth=bound by MCU Y.Hsize
   LET DV_=DVM               !Vwidth=bound by MCU Y.Vsize
   LET DU8=CEIL(DX/8)*8      !Uwidth=bound by block Y.Hsize
   LET DV8=CEIL(DY/8)*8      !Vwidth=bound by block Y.Vsize
   !---
   PRINT "/ ";STR$(DU8);",";STR$(DV8);"/ ";STR$(DUM);",";STR$(DVM);")"
   CALL frame
   !---
   PRINT "M3()=";M3(0);M3(1);M3(2)
   CALL MAIN65 ! Baseline.最終、Progressive.1st.
   !---
   IF 0< M THEN PRINT " (";STR$(DX);"x";STR$(DY);"/";STR$(U0);",";STR$(V0);") ";debug$;" abort by ";BSTR$(M,16) !!!
   PRINT right$("000"& BSTR$(byt-2*SGN(M),16),4) !!!
   CALL R_BIN31(M) ! return at img.top, or EOI
   !---
   DO WHILE M=BVAL("DA",16) !SOS
      IF 0<=HAC(0) THEN
         LET MV(0)=1
         LET MH(0)=1
         LET DU=DU8
         LET DV_=DV8
      END IF
      CALL frame
      LET MV(0)=MV_
      LET MH(0)=MH_
      LET DU=DUM
      LET DV_=DVM
      !---
      PRINT "M3()=";M3(0);M3(1);M3(2)     !文末参照:M30<>99(balance), M30=99(un-balance)
      IF M30=0 OR M30=64 THEN CALL MAIN65 !Progressive.最終スキャン後の画像
      !IF M30<>99 THEN CALL MAIN65         !Progressive.各スキャン毎、Ybr 揃った画像のみ
      !CALL MAIN65                         !Progressive.各スキャン毎、全画像
      !---
      IF 0< M THEN PRINT " (";STR$(DX);"x";STR$(DY);"/";STR$(U0);",";STR$(V0);") ";debug$;" abort by ";BSTR$(M,16) !!!
      PRINT right$("000"& BSTR$(byt-2*SGN(M),16),4)
      CALL R_BIN31(M) ! return at img.top
   LOOP
   CLOSE #1 ! FL$
END SUB

SUB reset0
   LET B2(0)=0 !ROUND( YDC0/DQ(0,0,QS(0)) ) !prediction YDC.( 1st.reference level)
   LET B2(1)=0 !prediction CbDC.
   LET B2(2)=0 !prediction CrDC.
   LET Hx=0  !bits stream input buffer 0~(7+8)bits, use fraction
   LET BC=0  !stored bits in Hx
   LET NA=0  !nest adr. in A()
   LET EOB=0 !counter( end_of_band)
   LET M=0
   LET ext=0
END SUB

SUB frame
   PRINT "  Ss Se AhAl: ";Ss_;Se_;STR$(Ah);STR$(Al)
   PRINT "  Y  HDC HAC: ";IP(HDC(0)/2);IP(HAC(0)/2)
   PRINT "  Cb        : ";IP(HDC(1)/2);IP(HAC(1)/2)
   PRINT "  Cr        : ";IP(HDC(2)/2);IP(HAC(2)/2)
   CALL reset0
   !---
   FOR V09=0 TO DV_-1 STEP 8*MV(0)
      FOR U09=0 TO DU-1 STEP 8*MH(0)
         IF rct=0 THEN
            CALL R_BIN31(0)        ! read marker
            IF rct<>DRI THEN BREAK ! not RST0~7
            CALL reset0 ! Restart
         END IF
         CALL MCUxx11 ! read picture data
         LET rct=rct-1
         !---
         IF 0< ext THEN
            IF ext=103001 THEN
               PRINT "abort marker ";BSTR$(M,16)
               IF BVAL("D0",16)<=M AND M<=BVAL("D7",16) THEN ! RST0~7( restart marker)
                  LET rct=DRI ! set counter
                  CALL reset0 ! Restart
               ELSE
                  EXIT SUB ! others marker
               END IF
            ELSE
               PRINT "file error. display fragment"
               LET M=BVAL("D9",16) ! EOI
               EXIT SUB
            END IF
         END IF
      NEXT U09
   NEXT V09
   IF 0< EOB THEN PRINT "EOBn over frame";EOB  !!!
END SUB

SUB MCUxx11
!---read MCU
   FOR P=0 TO CMO
      IF 0<=HDC(P) OR 0<=HAC(P) THEN
         FOR V0=V09 TO V09+8*MV(P)-1 STEP 8
            FOR U0=U09 TO U09+8*MH(P)-1 STEP 8
               WHEN EXCEPTION IN
                  IF EOB=0 THEN CALL R_BLK0 ELSE LET EOB=EOB-1
               USE
                  LET ext=EXTYPE
                  EXIT SUB
               END WHEN
               !---extend bitmap
               IF 0< Ah AND 0< Se_ THEN
                  FOR i=A_ TO Se_
                     IF D2(U0+U(i),V0+V(i),P)<>0 THEN
                        LET L_=1
                        WHEN EXCEPTION IN
                           CALL DEC1_EX
                        USE
                           LET ext=EXTYPE
                           EXIT SUB
                        END WHEN
                        LET V_=SGN(D2(U0+U(i),V0+V(i),P))*V_
                        LET D2(U0+U(i),V0+V(i),P)=D2(U0+U(i),V0+V(i),P) +V_*2^Al
                     END IF
                  NEXT i
                  LET A_=Ss_
               END IF
               !---
            NEXT U0
         NEXT V0
      END IF
   NEXT P
END SUB

!------
SUB R_BLK0
   IF Ss_=0 THEN
   !===D.C.part
      LET debug$="DC.huffman" !!!
      IF Ah=0 THEN
      !-----baseline.progSS.progSA(1st.scan).
         LET J=HDC(P)                     !huffman D.C.table selection P( 0=Y 1=Cb 2=Cr)
         CALL DEC1_NS
         LET EL=V_                        !extent length
         !---D.C.extent
         LET debug$="DC.huffman extend" !!!
         IF 0< EL THEN
            LET L_=EL
            CALL DEC1_EX                  !keep EL, V_=extent value( length EL bits)
            LET W=2^(EL-1)                !minimum in EL bits length
            IF V_< W THEN LET V_=V_-W*2+1 !restore signed value
            LET B2(P)=B2(P)+V_*2^Al       !point transform, integrate to D.C.
         END IF
         LET D2(U0+U(0),V0+V(0),P)=B2(P)
      ELSE
      !-----progSA(2st.scan).
         LET L_=1
         CALL DEC1_EX
         !!! LET V_=SGN(D2(U0+U(0),V0+V(0),P))*V_
         LET D2(U0+U(0),V0+V(0),P)=D2(U0+U(0),V0+V(0),P) +V_*2^Al
      END IF
      !===A.C.parts
      LET Sa_=1
   ELSE
   !===A.C.parts
      LET Sa_=Ss_
   END IF
   IF Se_=0 THEN EXIT SUB                 !band Ss_~Se_
   LET J=HAC(P)                           !huffman A.C.table selection P( 0=Y 1=Cb 2=Cr)
   LET debug$="AC.huffman" !!!
   FOR A_=Sa_ TO Se_
      CALL DEC1_NS
      LET EL=MOD(V_,16)                   !extent length
      LET RL= IP(V_/16)                   !run length
      !---
      IF RL<=14 AND EL=0 THEN             !End Of Block(00). End Of Band n(10,20,,E0)
      !---EOBn extend
         LET debug$="EOBn extend"& STR$(RL) !!!
         IF 0< RL THEN
            LET L_=RL                     !RL= 1,2,,E (EOB1, EOB2, ・・・, EOB14)
            CALL DEC1_EX                  !keep RL, run_length= V_+2^RL
            LET EOB=V_+2^RL -1            !※-1 (1st.count)
         END IF
         EXIT SUB
         !---
      END IF
      !---RL=(0~15)EL=(1~10), RL=(15)EL=(0)
      LET debug$="AC.huffman extend" !!!
      IF Ah=0 THEN
      !-----baseline.progSS.progSA(1st.scan).
         LET A_=A_+RL                     !skip zero_run_length 0~15
         !---A.C.extent
         IF 0< EL THEN                    !ZRL(16) only skip
            LET L_=EL
            CALL DEC1_EX                  !keep EL, V_=extent value( length EL bits)
            LET w=2^(EL-1)                !minimum in EL bits length
            IF V_< w THEN LET V_=V_-w*2+1       !restore signed value
            LET D2(U0+U(A_),V0+V(A_),P)=V_*2^Al !point transform
         END IF
      ELSE
      !-----progSA(2st.scan).
         IF 0< EL THEN                    !ZRL(16) only skip
            LET L_=EL
            CALL DEC1_EX                  !keep EL, V_=extent value( length EL bits)
            IF EL<>1 THEN PRINT "AC.2nd.=";EL;V_ !!!
            LET V01=V_
         END IF
         FOR i=A_ TO Se_
            IF D2(U0+U(i),V0+V(i),P)<>0 THEN  !zz(k)=xxx_1?/0?
               LET L_=1
               CALL DEC1_EX
               LET V_=SGN(D2(U0+U(i),V0+V(i),P))*V_
               LET D2(U0+U(i),V0+V(i),P)=D2(U0+U(i),V0+V(i),P) +V_*2^Al
            ELSEIF RL=0 THEN              !zz(k)=000_V01
               EXIT FOR
            ELSE                          !zz(k)=000_0  ,zero run
               LET RL=RL-1
            END IF
         NEXT i
         IF 0< EL THEN                    !ZRL(16) skip
            IF V01=0 THEN LET V01=-1      !group1( -1, 1)
            LET D2(U0+U(i),V0+V(i),P)=V01*2^Al
         END IF
         LET A_=i
      END IF
   NEXT A_
END SUB

!
Page-2 へ続く
 

整数の組による積の和

 投稿者:山中和義  投稿日:2013年 3月 2日(土)10時21分14秒
  問題
nを任意の正の整数とする。
a≧b≧0、a+2b=n
を満たす整数の組(a,b)のそれぞれに対して、積abを考える。
その積のすべての和をf(n)とすると、f(n)をnの式で表せ。

答え
a≧bなので、n=a+2b≧(1+2)bより、1≦b≦[n/3]である。
Σab
=Σ[B=1,[N/3]](N-2B)B
=NΣ[B=1,[N/3]]B - 2Σ[B=1,[N/3]]B^2
=N{x(x+1)/2} - 2{x(x+1)(2x+1)/6} ただし、x=[N/3]
=x(x+1)(3N-2-4x)/6
または
=( -4x^3+3(N-2)x^2+(3N-2)x )/6
(終り)


FOR N=1 TO 50
   PRINT "N="; N

   LET S=0 !a≧b≧1として考える
   FOR B=1 TO INT( N/(1+2) ) !n=a+2b≧(1+2)bより
      LET A=N-2*B
      IF A< B THEN STOP !論理エラー

      PRINT A;B !題意を満たす
      LET S=S+A*B

   NEXT B
   PRINT "積="; S


   LET X=INT(N/3) !f(n)
   !!PRINT X*(X+1)*(3*N-2-4*X)/6
   PRINT ( -4*X^3+3*(N-2)*X^2+(3*N-2)*X )/6
NEXT N

END



問題
nを任意の正の整数とする。
a≧b≧c≧0、a+2b+3c=n
を満たす整数の組(a,b,c)のそれぞれに対して、積abcを考える。
その積のすべての和をf(n)とすると、f(n)をnの式で表せ。

考察
類題として問題文が展開ができるので、いくつか先を見ていくと、

漸化式を用いて、

FOR n=1 TO 60
   PRINT n;":"; F2(n,INT(n/3)); F3(n,INT(n/6)); F4(n,INT(n/10)); F5(n,INT(n/15))
NEXT n
END

!a+2b=n、a≧b≧0、Σab=Σ[b=1,[n/3]]b*(n-2b)
EXTERNAL FUNCTION F2(n,k) !Σ[i=1,k]i(n-2i)
LET S=0
FOR i=1 TO k
   LET S=S+i*(n-2*i)
NEXT i
LET F2=S
END FUNCTION

!a+2b+3c=n、a≧b≧c≧0、Σabc=Σ[c=1,[n/6]] c*{ Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) }
EXTERNAL FUNCTION F3(n,k)
LET S=0
FOR i=1 TO k
   LET x=n-3*i
   LET S=S+i*(F2(x,INT(x/3)) - F2(x,i-1))
NEXT i
LET F3=S
END FUNCTION

EXTERNAL FUNCTION F4(n,k)
LET S=0
FOR i=1 TO k
   LET x=n-4*i
   LET S=S+i*(F3(x,INT(x/6)) - F3(x,i-1))
NEXT i
LET F4=S
END FUNCTION

EXTERNAL FUNCTION F5(n,k)
LET S=0
FOR i=1 TO k
   LET x=n-5*i
   LET S=S+i*(F4(x,INT(x/10)) - F4(x,i-1))
NEXT i
LET F5=S
END FUNCTION

(終り)


Σabc=Σ[c=1,[n/6]] c*{ Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) } なので、
Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) の部分を、
 a+2b=n の式 f(N)=( -4x^3+3(N-2)x^2+(3N-2)x )/6
のxに、[n/3]-c と c-1 を代入して求めると、


FOR N=1 TO 60
   PRINT "N="; N

   LET S=0 !a≧b≧c≧1として考える
   FOR C=1 TO INT( N/(1+2+3) ) !n=a+2b+3c≧(1+2+3)cより
      FOR B=C TO INT( (N-3*C)/(1+2) ) !n-3c=a+2b≧(1+2)bより
         LET A=N-3*C-2*B
         IF A< B THEN STOP !論理エラー

         PRINT A;B;C !題意を満たす
         LET S=S+A*B*C

      NEXT B
   NEXT C
   PRINT "積="; S


   LET y=INT(N/6) !f(n)
   LET x=INT(N/3)
   PRINT y*(y+1)* ( 16*y^3  +3*(5*x-2)*y^2  +(10*x^2 +5*(5-4*N)*x -14)*y  -5*x*(4*x^2 +(5-3*N)*x -N+1) +4 )/60


NEXT N

END


a+2b+3c+4d=n、a≧b≧c≧d≧0 となると、手計算では難しい。。。

 

Re: 整数の組による積の和

 投稿者:山中和義  投稿日:2013年 3月 4日(月)13時15分20秒
  > No.2993[元記事へ]

> 問題
> nを任意の正の整数とする。
> a≧b≧0、a+2b=n
> を満たす整数の組(a,b)のそれぞれに対して、積abを考える。
> その積のすべての和をf(n)とすると、f(n)をnの式で表せ。

答え
A=a-bとする。a≧bより、A≧0
また、A=(n-2b)-b=n-3b ∴A+3b=n
Σ[a+2b=n,a≧b≧0]ab
=Σ[A+3b=n,A≧0,b≧0](A+b)b
3b=n-A≦nより、b≦n/3なので、
=Σ[1≦b≦[n/3]](A+b)b ただし、A=n-3b
(終り)


FOR N=1 TO 50
   PRINT "N="; N

   LET S=0
   FOR b=1 TO INT(N/3) !b≧1として考える
      LET A=N-3*b
      IF A<0 THEN STOP !論理エラー

      PRINT A;b !題意を満たす
      LET S=S+(A+b)*b

   NEXT b
   PRINT "積=";S
NEXT N

END



別解 母関数
(A+b)b=Ab+b^2なので、項Abと項b^2について考える。
項Abのf(n)に対する寄与をf(n:Ab)と表す。
f(n:Ab)の母関数Σ[k=0,∞]f(k:Ab)*x^kについて
 f(n:Ab)は、
  p[x]=0*1+1*x+2*x^2+3*x^3+4*x^4+5*x^5+6*x^6+7*x^7+ …  =x/(1-x)^2
  q[x]=0*1+1*x^3+2*x^6+3*x^9+4*x^12+5*x^15+6*x^18+7*x^21+ …  =x^3/(1-x^3)^2
 として、積pqを展開したときのx^nの係数になる。
 よって、x/(1-x)^2 * x^3/(1-x^3)^2 をマクローリン展開したときのx^nの係数になる。

同様に
 f(n:b^2)は、
  p[x]=1+x+x^2+x^3+x^4+x^5+x^6+x^7+ … =1/(1-x)
  q[x]=0^2*1+1^2*x^3+2^2*x^6+3^2*x^9+4^2*x^12+5^2*x^15+6^2*x^18+7^2*x^21+ …  =(x^6+x^3)/(1-x^3)^3
 として、積pqを展開したときのx^nの係数になる。
 よって、1/(1-x) * (x^6+x^3)/(1-x^3)^3 をマクローリン展開したときのx^nの係数になる。

したがって、f(n)の母関数は、
Σ[k=0,∞]f(k)*x^k
=x^4/{(1-x)^2(1-x^3)^2} + (x^6+x^3)/{(1-x)(1-x^3)^3}
=x^3(2x^3+x^2+x+1)/{(1-x)(1-x^3)^3}
これをマクローリン展開したときのx^nの係数になる。、
(終り)


!マクローリン展開
! P(x)=P(0)+{P'(0)/1!}x+{P''(0)/2!}x^2+{P'''(0)/3!}x^3+ …
!例
!P(x)=1/(1-x)=1+x+x^2+x^3+x^4+ …
!
!考察
!P(0)は、x=0を代入して、1/(1-0)=1
!P'(0)は、
! P(x)=f(x)/g(x)より、P'=(f'g-fg')/g^2なので、
! 1'(1-x)-1(1-x)'/(1-x)^2=1/(1-x)^2
! x=0を代入して、1
!P''(0)は、
! P''(x)=(P'(x))'なので、
! 上記の結果をあらためて、f(x)=f'g-fg'、g(x)=g^2と考える。上記と同じ議論を繰り返す。
!(終り)

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC N !次数
LET N=50

!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
!「dim a(0 to n) !係数」で定義する
DIM P(0 TO N)
DIM F(0 TO N),G(0 TO N) !p=f/g
MAT F=ZER
MAT G=ZER

DATA 6 !次数 f=x^3(2x^3+x^2+x+1)=2*x^6+x^5+x^4+x^3 ※
DATA 0,0,0,1,1,1,2 !係数 ※展開して次数が小さい方から
READ R
FOR i=0 TO R
   READ F(i)
NEXT i
!!!MAT PRINT F; !debug
CALL poly_disp(F) !多項式を表示する
PRINT

DATA 10 !次数 g=(1-x)(1-x^3)^3=x^10-x^9-3x^7+3x^6+3x^4-3x^3-x+1 ※
DATA 1,-1,0,-3,3,0,3,-3,0,-1,1 !係数 ※展開して次数が小さい方から
READ R
FOR i=0 TO R
   READ G(i)
NEXT i
!!!MAT PRINT G; !debug
CALL poly_disp(G) !多項式を表示する
PRINT


LET P(0)=F(0)/G(0)/FACT(0) !定数項
PRINT 0; P(0) !debug

DIM F1(0 TO N),G1(0 TO N), W1(0 TO N),W2(0 TO N),W3(0 TO N) !作業用
FOR i=1 TO N !i階微分

   CALL poly_diff(F,W3) !f'g
   CALL poly_mul(W3,G, W1)
   !!!MAT PRINT W1; !debug

   CALL poly_diff(G,W3) !fg'
   CALL poly_mul(F,W3, W2)
   !!!MAT PRINT W2; !debug

   CALL poly_sub(W1,W2, F1) !分子 f'g-fg'
   !!!MAT PRINT F1; !debug


   CALL poly_mul(G,G, G1) !分母 g^2
   !!!MAT PRINT G1; !debug


   LET P(i)=F1(0)/G1(0)/FACT(i) !x^iの係数
   PRINT i; P(i) !debug


   MAT F=F1 !次へ
   MAT G=G1
NEXT i

CALL poly_disp(P) !多項式を表示する
PRINT

END


!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
!「dim a(0 to n) !係数」で定義する

!演算関連

EXTERNAL SUB poly_add(v1(),v2(), v()) !加算 v=v1+v2
OPTION ARITHMETIC RATIONAL !有理数モード
MAT v=v1+v2
END SUB

EXTERNAL SUB poly_sub(v1(),v2(), v()) !減算 v=v1-v2
OPTION ARITHMETIC RATIONAL !有理数モード
MAT v=v1-v2
END SUB

EXTERNAL SUB poly_mul(v1(),v2(), v()) !乗算 v=v1*v2
OPTION ARITHMETIC RATIONAL !有理数モード
DIM w(0 TO 2*N) !桁数は2倍になる
MAT w=ZER
FOR i=0 TO N !係数
   FOR j=0 TO N
      LET w(i+j)=w(i+j)+v1(i)*v2(j) !畳み込み
   NEXT j
NEXT i
FOR i=0 TO N !※下n桁をコピーする ※オーバーフローは考慮していない
   LET v(i)=w(i)
NEXT i
END SUB

EXTERNAL SUB poly_diff(v1(), v()) !微分 v=v1'
OPTION ARITHMETIC RATIONAL !有理数モード
FOR i=1 TO N
   LET v(i-1)=v1(i)*i
NEXT i
LET v(N)=0
END SUB


!表示関連

EXTERNAL SUB poly_disp(A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
OPTION ARITHMETIC RATIONAL !有理数モード
CALL mono_disp(A(N),N)
FOR i=N-1 TO 0 STEP -1 !次項
   LET w=A(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 OR N=0 THEN CALL mono_disp(w,i)
NEXT i
END SUB

EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
OPTION ARITHMETIC RATIONAL !有理数モード
IF k<>0 THEN !x^nで
   IF ak=0 OR ak=1 THEN !係数が0,1なら
   ELSEIF ak=-1 THEN !係数が-1なら
      PRINT "-"; !符号
   ELSE
      PRINT STR$(ak);"*";
   END IF
END IF
IF k=0 THEN !次数が0なら
   PRINT STR$(ak);
ELSEIF k=1 THEN !次数が1なら
   PRINT "X";
ELSE
   IF ak<>0 THEN PRINT "X^";STR$(k); !係数が0以外なら
END IF
END SUB

 

Re: 整数の組による積の和

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

> 問題
> nを任意の正の整数とする。
> a≧b≧c≧0、a+2b+3c=n
> を満たす整数の組(a,b,c)のそれぞれに対して、積abcを考える。
> その積のすべての和をf(n)とすると、f(n)をnの式で表せ。

答え
A=a-b、B=b-cとする。a≧b≧cより、A≧0、B≧0
また、A=(n-3c-2b)-b=n-3c-3b=n-3(b-c)-6c=n-3B-6c ∴A+3B+6c=n
Σ[a+2b+3c=n,a≧b≧c≧0]abc
=Σ[A+3B+6c=n,A≧0,B≧0,c≧0](A+B+c)(B+c)c
(終り)


FOR N=1 TO 50
   PRINT "N="; N

   LET S=0
   FOR c=1 TO INT(N/6) !c≧1として考える
      FOR B=0 TO INT((N-6*c)/3) !B≧0として考える
         LET A=N-6*c-3*B
         IF A<0 THEN STOP !論理エラー

         PRINT A;B;c !題意を満たす
         LET S=S+(A+B+c)*(B+c)*c

      NEXT B
   NEXT c
   PRINT "積=";S
NEXT N

END


別解 母関数
(A+B+c)(B+c)c=(AB+B^2)c+(A+2B)c^2+c^3である。
項ABcのf(n)に対する寄与をf(n:ABc)と表す。
変数1a,A,1b,B,B^2,c,c^2,c^3に相当するxの多項式は、
  1a =1+x+x^2+x^3+x^4+x^5+x^6+x^7+ … =1/(1-x)
  A =0*1+1x+2x^2+3x^3+4x^4+5x^5+6x^6+7x^7+ …  =x/(1-x)^2
  1b =1+x^3+x^6+x^9+x^12+x^15+x^18+x^21+ … =1/(1-x^3)
  B =0*1+1x^3+2x^6+3x^9+4x^12+5x^15+6x^18+7x^21+ …  =x^3/(1-x^3)^2
  B^2 =0^2*1+1^2x^3+2^2x^6+3^2x^9+4^2x^12+5^2x^15+6^2x^18+7^2x^21+ …  =(x^6+x^3)/(1-x^3)^3
  c =0*1+1x^6+2x^12+3x^18+4x^24+5x^30+6x^36+7x^42+ …  =x^6/(1-x^6)^2
  c^2 =0^2*1+1^2x^6+2^2x^12+3^2x^18+4^2x^24+5^2x^30+6^2x^36+7^2x^42+ …  =(x^12+x^6)/(1-x^6)^3
  c^3 =0^3*1+1^3x^6+2^3x^12+3^3x^18+4^3x^24+5^3x^30+6^3x^36+7^3x^42+ …  =(x^18+4x^12+x^6)/(1-x^6)^4
である。
f(n:ABc)の母関数Σ[k=0,∞]f(k:ABc)*x^kについて
 f(n:ABc)は、積A*B*cをマクローリン展開したときのx^nの係数になる。
同様に
 f(n:B^2c)は、積1a*B^2*c
 f(n:Ac^2)は、積A*1b*c^2
 f(n:Bc^2)は、積1a*B*c^2
 f(n:c^3)は、積1a*1b*c^3

したがって、f(n)の母関数は、
Σ[k=0,∞]f(k)*x^k
=f(n:ABc) + f(n:B^2c) + f(n:Ac^2) + 2*f(n:Bc^2) + f(n:c^3)
= x/(1-x)^2 * x^3/(1-x^3)^2 * x^6/(1-x^6)^2
 + 1/(1-x) * (x^6+x^3)/(1-x^3)^3 * x^6/(1-x^6)^2
 + x/(1-x)^2 * 1/(1-x^3) * (x^12+x^6)/(1-x^6)^3
 + 2 * { 1/(1-x) * x^3/(1-x^3)^2 * (x^12+x^6)/(1-x^6)^3 }
 + 1/(1-x) * 1/(1-x^3) * (x^18+4x^12+x^6)/(1-x^6)^4
= (6x^20+8x^19+10x^18+12x^17+13x^16+14x^15+17x^14+16x^13+15x^12+8x^11+7x^10+6x^9+3x^8+2x^7+x^6 )
 / { (1-x^3)^2 * (1-x^6)^4 }
これをマクローリン展開したときのx^nの係数になる。、
(終り)

先のマクローリン展開のプログラムでは、DATA文の箇所を、

DATA 20 !次数 f=6x^20+8x^19+10x^18+12x^17+13x^16+14x^15+17x^14+16x^13+15x^12+8x^11+7x^10+6x^9+3x^8+2x^7+x^6
DATA 0,0,0,0,0,0,1,2,3,6,7,8,15,16,17,14,13,12,10,8,6 !係数 ※展開して次数が小さい方から


DATA 30 !次数 g=x^30-2x^27-3x^24+8x^21+2x^18-12x^15+2x^12+8x^9-3x^6-2x^3+1
DATA 1,0,0,-2,0,0,-3,0,0,8,0,0,2,0,0,-12,0,0,2,0,0,8,0,0,-3,0,0,-2,0,0,1 !係数 ※展開して次数が小さい方から

とする。
 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月10日(日)09時40分8秒
  > No.3009[元記事へ]

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

山中さんが作成された下記「マクローリン展開」プログラムを、任意関数P(x)のマクローリン展開に利用したのですが、任意関数を

DEF F(x)=....
DEF G(x)=....
DEF P(x)=F(x)/G(x)

と設定して簡単に使える様にできないでしょうか?

> !マクローリン展開
> ! P(x)=P(0)+{P'(0)/1!}x+{P''(0)/2!}x^2+{P'''(0)/3!}x^3+ …
> !例
> !P(x)=1/(1-x)=1+x+x^2+x^3+x^4+ …
> !
> !考察
> !P(0)は、x=0を代入して、1/(1-0)=1
> !P'(0)は、
> ! P(x)=f(x)/g(x)より、P'=(f'g-fg')/g^2なので、
> ! 1'(1-x)-1(1-x)'/(1-x)^2=1/(1-x)^2
> ! x=0を代入して、1
> !P''(0)は、
> ! P''(x)=(P'(x))'なので、
> ! 上記の結果をあらためて、f(x)=f'g-fg'、g(x)=g^2と考える。上記と同じ議論を繰り返す。
> !(終り)
>
> OPTION ARITHMETIC RATIONAL !有理数モード
>
> PUBLIC NUMERIC N !次数
> LET N=50
>
> !変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
> !「dim a(0 to n) !係数」で定義する
> DIM P(0 TO N)
> DIM F(0 TO N),G(0 TO N) !p=f/g
> MAT F=ZER
> MAT G=ZER
>
> DATA 6 !次数 f=x^3(2x^3+x^2+x+1)=2*x^6+x^5+x^4+x^3 ※
> DATA 0,0,0,1,1,1,2 !係数 ※展開して次数が小さい方から
> READ R
> FOR i=0 TO R
>    READ F(i)
> NEXT i
> !!!MAT PRINT F; !debug
> CALL poly_disp(F) !多項式を表示する
> PRINT
>
> DATA 10 !次数 g=(1-x)(1-x^3)^3=x^10-x^9-3x^7+3x^6+3x^4-3x^3-x+1 ※
> DATA 1,-1,0,-3,3,0,3,-3,0,-1,1 !係数 ※展開して次数が小さい方から
> READ R
> FOR i=0 TO R
>    READ G(i)
> NEXT i
> !!!MAT PRINT G; !debug
> CALL poly_disp(G) !多項式を表示する
> PRINT
>
>
> LET P(0)=F(0)/G(0)/FACT(0) !定数項
> PRINT 0; P(0) !debug
>
> DIM F1(0 TO N),G1(0 TO N), W1(0 TO N),W2(0 TO N),W3(0 TO N) !作業用
> FOR i=1 TO N !i階微分
>
>    CALL poly_diff(F,W3) !f'g
>    CALL poly_mul(W3,G, W1)
>    !!!MAT PRINT W1; !debug
>
>    CALL poly_diff(G,W3) !fg'
>    CALL poly_mul(F,W3, W2)
>    !!!MAT PRINT W2; !debug
>
>    CALL poly_sub(W1,W2, F1) !分子 f'g-fg'
>    !!!MAT PRINT F1; !debug
>
>
>    CALL poly_mul(G,G, G1) !分母 g^2
>    !!!MAT PRINT G1; !debug
>
>
>    LET P(i)=F1(0)/G1(0)/FACT(i) !x^iの係数
>    PRINT i; P(i) !debug
>
>
>    MAT F=F1 !次へ
>    MAT G=G1
> NEXT i
>
> CALL poly_disp(P) !多項式を表示する
> PRINT
>
> END
>
>
> !変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
> !「dim a(0 to n) !係数」で定義する
>
> !演算関連
>
> EXTERNAL SUB poly_add(v1(),v2(), v()) !加算 v=v1+v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> MAT v=v1+v2
> END SUB
>
> EXTERNAL SUB poly_sub(v1(),v2(), v()) !減算 v=v1-v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> MAT v=v1-v2
> END SUB
>
> EXTERNAL SUB poly_mul(v1(),v2(), v()) !乗算 v=v1*v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> DIM w(0 TO 2*N) !桁数は2倍になる
> MAT w=ZER
> FOR i=0 TO N !係数
>    FOR j=0 TO N
>       LET w(i+j)=w(i+j)+v1(i)*v2(j) !畳み込み
>    NEXT j
> NEXT i
> FOR i=0 TO N !※下n桁をコピーする ※オーバーフローは考慮していない
>    LET v(i)=w(i)
> NEXT i
> END SUB
>
> EXTERNAL SUB poly_diff(v1(), v()) !微分 v=v1'
> OPTION ARITHMETIC RATIONAL !有理数モード
> FOR i=1 TO N
>    LET v(i-1)=v1(i)*i
> NEXT i
> LET v(N)=0
> END SUB
>
>
> !表示関連
>
> EXTERNAL SUB poly_disp(A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
> OPTION ARITHMETIC RATIONAL !有理数モード
> CALL mono_disp(A(N),N)
> FOR i=N-1 TO 0 STEP -1 !次項
>    LET w=A(i)
>    IF w>0 THEN PRINT "+";
>    IF w<>0 OR N=0 THEN CALL mono_disp(w,i)
> NEXT i
> END SUB
>
> EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
> OPTION ARITHMETIC RATIONAL !有理数モード
> IF k<>0 THEN !x^nで
>    IF ak=0 OR ak=1 THEN !係数が0,1なら
>    ELSEIF ak=-1 THEN !係数が-1なら
>       PRINT "-"; !符号
>    ELSE
>       PRINT STR$(ak);"*";
>    END IF
> END IF
> IF k=0 THEN !次数が0なら
>    PRINT STR$(ak);
> ELSEIF k=1 THEN !次数が1なら
>    PRINT "X";
> ELSE
>    IF ak<>0 THEN PRINT "X^";STR$(k); !係数が0以外なら
> END IF
> END SUB
>
>
 

Re: 整数の組による積の和

 投稿者:山中和義  投稿日:2013年 3月10日(日)12時28分33秒
  > No.3012[元記事へ]

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

> DEF F(x)=....
> DEF G(x)=....
> DEF P(x)=F(x)/G(x)
> と設定して簡単に使える様にできないでしょうか?

提示したプログラムは、有理式に特化した手法です。
途中で算出される分数は、既約分数ではありませんが、厳密に微分した式になります。
よって、x=0を代入した値は誤差はありません。

一般の関数では、個々の関数に応じて微分しないといけませんので、プログラムは複雑になります。
汎用的な計算では、微分係数などで微分を近似します。したがって、誤差が累積していきます。
中点法、前進法、後退法の1,2,3次などを使えばある程度の精度は保証されますが、期待通りにはなりません。

F(X)=X/(1-X)^2の場合、係数 0,1,2,3,4,5,…

!マクローリン展開にみる数値微分の誤差と計算量 - 再帰呼び出しによるn階微分

LET A=0 !X=0 ※マクローリン展開
LET N=9 !N次近似

DIM c(0 TO N) !係数
LET c(0)=DF(A,0) !f(a)
PRINT c(0)

FOR i=1 TO N
   LET c(i)=DF(A,i)/FACT(i)
   PRINT c(i);"X^";STR$(i)
NEXT i

END


EXTERNAL FUNCTION F(X) !関数
!LET F=SIN(X)
!LET F=COS(X)
!LET F=EXP(X)
LET F=X/(1-X)^2 !0,1,2,3,4,5,…
!LET F=1/(1-X) !1,1,1,1,…
!LET F=(1-X)^4 !1,-4,6,-4,1,0,0,…
END FUNCTION

EXTERNAL FUNCTION DF(x,n) !f(x)のn階微分
IF n>0 THEN !微分係数から求める
   LET h=1/1024
   LET DF=(DF(x+h,n-1)-DF(x,n-1))/h
ELSE
   LET DF=F(x)
END IF
END FUNCTION


実行結果

0
1.00195598975279 X^1
2.00881583539961 X^2
3.02355721412682 X^3
4.04920235221334 X^4
5.08883308900731 X^5
6.14561086632151 X^6
7.22195861264053 X^7
8.4220216127928 X^8
7.07402933721543 X^9



初等関数のように、n階微分がnの一般式で定義できる場合は、精度はかなり保証されます。

F(X)=SIN(X)の場合

!マクローリン展開にみる数値微分の誤差と計算量 - 再帰呼び出しによるn階微分

LET A=0 !X=0 ※マクローリン展開
LET N=9 !N次近似

DIM c(0 TO N) !係数
LET c(0)=DF(A,0) !f(a)
PRINT c(0)

FOR i=1 TO N
   LET c(i)=DF(A,i)/FACT(i)
   PRINT c(i);"X^";STR$(i)
NEXT i

END


EXTERNAL FUNCTION F(X) !関数
LET F=SIN(X)
!LET F=COS(X)
!LET F=EXP(X)
END FUNCTION

EXTERNAL FUNCTION DF(x,n) !f(x)のn階微分
LET DF=SIN(x+n*PI/2) !f(x)=SIN(x)
!LET DF=COS(x+n*PI/2) !f(x)=COS(x)
!LET DF=EXP(x) !f(x)=EXP(x)
END FUNCTION


実行結果

0
1 X^1
2.31321691639751E-19 X^2
-.166666666666667 X^3
-3.85536152732919E-20 X^4
8.33333333333333E-3 X^5
1.9276807636646E-21 X^6
-1.98412698412698E-4 X^7
-4.58971610396332E-23 X^8
2.75573192239859E-6 X^9

 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月10日(日)13時14分8秒
  山中和義さんへのお返事です。

山中さん、早速のご教示有難う御座いました。

山中さんがご教示くださった
「汎用的な計算では、微分係数などで微分を近似する」方法のプログラムにF(x)=sin(x)と設定し出力したマクローリン係数と

「初等関数のように、n階微分がnの一般式で定義できる場合」の方法で出力されたF(x)=sin(x)のマクローリン係数

とを見比べると、x^5までの係数は概ね一致ですが、x^6以上の項では大きな差が出ており、任意関数を数値計算でマクローリン展開する場合は誤差の累積に注意が必要とのことが良く分かりました。
 

Re: 整数の組による積の和

 投稿者:しばっち  投稿日:2013年 3月12日(火)21時50分7秒
  > No.3013[元記事へ]

再帰を使った方法より、下記の方が若干精度がいいようです

EXTERNAL  FUNCTION DF(X,K)
LET H=1/1024
FOR J=0 TO K
   LET  S=S+(-1)^J*COMB(K,J)*F(X+(K/2-J)*H)
NEXT J
LET  DF=S/(H^K)
END FUNCTION

また1000桁モードを使用して、下記のようにすればある程度は使えそうです

OPTION ARITHMETIC DECIMAL_HIGH
PUBLIC NUMERIC H
LET X=0
LET N=9
LET EPS=1E-10 !'計算精度
FOR I=0 TO N
   LET H=1/128
   DO
      LET H=H/2
      LET A=DF1(X,I)
      LET B=DF2(X,I)
   LOOP UNTIL ABS(A - B) < EPS
   LET DF=(A+B)/2
   PRINT DF/FACT(I)
NEXT I
END

EXTERNAL FUNCTION F(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET F=X/(1-X)^2
END FUNCTION

EXTERNAL FUNCTION DF1(X,N)
OPTION ARITHMETIC DECIMAL_HIGH
IF N>0 THEN
   LET DF1=(DF1(X-2*H,N-1)-4*DF1(X-H,N-1)+3*DF1(X,N-1))/(2*H) !'3点前進法
   !'LET DF1=(3*DF1(X-4*H,N-1)-16*DF1(X-3*H,N-1)+36*DF1(X-2*H,N-1)-48*DF1(X-H,N-1)+25*DF1(X,N-1))/(12*H) !'5点前進法
ELSE
   LET DF1=F(X)
END IF
END FUNCTION

EXTERNAL FUNCTION DF2(X,N)
OPTION ARITHMETIC DECIMAL_HIGH
IF N>0 THEN
   LET DF2=(-3*DF2(X,N-1)+4*DF2(X+H,N-1)-DF2(X+2*H,N-1))/(2*H) !'3点後退法
   !'LET DF2=(-25*DF2(X,N-1)+48*DF2(X+H,N-1)-36*DF2(X+2*H,N-1)+16*DF2(X+3*H,N-1)-3*DF2(X+4*H,N-1))/(12*H) !'5点後退法
ELSE
   LET DF2=F(X)
END IF
END FUNCTION
 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月13日(水)09時25分4秒
  > No.3015[元記事へ]

しばっちさんへのお返事です。

しばっちさん、ご教示有難う御座いました。
関数 F(X)=X/(1-X)^2
についてご提示のあった二つのプロ(理屈は理解不能)を実行してみました。
---------------------------------------------------------
> 再帰を使った方法より、下記の方が若干精度がいいようです
---------------------------------------------------------
このプロの場合は結果が
0
1.00000071525602 X^1
2.00000381470259 X^2
3.00001192084544 X^3
4.00002806202375 X^4
5.00015669041249 X^5
6.01465745988539 X^6
24.1746473103899 X^7
-2263.61524295701 X^8
303480.118194826 X^9
となり、X^6の係数までは精度が高かったですが、X^7以降の係数は当てにならない結果でした。演算時間は速いので6次(必ずそう言えるか不明な点が気になるが)以下の係数には使えるようです。

----------------------------------------------------------------------
> また1000桁モードを使用して、下記のようにすればある程度は使えそうです
----------------------------------------------------------------------
上記2番目のプロは、9次までの係数が極めて高い精度で得られたので、幾らの次数まで正しい値かということを意識せず?に使えそうです。
ただし、私のコンピュータは遅い(AMD-AthlonXP2200+ 2.2GHz相当)ので8次以上の結果が出るまで5~6分必要としました。
 

Re: 整数の組による積の和

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

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

5次程度なら、次の連立方程式を解けば求まります。


!マクローリン展開
!f(x)=f(0)+{f'(0)/1!}x+{f''(0)/2!}x^2+{f'''(0)/3!}x^3+ …
!    =f(0)+a[1]x+a[2]x^2+a[3]x^3+a[4]x^4+ …

!DEF F(X)=SIN(X)
!DEF F(X)=COS(X)
!DEF F(X)=EXP(X)
DEF F(X)=X/(1-X)^2 !0,1,2,3,4,5,…
!DEF F(X)=1/(1-X) !1,1,1,1,1,…
!DEF F(x)=(1-X)^4 !1,-4,6,-4,1,0,0,…


LET N=9 !次数

!A=
!  x   x^2   x^3    x^4 …
! 2x  4x^2  8x^3  16x^4 …
! 3x  9x^2 27x^3  81x^4 …
! 4x 16x^2 64x^3 256x^4 …
!   :

LET x=1E-3 !x≒0

DIM A(N,N)
FOR i=1 TO N
   FOR J=1 TO N
      LET A(i,J)=(i*x)^J
   NEXT J
NEXT i
!!!MAT PRINT A; !debug

!b=
! f( x)-f(0)
! f(2x)-f(0)
! f(3x)-f(0)
! f(4x)-f(0)
!   :
DIM b(N)
LET F0=F(0)
FOR i=1 TO N
   LET b(i)=F(i*x)-F0
NEXT i

DIM p(N),iA(N,N) !連立方程式Ap=bを解く
MAT iA=INV(A)
MAT p=iA*b

PRINT F(0) !各係数 定数項
MAT PRINT p; !x,x^2,x^3,…の項

END


実行結果

0
1.00000000000017  1.99999999953607  3.00000058623451  3.999024242  5.03640518 -18.75867688  1689.07931105014 -130559.084358461  2609878


 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月14日(木)13時16分45秒
  山中和義さんへのお返事です。

山中さん、度重なるご教示有難う御座いました。

> 5次程度なら、次の連立方程式を解けば求まります。

上記プログラムの考え方も記載して頂き、私の頭でも「なるほどな~」と良く分かる計算法で感心するばかりでした。

コード中に「x=1E-3 !x≒0」の箇所が有りましたが、x=1E-2、x=1E-4、等と変えてみましたが、xを小さくすれば精度が上がると言う事でもない様ですね。
(この「x=1E-3 !x≒0」は「行列Aの高次係数が大きくなり過ぎない様にする為」という理由でしょうか?)

さてこのプログラムで「F(X)=X/(1-X)^2」を、x=1E-3のまま1000桁モードで計算させたら瞬時に9次までの高精度結果が得られました。難解な数値計算理論を使っていないのに、この方法は凄いですね。





 

Re: 整数の組による積の和

 投稿者:山中和義  投稿日:2013年 3月14日(木)14時20分0秒
  > No.3018[元記事へ]

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

> コード中に「x=1E-3 !x≒0」の箇所が有りましたが、x=1E-2、x=1E-4、等と変えてみましたが、xを小さくすれば精度が上がると言う事でもない様ですね。

1E-3あたりが実用値でしょう。


> (この「x=1E-3 !x≒0」は「行列Aの高次係数が大きくなり過ぎない様にする為」という理由でしょか?)

提示したプログラムは、X=x,2x,3x,…を代入して、これを満たす補間多項式を得ます。
x=0は、0を代入するのですが、x^kがすべて0になって、行列Aが成り立ちません。

Xは、テイラー展開におけるX=aと考えることもできます。
このことは、プログラムの最後に、

!F(x)の値
LET S=F(0)
FOR i=1 TO N
   LET S=S+p(i)*x^i
NEXT i
PRINT S; F(x)

を追加して、
先頭部分の関数定義とXの値を(別の関数と値でよいのですが)、

 DEF F(X)=SIN(X)

 LET x=PI/3

と変更して、確認できます。

 

Re: 整数の組による積の和

 投稿者:しばっち  投稿日:2013年 3月14日(木)21時36分13秒
  高階微分の計算に時間がかかるのは、再帰ルーチン内で多重呼び出しを行っているためです
これを直接(10階微分まで)求めるようにすれば速くなります
(精度については注意を払う必要がある)

OPTION ARITHMETIC DECIMAL_HIGH
PUBLIC NUMERIC H
LET X=0
LET EPS=1E-20 !'精度
FOR I=1 TO 10
   LET H=1/2^10
   DO
      LET H=H/2
      SELECT CASE I
      CASE 1
         LET A=(-25*F(X)+48*F(X+H)-36*F(X+2*H)+16*F(X+3*H)-3*F(X+4*H))/(12*H)
         LET B=(3*F(X-4*H)-16*F(X-3*H)+36*F(X-2*H)-48*F(X-H)+25*F(X))/(12*H)
      CASE 2
         LET A=(F(X)-2*F(X+H)+F(X+2*H))/(H^2)
         LET B=(F(X-2*H)-2*F(X-H)+F(X))/(H^2)
      CASE 3
         LET A=(-49*F(X)+232*F(X+H)-461*F(X+2*H)+496*F(X+3*H)-307*F(X+4*H)+104*F(X+5*H)-15*F(X+6*H))/(8*H^3)
         LET B=(15*F(X-6*H)-104*F(X-5*H)+307*F(X-4*H)-496*F(X-3*H)+461*F(X-2*H)-232*F(X-H)+49*F(X))/(8*H^3)
      CASE 4
         LET A=(F(X)-4*F(X+H)+6*F(X+2*H)-4*F(X+3*H)+F(X+4*H))/(H^4)
         LET B=(F(X-4*H)-4*F(X-3*H)+6*F(X-2*H)-4*F(X-H)+F(X))/(H^4)
      CASE 5
         LET A=(-81*F(X)+575*F(X+H)-1790*F(X+2*H)+3195*F(X+3*H)-3580*F(X+4*H)+2581*F(X+5*H)-1170*F(X+6*H)+305*F(X+7*H)-35*F(X+8*H))/(6*H^5)
         LET B=(35*F(X-8*H)-305*F(X-7*H)+1170*F(X-6*H)-2581*F(X-5*H)+3580*F(X-4*H)-3195*F(X-3*H)+1790*F(X-2*H)-575*F(X-H)+81*F(X))/(6*H^5)
      CASE 6
         LET A=(F(X)-6*F(X+H)+15*F(X+2*H)-20*F(X+3*H)+15*F(X+4*H)-6*F(X+5*H)+F(X+6*H))/(H^6)
         LET B=(F(X-6*H)-6*F(X-5*H)+15*F(X-4*H)-20*F(X-3*H)+15*F(X-2*H)-6*F(X-H)+F(X))/(H^6)
      CASE 7
         LET A=(-605*F(X)+5628*F(X+H)-23583*F(X+2*H)+58632*F(X+3*H)-95802*F(X+4*H)+107520*F(X+5*H)-83958*F(X+6*H)+45048*F(X+7*H)-15897*F(X+8*H)+3332*F(X+9*H)-315*F(X+10*H))/(24*H^7)
         LET B=(315*F(X-10*H)-3332*F(X-9*H)+15897*F(X-8*H)-45048*F(X-7*H)+83958*F(X-6*H)-107520*F(X-5*H)+95802*F(X-4*H)-58632*F(X-3*H)+23583*F(X-2*H)-5628*F(X-H)+605*F(X))/(24*H^7)
      CASE 8
         LET A=(F(X)-8*F(X+H)+28*F(X+2*H)-56*F(X+3*H)+70*F(X+4*H)-56*F(X+5*H)+28*F(X+6*H)-8*F(X+7*H)+F(X+8*H))/(H^8)
         LET B=(F(X-8*H)-8*F(X-7*H)+28*F(X-6*H)-56*F(X-5*H)+70*F(X-4*H)-56*F(X-3*H)+28*F(X-2*H)-8*F(X-H)+F(X))/(H^8)
      CASE 9
         LET A=(-169*F(X)+1932*F(X+H)-10128*F(X+2*H)+32196*F(X+3*H)-69129*F(X+4*H)+105624*F(X+5*H)-117768*F(X+6*H)+96552*F(X+7*H)-57771*F(X+8*H)+24604*F(X+9*H)-7080*F(X+10*H)+1236*F(X+11*H)-99*F(X+12*H))/(4*H^9)
         LET B=(99*F(X-12*H)-1236*F(X-11*H)+7080*F(X-10*H)-24604*F(X-9*H)+57771*F(X-8*H)-96552*F(X-7*H)+117768*F(X-6*H)-105624*F(X-5*H)+69129*F(X-4*H)-32196*F(X-3*H)+10128*F(X-2*H)-1932*F(X-H)+169*F(X))/(4*H^9)
      CASE 10
         LET A=(F(X)-10*F(X+H)+45*F(X+2*H)-120*F(X+3*H)+210*F(X+4*H)-252*F(X+5*H)+210*F(X+6*H)-120*F(X+7*H)+45*F(X+8*H)-10*F(X+9*H)+F(X+10*H))/(H^10)
         LET B=(F(X-10*H)-10*F(X-9*H)+45*F(X-8*H)-120*F(X-7*H)+210*F(X-6*H)-252*F(X-5*H)+210*F(X-4*H)-120*F(X-3*H)+45*F(X-2*H)-10*F(X-H)+F(X))/(H^10)
      END SELECT
   LOOP UNTIL ABS(A - B) < EPS
   LET DF=(A+B)/2
   PRINT DF/FACT(I)
NEXT I
END

EXTERNAL FUNCTION F(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET F=X/(1-X)^2
END FUNCTION
 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月15日(金)16時25分44秒
  > No.3019[元記事へ]

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

山中さん、ご教示有難うございます。

> Xは、テイラー展開におけるX=aと考えることもできます。

ご指示頂いた様に、x=1E-3ではなく、x=pi/3と設定しF(x)=sin(x)について確認しましたら、ご教示のとおりになりました。
上記「Xはテーラー展開における・・・」の意味は下記で解釈すると納得出来たのですが誤りでしょうか?

X=aの近傍X=a+hに於けるF(a+h)はテイラー展開によって
  F(a+h)=F(a)+F'(a)*h+F''(a)*h^2/2!+・・・
だから、これを
  F(a+h)-F(a)=F'(a)*h+F''(a)*h^2/2!+・・・
と変形して「a=0,h=pi/3」と置けば、「多元連立式[A][p]=[b]を[p]について解きマクローリン係数を求めるプログラム」を利用してF(pi/3)が得られる。
 

Re: 整数の組による積の和

 投稿者:島村1243  投稿日:2013年 3月16日(土)14時48分27秒
  > No.3020[元記事へ]

しばっちさんへのお返事です。

> 高階微分の計算に時間がかかるのは、再帰ルーチン内で多重呼び出しを行っているためです
> これを直接(10階微分まで)求めるようにすれば速くなります
> (精度については注意を払う必要がある)

ご教示頂いたコードを走らせて、瞬時に結果が得られることを確認しました。
どうも有難うございました。
 

マクローリン展開(テイラー展開)

 投稿者:山中和義  投稿日:2013年 3月16日(土)15時40分51秒
  > No.3021[元記事へ]

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

> Xは、テイラー展開におけるX=aと考えることもできます。

申し訳ありません。誤解を招く言い方になりました。
べき級数(x^kの和、多項式)で補間(近似)しているので、f(a)は求まるのは当然ですね。
これについての記述は取り下げます。


テイラー展開を考えると、プログラムは次のようになりますね。


!テイラー展開
!f(x)=c0 + c1(x-a) + c2(x-a)^2 + c3(x-a)^3 + c4(x-a)^4 + …

!参考サイト http://www.ice.tohtech.ac.jp/~nakagawa/taylorexp/taylor5.htm

!f(x)=1/(x+9)をx=1の周りでテイラー展開しなさい。
DEF F(X)=1/(X+9)

LET N=10 !次数
LET A=1 !3 !x=aの周り

LET x=1E-3 !⊿x≒0 ※1E-2、1E-4

!P=
!  x   x^2   x^3    x^4 …
! 2x  4x^2  8x^3  16x^4 …
! 3x  9x^2 27x^3  81x^4 …
! 4x 16x^2 64x^3 256x^4 …
!   :

DIM P(N,N)
FOR i=1 TO N
   FOR J=1 TO N
      LET P(i,J)=(i*x)^J
   NEXT J
NEXT i
!!!MAT PRINT P; !debug

!q=
! f(a+ x)-f(a)
! f(a+2x)-f(a)
! f(a+3x)-f(a)
! f(a+4x)-f(a)
!   :

DIM q(N)
LET FA=F(A)
FOR i=1 TO N
   LET q(i)=F(A+i*x)-FA
NEXT i
!!!MAT PRINT q; !debug


DIM c(N),W(N,N) !連立方程式Pc=qを解く
MAT W=INV(P)
MAT c=W*q


PRINT FA !各係数 定数項
MAT PRINT c; !(x-a),(x-a)^2,(x-a)^3,…の項

END

 

Re: マクローリン展開(テイラー展開)

 投稿者:島村1243  投稿日:2013年 3月16日(土)20時18分46秒
  山中和義さんへのお返事です。

> > Xは、テイラー展開におけるX=aと考えることもできます。
>
> べき級数(x^kの和、多項式)で補間(近似)しているので、f(a)は求まるのは当然ですね。
> これについての記述は取り下げます。
> テイラー展開を考えると、プログラムは次のようになりますね。

山中さん、大変良く分かりました。
マクローリン級数やテイラー展開の係数を、「多元一次連立方程式で求める」と言う発想が素晴らしいと思いました。
ご教示有難うございました。(完)
 

合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月24日(日)18時54分0秒
  電気回路の問題というより、数学の問題です。

問題
抵抗値が1Ωの抵抗がたくさんある。
この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

考察
合成抵抗の公式
 直列 R1+R2+R3+ … +Rn
 並列 1/(1/R1+1/R2+1/R3+ … +1/Rn)

仮分数A/Bを考える。それを帯分数にして、真分数の部分を単位分数で表す。
A/B=K+a/B=K+(1/b1+1/b2+1/b3+ … +1/bm)
※K個の直列、b1個の並列、b2個の並列、b3個の並列、…、bm個の並列
個数は、(K+b1+b2+b3+ … +bm)個

単位分数は、エジプト分数を使う。 参考プログラム Mathフォルダ内 EGYPT.BAS

例 3/2の場合
 3/2=1+1/2より、
  ─R┬R┬
    └R┘
のように接続する。

例 2/3の場合
 2/3=1/3+1/3=1/2+1/6 のように一通りではない。

また、2/3=1/(1/1+1/2)なので、上記の3/2の並びを縦に見て、
  ├┐
  R R
  ││
  │ R
  ├┘
がその逆数の値の接続となる。

2/3のように個数を減らすには、仮分数で考えた方がよい。
(終り)

●n個のときの接続パターン(場合の数)
分割数(自然数を1以上の自然数の和で表すことを考える。ただし、順序は問わない)を利用する。

例 4個の場合
 4
 3+1
 2+2
 2+1+1
 1+1+1+1
なので、
 ─R─R─R─R─

 ┬R┬R┬R┬
 └R─

 ┬R┬R┬
 └R┬R─

 ┬R┬R┬
 ├R┬
 └R─

 ┬R┬
 ├R┬
 ├R┬
 └R─
を得る。

┬ の解釈

     ↑上の段の縦線(┬)への接続
  ┬ ┘
  ↑下の段の横線(─、┬)からの接続

 結線が交差しない(包含する)ように、さらに上の段へ接続できる。(※1を参照のこと)
 自分の位置より左側の位置とは、接続できない。(※2を参照のこと)

に注意して、

─R─R─R─R─ の解釈は、─R─R─R─R─

┬R┬R┬R┬ の解釈は、
└R─

 ┬R ─┬R┬R┬
 │    ↑   ×3
 └R─ ┘

┬R┬R┬ の解釈は、
└R┬R─

 ┬R┬R ─┬      ┬R┬R ─┬
 │       ↑ ※2    │ ↑    ↑
 └R┬R─ ┘      └R┴R─ ┘

┬R┬R┬ の解釈は、
├R┬
└R─

 ┬R ──┬R┬     ┬R ─┬R┬
 │      ↑  ×2   │    ↑ ↑
 ├R─ ┬┘       ├R─ ┘ ↑ ※1
 │    ↑        │       ↑
 └R─ ┘        └R ── ┘

┬R┬ の解釈は、
├R┬
├R┬
└R─

 ┬R─── ┬
 │        ↑
 ├R── ┬┘
 │      ↑
 ├R─ ┬┘
 │    ↑
 └R─ ┘

以上、10通り
具体的な値は、4,  5/2, 5/3, 3/4,  1, 1,  4/3, 2/5, 3/5,  1/4

1,2,3,4,5,…個で 1,2,4,10,24,…通り  参考サイト http://oeis.org/A000084
(終り)


LET N=4 !非負の整数

PUBLIC NUMERIC A(50) !※50は、Nの最大値
MAT A=ZER

PUBLIC NUMERIC HEIGHT !段数
FOR HEIGHT=1 TO N
   CALL print_young(HEIGHT,N,N)
NEXT HEIGHT

END


EXTERNAL SUB print_young(d,n,c) !ヤング図形を表示する
IF d>0 THEN
   LET upper=n-d+1
   LET lower=INT((n-1)/d)+1
   FOR i=MIN(c,upper) TO lower STEP -1
      LET A(HEIGHT-d+1)=i
      CALL print_young(d-1,n-i,i) !次へ
   NEXT i
ELSE !揃ったら
   MAT PRINT A; !debug
   CALL connect(1,A)
END IF
END SUB


EXTERNAL SUB connect(P,A()) !p段目を表示する
!左端の分岐
LET W=A(P+1) !次の段の有無
IF P=1 THEN !1段目なら
   IF W>0 THEN PRINT "┬"; ELSE PRINT "─";
ELSE !2段目以降
   IF W>0 THEN PRINT "├"; ELSE PRINT "└";
END IF

FOR i=1 TO A(P) !各抵抗への接続位置
   IF W=0 AND (P=1 OR i=A(P)) THEN PRINT "R─"; ELSE PRINT "R┬";
NEXT i
PRINT

IF W>0 THEN CALL connect(P+1,A) !次の段へ
END SUB

 

LOGでエラー

 投稿者:島村1243  投稿日:2013年 3月25日(月)13時55分24秒
  取り消します。  

Re: 合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月25日(月)19時15分4秒
  > No.3025[元記事へ]

> 問題
> 抵抗値が1Ωの抵抗がたくさんある。
> この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

特別な場合は、簡単に生成できるようです。

n=5の場合
分割数を考える。
 5
 4+1
 3+2
 3+1+1
 2+2+1
 2+1+1+1
 1+1+1+1+1
より、

5から、
 No. 1
 ─R─R─R─R─

4+1から、
 No. 1
 ┬R┬R┬R┬R┬
 └R┘

 No. 2
 ┬R─R┬R┬R┬
 └   R┘

 No. 3
 ┬R─R─R┬R┬
 └      R┘

 No. 4
 ┬R─R─R─R┬
 └         R┘

3+2から、
 No. 1       No. 3
 ┬R┳R┬R┬   ┬R┳R┬R┬
 │    │     │ ┃ │
 └R┻R┘     └R┻R┘

 No. 2       No. 4
 ┬R┳R┬R┬   ┬R┳R┬R┬
 │       │   │ ┃    │
 └R┻R   ┘   └R┻R   ┘


3+1+1から、
 No. 1
 ┬R┬R┬R┬
 ├R┤
 └R┘

 No. 2
 ┬R┬R┬R┬
 ├R┘
 └   R┘

 No. 3
 ┬R┬R┬R┬
 ├R┘
 └      R┘

 No. 4
 ┬R─R┬R┬
 ├   R┤
 └   R┘

 No. 5
 ┬R─R┬R┬
 ├   R┘
 └      R┘

 No. 6
 ┬R─R─R┬
 ├      R┤
 └      R┘

2+2+1から、
 2+1として、
  No. 1
  ┬R┬R┬
  └R┘

  No. 2
  ┬R─R┬
  └   R┘
 を得る。
 1段目の前に、┬R┳R┬ を追加して、これへの接続の有無を考える。
 No. 1    No. 3
 ┬R┳R┬  ┬R┳R┬
 │    │  │ ┃ │
 ├R╋R┤  ├R╋R┤
 └R┘     └R┘

 No. 2    No. 4
 ┬R┳R┬  ┬R┳R┬
 │    │  │ ┃ │
 ├R╋R┤  ├R╋R┤
 └   R┘  └   R┘


2+1+1+1から、
 No. 1
 ┬R┬R┬
 ├R┤
 ├R┤
 └R┘

 No. 2
 ┬R┬R┬
 ├R┤
 ├R┘
 └   R┘

 No. 3
 ┬R┬R┬
 ├R┘
 ├   R┤
 └   R┘

 No. 4
 ┬R─R┬
 ├   R┤
 ├   R┤
 └   R┘

1+1+1+1+1から、
 No. 1
 ┬R┬
 ├R┤
 ├R┤
 ├R┤
 └R┘

以上より、1+4+4+6+4+4+1=24通り


●n,1,1,…,1形式
 └  m個  ┘


LET M=3 !段数m ※2以上
LET N=3 !n

DIM B(M+1) !各段の配置位置
MAT B=(N+1)*CON

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(2,M,B,1,N)

END


EXTERNAL SUB try(P,M,B(),R,L)
FOR i=R TO L !配置位置の候補 ※ひとつ上の段の右側へ
   LET B(P)=i

   IF P<M THEN !次の段があれば
      CALL try(P+1,M,B,i,L)
   ELSE !結果を表示する
      LET C=C+1
      PRINT "No."; C

      PRINT "┬"; !1段目
      FOR J=1 TO L
         IF B(2)>J THEN PRINT "R─"; ELSE PRINT "R┬";
      NEXT J
      PRINT

      !!!MAT PRINT B; !debug
      FOR J=2 TO M !2段目以降
         IF J=M THEN PRINT "└"; ELSE PRINT "├"; !左端
         PRINT REPEAT$(" ",3*(B(J)-1));
         IF B(J+1)>B(J) THEN PRINT "R┘" ELSE PRINT "R┤"
      NEXT J
      PRINT
   END IF
NEXT i
END SUB


●n,n,…,n,1,1,…,1形式
 └ p個 ┘

n,1,1,…,1形式をs通りとすると、2^{(p-1)(n-1)}×s通り

 

Re: 合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月26日(火)11時26分45秒
  > No.3027[元記事へ]

> 問題
> 抵抗値が1Ωの抵抗がたくさんある。
> この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

式で接続形態を表すことにする。 + は直列、/ は並列 を表すとする。

 ─R┬R┬  式 R+R/R
   └R┘


OPTION ARITHMETIC RATIONAL !有理数

DEF s(a,b)=a+b !直列
DEF p(a,b)=a*b/(a+b) !並列 ∵1/(1/a+1/b)より
LET R=1 !1Ω

!●5より
!式 R+R+R+R
! ─R─R─R─
PRINT s(s(s(R,R),R),R)


!●4+1より
!式 R/R+R+R
! ┬R┬R┬R┬
! └R┘
PRINT s(s(p(R,R),R),R)

!(R+R)/R+R
! ┬R─R ┬R┬
! └R──┘
PRINT s(p(s(R,R),R),R)

!式 (R+R+R)/R
! ┬R─R─R┬
! └R───┘
PRINT p(s(s(R,R),R),R)


!●2+2より
!式 (R+R)/(R+R)
! ┬R─R┬
! └R─R┘
PRINT p(s(R,R),s(R,R))

!式 R/R+R/R
! ┬R┬R┬
! └R┴R┘
PRINT s(p(R,R),p(R,R))


!●2+1+1より
!式 R/R/R+R
! ┬R┬R┬
! ├R┤
! └R┘
PRINT s(p(p(R,R),R),R)

!式 (R/R+R)/R
! ┬R┬R┬
! ├R┘
! └   R┘
PRINT p(s(p(R,R),R),R)

!式 (R+R)/R/R
! ┬R┬R┬
! ├   R┘
! └   R┘
PRINT p(p(s(R,R),R),R)


!●1+1+1+1より
!式 R/R/R/R
! ┬R┬
! ├R┤
! ├R┤
! └R┘
PRINT p(p(p(R,R),R),R)

END


実行結果 4個の場合(10通り)

4
5/2
5/3
3/4
1
1
4/3
3/5
2/5
1/4


逆数どうしの組が現れる。

 

Re: 合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月27日(水)12時47分26秒
  > No.3028[元記事へ]

> 問題
> 抵抗値が1Ωの抵抗がたくさんある。
> この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

今までみてきた「分割数と右スライド」方式から展開してみました。

考察
分割数から左端を固定した並列を列挙する。
例 6の場合
 6, 5+1, 4+2, 4+1+1, …

例 4+2の場合
 ┬R┬R┬R┬R┬
 └R┴R┘
なので、各抵抗どうしの接続の組み合わせを考える。

1段目を並べる。
 ┬R┬R┬R┬R┬

2段目以降は、ひとつ上の段と左端を揃えるように、
隙間がない状態で並べる。
 ┬R┬R┬R┬R┬    (R+R)/(R+R)+R+R  R/R+R/R+R+R
 └R┻R┘    ×2

末尾を右へずらす。
 ┬R┬R┬R┬R┬    (R+R+R)/(R+R)+R  R/R+(R+R)/R+R
 └R┻   R┘   ×2

 ┬R┬R┬R┬R┬    (R+R+R+R)/(R+R)  R/R+(R+R+R)/R
 └R┻      R┘ ×2

次に、1個分の隙間にした状態で並べる。
ただし、上の段への接続は「接続」の状態とする。
 ┬R┬R┬R┬R┬    (R+R)/R+(R+R)/R
 └   R┴   R┘
    ↑

末尾を右へずらす。(この場合はない!)

次に、2個分の隙間にした状態で並べる。(この場合はない!)
末尾を右へずらす。
  :
  :
なければ、次の段へ進む。

以上を(再帰的に)繰り返す。
(終り)

6個の場合、66通り

OPTION ARITHMETIC RATIONAL !有理数

DEF s(a,b)=a+b !直列
DEF p(a,b)=a*b/(a+b) !並列 ∵1/(1/a+1/b)より
LET R=1 !1Ω


!●6
!No. 1
!─R─R─R─R─R─R─  R+R+R+R+R+R
PRINT s(s(s(s(s(R,R),R),R),R),R)

PRINT


!●5+1
!No. 1
!┬R┬R┬R┬R┬R┬  R/R+R+R+R+R
!└R┘
PRINT s(s(s(s(p(R,R),R),R),R),R)

!No. 2
!┬R─R┬R┬R┬R┬  (R+R)/R+R+R+R
!└   R┘
PRINT s(s(s(p(s(R,R),R),R),R),R)

!No. 3
!┬R─R─R┬R┬R┬  (R+R+R)/R+R+R
!└      R┘
PRINT s(s(p(s(s(R,R),R),R),R),R)

!No. 4
!┬R─R─R─R┬R┬  (R+R+R+R)/R+R
!└         R┘
PRINT s(p(s(s(s(R,R),R),R),R),R)

!No. 5
!┬R─R─R─R─R┬  (R+R+R+R+R)/R
!└            R┘
PRINT p(s(s(s(s(R,R),R),R),R),R)

PRINT


!●4+2
!No. 1
!┬R┬R┬R┬R┬    (R+R)/(R+R)+R+R  R/R+R/R+R+R
!└R┻R┘    ×2
PRINT s(s(p(s(R,R),s(R,R)),R),R)
PRINT s(s(s(p(R,R),p(R,R)),R),R)

!No. 2
!┬R┬R─R┬R┬    (R+R+R)/(R+R)+R  R/R+(R+R)/R+R
!└R┻   R┘   ×2
PRINT s(p(s(s(R,R),R),s(R,R)),R)
PRINT s(s(p(R,R),p(s(R,R),R)),R)

!No. 3
!┬R┬R─R─R┬    (R+R+R+R)/(R+R)  R/R+(R+R+R)/R
!└R┻      R┘ ×2
PRINT p(s(s(s(R,R),R),R),s(R,R))
PRINT s(p(R,R),p(s(s(R,R),R),R))

!No. 7
!┬R─R┬R┬R┬  (R+R)/R+(R+R)/R
!│    ┃    │
!└   R┻   R┘

PRINT s(p(s(R,R),R),p(s(R,R),R))

PRINT


!●3+3+3
!No. 1
!┬R┬R┬R┬  (R+R+R)/(R+R+R)
!│     │
!└R┻R┻R┘
PRINT p(s(s(R,R),R),s(s(R,R),R))

!No. 2
!┬R┬R┬R┬  R/R+(R+R)/(R+R)
!│ ┃  │
!└R┻R┻R┘
PRINT s(p(R,R),p(s(R,R),s(R,R)))

!No. 3
!┬R┬R┬R┬  R/R+R/R+R/R
!│ ┃ ┃ │
!└R┻R┻R┘
PRINT s(s(p(R,R),p(R,R)),p(R,R))

PRINT


!●4+1+1
!No. 1
!┬R┬R┬R┬R┬  R/R/R+R+R+R
!├R┤
!└R┘
PRINT s(s(s(p(p(R,R),R),R),R),R)

!No. 2
!┬R┬R┬R┬R┬  (R/R+R)/R+R+R
!├R┘
!└   R┘
PRINT s(s(p(s(p(R,R),R),R),R),R)

!No. 3
!┬R┬R┬R┬R┬  (R/R+R+R)/R+R
!├R┘
!└      R┘
PRINT s(p(s(s(p(R,R),R),R),R),R)

!No. 4
!┬R┬R┬R┬R┬  (R/R+R+R+R)/R
!├R┘
!└         R┘
PRINT p(s(s(s(p(R,R),R),R),R),R)

!No. 5
!┬R─R┬R┬R┬  (R+R)/R/R+R+R
!├   R┤
!└   R┘
PRINT s(s(p(p(s(R,R),R),R),R),R)

!No. 6
!┬R─R┬R┬R┬  ((R+R)/R+R)/R+R
!├   R┘
!└      R┘
PRINT s(p(s(p(s(R,R),R),R),R),R)

!No. 7
!┬R─R┬R┬R┬  ((R+R)/R+R+R)/R
!├   R┘
!└         R┘
PRINT p(s(s(p(s(R,R),R),R),R),R)

!No. 8
!┬R─R─R┬R┬  (R+R+R)/R/R+R
!├      R┤
!└      R┘
PRINT s(p(p(s(s(R,R),R),R),R),R)

!No. 9
!┬R─R─R┬R┬  ((R+R+R)/R+R)/R
!├      R┘
!└         R┘
PRINT p(s(p(s(s(R,R),R),R),R),R)

!No. 10
!┬R─R─R─R┬  (R+R+R+R)/R/R
!├         R┤
!└         R┘
PRINT p(p(s(s(s(R,R),R),R),R),R)

PRINT


!●3+2+1
!No. 1
!┬R┬R┬R┬    (R+R)/(R/R+R)+R  R/R/R+R/R+R
!├R┻R┘  ×2
!└R┘
PRINT s(p(s(R,R),s(p(R,R),R)),R)
PRINT s(s(p(p(R,R),R),p(R,R)),R)

!No. 2
!┬R┬R┬R┬    (R+R)/(R+R)/R+R  (R/R+R/R)/R+R
!├R┻R┤  ×2
!└   R┘
PRINT s(p(p(s(R,R),s(R,R)),R),R)
PRINT s(p(s(p(R,R),p(R,R)),R),R)

!No. 3
!┬R┬R┬R┬    ((R+R)/(R+R)+R)/R  (R/R+R/R+R)/R
!├R┻R┘  ×2
!└      R┘
PRINT p(s(p(s(R,R),s(R,R)),R),R)
PRINT p(s(s(p(R,R),p(R,R)),R),R)

!No. 4
!┬R┬R─R┬    (R+R+R)/(R/R+R)  R/R/R+(R+R)/R
!├R┻   R┤ ×2
!└R┘
PRINT p(s(s(R,R),R),s(p(R,R),R))
PRINT s(p(p(R,R),R),p(s(R,R),R))

!No. 5
!┬R┬R─R┬    (R+R+R)/(R+R)/R  (R/R+(R+R)/R)/R
!├R┻   R┘ ×2
!└      R┘
PRINT p(p(s(s(R,R),R),s(R,R)),R)
PRINT p(s(p(R,R),p(s(R,R),R)),R)

!No. 7
!┬R┬R┬R┬    (R/R+R+R)/(R+R)  (R/R+R)/R+R/R
!├R┘
!└   R┻R┘   ×2

PRINT p(s(s(p(R,R),R),R),s(R,R))
PRINT s(p(s(p(R,R),R),R),p(R,R))

!No. 8
!┬R┬R┬R┬    ((R+R)/R+R)/(R+R)  (R+R)/R/R+R/R
!├   R┘
!└   R┻R┘   ×2

PRINT p(s(p(s(R,R),R),R),s(R,R))
PRINT s(p(p(s(R,R),R),R),p(R,R))

PRINT


!●2+2+2
!No. 1
!┬R┬R┬  (R+R)/(R+R)/(R+R)
!│    │
!├R┻R┤
!│    │
!└R┻R┘
PRINT p(p(s(R,R),s(R,R)),s(R,R))

!No. 2
!┬R┬R┬  (R/R+R/R)/(R+R)
!│ ┃ │
!├R┻R┤
!│    │
!└R┻R┘
PRINT p(s(p(R,R),p(R,R)),s(R,R))

!No. 3
!┬R┬R┬  (R/R/R)+(R/R/R)
!│ ┃ │
!├R╋R┤
!│ ┃ │
!└R┻R┘
PRINT s(p(p(R,R),R),p(p(R,R),R))

PRINT


!●3+1+1+1
!No. 1
!┬R┬R┬R┬  R/R/R/R+R+R
!├R┤
!├R┤
!└R┘
PRINT s(s(p(p(p(R,R),R),R),R),R)

!No. 2
!┬R┬R┬R┬  (R/R/R+R)/R+R
!├R┤
!├R┘
!└   R┘
PRINT s(p(s(p(p(R,R),R),R),R),R)

!No. 3
!┬R┬R┬R┬  (R/R/R+R+R)/R
!├R┤
!├R┘
!└      R┘
PRINT p(s(s(p(p(R,R),R),R),R),R)

!No. 4
!┬R┬R┬R┬  (R/R+R)/R/R+R
!├R┘
!├   R┤
!└   R┘
PRINT s(p(p(s(p(R,R),R),R),R),R)

!No. 5
!┬R┬R┬R┬  ((R/R+R)/R+R)/R
!├R┘
!├   R┘
!└      R┘
PRINT p(s(p(s(p(R,R),R),R),R),R)

!No. 6
!┬R┬R┬R┬  (R/R+R+R)/R/R
!├R┘
!├      R┤
!└      R┘
PRINT p(p(s(s(p(R,R),R),R),R),R)

!No. 7
!┬R─R┬R┬  ((R+R)/R/R/R+R
!├   R┤
!├   R┤
!└   R┘
PRINT s(p(p(p(s(R,R),R),R),R),R)

!No. 8
!┬R─R┬R┬  ((R+R)/R/R+R)/R
!├   R┤
!├   R┘
!└      R┘
PRINT p(s(p(p(s(R,R),R),R),R),R)

!No. 9
!┬R─R┬R┬  ((R+R)/R+R)/R/R
!├   R┘
!├      R┤
!└      R┘
PRINT p(p(s(p(s(R,R),R),R),R),R)

!No. 10
!┬R─R─R┬  (R+R+R)/R/R/R
!├      R┤
!├      R┤
!└      R┘
PRINT p(p(p(s(s(R,R),R),R),R),R)

PRINT


!●2+2+1+1
!No. 1
!┬R┬R┬    (R+R)/(R/R/R+R)  R/R/R/R+R/R
!├R┻R┘ ×2
!├R┤
!└R┘
PRINT p(s(R,R),s(p(p(R,R),R),R))
PRINT s(p(p(p(R,R),R),R),p(R,R))

!No. 2
!┬R┬R┬    (R+R)/(R/R+R)/R  (R/R/R+R/R)/R
!├R┻R┘ ×2
!├R┘
!└   R┘
PRINT p(p(s(R,R),s(p(R,R),R)),R)
PRINT p(s(p(p(R,R),R),p(R,R)),R)

!No. 3
!┬R┬R┬    (R+R)/(R+R)/R/R  (R/R+R/R)/R/R
!├R┻R┤ ×2
!├   R┤
!└   R┘
PRINT p(p(p(s(R,R),s(R,R)),R),R)
PRINT p(p(s(p(R,R),p(R,R)),R),R)

!No. 7
!┬R┬R┬    (R/R+R)/(R/R+R)
!├R┘
!├R┬R┘
!└R┘

PRINT p(s(p(R,R),R),s(p(R,R),R))

PRINT


!●2+1+1+1+1
!No. 1
!┬R┬R┬  R/R/R/R/R+R
!├R┤
!├R┤
!├R┤
!└R┘
PRINT s(p(p(p(p(R,R),R),R),R),R)

!No. 2
!┬R┬R┬  (R/R/R/R+R)/R
!├R┤
!├R┤
!├R┘
!└   R┘
PRINT p(s(p(p(p(R,R),R),R),R),R)

!No. 3
!┬R┬R┬  (R/R/R+R)/R/R
!├R┤
!├R┘
!├   R┤
!└   R┘
PRINT p(p(s(p(p(R,R),R),R),R),R)

!No. 4
!┬R┬R┬  (R/R+R)/R/R/R
!├R┘
!├   R┤
!├   R┤
!└   R┘
PRINT p(p(p(s(p(R,R),R),R),R),R)

!No. 5
!┬R─R┬  (R+R)/R/R/R/R
!├   R┤
!├   R┤
!├   R┤
!└   R┘
PRINT p(p(p(p(s(R,R),R),R),R),R)

PRINT


!●1+1+1+1+1+1
!No. 1
!┬R┬  R/R/R/R/R/R
!├R┤
!├R┤
!├R┤
!├R┤
!└R┘
PRINT p(p(p(p(p(R,R),R),R),R),R)

END


つづく
 

Re: 合成抵抗の問題

 投稿者:山中和義  投稿日:2013年 3月27日(水)12時49分15秒
  > No.3029[元記事へ]

つづき

実行結果

6

9/2
11/3
11/4
9/5
5/6

3
3
11/5
13/6
4/3
5/4
4/3

3/2
3/2
3/2

10/3
13/5
12/7
7/9
12/5
13/8
8/11
10/7
7/11
4/9

13/7
11/6
3/2
3/2
2/3
2/3
1
1
6/11
7/13
10/9
11/10
10/11
9/10

2/3
2/3
2/3

9/4
11/7
7/10
11/8
8/13
5/12
9/7
7/12
5/13
3/10

4/5
3/4
6/13
5/11
1/3
1/3
3/4

6/5
5/9
4/11
3/11
2/9

1/6


逆数どうしの組が現れる。対称性がある。
 6と1+1+1+1+1+1
 5+1と2+1+1+1+1
 4+2と3+1+1+1
 など

ふたつの式の関係は、
たとえば、
 ┬R─R┬R┬R┬R┬  式 (R+R)/R+R+R+R
 └   R┘
と
 ┬R┬R┬  式 (R/R+R)/R/R/R
 ├R┘
 ├   R┤
 ├   R┤
 └   R┘
のように、+,/ の入れ替えることになる。(必要に応じて括弧がいる)

 

数列の一般項(多項式)

 投稿者:山中和義  投稿日:2013年 3月30日(土)19時51分20秒
  問題
1,3,7,13,21,31,43,57,…で与えられた数列について、
(1) 25番目の数はいくらでしょうか?
(2) 一般項を求めてください。

答え
数列なら、ココ! 参考サイト http://oeis.org/A002061
(終り)

答え 小学生
 1,3,7,13,21,31,43,57,…
+ 0,1,2, 3, 4, 5, 6, 7,…
--------------------------
 1,4,9,16,25,36,49,64,…
より、
(2) ●+(□-1)=□×□なので、●=□×□-□+1 ( 式 x+(n-1)=n^2 )
(1) 25×25-25+1=625-25+1=601
(終り)

答え 中学生
 1,3,7,13,21,31,43,57,…
- 1,2,3, 4, 5, 6, 7, 8,…
--------------------------
 0,1,4, 9,16,25,36,49,…
より、
(1) n番目は(n-1)^2なので、(25-1)^2+25=576+25=601
(2) x-n=(n-1)^2から、x=n^2-n+1
(終り)

答え 中学生
  1,3,7,13,21,31,43,57,…
から、
  0,1,2, 3, 4, 5, 6, 7,… (n-1)
× 1,2,3, 4, 5, 6, 7, 8,… n
---------------------------
  0,2,6,12,20,30,42,56,…
を引いて、
  1,1,1, 1, 1, 1, 1, 1,…
より、x-(n-1)n=1
(終り)

Eさん「オイラならこうする。」  参考サイト http://oeis.org/A202018
  1, 3, 7,13,21,31,43,57,…
+ 40,40,40,40,40,40,40,40,…
-----------------------------
 41,43,47,53,61,71,83,97,…


答え 高校生
 1,3,7,13,21,31,43,57,…
  2,4, 6, 8,10,12,14,… 第1階差が等差数列
      2, 2, 2, 2, 2, 2,…
より、
n≧2のとき、a[n]=1+Σ[k=1,n-1]2k=1+2*(n-1)n/2=n^2-n+1
これは、n=1のときも成り立つ。
したがって、a[n]=n^2-n+1、n≧1
(終り)

答え 高校生
一般に、
 階差数列を考える。
 a[0] a[1] a[2] a[3] a[4] a[5] a[6] …
      b[0] b[1] b[2] b[3] b[4] b[5] … 第1階差が等差数列
           c    c    c    c    c    …
 a[n]=pn^2+qn+r、n≧0とすると、
 a[0]=r
 b[0]=a[1]-a[0]=(p+q+r)-r=p+q
 c=b[1]-b[0]=(a[2]-a[1])-b[0]={(4p+2q+r)-(p+q+r)}-(p+q)=2p
なので、
 1=r
 2=p+q
 2=2p
から、p=1、q=1、r=1
よって、a[n]=n^2+n+1(n≧0) ∴a[n]=(n-1)^2+(n-1)+1=n^2-n+1(n≧1)
(終り)


OPTION ARITHMETIC RATIONAL !有理数

DATA 1,2,2

DIM P(0 TO 2,0 TO 2),Q(0 TO 2) !連立方程式Px=qを解く
MAT READ Q

DATA 0,0,1 !r
DATA 1,1,0 !p+q
DATA 2,0,0 !2p
MAT READ P

DIM W(3,3),x(0 TO 2)
MAT W=INV(P)
MAT x=W*Q
MAT PRINT x; !n^2,n,1の係数 ※n≧0

FOR n=0 TO 10 !検算
   PRINT n; poly_val(2,x,n) !第n項
NEXT n


DIM y(0 TO 2) !nにn-1を代入して、展開する ※a[n]、n≧1
LET y(0)=  x(0)
LET y(1)=2*x(0)*(-1)   +x(1)
LET y(2)=  x(0)*(-1)^2 +x(1)*(-1) +x(2)
FOR n=1 TO 10 !検算
   PRINT n; poly_val(2,y,n) !第n項
NEXT n

END

EXTERNAL FUNCTION poly_val(k,c(),x) !関数値 f(x)=c[0]x^k+c[1]x^(k-1)+ … +c[n-2]x^2+c[n-1]x+c[n]
OPTION ARITHMETIC RATIONAL !有理数モード
LET f=c(0) !ホーナー法による
FOR i=1 TO k
   LET f=f*x+c(i)
NEXT i
LET poly_val=f
END FUNCTION


●3次式

問題
数列 1,3,4,6,11,21,… の一般項を求めよ。


OPTION ARITHMETIC RATIONAL !有理数

DIM P(0 TO 3,0 TO 3),Q(0 TO 3) !連立方程式Px=qを解く

!1,3,4,6,11,21,…
!  2,1,2, 5,10,… 第1階差
!   -1,1, 3, 5,… 第2階差が等差数列
!      2, 2, 2,…
!より、
DATA 1,2,-1,2

MAT READ Q

!階差数列を考える。
! a[0] a[1] a[2] a[3] a[4] a[5] a[6] …
!      b[0] b[1] b[2] b[3] b[4] b[5] … 第1階差
!           c[0] c[1] c[2] c[3] c[4] … 第2階差が等差数列
!                d    d    d    d    …
!a[n]=pn^3+qn^2+rn+s、n≧0とすると、
!a[0]=s
!b[0]=a[1]-a[0]=(p+q+r+s)-s=p+q+r
!c[0]=b[1]-b[0]=(a[2]-a[1])-b[0]={(8p+4q+2r+s)-(p+q+r+s)}-(p+q+r)=6p+2q
!d=c[1]-c[0]
! =(b[2]-b[1])-c[0]
! ={(a[3]-a[2])-(a[2]-a[1])}-c[0]
! ={(a[3]-2a[2]+a[1])}-c[0]
! ={(27p+9q+3r+s)-2(8p+4q+2r+s)+(p+q+r+s)}-(6p+2q)
! =6p
DATA 0,0,0,1 !s
DATA 1,1,1,0 !p+q+r
DATA 6,2,0,0 !6p+2q
DATA 6,0,0,0 !6p
MAT READ P

DIM W(4,4),x(0 TO 3)
MAT W=INV(P)
MAT x=W*Q
MAT PRINT x; !n^3,n^2,n,1の係数 ※n≧0

FOR n=0 TO 10 !検算
   PRINT n; poly_val(3,x,n) !第n項
NEXT n


DIM y(0 TO 3) !n-1を代入して、展開する ※a[n]、n≧1
LET y(0)=x(0)
LET y(1)=3*x(0)*(-1)    +x(1)
LET y(2)=3*x(0)*(-1)^2+2*x(1)*(-1)  +x(2)
LET y(3)=  x(0)*(-1)^3  +x(1)*(-1)^2+x(2)*(-1)+x(3)
FOR n=1 TO 10 !検算
   PRINT n; poly_val(3,y,n) !第n項
NEXT n

END

EXTERNAL FUNCTION poly_val(k,c(),x) !関数値 f(x)=c[0]x^k+c[1]x^(k-1)+ … +c[n-2]x^2+c[n-1]x+c[n]
OPTION ARITHMETIC RATIONAL !有理数モード
LET f=c(0) !ホーナー法による
FOR i=1 TO k
   LET f=f*x+c(i)
NEXT i
LET poly_val=f
END FUNCTION


 

Re: 数列の一般項(多項式)

 投稿者:山中和義  投稿日:2013年 3月31日(日)10時02分40秒
  > No.3031[元記事へ]

> 問題
> 1,3,7,13,21,31,43,57,…で与えられた数列について、
> (1) 25番目の数はいくらでしょうか?
> (2) 一般項を求めてください。

前回は、
 数列の一般項が2次式なので、2階差分で定数になる
と考えた訳だが、
n次式とすると、ラグランジュの補間公式などを使っても求められる。

連立方程式を計算機で解くことを考えれば、単純に、
 a(n)=pn^2+qn+rとして、
 a(1)=p+q+r
 a(2)=4p+2q+r
 a(3)=9p+3q+r
より、p,q,rを求める。


!問題
!数列 1,3,7,13,21,31,43,57,… の一般項を求めよ。

!nの2次式f(n)=pn^2+qn+rなので、
! 3点(1,a[1])、(2,a[2])、(3,a[3])を通る放物線の方程式
!を求めてみる。

DIM A(0 TO 2,0 TO 2),b(0 TO 2)
DATA 1,1,1 !f(1)
DATA 4,2,1 !f(2)
DATA 9,3,1 !f(3)
MAT READ A

DATA 1,3,7 !13,21,31,43,57,…
MAT READ b

DIM W(3,3),x(0 TO 2) !連立方程式Ax=bを解く
MAT W=INV(A)
MAT x=W*b
MAT PRINT x;

FOR n=1 TO 10 !検算
   LET f=0
   FOR k=0 TO 2
      LET f=f*n+x(k)
   NEXT k
   PRINT n; f !第n項
NEXT n

END

 

ショートプログラム集

 投稿者:しばっち  投稿日:2013年 4月13日(土)22時16分50秒
  !'シュヴァルツシルト半径
!'LET  M=5.9723E+24   !'地球の重量(Kg)
!'LET  M=1.9884E+30   !'太陽の重量(Kg)
INPUT PROMPT  "重量(Kg)=":M
LET  G=6.673848E-11 !'万有引力定数
LET  C=299792458 !'光速度(m/s)
LET  R=2*M*G/C/C
PRINT "ブラックホールの半径 ";R;"m"
END
-----------------------------------------------------------
!'プランク時間
LET C=299792458 !'光速度(m/s)
LET H=1.054571726E-34 !'ディラック定数
LET G=6.673848E-11 !'万有引力定数
PRINT SQR(H*G/C^5);"秒"
END
-----------------------------------------------------------
!'レムニスケート周率
LET S=1
FOR I=20000 TO 1 STEP -1
   LET S=(2+(2*I)*(2*I+1)/S)
NEXT I
LET W=2*(1+1/S)
PRINT W

LET S=0
FOR R=0 TO 1-1/2^18 STEP 1/2^18
   LET S=S+1/SQR(1-R^4)
NEXT R
PRINT 2*S/2^18

LET W=1
FOR N=10000 TO 1 STEP -1
   LET W=1-W*(2*N-3)^2/(2*N)^2
NEXT N
LET W=W/2
PRINT 1/W
END
-----------------------------------------------------------
!'預金
INPUT PROMPT  "預金    =": X
INPUT PROMPT  "預け入れ年数=": N
INPUT PROMPT  "利率 =": R
PRINT "単利法     "; INT(X * (1 + N * R / 100))
PRINT "年複利法   "; INT(X * (1 + R / 100)^N)
PRINT "半年複利法 "; INT(X * (1 + R / 200)^(2 * N))
PRINT "複利法     "; INT(X * EXP(N * R / 100))
END
-----------------------------------------------------------
!'ローン返済
INPUT PROMPT  "借入金  =": A
INPUT PROMPT  "年利 (%)=": R
INPUT PROMPT  "返還年数=": N
LET  R = R / 100
LET  X1 = A * R * (1 + R)^ N / ((1 + R)^N - 1)
PRINT "元利均等返済方式 "; INT(X1);"円"
PRINT "元金均等返済方式"
FOR I = 1 TO N
   LET  X2=A/N*(1+(N-I+1)*R)
   PRINT "No.";I; INT(X2);"円"
NEXT I
END
-----------------------------------------------------------
!'遠心力
!'F=質量*速度^2/半径
!'F=質量*半径*角速度^2
!'LET M=5.9723E+24   !'地球の重量(Kg)
!'LET G=6.673848E-11 !'万有引力定数
!'LET R=6.378E+6  !' 地球の半径(m)
!'PRINT G*M/R^2;"N"
INPUT  PROMPT "半径(m)=":R
INPUT  PROMPT "回転数(秒)=":L
!'INPUT PROMPT "回転速度(m/s)=":LL
!'LET  L=LL/(2*PI*R)
INPUT  PROMPT "重量(Kg)=":M
!'LET V=2*PI*L*R !'角速度
LET  W=2*PI*L
LET  V=W*R !'速度
!'LET  F=M*V^2/R
LET  F=M*R*W^2
PRINT F;"N" !'!遠心力
PRINT V^2/R/9.80665;"G" !'G=V^2(m/s)/R(m)/g(9.80665)
PRINT F/M/9.80665;"G"
LET  RPM=L*60 !'毎分回転
LET  RCF= 11.1824395816324*(RPM/1000)^2*R*100 !'R(cm) RPM(回転/分)
PRINT RCF;"G"
PRINT 299.041677197263*SQR(RCF/R/100)/60;"回転/秒"
PRINT L;"回転/秒"
END
-----------------------------------------------------------
!'長生き
INPUT PROMPT  "移動速度(Km/h)=":V
INPUT PROMPT  "移動し続けた時間(秒)=":S
LET  V=V/3.6
LET  C=299792458 !'光速度(m/s)
IF V>=C THEN
   PRINT"光速を超えています"
   STOP
END IF
LET  A=S*SQR(1-V*V/C/C)
PRINT"時間 ";A;"秒"
PRINT"遅れた時間 ";S-A;"秒"
END
-----------------------------------------------------------
!'長生き
INPUT PROMPT  "高さ(m)=":H
INPUT  PROMPT "時間(秒)=":S
LET  C=299792458 !'光速度(m/s)
LET G=9.80665 !' 重力加速度
LET  A=G*H/C/C
PRINT"地上より";S*A;"秒 時間が進む"
END
-----------------------------------------------------------
!'質量増加
INPUT PROMPT  "質量 Kg=":G
INPUT PROMPT  "移動速度(Km/h)=":V
LET  V=V/3.6
LET  C=299792458 !'光速度(m/s)
IF V>=C THEN
   PRINT"光速を超えています"
   STOP
END IF
LET  A=G/SQR(1-V*V/C/C)
PRINT"質量 ";A;"Kg"
PRINT"増えた質量 ";A-G;"Kg"
END
-----------------------------------------------------------
!'水平投射
SET BITMAP SIZE 600,300
SET WINDOW  0 , 299 ,20,-279
DRAW AXES(20,20)
INPUT  PROMPT "初速度(m/s)=":V0
INPUT  PROMPT "高さ=":H
LET G=9.80665 !'重力加速度
PLOT LINES: 0,-H;
DO
   LET T=T+1/128
   LET X=V0*T
   LET Y=-H+G*T^2/2
   PLOT LINES: X,Y;
LOOP UNTIL Y>=0
PRINT"水平到達距離(m)";X;V0*SQR(2*H/G)
PRINT "到達時間(秒)";SQR(2*H/G)
END
-----------------------------------------------------------
!'斜方投射
LET XSIZE=800
LET YSIZE=600
LET RATE=5
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW  0 , (XSIZE-1)/RATE , -20/RATE,(YSIZE-21)/RATE
DRAW AXES(10,20)
INPUT  PROMPT "初速度(m/s)=":V0
LET G=9.80665
INPUT  PROMPT "角度=":TT
LET TH=TT*PI/180
PLOT LINES: 0,0;
LET YY=0
LET T=0
DO
   LET T=T+1/128
   LET X=V0*COS(TH)*T
   LET Y=V0*SIN(TH)*T-G*T^2/2
   PLOT LINES: X,Y;
   LET YY=MAX(YY,Y)
LOOP UNTIL Y=<0
PRINT "距離(m)";X;"到達高度(m)";YY;"到達時間(秒)";T;V0*SIN(TH)*2/G
PRINT "距離(m)";V0^2/G*SIN(2*TH);"到達高度(m)";(V0*SIN(TH))^2/2/G;"最高点到達時間(秒)";V0*SIN(TH)/G
END
-----------------------------------------------------------
!'十二支
OPTION BASE 0
DIM A$(11)
FOR I=0 TO 11
   READ A$(I)
NEXT I
DATA "申(さる)","酉(とり)","戌(いぬ)","亥(い)","子(ね)","丑(うし)"
DATA "寅(とら)","卯(う)","辰(たつ)","巳(み)","午(うま)","未(ひつじ)"
INPUT PROMPT  "西暦=":Y
PRINT "十二支=";A$(MOD(Y,12))
END
-----------------------------------------------------------
!'重力加速度
LET R=6378137  !' 地球の半径(m)
LET G0=9.80665 !'高度0での重力加速度
INPUT  PROMPT "高さ(m) H=":H
LET G=G0*(R/(R+H))^2
PRINT "高度Hでの重力加速度";G;"m/s^2"
LET M=5.9723E+24   !'地球の重量(Kg)
LET G=6.673848E-11 !'万有引力定数
LET GG=G*M/(R+h)^2
PRINT "高度Hでの重力加速度";GG;"m/s^2"
END
-----------------------------------------------------------
!'星座
DIM NISU(12), D$(13), N1(13), N2(13)
DO
   INPUT PROMPT  "月,日 =": M, D
LOOP WHILE M < 1 OR M > 12 OR D < 1 OR D > 31
FOR I = 1 TO 12
   READ NISU(I)
NEXT I
FOR I = 1 TO 13
   READ M1, D1, M2, D2, D$(I)
   LET  N1(I) = NISU(M1) + D1
   LET  N2(I) = NISU(M2) + D2
NEXT I
LET  N = NISU(M) + D
LET  I = 0
DO
   LET  I = I + 1
LOOP UNTIL N1(I) <= N AND N2(I) >= N
PRINT M; "月"; D; "日は"; D$(I); "です"
DATA 0,31,59,90,120,151,181,212,242,273,304,334
DATA 1,1,1,19,山羊座
DATA 1,20,2,18,水瓶座
DATA 2,19,3,20,魚座
DATA 3,21,4,19,牡羊座
DATA 4,20,5,20,牡牛座
DATA 5,21,6,21,双子座
DATA 6,22,7,22,蟹座
DATA 7,23,8,22,獅子座
DATA 8,23,9,22,乙女座
DATA 9,23,10,23,天秤座
DATA 10,24,11,22,さそり座
DATA 11,23,12,21,射手座
DATA 12,22,12,31,山羊座
END
-----------------------------------------------------------
!'太陽質量
LET R=1.4959E+11 !'地球との平均距離
LET G=6.673848E-11 !'万有引力定数
LET T=365.24*24*60*60 !'秒
PRINT 4*PI^2*R^3/(G*T^2);"Kg"
LET K=3E-19 !'s2/m^3
PRINT 4*PI^2/(G*K);"Kg"
END
-----------------------------------------------------------
!'地球質量
LET G0=9.80665 !'重力加速度
LET R=6378137 !'地球の半径(m)
LET G=6.673848E-11 !'万有引力定数
PRINT G0*R^2/G;"Kg"
END
 

Re: ショートプログラム集

 投稿者:しばっち  投稿日:2013年 4月13日(土)22時17分43秒
  > No.3033[元記事へ]

!'天文単位
LET AU=149597870700 !'(m) 天文単位
LET D=86400 !'(日/秒)
LET K=0.01720209895 !'ガウス引力定数
LET MS=1.9884E30 !'太陽質量(Kg)
LET G=6.673848E-11 !'m^3/s^2/Kg 万有引力定数
LET A=((D/K)^2*G*MS)^(1/3)
PRINT INT(A);"m"
PRINT AU;"m"
END
-----------------------------------------------------------
!'半減期
INPUT  PROMPT "年数=":T
INPUT  PROMPT "半減期(年)=":TT
PRINT 100-.5^(T/TT)*100;"%  減少"
END
-----------------------------------------------------------
!'卵のゆで時間
INPUT  PROMPT "卵 短直径(mm)=":D !'D=50
INPUT  PROMPT "黄身の最終温度=":TY !'TY=73
INPUT  PROMPT "初期温度=":T0 !'T0=20
INPUT  PROMPT "お湯の温度=":TH !'TH=100
LET T=0.0015*D^2*LOG(2*(TH-T0)/(TH-TY))
PRINT "茹時間(分)=";INT(T);"分";INT((T-INT(T))*60);"秒"
END
-----------------------------------------------------------
!'速度合成
INPUT PROMPT  "(1)速度 時速(Km/h)=":V1
INPUT PROMPT  "(2)速度 時速(Km/h)=":V2
LET  V1=V1/3.6
LET  V2=V2/3.6
LET  C=299792458
IF V1>=C OR V2>=C THEN
   PRINT"光速を超えています"
   STOP
END IF
LET  A=(V1+V2)/(1+V1*V2/C/C)*3.6
LET  B=(V1-V2)/(1-V1*V2/C/C)*3.6
PRINT"速度の和 ";A;"(Km/h)"
PRINT"速度の差 ";B;"(Km/h)"
END
-----------------------------------------------------------
!'相性占い
OPTION CHARACTER KANJI
DIM WORD$(100)
DO
   LET  N=N+1
   READ WORD$(N)
LOOP UNTIL WORD$(N)="END"
INPUT  PROMPT "NAME1=": AA$ !'平仮名で入力
INPUT  PROMPT "NAME2=": BB$
FOR I = 1 TO LEN(AA$ & BB$)
   FOR A=1 TO N
      IF WORD$(A) = MID$(AA$ & BB$, I, 1) THEN EXIT FOR
   NEXT A
   LET  A = MOD(A,5)
   IF A = 0 THEN LET  A = 5
   LET  A$ = A$ & LTRIM$(STR$(A))
NEXT I
LET  C$ = A$
CALL DISPLAY(C$,0)
LET  C$ = ""
LET  D = 1
DO
   FOR I = 1 TO LEN(A$) - 1
      LET  A = VAL(MID$(A$, I, 1))
      LET  B = VAL(MID$(A$, I + 1, 1))
      LET  C = A + B
      IF C > 9 THEN LET  C = C - 10
      LET  C$ = C$ & LTRIM$(STR$(C))
   NEXT I
   CALL DISPLAY(C$,D)
   LET  D = D + 1
   IF C$ = "100" THEN
      PRINT "100 % ダヨーン"
      STOP
   END IF
   IF LEN(C$) = 2 THEN
      PRINT C$; "% デース"
      STOP
   END IF
   LET  A$ = C$
   LET  C$ = ""
LOOP
DATA あ,い,う,え,お,か,き,く,け,こ
DATA さ,し,す,せ,そ,た,ち,つ,て,と
DATA な,に,ぬ,ね,の,は,ひ,ふ,へ,ほ
DATA ま,み,む,め,も,や,"",ゆ,"",よ
DATA ら,り,る,れ,ろ,わ,"","","",を
DATA "","",っ,"",ん
DATA が,ぎ,ぐ,げ,ご,ざ,じ,ず,ぜ,ぞ
DATA だ,ぢ,づ,で,ど,ば,び,ぶ,べ,ぼ
DATA ぱ,ぴ,ぷ,ぺ,ぽ
DATA ぁ,ぃ,ぅ,ぇ,ぉ,ゃ,"",ゅ,"",ょ
DATA "END"
END

EXTERNAL  SUB DISPLAY(C$,D)
FOR I = 1 TO LEN(C$)
   LET  D$ = D$ & MID$(C$, I, 1) & " "
NEXT I
IF D <> 0 THEN LET  D$ = REPEAT$(" ",D) & D$ & REPEAT$(" ",D - 1)
PRINT D$
END SUB
-----------------------------------------------------------
!'脱出速度
LET G=6.673848E-11 !'万有引力定数
LET M=5.972E+24 !'地球質量(Kg)
LET R=6378137 !'地球半径(m)
LET RE=1.5E+11 !'公転半径(m)
LET Msun=1.9884E+30 !'太陽質量(Kg)
LET V1=SQR(G*M/R)
LET V2=SQR(2*G*M/R)
LET VS=SQR(2*G*Msun/RE)
LET VE=SQR(G*Msun/RE)
LET VEO=VS-VE
LET V3=SQR(2*G*M/R+VEO^2)
PRINT "第一脱出速度";V1;"m/s"
PRINT "第二脱出速度";V2;"m/s"
PRINT "第三脱出速度";V3;"m/s"
END
-----------------------------------------------------------
!'振り子周期
INPUT  PROMPT "長さ(m)=":L
LET G=9.80665 !'重力加速度
LET T=2*PI*SQR(L/G)
INPUT  PROMPT "角度=":THETA
LET THETA=THETA*PI/180
LET A=1
FOR N=0 TO 100
   IF N>0 THEN LET A=A*((2*N-1)/(2*N))^2*SIN(THETA/2)^2
   LET S=S+A
NEXT N
PRINT "周期(秒)=";T*S
!'LET M=1000 !'(g)
!'PRINT "位置エネルギー";M*G*L*(1-COS(THETA))
END
-----------------------------------------------------------
!'万有引力
LET G=6.673848E-11 !'万有引力定数
INPUT PROMPT  "あなたの体重を入れて下さい (Kg)": M1
INPUT PROMPT  "相手の体重を入れて下さい (Kg)": M2
INPUT PROMPT  "2人の間の距離を入れて下さい (m)": R
LET  F = G * ((M1 * M2) / (R * R))
PRINT "2人の間にはたらく引力は"; F; "N です"
END
-----------------------------------------------------------
!'等加速度運動
INPUT  PROMPT "初速度(Km/h)=":V0
LET V0=V0/3.6
INPUT  PROMPT "加速度(m/s^2)=":A
INPUT  PROMPT "時間(秒)=":T
LET V=V0+A*T
PRINT "速度(Km/h)=";V*3.6
LET X=V0*T+A*T^2/2
!'X=(V^2-V0^2)/(2*A)
!'G=9.80665
!'X=V0*COS(TH*PI/180)*V0*2*SIN(TH*PI/180)/G
PRINT"進んだ距離(m)";X

INPUT  PROMPT "進んだ距離(m)":X
INPUT  PROMPT "初速度(Km/h)=":V0
LET V0=V0/3.6
INPUT  PROMPT "加速度(m/s^2)=":A
!'A/2*T^2+V0*T-X=0
LET D=V0^2+4*A/2*X
IF D<0 THEN STOP
LET T=(-V0+SQR(D))/A
!'IF T<0 THEN LET T=(-V0-SQR(D))/A
PRINT T;"秒"
END
-----------------------------------------------------------
!'等級
INPUT  PROMPT "恒星の見かけの等級=":MM
INPUT  PROMPT "絶対等級=":M
LET R=10*10^(0.2*(MM-M))
LET RR=3.26*R
PRINT "距離";R;"パーセク"
PRINT RR;"光年" !'1パーセク=3.26光年
PRINT RR*299792.458*60*60*24*365;"Km"
!'M=MM+5-5*LOG(R)/LOG(10)
END
 

テキストアドベンチャー

 投稿者:しばっち  投稿日:2013年 4月13日(土)22時19分19秒
  !'選ばれし者
PRINT "  ***  STORY  ***"
PRINT
PRINT
FOR I = 1 TO 4
   READ A$
   FOR J = 1 TO LEN(A$)
      PRINT MID$(A$, J, 1);
      WAIT DELAY .4
   NEXT J
   PRINT
NEXT   I
WAIT DELAY 2
DATA "貴方はごく平凡な社会人。"
DATA "ある日、道を歩いて何気無く財布を拾ったことで、"
DATA "貴方はアドベンチャーの世界へ引き込まれてしまった。"
DATA "貴方は様々な試練に耐え、目的を果たすことができるか?"
1 PRINT "貴方は財布を拾った。"
  PRINT "届ける (1)  中を調べる (2) ";
  INPUT PROMPT  "": N
  IF N=1 THEN 11
  IF N=2 THEN 31
2 PRINT "「よし、一緒に行ってやるよ」と言ってくれた。"
  PRINT "一緒に行ってもらう (1)   やっぱり一人で行く (2) ";
  INPUT PROMPT  "": N
  IF N=1 THEN 60
  IF N=2 THEN 22
3 PRINT "岸に向かって君は泳いでいた。しかし、敵は先回りしていた。"
  PRINT "君にめがけて銃が火を吹いた。"
  PRINT " ***  GAME  OVER  ***"
  STOP
4 PRINT "相手の態度が変わった。「貴方こそ、私達が捜していた悪魔を封じ込める力を持つものです。"
  PRINT "お願いです。カギを握る「魔の家」へ行ってください」と頼まれた。"
  PRINT "「魔の家」にいく (1)  行かない (2) ";
  INPUT PROMPT  "": N
  IF N=1 THEN 51
  IF N=2 THEN 103
5 PRINT "2階は大広間になっていた。"
  PRINT "床を調べる (1)  壁を調べる (2)  家具を調べる (3) ";
  INPUT PROMPT  "": N
  IF N=1 THEN 84
  IF N=2 THEN 26
  IF N=3 THEN 99
6 PRINT "森の中に小屋を発見した。"
  PRINT "中にはいる (1)   無視する (2) ";
  INPUT PROMPT  "": N
  IF N=1 THEN 16
  IF N=2 THEN 96
7 PRINT "逃げようとしたが、壁の穴に吸い込まれてしまった。"
  PRINT "君はもう戻れない。"
  PRINT " ***  GAME  OVER  ***"
  STOP
8 PRINT "何とか捕まえることができた。これからどうする?"
  PRINT "人質にして交換を要求する (1)  服を取り替えて相手に近づく (2) ";
  INPUT PROMPT  "": N
  IF N=1 THEN 65
  IF N=2 THEN 53
9 PRINT "君はついに悪魔の壷のある部屋に着いた。どこを調べますか?"
  PRINT "壁を調べる (1)   祭壇を調べる (2)   天井を調べる (3) ";
  INPUT PROMPT  "": N
  IF N=1 THEN 20
  IF N=2 THEN 59
  IF N=3 THEN 54
10 PRINT "入口が自動的に締まり、君は永遠に閉じ込められた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
11 PRINT "君は何の冒険にも会わず、ごく日常的な生活を送った。"
   PRINT " ***  GAME  OVER  ***"
   STOP
12 PRINT "突然、男にピストルを突きつけられた。「一緒にきてもらうぞ!」"
   PRINT "一緒に行く (1)   逃げる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 32
   IF N=2 THEN 55
13 PRINT "何とか無事に戻れたが結局、謎は何も解けないままだった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
14 PRINT "中に入ると、まず2階への階段が目に付いた。"
   PRINT "1階を調べる (1)  2階へ上がる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 81
   IF N=2 THEN 62
15 PRINT "カギを穴にいれた途端、君の身体にショックが走った。高圧電流が襲ったのだ!!"
   PRINT " ***  GAME  OVER  ***"
   STOP
16 PRINT "中には人がいた。「私も壷を捜している。森の中の洞窟にあるのは分かっているが、"
   PRINT "私では行けない。お前が代わりに行ってくれないか?」と言われた。"
   PRINT "言葉を信じて行く (1)  信じないで別の道を行く (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 75
   IF N=2 THEN 96
17 PRINT "獣が群れを成している。幸い君は小屋で武器を手にいれているが・・・"
   PRINT "戦う (1)  回り道をする (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 58
   IF N=2 THEN 48
18 PRINT "地下の迷路に迷い込んだ。2度と出られなかった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
19 PRINT "「嘘をつくな!  ボスはここにはいない。お前はニセ者だ!」"
   PRINT "そう言ったと同時に男の剣は君を貫いていた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
20 PRINT "壁に書かれている絵の一部が崩れている。どうやらここに秘密がありそうだ!"
   PRINT "叩いてみる (1)   押してみる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 10
   IF N=2 THEN 39
21 PRINT "調べてみると、どうやら古代の文字で書かれているようだ。資料が必要だ。"
   PRINT "図書館にいく (1)   専門家を尋ねる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 50
   IF N=2 THEN 73
22 PRINT "指定の場所にいった君はそこで待っていた男に封筒を渡した。"
   PRINT "「ご苦労様、メシでもおごろうか?」男は誘ってくれたが・・・"
   PRINT "一緒に行く (1)   断る (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 88
   IF N=2 THEN 12
23 PRINT "帰り道、君は何者かに付けられているのに気が付かなかった。"
   PRINT "暗い道に入ったとき、君の運命は終わった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
24 PRINT "葵はこの中には紙が入っていた。見たこともない字だが、君には読めた。"
   PRINT "そこには「この文字が読めるものは悪魔を封ずる力のある選ばれし者なり」"
   PRINT "と書かれていた"
   PRINT "誘拐した相手にこのことを言う (1)   黙っている (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 4
   IF N=2 THEN 71
25 PRINT "廊下を進むと、左右に部屋があり、前には2階へいく階段がある。"
   PRINT "部屋を調べる (1)  2階へいく (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 68
   IF N=2 THEN 62
26 PRINT "壁の一部が崩れ、君はまっ逆さまに下へ落ちていった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
27 PRINT "銀の壷に手にいれると突然痛みが走った。慌てて手を見ると毒虫が噛みついていた。"
   PRINT "君は後一歩のところで目的を達成できなかった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
28 PRINT "相手がだまされているうちに、捕らえられていた男を助け出した。"
   PRINT "一緒に行動する (1)   別行動をとる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 49
   IF N=2 THEN 9
29 PRINT "敵は強かった。君は歯が立たなかった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
30 PRINT "逃げる途中、道が二つに分かれていた。"
   PRINT "右へいく (1)  左へいく (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN  9
   IF N=2 THEN 72
31 PRINT "中には名刺と封筒が入っていた。"
   PRINT "名刺のところに電話する (1)   面倒だから捨てる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 64
   IF N=2 THEN 11
32 PRINT "君は車に乗せられた。どこを走っているのか分からない。"
   PRINT "やがて車は止まった。ふと見ると男は油断しているようだ。"
   PRINT "すきを見て逃げる (1)  そのまま乗る (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 55
   IF N=2 THEN 40
33 PRINT "君は島に出かけて行った。ところが、島に着くと怪しい男たちが、"
   PRINT "先に上陸していた。隠れようとしたが見つかってしまった。"
   PRINT "わざと捕まる (1)  逃げる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 94
   IF N=2 THEN 78
34 PRINT "「どうしてあそこで溺れていたのかね?」助けてもらった船の船長に尋ねられた。"
   PRINT "今までのことを話す (1)   嘘をいう (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 56
   IF N=2 THEN 13
35 PRINT "階段が崩れ落ち、君は下敷きになった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
36 PRINT "「あいつ逃げる気だな」見張りの男が君を撃った。"
   PRINT " ***  GAME  OVER  ***"
   STOP
37 PRINT "壁の一部が開いて、別の通路を見つけた。その通路を進んでいくと、"
   PRINT "一人の男を二人の番人が縛りあげているのが見えた。"
   PRINT "出ていって救うために戦う (1)  様子を見る (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 29
   IF N=2 THEN 69
38 PRINT "突然、頭上から獣が襲ってきた。君は逃げられない。"
   PRINT " ***  GAME  OVER  ***"
   STOP
39 PRINT "壁が開き、中から二つの壷が出てきた。"
   PRINT "金の壷を調べる (1)  銀の壷を調べる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 105
   IF N=2 THEN 27
40 PRINT "車が止まった。降りるとそこは港で船があった。それに乗せられそうである。"
   PRINT "おとなしく乗る (1)   海に飛び込んで逃げる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 80
   IF N=2 THEN 87
41 PRINT "箱を開けると中から毒ガスが出てきた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
42 PRINT "浜を歩いていると、何か光るものを見つけた。"
   PRINT "掘って調べる (1)  無視する (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 57
   IF N=2 THEN 101
43 PRINT "隠れようとしたとき、音を立ててしまった。"
   PRINT "何者だ!」君は見つかってしまった。"
   PRINT "逃げる (1)   わざと捕まる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 30
   IF N=2 THEN 83
44 PRINT "壁から槍が飛び出し、君は刺された。"
   PRINT " ***  GAME  OVER  ***"
   STOP
45 PRINT "誰に相談する?"
   PRINT "喧嘩に強いA (1)  推理マニアのB (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 2
   IF N=2 THEN 79
46 PRINT "なかには特に怪しいものはない。ふと見ると机上に二つの箱がある。"
   PRINT "赤い箱を開ける (1)   青い箱を開ける (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 61
   IF N=2 THEN 74
47 PRINT "下への階段は行き止まりだ。戻ろうとすると突然入口が締まり、閉じ込められた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
48 PRINT "君は洞窟の前にたどり着いた。中に入ると何か聞こえる。どうやら壁の中から聞こえてくる。"
   PRINT "壁を調べる (1)   そのまま進む (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 37
   IF N=2 THEN 18
49 PRINT "一緒に行動しているうちに行き止まりにきた。引き返そうとすると男は突然刀で君を刺した。"
   PRINT "「悪く思うな。私が最後の番人だ!」"
   PRINT " ***  GAME  OVER  ***"
   STOP
50 PRINT "図書館で調べていると、一人の女性が覗き込んできて、こう言った。"
   PRINT "「この文字は私の父が研究している文字です。来て戴けると分かります」"
   PRINT "一緒にいく (1)   一人でやるからと断る (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 85
   IF N=2 THEN 23
 

Re: テキストアドベンチャー

 投稿者:しばっち  投稿日:2013年 4月13日(土)22時20分2秒
  > No.3035[元記事へ]

続き

51 PRINT "「魔の家」に着いたが、どこから入る?"
   PRINT "正面から (1)   裏口から (2)   秘密の入口を捜す (3) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 14
   IF N=2 THEN 92
   IF N=3 THEN 102
52 PRINT "壁を動かそうとすると、どこからか槍が飛んできた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
53 PRINT "近づくことには成功したが、もう一人がどうも邪魔だ。"
   PRINT "嘘を行って追い払いたいが何と言う?"
   PRINT "怪しい奴がいるようだ (1)   ボスが呼んでいる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 28
   IF N=2 THEN 19
54 PRINT "調べようとして台の上に乗ったが、その台が崩れ頭を強く打った。"
   PRINT " ***  GAME  OVER  ***"
   STOP
55 PRINT "「逃げられるとでも思ってるのか!」男の銃が火を吹いた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
56 PRINT "船長は急に顔を曇らせた。「残念だが君を帰すわけには行かない。我々と一緒に来てもらいたい」"
   PRINT "と言われた。"
   PRINT "断る (1)   行く (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 70
   IF N=2 THEN 94
57 PRINT "掘ってみると瓶が出てきた。中には地図が入っていた。"
   PRINT "地図通り行く (1)   無視する (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN  75
   IF N=2 THEN 101
58 PRINT "君は勇敢に戦ったが、あまりにも獣は強すぎた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
59 PRINT "祭壇を調べると、二枚の紙にそれぞれちがうメッセージが書いてあった。どちらを信じる?"
   PRINT "赤い龍の絵を押せ (1)  青い龍の絵を押せ (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 39
   IF N=2 THEN 44
60 PRINT "二人で待ち合わせのところに行ったが誰もいない。と、遠くから音がした課と思うと、"
   PRINT "君の頭に激しい痛みが走った。隣のビルの屋上でライフルを構えた男がこうつぶやいた。"
   PRINT "「悪く思うな、深入りされては困るのでな」と。"
   PRINT " ***  GAME  OVER  ***"
   STOP
61 PRINT "箱の中には地図がある。この地図にある島が全ての秘密を解くカギだ。"
   PRINT "島に行く (1)  行かない (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 33
   IF N=2 THEN 86
62 PRINT "2階に行く階段の手すりに何かスイッチのようなものがあった。"
   PRINT "スイッチを入れる (1)  触らない (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 35
   IF N=2 THEN 5
63 PRINT "川を下っていくと急に身動きができなくなった。そこは底無し沼だった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
64 PRINT "「拾ってくれて有難うございます。すぐに封筒をもってきて下さい。"
   PRINT "但し一人で」と言われた。"
   PRINT "一人で出かける (1)   友人に相談する (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 22
   IF N=2 THEN 45
65 PRINT "「仲間は預かった。人質の交換をしろ!」君は要求した。"
   PRINT "しかし、相手は要求に応じず、君を攻撃してきた。勝ち目はない。"
   PRINT " ***  GAME  OVER  ***"
   STOP
66 PRINT "どうやら敵は諦めたようだ。しかし、漂っていると別の船が近づいてきた。"
   PRINT "乗せてもらう (1)  やり過ごす (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 34
   IF N=2 THEN 98
67 PRINT "壁の一部が開いた。そこには穴があり、その穴から声がする。"
   PRINT "「この穴は悪魔の壷のある場所へ通じる穴だ。さあ、とびこめ!」"
   PRINT "飛び込む (1)   入らない (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 48
   IF N=2 THEN 7
68 PRINT "部屋を調べていると、突然天井が落ちてきて、下敷きになった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
69 PRINT "一人の番人がこちらへ向かってきた。"
   PRINT "やり過ごす (1)  捕まえる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 43
   IF N=2 THEN 8
70 PRINT "「そうか、では死んでもらう」船長の目が冷たく光った。"
   PRINT " ***  GAME  OVER  ***"
   STOP
71 PRINT "どっちへ行くか?"
   PRINT "上流のほう (1)  下流のほう (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 48
   IF N=2 THEN 63
72 PRINT "逃げ回っているうちに元の場所へ戻ってしまった。君は番人に捕まった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
73 PRINT "二人の専門家のうちどちらを尋ねますか?"
   PRINT "A博士 (1)  B教授 (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 85
   IF N=2 THEN 91
74 PRINT "箱を開けると突然爆発し、君は吹き飛ばされた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
75 PRINT "道を進んでいくと別れ道があった。"
   PRINT "右にいく (1)   左にいく (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 89
   IF N=2 THEN 97
76 PRINT "川を渡っていると突然痛みを感じた。この辺には人喰魚がいたのだ!"
   PRINT " ***  GAME  OVER  ***"
   STOP
77 PRINT "君はそのまま見知らぬところにつれて行かれた。2度と帰れなかった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
78 PRINT "「逃げるぞ、撃て!」男たちの声とともに銃声が聞こえ、君の頭部は打ち抜かれた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
79 PRINT "一緒に封筒を調べることにした。中から暗号文と住所を書いた紙が出てきた。"
   PRINT "暗号を解く (1)  住所を尋ねる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 21
   IF N=2 THEN 82
80 PRINT "君は船底に押し込められた。ふと見ると、2つの箱が目に入った。"
   PRINT "赤い箱を開ける (1)   青い箱を開ける (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 41
   IF N=2 THEN 24
81 PRINT "調べているうちに突然底が抜けた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
82 PRINT "住所の家は空き家だった。"
   PRINT "帰る (1)  中に入る (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 23
   IF N=2 THEN 46
83 PRINT "すきを見て逃げようとわざと捕まったのが甘かった。"
   PRINT "「御前は悪魔のいけにえとなるのだ!」それが君の聞いた最後の言葉だった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
84 PRINT "床の一部が開き、2つのボタンを見つけた。"
   PRINT "Aボタンを押す (1)   Bボタンを押す (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 67
   IF N=2 THEN 93
85 PRINT "博士はその文を読んでくれた。「悪魔が甦ろうとしている。選ばれし者よ、すぐに「魔の家」に行け」"
   PRINT "と書かれていて、「魔の家」までの道順が書かれていた。"
   PRINT "魔の家に行く (1)   行かない (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 51
   IF N=2 THEN 95
86 PRINT "何事もなく数日が過ぎ、忘れ去られようとしていたとき、君は突然暴漢に襲われた。"
   PRINT "君はそれが何者なのか、目的は何だったのか分からなかった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
87 PRINT "「逃がすな、追え!」相手も泳いで追ってきた。どちらへ逃げる?"
   PRINT "岸のほう (1)  沖のほう (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 3
   IF N=2 THEN 66
88 PRINT "食事をおごってもらって帰る途中、突然気分が悪くなった。"
   PRINT "後をつけてきた男がつぶやいた「悪く思うな、これも掟なのだから・・・」"
   PRINT " ***  GAME  OVER  ***"
   STOP
89 PRINT "川にたどり着いた。"
   PRINT "川を泳いで渡る (1)   川に沿って歩く (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 76
   IF N=2 THEN 71
90 PRINT "棚の中に二つのカギ穴を見つけた。"
   PRINT "Aのカギ穴にカギを入れる (1)   Bのカギ穴にカギを入れる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 93
   IF N=2 THEN 67
91 PRINT "B教授はニセ者だった。発見したものは全て盗まれ、これ以上は何もできなかった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
92 PRINT "裏口から入るとすぐに左右に別れる廊下があった。"
   PRINT "右へいく (1)    左へいく (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 81
   IF N=2 THEN 25
93 PRINT "それは時限装置のスイッチだった。君は爆弾で吹き飛ばされた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
94 PRINT "君は島に連れて行かれた。「我々はこの島で悪魔の壷を捜し、復活させねばならない。お前も捜せ!」"
   PRINT "と言われた。どうやら反抗できそうにない。"
   PRINT "海岸を捜す (1)   森を捜す (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 104
   IF N=2 THEN 6
95 PRINT "「そうか、しかし気の毒だが今までの記憶は消させてもらう」"
   PRINT "博士によって君は記憶を消された。"
   PRINT " ***  GAME  OVER  ***"
   STOP
96 PRINT "君は森で迷子になり、2度と出られなかった。"
   PRINT " ***  GAME  OVER  ***"
   STOP
97 PRINT "そのまま進んでいくと、何か物音が聞こえてきた。"
   PRINT "そのまま行く (1)   調べる (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 38
   IF N=2 THEN 17
98 PRINT "その後、船は来ず、君の体力は尽きた。"
   PRINT " ***  GAME  OVER  ***"
   STOP
99 PRINT "タンスの中からカギを見つけた。"
   PRINT "金庫があるので開けてみる (1)   他のカギ穴を捜す (2) ";
   INPUT PROMPT  "": N
   IF N=1 THEN 15
   IF N=2 THEN 90
100 PRINT "開けると階段になっていて、上か下かに行けるようだ。"
    PRINT "2階へいく (1)   地下へいく (2) ";
    INPUT PROMPT  "": N
    IF N=1 THEN 62
    IF N=2 THEN 47
101 PRINT "その後、君は何の手がかりも見つけられず、そのまま島にいることになった。"
    PRINT " ***  GAME  OVER  ***"
    STOP
102 PRINT "動きそうな壁が2ヵ所見つかった。"
    PRINT "Aの壁を動かす (1)  Bの壁を動かす (2) ";
    INPUT PROMPT  "": N
    IF N=1 THEN 100
    IF N=2 THEN 52
103 PRINT "「あなたは知り過ぎました。残念ですが死んでもらいます」。"
    PRINT " ***  GAME  OVER  ***"
    STOP
104 PRINT "海岸を歩いていると、向こうから船がくるのが見えた。"
    PRINT "助けを呼ぶ (1)   無視する (2) ";
    INPUT PROMPT  "": N
    IF N=1 THEN 36
    IF N=2 THEN 42
105 PRINT "金の壷を開けると中からカードが出てきた。これこそが悪魔を封じ込めるカードなのだ。"
    PRINT "そして、このカードを破れる者は、「選ばれし者」なのだ。君は見事世界を救った。"
    PRINT " ***  THE  END  ***"
END
 

不定方程式の整数解

 投稿者:山中和義  投稿日:2013年 5月 1日(水)11時12分45秒
  高校数学では、「数と式」で式の展開、因数分解を学ぶ。
そこに出てくる等式を使って、不定方程式の整数解を求めてみる。


問題 ピタゴラス数、円周上の格子点
x^2+y^2=z^2の整数解を求めよ。
(考察)
(a±b)^2=(a干b)^2±4abを考える。
a=m^2、b=n^2とすると、(m^2±n^2)^2=(m^2干n^2)^2±(2mn)^2
(終り)


問題
x^2+2y^2=z^2の整数解を求めよ。
(考察)
(a±b)^2=(a干b)^2±4abを考える。
a=m^2、b=2n^2とすると、(m^2±2n^2)^2=(m^2干2n^2)^2±2(2mn)^2
(終り)

100 !x^2+2y^2=z^2
110 FOR m=-10 TO 10
120    FOR n=-10 TO 10
130       LET z=m^2+2*n^2
140       LET x=m^2-2*n^2
150       LET y=2*m*n
160       IF x^2+2*y^2=z^2 THEN PRINT m;n; x;y;z
170    NEXT n
180 NEXT m
190 END


問題
x^2±y^2=±z^3の整数解を求めよ。
・x^2+y^2=z^3の整数解を求めよ。
・x^2+y^3=z^2の整数解を求めよ。
(考察)
(a±b)^3=a^2(a±3b)±b^2(b±3a)を考える。
 a±3b=4m^2 ← 式1
 ±3a+b=4n^2 ← 式2
とすると、
式1±式2より、a±b=m^2±n^2
3*式1±式2より、b=(3m^2干n^2)/2
式1±3*式2より、a=(m^2干3n^2)/2
よって、(m^2±n^2)^3={(m^2干3n^2)*m}^2±{(3m^2干n^2)*n}^2
(終り)

100 !x^2+y^2=z^3
110 FOR m=-10 TO 10
120    FOR n=-10 TO 10
130       LET z=m^2+n^2
140       LET x=(m^2-3*n^2)*m
150       LET y=(3*m^2-n^2)*n
160       IF x^2+y^2=z^3 THEN PRINT m;n; x;y;z
170    NEXT n
180 NEXT m
190 END


100 !x^2+y^3=z^2
110 FOR m=-10 TO 10
120    FOR n=-10 TO 10
130       LET y=m^2-n^2
140       LET z=(m^2+3*n^2)*m
150       LET x=(3*m^2+n^2)*n
160       IF x^2+y^3=z^2 THEN PRINT m;n; x;y;z
170    NEXT n
180 NEXT m
190 END



次の等式も使い勝手が良い。

x^3+y^3+z^3-3xyz
=(x+y+z)(x^2+y^2+z^2-xy-yz-zx)
=(x+y+z){(x+y+z)^2-3(xy+yz+zx)}
=(1/2)(x+y+z){(x-y)^2+(y-z)^2+(z-x)^2}
=(x+y+z)(x+ωy+ω^2z)(x+ω^2y+ωz) ただし、ω=(-1+(√3)i)/2 ※1の虚数立方根

例
 問題
 (a-b)^3+(b-c)^3+(c-a)^3を因数分解せよ。

 問題 相加・相乗平均の関係
 a,b,cを任意の正数とするとき、(a+b+c)/3≧(abc)^(1/3)を示せ。

 問題
 3次方程式x^3+3px+q=0の解を求めよ。 →カルダノの公式、フォンタナ(タルタリア)の公式

など

 

Re: 不定方程式の整数解

 投稿者:山中和義  投稿日:2013年 5月 4日(土)20時13分49秒
  > No.3037[元記事へ]

問題
(x+y-1)(y+z-1)(z+x-1)=6xyz、1<x<y<z
を満たす自然数の組をすべて答えよ。


答え
f(x,y,z)=(x+y-1)(y+z-1)(z+x-1)-6xyz とおく。
zで偏微分すると、
fz(x,y,z)
=(x+y-1){(y+z-1)+(z+x-1)}-6xy
={x+(y-1)}{y+(z-1)+(z-1)+x}-6xy
≧2x(3y+x)-6xy=2x^2>0
よって、fはzに関して狭義単調増加となる。
f(x,y,y+1)≦f(x,y,z)<f(x,y,z+1) ← 式1

g(x,y)=f(x,y,y+1)とおくと、g(x,y)=2y^3-2(x+1)y^2+2x(x-4)y
yで偏微分すると、gy(x,y)=6y^2-4(x+1)y+2x(x-4)
さらにyで偏微分すると、gyy(x,y)=12y-4(x+1)>0
よって、gy(x,y)は、yに関して単調増加となる。
gy(x,x+1)=4x^2-4x+2=2x^2+2(x-1)^2>0 したがって、gy(x,x+1)>0
よって、g(x,y)=f(x,y,y+1)は、yに関して狭義単調増加となる。
f(x,x+1,x+2)≦f(x,y,y+1)<f(x,y+1,y+2) ← 式2

式1と式2より、f(x,x+1,x+2)≦f(x,y,z)
よって、f(x,y,z)=0とすると、f(x,x+1,x+2)≦0でなければならない。
これより、f(x,x+1,x+2)=2x(x+1)(x-4)なので x=2,3,4でなければならない。

x=2,3,4について、f(x,y,z)≧0になるまでy,zを昇順に調べる。


LET x=2
DO
   LET y=x+1
   DO
      LET z=y+1
      DO
         LET f=(x+y-1)*(y+z-1)*(z+x-1)-6*x*y*z
         PRINT x;y;z; f
         IF f>=0 THEN EXIT DO !f(x,y,z)≧0になるまで
         LET z=z+1 !昇順に調べる
      LOOP
      PRINT
      IF z=y+1 THEN EXIT DO !f(x,y,y+1)>0なら可能性がない
      LET y=y+1
   LOOP
   IF y=x+1 THEN EXIT DO !f(x,x+1,x+2)>0なら可能性がない
   LET x=x+1
LOOP

END



答え
相加・相乗平均の関係より、
 x+(y-1)≧2√{x(y-1)}
 y+(z-1)≧2√{y(z-1)}
 (z-1)+x≧2√{(z-1)x}
辺々掛け合わせて、
 (x+y-1)(y+z-1)(z+x-1)≧8x(z-1)√{(y-1)y}
∴6xyz≧8x(z-1)√{(y-1)y}
両辺を8xyz(≠0)で割って、
 3/4≧(1-1/z)√(1-1/y)
両辺を2乗して、
 9/16≧(1-1/z)^2(1-1/y)
∴9/16≧(1-1/z)^2(1-1/y)>(1-1/y)^2(1-1/y)=(1-1/y)^3
∴9/16>(1-1/y)^3
∴(9/16)^(1/3)>1-1/y
∴1-(9/16)^(1/3)<1/y
∴y<1/{1-(9/16)^(1/3)}=5.730… <6
よって、(x,y)の組は、(2,3)、(2,4)、(2,5)、(3,4)、(3,5)、(4,5)のみである。

また、zの上限は、
1<x<y<zより、
1+y-1<x+y-1 ∴y<x+y-1
1+z-1<y+z-1 ∴z<y+z-1
これより、
yz(z+x-1)<(x+y-1)(y+z-1)(z+x-1)=6xyz ∴(z+x-1)<6x ∴z<5x+1
よって、1<x<y<z≦5x


FOR x=2 TO 4
   FOR y=x+1 TO 5
      FOR z=y+1 TO 5*x
         IF (x+y-1)*(y+z-1)*(z+x-1)=6*x*y*z THEN PRINT x;y;z
      NEXT z
   NEXT y
NEXT x

END


!後半の「また、zの上限は、… 」の部分を、
! x=X,y=Yを代入すると、zの2次式なので、解の公式からzを求める。
!とする。
!(X+Y-1)(Y+z-1)(z+X-1)-6XYz=0 ∴(X+Y-1)z^2+{(X+Y-1)(X+Y-2)-6XY}z+(X+Y-1)(X-1)(Y-1)}=0


FOR x=2 TO 4
   FOR y=x+1 TO 5
      LET A=x+y-1 !2次方程式 Az^2+Bz+C=0
      LET B=(x+y-1)*(x+y-2)-6*x*y
      LET C=(x+y-1)*(x-1)*(y-1)
      LET D=B^2-4*A*C !判別式
      IF D>=0 THEN
         LET z=(-B+SQR(D))/(2*A)
         IF z>y AND z=INT(z) THEN PRINT x;y;z
         LET z=(-B-SQR(D))/(2*A)
         IF z>y AND z=INT(z) THEN PRINT x;y;z
      END IF
   NEXT y
NEXT x

END



答え グラフによる
f(x,y,z)=(x+y-1)(y+z-1)(z+x-1)-6xyzのz=Zでの断面(等高線)のグラフを描く。
1<x<y<zなので、第1象限の格子点に着目する。

参考サイト
Full BASICと十進BASICの Q&A
 関数のグラフ・曲線を描くプログラム
  基本サンプル
   関数のグラフ・曲線を描くプログラム http://hp.vector.co.jp/authors/VA008683/F_GRAPH.htm


DEF f(x,y)=(x+y-1)*(y+ZZ-1)*(ZZ+x-1)-6*x*y*ZZ

LET left=-1 !表示範囲
LET right=8
LET bottom=-1
LET top=8
SET WINDOW left,right,bottom,top
DRAW grid
SET POINT STYLE 1

FOR ZZ=4 TO 10 !z=Zとする
   SET POINT COLOR ZZ-3

   FOR y=bottom TO top STEP (top-bottom)/2000 !y方向への走査
      LET x=left
      LET z0=f(x,y)
      FOR x=left TO right STEP (right-left)/2000 !x方向への走査
         LET z=f(x,y)
         IF z0*z<0 THEN  PLOT POINTS: x,y
         LET z0=z
      NEXT x
   NEXT y

NEXT ZZ

END


 

2変数関数のニュートン法

 投稿者:島村1243  投稿日:2013年 5月 5日(日)10時22分21秒
  後記のプログラムは、x,y,z 3次元空間中に点電荷と接地球導体が有る場合のz=0平面上の等電位曲線を描くもので、以前、この掲示板を通じて山中さんにご教示頂いたニュートン法のコードを使用しており正しく動作します。
しかしコードの一部が理解出来ず、お教え頂ければ有り難いです。

このプログラム中の「SUB newton(fc,x,y, fx,fy,grad2) !ニュートン法」に記述されている
      LET t=(fc-ff)/grad2
      LET x=x+t*fx
      LET y=y+t*fy
のgrad2は、ヤコビ行列の逆行列作成で生じる行列式と推測されます。
電位ff=f(x,y)は2変数関数なので、ニュートン法でヤコビ行列を作成する為には、x,yに関するもう1個別の関数g(x,y)=kが必要と思うのですが、その関数はどのように考えればよいのでしょうか?

!**************************************************************
! 1個の点電荷と接地導体球が存在する電場の等電位曲線作図プログラム
!        <山中和義氏作の描画手法を利用>
!**************************************************************
!----描画座標・条件設定
LET Xa=-10
LET Xb=-Xa+4
LET Ya=Xa-2
LET Yb=-Ya+2
SET WINDOW Xa,Xb,Ya,Yb !描画範囲
DRAW grid
LET cEps=1E-3 !誤差精度設定

!----電荷位置設定と描画
LET r=1 !導体球の半径
LET a1=4 !点電荷のx座標
LET a2=r^2/a1 !影像電荷のx座標
LET q1=1 !点電荷の大きさ
LET q2=-r/a1*q1 !影像電荷の大きさ
DEF f(x,y)=q1/SQR((x-a1)^2+y^2)+q2/SQR((x-a2)^2+y^2) !合成電位関数
SET AREA COLOR "red" !点電荷の位置に赤丸印を表示
DRAW disk WITH SCALE(0.1)*SHIFT(a1,0)
SET AREA COLOR "green" !接地導体球の位置に緑丸印を表示
DRAW disk WITH SCALE(r)*SHIFT(0,0)

!---等電位分布作図(関数f(x,y)の等高線)-----
SET LINE COLOR "red"
LET h=0.001 !増分(偏微分係数)
LET d=0.015 !増分
FOR fc=0 TO 0.5 STEP d !等高線の関数値
   CALL contour(fc,1,1,d)
NEXT fc
FOR fc=0 TO 0.06 STEP d !※左端
   CALL contour(fc,-10,1,d)
NEXT fc

!--以下はSUB_routine------
SUB newton(fc,x,y, fx,fy,grad2) !ニュートン法
   DO
      LET ff=f(x,y) !∇f
      LET fx=(f(x+h,y)-ff)/h
      LET fy=(f(x,y+h)-ff)/h
      LET grad2=fx*fx+fy*fy

      IF grad2<1e-10 THEN
         LET x=1e30
         EXIT SUB
      END IF

      LET t=(fc-ff)/grad2
      LET x=x+t*fx
      LET y=y+t*fy
   LOOP WHILE t*t*grad2>cEps*cEps
END SUB

SUB contour(fc,x,y,d) !等高線を描く
   LET i=0
   DO
      CALL newton(fc,x,y, fx,fy,grad2)
      IF ABS(x)+ABS(y)>1e10 THEN EXIT SUB
      IF i=0 THEN
         PLOT LINES: x,y; !始点
         LET x0=x
         LET y0=y
      ELSE
         PLOT LINES: x,y; !折れ線でつなげる
      END IF
      IF i>2 AND (x-x0)^2+(y-y0)^2<d*d THEN EXIT DO !始点近傍なら、終了

      LET t=d/SQR(grad2)
      LET x=x+fy*t
      LET y=y-fx*t

      LET i=i+1
   LOOP
   PLOT LINES: x0,y0 !閉じる
END SUB
END
 

Re: 2変数関数のニュートン法

 投稿者:山中和義  投稿日:2013年 5月 6日(月)11時06分48秒
  > No.3039[元記事へ]

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

> このプログラム中の「SUB newton(fc,x,y, fx,fy,grad2) !ニュートン法」に記述されている
>       LET t=(fc-ff)/grad2
>       LET x=x+t*fx
>       LET y=y+t*fy
> のgrad2は、ヤコビ行列の逆行列作成で生じる行列式と推測されます。

出典は、
 『C言語による最新アルゴリズム事典』 contour.c
です。
最近は、Java版などもあります。
この本を持っていないので、はっきりとは言えませんが、記述はあると思います。
ソースは、http://oku.edu.mie-u.ac.jp/~okumura/algo/ で入手できます。

さて、質問箇所ですが、
勾配(∇f、grad f)が0になるを見つけています。
繰り返し見つけることを、ニュートン法と言っているようです。(予想)
うまく説明できません。ブラックボックスになっています。(泣)
 

Re: 2変数関数のニュートン法

 投稿者:島村1243  投稿日:2013年 5月 6日(月)18時06分29秒
  > No.3040[元記事へ]

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

> 出典は、
>  『C言語による最新アルゴリズム事典』 contour.c
> です。

山中さん、ご回答有難うございます。
お示し頂いたサイトからファイルをダウンロードし、「contour.c」を見て、十進BASICのコードと同じ内容であることを確認しました。が、grad2の根拠は示されておりませんでした。

そこで、ヤコビ行列の考え方を捨て次の様に再考してみました。

初期座標位置(x0,y0)は「φ(x0,y0)≒fc 」であり、(完璧に)φ(x,y)=fc を満たす座標位置を(x,y)とは異なっていると仮定します。等電位曲線を正確に描くためには正確な位置(x,y)が必要なので、それを求める為、(x0,y0)の補正微分量を⊿x、⊿yとすると
  x=x0+⊿x
  y=y0+⊿y

このときφ(x,y)を1次近似のテーラー展開で表すと
  φ(x,y)=φ(x0,y0)+fx*⊿x+fy*⊿y=fc  (1)
      ただし、fx=δφ(x0,y0)/δx、fy=δφ(x0,y0)/δy

式(1)から
  fx*⊿x+fy*⊿y=fc-φ(x0,y0)  (2)

これに位置(x,y)における電気力線の微分方程式
  dx/fx=dy/fy

を、強引に位置(x0,y0)における電気力線の方程式
  ⊿x/fx=⊿y/fy    (3)

と近似し、式(2)と連立させると
  ⊿x=(fc-φ(x0,y0))*fx/(fx^2+fy^2)
         =(fc-φ(x0,y0))*fx/grad2

となり、grad2が現れましたので、この考え方が「 SUB newton() 」に出ているgrad2の根拠ではないかと推測しました。
 

原始反復法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時27分44秒
  !' 原始反復法
PUBLIC NUMERIC T
INPUT  PROMPT "X=":T
LET  EPS=1E-8
LET  X=T
LET  H=1
DO
   LET  H=H/2
LOOP UNTIL ABS(H*F(X))<3
DO
   LET  X=X-H*F(X)
   PRINT X
LOOP UNTIL ABS(F(X))<EPS
PRINT X;X*X
END

EXTERNAL  FUNCTION F(X)
LET  F=X*X-T
END FUNCTION
 

逐次代入法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時28分17秒
  !' 逐次代入法
!'(X+1)^2=T
!'X^2+2*X=T-1
!'X*(X+2)=T-1
!'X=(T-1)/(X+2)
PUBLIC NUMERIC T,N
INPUT  PROMPT "n乗根=":N
INPUT PROMPT  "X=": T
LET EPS=1E-8
LET  XX = T
DO
   LET  X=XX
   LET  XX = F(X)
   PRINT XX + 1
LOOP UNTIL ABS(X-XX)<EPS
PRINT XX + 1;(XX+1)^N
END

EXTERNAL  FUNCTION F(X)
!'LET F=(T-1)/(X+2)
!'LET F=(T-1)/(X^2+3*X+3)
!'LET F=(T-1)/(X^3+4*X^2+6*X+4)
!'LET F=(T-1)/(X^4+5*X^3+10*X^2+10*X+5)
!'LET F=(T-1)/(((X+1)^N)/X-1/X)
FOR I=0 TO N-1
   LET S=S*X+COMB(N,I)
NEXT I
LET F=(T-1)/S
END FUNCTION
 

相加平均代入法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時28分48秒
  !' 相加平均代入法
PUBLIC NUMERIC T,N
LET N=2
INPUT PROMPT  "X=": T
LET EPS=1E-8
LET  X = T
DO WHILE ABS(F(X) - X) > EPS
   LET  X = (F(X) + X) / 2
   PRINT X
LOOP
PRINT X;X^N
END

EXTERNAL  FUNCTION F(X)
LET F=T/X^(N-1)
END FUNCTION
 

10分法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時29分19秒
  !' 10分法
PUBLIC NUMERIC T,N
INPUT PROMPT  "n乗根 =": N
INPUT PROMPT  "X=": T
FOR KETA = 4 TO -15 STEP -1
   LET  A = 10 ^ KETA
   FOR I = 1 TO 10
      IF F(X + A * I) > 0 THEN
         LET  X = X + A * (I - 1)
         EXIT FOR
      END IF
   NEXT I
   PRINT X
NEXT KETA
PRINT X;X^N
END

EXTERNAL  FUNCTION F(X)
LET F=X^N-T
END FUNCTION
 

割線法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時29分52秒
  !' 割線法 (SECANT法)
PUBLIC NUMERIC T
INPUT PROMPT  "X=": T
LET EPS=1E-8
LET  X0 = T + 1
LET  X1 = T
DO WHILE ABS(X0 - X1) > EPS
   LET  X = X0 - F(X0) / G(X0, X1)
   PRINT X
   LET  X0 = X1
   LET  X1 = X
LOOP
PRINT X;X*X
END

EXTERNAL  FUNCTION F(X)
LET F=X*X-T
END FUNCTION

EXTERNAL  FUNCTION G(X0,X1) !'   f'(x)の代用
LET G=(F(X0) - F(X1)) / (X0 - X1)
END FUNCTION
 

ステッフェッセン法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時30分29秒
  !' ステッフェッセン法(STEFFENSEN法)
PUBLIC NUMERIC T
INPUT  PROMPT "X=":T
LET EPS=1E-8
LET X=T
DO
   LET X=X-F(X)/G(X)
PRINT X
LOOP UNTIL ABS(F(X))<EPS
PRINT X;X*X
END

EXTERNAL  FUNCTION F(X)
LET F=X*X-T
END FUNCTION

EXTERNAL  FUNCTION G(X) !'   f'(x)の代用
LET G=(F(F(X)+X)-F(X))/F(X)
END FUNCTION
 

線形逆補間法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時30分58秒
  !' 線形逆補間法
PUBLIC NUMERIC T
INPUT PROMPT  "X=": T
LET EPS=1E-8
LET  X2= T
LET  X1= 1
DO
   LET  X3 = X2 - (X2 - X1) / (F(X2) - F(X1)) * F(X2)
   IF F(X1)*F(X3)<0 THEN LET X2=X3 ELSE LET X1=X3
PRINT X3
LOOP WHILE ABS(F(X3)) > EPS
PRINT X3;X3^3
END

EXTERNAL  FUNCTION F(X)
LET F=X * X * X - T
END FUNCTION
 

はさみうち法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時31分31秒
  !' はさみうち法(REGULA-FALSI法)
PUBLIC NUMERIC T
INPUT PROMPT  "X=": T
LET  A = 0
LET  B = T
LET  EPS=1E-8
DO WHILE ABS(A - B) > EPS
   LET  C = (A * F(B) - B * F(A)) / (F(B) - F(A))
   IF F(C) < 0 THEN LET  A = C ELSE LET  B = C
   PRINT C
LOOP
PRINT C;C*C
END

EXTERNAL  FUNCTION F(X)
LET F=X*X-T
END FUNCTION
 

拡張ニュートン法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時34分37秒
  !' 拡張ニュートン法
OPTION ARITHMETIC DECIMAL_HIGH
PUBLIC NUMERIC T,N
INPUT  PROMPT "n乗根=":N
INPUT PROMPT "X=":T
LET XX=T
DO
   LET X=XX
   SELECT CASE N
   CASE 2
      LET XX=X-F(X)/DF(X,1)
   CASE 3
      LET XX=X-F(X)/(DF(X,1)-DF(X,2)/FACT(2)*(F(X)/DF(X,1)))
   CASE 4
      LET XX=X-F(X)/(DF(X,1)-DF(X,2)/FACT(2)*(F(X)/DF(X,1))-DF(X,3)/FACT(3)*(F(X)/DF(X,1))^2)
   CASE 5
      LET XX=X-F(X)/(DF(X,1)-DF(X,2)/FACT(2)*(F(X)/DF(X,1))-DF(X,3)/FACT(3)*(F(X)/DF(X,1))^2-DF(X,4)/FACT(4)*(F(X)/DF(X,1))^3)
   CASE ELSE
      LET S=0
      FOR I=2 TO N-1
         LET  S=S+DF(X,I)/FACT(I)*(F(X)/DF(X,1))^(I-1)
      NEXT I
      LET XX=X-F(X)/(DF(X,1)-S)
   END SELECT
   PRINT XX
LOOP UNTIL X=XX
PRINT XX
END

EXTERNAL FUNCTION F(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET F=X^N-T
END FUNCTION

EXTERNAL  FUNCTION DF(X,NN)
OPTION ARITHMETIC DECIMAL_HIGH
LET S=N
FOR I=1 TO NN-1
   LET S=S*(N-I)
NEXT I
LET DF=S*X^(N-NN)
END FUNCTION
 

改良ニュートン法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時35分9秒
  !' 改良ニュートン法
PUBLIC NUMERIC T
INPUT  PROMPT "X=":T
LET EPS=1E-8
LET XX=T
DO
   LET X=XX
   LET L=DF(X)*(F(X)-F(X-F(X)/DF(X)))
   IF L=0 THEN
      LET XX=X
      EXIT DO
   END IF
   LET XX=X-F(X)^2/L
   PRINT XX
LOOP UNTIL ABS(X-XX)<EPS
PRINT XX;XX^3
END

EXTERNAL  FUNCTION F(X)
LET F=X*X*X-T
END FUNCTION

EXTERNAL  FUNCTION DF(X)!'   f'(x)
LET DF=3*X^2
END FUNCTION
 

ウェグスティン法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時35分42秒
  !' ウェグスティン法(WEGSTEIN法)
PUBLIC NUMERIC T
INPUT PROMPT  "X=": T
LET EPS=1E-8
LET  X0 = T
LET  X1 = F(X0)
DO WHILE ABS(F(X2) - X2) > EPS
   LET  X2 = X1 + (X1 - X0) / ((X0 - F(X0)) / (X1 - F(X1)) - 1)
   PRINT X2
   LET  X0 = X1
   LET  X1 = X2
LOOP
PRINT X2;X2*X2
END

EXTERNAL  FUNCTION F(X) !' X=F(X) F(X)-X=0
LET F=X * X + X - T
END FUNCTION
 

エイトケン法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時36分15秒
  !' エイトケン法(AITKEN法)
PUBLIC NUMERIC T
INPUT  PROMPT "X=": T
LET EPS=1E-8
LET  X0 = T
DO WHILE ABS(F(X0) - X0) > EPS
   LET  X1 = F(X0)
   LET  X2 = F(X1)
   LET  X3 = X0 - (X1 - X0) * (X1 - X0) / (X2 - 2 * X1 + X0)
   LET  X0 = X3
   PRINT X0
LOOP
PRINT X0;X0*X0
END

EXTERNAL  FUNCTION F(X) !' X=F(X)  F(X)-X=0
LET F=X * X + X - T
END FUNCTION
 

スラー法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時37分1秒
  !' スラー法
PUBLIC NUMERIC N,T
INPUT PROMPT "n乗根=":N
INPUT PROMPT  "X=": T
LET EPS=1E-8
LET  XX = T
DO
   LET  X=XX
   LET  XX = X - G(X) / DG(X) !' f(x)=x^n-t g(x)=f(x)/f'(x) x=x-g(x)/g'(x)
   PRINT XX
LOOP UNTIL ABS(X-XX)<EPS
PRINT XX;XX^N
END

EXTERNAL  FUNCTION F(X)
LET F=X^N-T
END FUNCTION

EXTERNAL  FUNCTION DF(X)!'   f'(x)
LET DF=N*X^(N-1)
END FUNCTION

EXTERNAL  FUNCTION DF2(X)!'   f''(x)
LET DF2=N*(N-1)*X^(N-2)
END FUNCTION

EXTERNAL  FUNCTION G(X)
LET G=F(X)/DF(X)
END FUNCTION

EXTERNAL  FUNCTION DG(X)!'   (f(x)/f'(x))'
LET DG=(DF(X)^2-DF2(X)*F(X))/DF(X)^2
END FUNCTION
 

???

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時38分33秒
  !' ???(不明です)
PUBLIC NUMERIC N,T
INPUT  PROMPT "n乗根=":N
INPUT PROMPT  "X=": T
LET  XX = T
LET EPS=1E-8
!' XA=X-F(X)/F'(X)  G(X)=F(X)/F'(X)
!' XB=X-G(X)/G'(X)
!' X=(XA+XB)/2
DO
   LET  X=XX
   LET  X1 = X - F(X)/DF(X)
   LET  X2 = X - G(X)/DG(X)
   LET  XX = (X1 + X2)/2
   PRINT XX
LOOP UNTIL ABS(X-XX)<EPS
PRINT XX;XX^N
END

EXTERNAL  FUNCTION F(X)
LET F=X^N-T
END FUNCTION

EXTERNAL  FUNCTION DF(X)!'    f'(X)
LET DF=N*X^(N-1)
END FUNCTION

EXTERNAL  FUNCTION DF2(X)!'   f''(X)
LET DF2=N*(N-1)*X^(N-2)
END FUNCTION

EXTERNAL  FUNCTION G(X)
LET G=F(X)/DF(X)
END FUNCTION

EXTERNAL  FUNCTION DG(X)!'   (f(x)/f'(x))'
LET DG=(DF(X)^2-DF2(X)*F(X))/DF(X)^2
END FUNCTION
 

ラゲール法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時39分5秒
  !' ラゲール法(LAGUERRE法)
PUBLIC NUMERIC T,N
INPUT  PROMPT "n乗根=":N
INPUT  PROMPT "X=":T
LET EPS=1E-8
LET X=T
DO
   LET XX=X-N*F(X)/(DF(X)+SGN(DF(X))*SQR(H(X)))
   PRINT XX
   LET X=XX
LOOP UNTIL ABS(F(X))<EPS
PRINT X;X^N
END

EXTERNAL  FUNCTION H(X)
LET H=(N-1)^2*DF(X)^2-N*(N-1)*F(X)*DF2(X)
END FUNCTION

EXTERNAL  FUNCTION F(X)
LET F=X^N-T
END FUNCTION

EXTERNAL  FUNCTION DF(X)
LET DF=N*X^(N-1)
END FUNCTION

EXTERNAL  FUNCTION DF2(X)
LET DF2=N*(N-1)*X^(N-2)
END FUNCTION
 

ハリー法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時39分44秒
  !' ハリー法(HALLEY法)
PUBLIC NUMERIC T
INPUT  PROMPT "X=":T
LET EPS=1E-8
LET X=T
DO
   LET X=X-H(X)/DH(X)
   PRINT X
LOOP UNTIL ABS(F(X))<EPS
PRINT X;X^3
END

EXTERNAL  FUNCTION H(X)
LET H=F(X)/SQR(DF(X))
END FUNCTION

EXTERNAL  FUNCTION DH(X)
LET DH=SQR(DF(X))-F(X)*DF2(X)/(2*DF(X)*SQR(DF(X)))
END FUNCTION

EXTERNAL  FUNCTION F(X)!'   f(x)
LET  F=X^3-T
END FUNCTION

EXTERNAL  FUNCTION DF(X)!'  f'(x)
LET  DF=3*X^2
END FUNCTION

EXTERNAL  FUNCTION DF2(X)!'  f''(x)
LET DF2=6*X
END FUNCTION
 

ハリー無理法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時40分20秒
  !' ハリー無理法
PUBLIC NUMERIC T
INPUT  PROMPT "X=":T
LET EPS=1E-8
LET XX=T
DO
   LET X=XX
   LET H=DF(X)^2-2*F(X)*DF2(X)
   IF H>0 THEN
      LET XX=X-(DF(X)-SQR(H))/DF2(X)
   ELSE
      LET XX=X-DF(X)/DF2(X)
   END IF
   PRINT XX
LOOP UNTIL ABS(XX-X)<EPS
PRINT XX;XX^3
END

EXTERNAL  FUNCTION F(X)
LET F=X*X*X-T
END FUNCTION

EXTERNAL  FUNCTION DF(X)
LET DF=3*X*X
END FUNCTION

EXTERNAL  FUNCTION DF2(X)
LET DF2=6*X
END FUNCTION
 

マラー法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時40分52秒
  !' マラー法(MULLER法)
PUBLIC NUMERIC T
INPUT PROMPT "X=":T
LET EPS=1E-8
LET X2=T
LET X0=1
LET X1=(X0+X2)/2
DO
   LET A=((X1-X2)*F(X0)+(X2-X0)*F(X1)+(X0-X1)*F(X2))/((X0-X1)*(X1-X2)^2)
   LET B=((X1-X2)*(2*X0-X1-X2)*F(X0)-(X0-X2)^2*F(X1)+(X0-X1)^2*F(X2))/((X0-X1)*(X1-X2)^2)
   LET C=(X0-X2)*F(X0)/(X1-X2)
   LET D=B*B-4*A*C
   IF D>0 THEN
      LET XA=(-B+SQR(D))/(2*A)
      LET XB=(-B-SQR(D))/(2*A)
      IF ABS(F(X0-XA))<ABS(F(X0)) THEN
         LET  XX=X0-XA
      ELSEIF ABS(F(X0+XA))<ABS(F(X0)) THEN
         LET  XX=X0+XA
      ELSEIF ABS(F(X0-XB))<ABS(F(X0)) THEN
         LET  XX=X0-XB
      ELSEIF ABS(F(X0+XB))<ABS(F(X0)) THEN
         LET  XX=X0+XB
      END IF
   ELSE
      LET  XA=-B/(2*A)
      IF ABS(F(X0-XA))<ABS(F(X0)) THEN
         LET XX=X0-XA
      ELSEIF ABS(F(X0+XA))<ABS(F(X0)) THEN
         LET  XX=X0+XA
      END IF
   END IF
   PRINT XX
   LET X2=X1
   LET X1=X0
   LET X0=XX
LOOP UNTIL ABS(F(XX))<EPS
PRINT XX;XX^4
END

EXTERNAL  FUNCTION F(X)
LET F=X*X*X*X-T
END FUNCTION
 

トラウブ法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時41分23秒
  !' トラウブ法(TRAUB法)
PUBLIC NUMERIC T
INPUT  PROMPT "X=": T
LET  EPS=1E-8
LET  X0=T
LET  X2=1
LET  X1=(X0+X2)/2
LET  Y0=F(X0)
LET  Y1=F(X1)
LET  Y2=F(X2)
LET  DX=(X0-X2)/2
LET  D1=(Y0-Y1)/DX
DO
   LET  D2=D1
   LET  D1=(Y0-Y1)/DX
   LET  H=(D1-D2)/(X0-X2)
   LET  OME=D1+(X0-X1)*H
   LET  S=OME*OME-4*Y0*H
   IF S>0 THEN
      LET  SQ=SQR(S)
      IF OME<0 THEN LET  SQ=-SQ
      LET  DX=-2*Y0/(OME+SQ)
   ELSE
      LET  DX=-.5*OME/EPS
   END IF
   LET  X=X0+DX
   LET  Y=F(X)
   LET  X2=X1
   LET  Y2=Y1
   LET  X1=X0
   LET  Y1=Y0
   LET  X0=X
   LET  Y0=Y
   IF ABS(F(X))<EPS THEN EXIT DO
   PRINT X
LOOP
PRINT X;X*X
END

EXTERNAL  FUNCTION F(X)
LET  F=X*X-T
END FUNCTION
 

オストロフスキー法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時41分56秒
  !' オストロフスキー法(OSTROWSKI法)
PUBLIC NUMERIC T
INPUT PROMPT  "X=": T
LET  X0=T
LET  X2=1
LET  X1=(X0+X2)/2
LET EPS=1E-8
DO
   LET TT=(X2-X1)/(X2-X0)*(F(X2)-F(X0))/(F(X2)-F(X1))*F(X1)/F(X0)
   LET X3=(X1-X0*TT)/(1-TT)
   LET X0=X1
   LET X1=X2
   LET X2=X3
   PRINT X3
LOOP UNTIL ABS(F(X3))<EPS
PRINT X3;X3*X3
END

EXTERNAL  FUNCTION F(X)
LET F=X*X-T
END FUNCTION
 

逆2次関数法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時42分22秒
  !' 逆2次関数法
PUBLIC NUMERIC T
INPUT PROMPT "X=":T
LET EPS=1E-8
LET XMIN=1
LET XMAX=T
DO
   LET XMID=(XMIN+XMAX)/2
   LET YMIN=F(XMIN)
   LET YMAX=F(XMAX)
   LET YMID=F(XMID)
   LET XNEW=XMIN*YMID*YMAX/(YMIN-YMID)/(YMIN-YMAX)+XMID*YMAX*YMIN/(YMID-YMAX)/(YMID-YMIN)+XMAX*YMIN*YMID/(YMAX-YMIN)/(YMAX-YMID)
   IF XNEW>XMID THEN
      LET XMIN=XMID
      LET YMIN=YMID
   ELSE
      LET XMAX=XMID
      LET YMAX=YMID
   END IF
   LET XMID=XNEW
   LET YMID=F(XNEW)
PRINT XMID
LOOP UNTIL ABS(YMID)<EPS
PRINT XMID;XMID^3
END

EXTERNAL  FUNCTION F(X)
LET F=X*X*X-T
END FUNCTION
 

ブレント法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時42分51秒
  !' ブレント法(BRENT法)
PUBLIC NUMERIC T
INPUT  PROMPT "X=":T
LET EPS=1E-8
LET A=1
LET B=T
LET C=A
LET FLG=0
DO UNTIL F(B)=0 OR F(S)=0 OR ABS(B-A)<EPS
   IF F(A)<>F(C) AND F(B)<>F(C) THEN
      LET S=A*F(B)*F(C)/(F(A)-F(B))/(F(A)-F(C))+B*F(A)*F(C)/(F(B)-F(A))/(F(B)-F(C))+C*F(A)*F(B)/(F(C)-F(A))/(F(C)-F(B))
   ELSE
      LET S=B-F(B)*(B-A)/(F(B)-F(A))
   END IF
   IF (S<(3*A+B)/4 OR S>B) OR (FLG=1 AND ABS(S-B)>=ABS(B-C)/2) OR (FLG=0 AND ABS(S-B)>=ABS(C-D)/2) OR (FLG=1 AND ABS(B-C)<EPS) OR (FLG=0 AND ABS(C-D)<EPS) THEN
      LET S=(A+B)/2
      LET FLG=1
   ELSE
      LET FLG=0
   END IF
   LET D=C
   LET C=B
   IF F(A)*F(S)<0 THEN LET B=S ELSE LET A=S
   IF ABS(F(A))<ABS(F(B)) THEN SWAP A,B
   PRINT B;S
LOOP
PRINT B;S;B*B*B;S*S*S
END

EXTERNAL  FUNCTION F(X)
LET F=X*X*X-T
END FUNCTION
 

高次収束式

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時43分51秒
  !' 高次収束式
OPTION ARITHMETIC DECIMAL_HIGH
OPTION BASE 0
PUBLIC NUMERIC N
INPUT  PROMPT "n乗根=":N
INPUT  PROMPT "X=":T
LET MODE=3
DIM A(N)
LET A(N)=1 !' A(N)*X^N+A(N-1)*X^(N-1)+...A(1)*X+A(0)=0
LET A(0)=-T
LET XX=T
DO
   LET X=XX
   CALL HORNER(A,X,Y,DY,DY2,DY3,DY4,DY5)
   SELECT CASE MODE
   CASE 2
      LET XX=X-Y/DY !'NEWTON法
   CASE 3
      LET XX=X-Y/(DY-Y*DY2/(2*DY)) !'BAILEY法
   CASE 4
      LET XX=X-Y*(DY^2-DY2*Y/2)/(DY^3-Y*DY*DY2+DY3*Y^2/6) !'KISS法
   CASE 5
      LET XX=X+(4*Y^3*DY3-24*Y^2*DY*DY2+24*Y*DY^3)/(Y^3*DY4-8*Y^2*DY*DY3-6*Y^2*DY2^2+36*Y*DY^2*DY2-24*DY^4)
   CASE 6
      LET XX=X+(5*Y^4*DY4-40*Y^3*DY*DY3-30*Y^3*DY2^2+180*Y^2*DY^2*DY2-120*Y*DY^4)/(Y^4*DY5-10*Y^3*DY*DY4+(60*Y^2*DY^2-20*Y^3*DY2)*DY3+90*Y^2*DY*DY2^2-240*Y*DY^3*DY2+120*DY^5)
   END SELECT
   PRINT XX
LOOP UNTIL X=XX
PRINT X
END

EXTERNAL  SUB HORNER(A(),X,Y,DY,DY2,DY3,DY4,DY5)
OPTION ARITHMETIC DECIMAL_HIGH
LET Y=A(N)
LET DY=Y
LET DY2=Y
LET DY3=Y
LET DY4=Y
LET DY5=Y
FOR I=N-1 TO 0 STEP -1
   LET Y=Y*X+A(I)
   IF I>0 THEN LET DY=DY*X+Y
   IF I>1 THEN LET DY2=DY2*X+DY
   IF I>2 THEN LET DY3=DY3*X+DY2
   IF I>3 THEN LET DY4=DY4*X+DY3
   IF I>4 THEN LET DY5=DY5*X+DY4
NEXT I
LET DY2=DY2*FACT(2)
LET DY3=DY3*FACT(3)
LET DY4=DY4*FACT(4)
LET DY5=DY5*FACT(5)
END SUB
 

アーバス法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時45分26秒
  !' アーバス法(Aberth法)
OPTION ARITHMETIC COMPLEX
OPTION BASE 0
PUBLIC NUMERIC N,EPS
LET N=10 !'次数
LET EPS=1E-8
DIM Z(N),A(N)
LET A(N)=1 !' A(N)*X^N+A(N-1)*X^(N-1)+...A(1)*X+A(0)=0
LET A(0)=-1
CALL HORNER(A,-A(N-1)/(N*A(N))/A(N),Y,DY)
FOR I=1 TO N
   LET Z(I)=-A(N-1)/(N*A(N))+ABS(Y)^(1/N)*EXP(SQR(-1)*2*PI*(I-1)/N+3/(2*N))
NEXT I
DO
   FOR I=1 TO N
      LET S=0
      FOR J=1 TO N
         IF I<>J THEN LET S=S+1/(Z(I)-Z(J))
      NEXT J
      CALL HORNER(A,Z(I),Y,DY)
      LET Z(I)=Z(I)-Y/(DY-Y*S)
   NEXT I
   LET FL=0
   FOR I=1 TO N
      CALL HORNER(A,Z(I),Y,DY)
      IF ABS(RE(Y))>EPS OR ABS(IM(Y))>EPS THEN
         LET FL=1
         EXIT FOR
      END IF
   NEXT  I
LOOP UNTIL FL=0
FOR I=1 TO N
   PRINT "ANSWER";I;":";
   CALL DISPLAY(Z(I))
NEXT I
END

EXTERNAL  SUB DISPLAY(Z)
OPTION ARITHMETIC COMPLEX
IF ABS(RE(Z))>EPS THEN PRINT RE((Z));
IF ABS(IM(Z))>EPS THEN
   IF IM(Z)<0 THEN
      PRINT "-";
   ELSE
      IF ABS(RE(Z))>EPS THEN PRINT "+";
   END IF
   PRINT ABS(IM(Z));"i";
END IF
PRINT
END SUB

EXTERNAL  SUB HORNER(A(),X,Y,DY)
OPTION ARITHMETIC COMPLEX
LET Y=A(N)
LET DY=Y
FOR I=N-1 TO 0 STEP -1
   LET Y=Y*X+A(I)
   IF I>0 THEN LET DY=DY*X+Y
NEXT I
END SUB
 

商差法

 投稿者:しばっち  投稿日:2013年 5月19日(日)22時46分17秒
  !' 商差法(QD法)
OPTION ARITHMETIC COMPLEX
PUBLIC NUMERIC EPS
OPTION BASE 0
INPUT PROMPT  "次数=": N
DIM D(N), A(N), Q(N)
LET EPS=1E-8
!' X^N+A(1)*X^(N-1)+A(2)*X^(N-2)+...A(N-1)*X+A(N)=0
FOR I = 0 TO N
   DO
      PRINT N - I;"次の複素係数 A+Bi A,B=";
      INPUT RR,II
      LET A(I)=COMPLEX(RR,II)
   LOOP WHILE A(I) = 0 !'各係数は0でない
   IF I>0 THEN LET A(I)=A(I)/A(0)
NEXT I
LET A(0)=1
LET Q(1)=-A(1)
FOR I = 1 TO N - 1
   LET  D(I) = A(I + 1) / A(I)
NEXT I
DO
   FOR I = 1 TO N
      LET  Q(I) = Q(I) + D(I) - D(I - 1)
   NEXT I
   FOR I = 1 TO N - 1
      LET  D(I) = D(I) * Q(I + 1) / Q(I)
   NEXT I
   LET FL=0
   FOR I = 1 TO N
      IF ABS(D(I)) >= EPS THEN
         LET FL=1
         EXIT FOR
      END IF
   NEXT I
LOOP UNTIL FL=0
FOR I=1 TO N
   PRINT "X(";STR$(I); ")=";
   CALL DISPLAY(Q(I))
NEXT I
END

EXTERNAL  SUB DISPLAY(Z)
OPTION ARITHMETIC COMPLEX
IF ABS(RE(Z))>EPS THEN PRINT RE((Z));
IF ABS(IM(Z))>EPS THEN
   IF IM(Z)<0 THEN
      PRINT "-";
   ELSE
      IF ABS(RE(Z))>EPS THEN PRINT "+";
   END IF
   PRINT ABS(IM(Z));"i";
END IF
PRINT
END SUB
 

減速ニュートン法

 投稿者:しばっち  投稿日:2013年 5月28日(火)22時02分33秒
  !' 減速ニュートン法
LET X=3 !'初期値
LET EPS=1E-8
DO
   LET U=2
   DO
      LET U=U/2
      LET Y=X-U*F(X)/DF(X) !'減速ニュートン法
   LOOP UNTIL ABS(F(Y))<(1-U/2)*ABS(F(X))
   LET X=Y
LOOP UNTIL ABS(F(X))<EPS
PRINT X;F(X)

LET X=3 !'初期値
LET I=0
DO
   LET X=X-F(X)/DF(X) !'ニュートン法
   LET I=I+1
   IF I>100 THEN
      PRINT"収束しません"
      STOP
   END IF
LOOP UNTIL ABS(F(X))<EPS
PRINT X;F(X)
END

EXTERNAL  FUNCTION F(X)
LET F=3*ATN(X-1)+X/4
END FUNCTION

EXTERNAL  FUNCTION DF(X)
LET DF=3/((X-1)^2+1)+1/4
END FUNCTION
 

遺伝的アルゴリズムで関数の最大値を求める

 投稿者:チムセー  投稿日:2013年 5月29日(水)18時33分39秒
  LET t0=TIME
RANDOMIZE
DECLARE EXTERNAL FUNCTION AP
DECLARE EXTERNAL FUNCTION TOP

DIM IN(1 TO 18,1 TO 10) !10個体を準備11から18は子孫
DIM CIN(1 TO 18,1 TO 10)
DIM INA(1 TO 18) !個体の評価値

FOR i=1 TO 10 !20個体をランダムに作成
   FOR n=1 TO 10
      LET IN(i,n)=INT(RND*2)
   NEXT  N
   LET INA(i)=AP(IN,i)
NEXT i

FOR i=1 TO 10000 !世代数
!交叉
   LET A=INT((TOP(INA)/100))
   LET B=TOP(INA)-INT((TOP(INA)/100))*100
   FOR t=1 TO 4
      FOR n=1 TO 10
         LET IN(10+2*t-1,n)=IN(A,n)
         LET IN(10+2*t,n)=IN(B,n)
      NEXT n
      FOR n=1 TO 10
         IF RND>0.9 THEN
            LET IN(10+2*t-1,n)=IN(10+2*t-1,n)+IN(10+2*t,n)
            LET IN(10+2*t,n)=IN(10+2*t-1,n)-IN(10+2*t,n)
            LET IN(10+2*t-1,n)=IN(10+2*t-1,n)-IN(10+2*t,n)
         END IF
      NEXT n
   NEXT t
   FOR n=1 TO 10
      LET CIN(1,n)=IN(A,n)
      LET CIN(2,n)=IN(B,n)
   NEXT n
   FOR t=3 TO 10
      FOR n=1 TO 10
         LET CIN(t,n)=IN(t+8,n)
      NEXT n
   NEXT t
   FOR t=1 TO 10 !IN書き出し&突然変異
      FOR n=1 TO 10
         IF RND>0.05 THEN
            LET IN(t,n)=CIN(t,n)
         ELSE
            LET IN(t,n)=1-CIN(t,n)
         END IF
      NEXT n
   NEXT t
   FOR t=1 TO 10
      LET INA(t)=AP(IN,t)
   NEXT t
NEXT i
LET P1=INT((TOP(INA)/100))
PRINT INA(P1)
PRINT time-t0
END

EXTERNAL FUNCTION AP(IN(,),i) !個体評価
DEF f(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50)
FOR n=0 TO 9
   LET T=IN(i,n+1)
   LET m=m+T*2^n
NEXT n
LET AP=f(m/1023)
END FUNCTION

EXTERNAL FUNCTION TOP(INA()) !優秀な個体の検索,返り値は配列番号0102見たいに上位2桁から一番
LET NO1=-10 !評価値の最低値以下の値
LET NO2=-10 !評価値の最低値以下の値
FOR i=1 TO 10
   IF NO1<INA(i) THEN
      LET NO1=INA(i)
      LET TNO1=i
   END IF
NEXT i
FOR i=1 TO 10
   IF NO2<INA(i) AND i<>TNO1 THEN
      LET NO2=INA(i)
      LET TNO2=i
   END IF
NEXT I
LET TOP=TNO1*100+TNO2
END FUNCTION
 

Re: 遺伝的アルゴリズムで関数の最大値を求める

 投稿者:島村1243  投稿日:2013年 5月29日(水)19時31分13秒
  チムセーさんへのお返事です。

珍しい方法ですが、方法の名称は有るのでしょうか?
また、使い方を知りたいのですが、最大値を求めたい関数を指定する箇所は下記「DEF f(x)」でしょうか?

EXTERNAL FUNCTION AP(IN(,),i) !個体評価
DEF f(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50)

また、最大値が得られるXの値を知るにはどこで「print x」を記述すれば良いでしょうか?
よろしくご教示お願い致します。
 

Re: 遺伝的アルゴリズムで関数の最大値を求める

 投稿者:山中和義  投稿日:2013年 6月 1日(土)06時10分40秒
  > No.3069[元記事へ]

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

チムセーさんが不在のようなので、代わりに回答します。

> 珍しい方法ですが、方法の名称は有るのでしょうか?

●遺伝的アルゴリズム(Genetic Algorithm、GA)で関数の最大値を求める問題
複雑な関数、特に山がいくつもあるような関数y=f(x)の最大値を数値的に求める。
適応度は関数f(x)の値、染色体(個体)の表現型は実数xとなる。
染色体の遺伝子型は、実数xをビット配列で表したものとなる。
最大値が入っていそうな区間0≦x<aを定める。
解の精度を定め、染色体の長さNを決める。a/2^Nの精度で解が求まることになる。


> 最大値を求めたい関数を指定する箇所は下記「DEF f(x)」でしょうか?

そうですね。 y=f(x)のグラフを描いてみました。

DEF f(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50)
SET WINDOW -1,3,-2,2
DRAW grid(0.5,0.5)
FOR x=-1 TO 3 STEP 1/2^8
   PLOT LINES: x,f(x);
NEXT x
PLOT LINES
END


> また、最大値が得られるXの値を知るにはどこで「print x」を記述すれば良いでしょうか?

xはIN(,)より、P1番目が候補で10ビットなので、
END文の前に、

LET m=0
FOR n=1 TO 10
   LET T=IN(P1,n)
   LET m=m+T*2^(n-1)
NEXT n
PRINT "x="; m/1024

END

または、
LET m=0
FOR n=10 TO 1 STEP -1
   LET m=m*2+IN(P1,n)
NEXT n
PRINT "x="; m/1024

END

とすればよいと思います。


補足 本プログラムの解析
非負整数のみの処理なので、0≦x<1の範囲ですね。
染色体の長さは10ビットなので、1024分割になります。

次の世代の10個体について
・選択淘汰は、エリート選択による適応度がベスト1,2の2個体
・上記の2個体を親として、染色体の各々の遺伝子について0.1の確率で交叉させた8個体
・突然変異は、染色体の各々の遺伝子について0.05の確率でビットの0,1を反転させる。



私もサンプルをつくってみました。

交叉は、Aaに対して(2進法で見ると)Ab,Acは近傍を表すので、山登り法に相当します。
また、突然変異は、特に上位ビットが変わればDb,Dcなので、焼きなまし法に相当します。


!遺伝的アルゴリズム(Genetic Algorithm、GA)で関数の最大値を求める問題

RANDOMIZE

DEF F(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50) !適応度
LET N=10 !染色体の長さ
LET M=9 !個体数 ※Mは3以上

DIM X(M) !個体
FOR i=1 TO M !第0世代
   LET X(i)=INT(RND*2^N) !x=[0,1)を2^N分割
NEXT i
MAT PRINT x; !debug

DIM NX(M) !次の世代
FOR t=1 TO 2000 !世代交代を進めて進化させる

!選択淘汰(Selection)
!※エリート選択による適応度がベスト1,2,3(一番大きな数から順に3つ)の3個体
   LET A=-99999 !1番目 値は-∞
   LET B=A !2番目
   LET C=A !3番目
   FOR i=1 TO M
      LET W=F(X(i)/2^N) !関数f(x)の値
      IF W>A THEN
         LET C=B !降格
         LET XC=XB
         LET B=A
         LET XB=XA
         LET A=W !ベスト1
         LET XA=i
      ELSE
         IF W>B THEN
            LET C=B !降格
            LET XC=XB
            LET B=W !ベスト2
            LET XB=i
         ELSE
            IF W>C THEN
               LET C=W !ベスト3
               LET XC=i
            END IF
         END IF
      END IF
   NEXT i
   !!!PRINT XA;A; XB;B XC;C !debug
   LET NX(1)=X(XA)
   LET NX(2)=X(XB)
   LET NX(3)=X(XC)


   !上記の3個体を親として、各々の染色体について交叉(Cross Over)させた6個体
   !※親Aa,Bb → 子Ab,Ba  親Aa,Cc → 子Ac,Ca  親Bb,Cc → 子Bc,Cb
   LET p=2^INT(N/2) !1点交叉法(上位と下位)
   LET NX(4)=INT(NX(1)/p)*p+MOD(NX(2),p) !Ab
   LET NX(5)=INT(NX(2)/p)*p+MOD(NX(1),p) !Ba
   LET NX(6)=INT(NX(1)/p)*p+MOD(NX(3),p) !Ac
   LET NX(7)=INT(NX(3)/p)*p+MOD(NX(1),p) !Ca
   LET NX(8)=INT(NX(2)/p)*p+MOD(NX(3),p) !Bc
   LET NX(9)=INT(NX(3)/p)*p+MOD(NX(2),p) !Cb


   FOR i=1 TO M !次の世代へ
      LET X(i)=NX(i)

      !各々の染色体について0.01の確率で遺伝子を変異させる
      !※1つのビットの0,1を反転させる
      IF RND<0.01 THEN LET X(i)=bitreverse(INT(RND*N),X(i)) !突然変異(Mutation)
   NEXT i

NEXT t
MAT PRINT x; !debug

LET x0=X(1)/2^N !進化の結果
PRINT "x=";x0; " f(x)=";f(x0) !検算 x=.140792279664446  f(x)=1.84931356430434

END


!UBASIC ビット演算関連より

EXTERNAL FUNCTION bitreverse(n,x) !n番目のビットを反転する ※n,xは非負整数
LET d=2^n !n桁
LET a=INT(x/d)
LET bitreverse=(INT(a/2)*4-a+1)*d+MOD(x,d) !大きい桁+NOT+小さい桁
END FUNCTION


 

関数の最大値を求める

 投稿者:山中和義  投稿日:2013年 6月 1日(土)10時41分0秒
  > No.3070[元記事へ]

区間で上に凸の関数の最大値を黄金分割法を用いて求めるプログラム


!上凸関数の最大値(黄金分割法)

DEF F(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50)

FUNCTION find_max(a,b) !区間[a,b]でf(x)が最大値を示すxの値
   LET r=2/(3+SQR(5))
   LET c=a+r*(b-a) !a<c<d<b
   LET d=b-r*(b-a)
   LET fc=F(c)
   LET fd=F(d)
   DO WHILE d-c>1E-14 !d=cまで
      IF fc<fd THEN !f(c)<f(d)なら
         LET a=c !区間を狭める a<a'=c<c'=d<d'<b
         LET c=d
         LET d=b-r*(b-a)
         LET fc=fd
         LET fd=F(d)
      ELSE
         LET b=d !a<c'<d'=c<b'=d<b
         LET d=c
         LET c=a+r*(b-a)
         LET fd=fc
         LET fc=F(c)
      END IF
   LOOP
   LET find_max=c
END FUNCTION

LET x=find_max(0, 0.3) !大域的最適解
!!LET x=find_max(0.4, 0.7) !局所的最適解
!!LET x=find_max(0.8, 1) !局所的最適解
PRINT x; f(x)

END


 

Re:Re: 遺伝的アルゴリズムで関数の最大値を求める

 投稿者:島村1243  投稿日:2013年 6月 1日(土)13時43分0秒
  山中和義さんへのお返事です。

山中さん、詳しい説明と新たなサンプルコードのご教示有難う御座いました。
(山中さんの詳しい説明とサンプルコード内容を見るには、これの元記事[No.3070]を参照)
 

01ナップサック問題

 投稿者:山中和義  投稿日:2013年 6月 3日(月)19時58分8秒
  問題
重さと価値がそれぞれW[i],V[i]であるようなN個の品物がある。
これらの品物から、重さの総和がAを超えないように選んだとき、
価値の総和の最大値を求めよ。

●総当り

LET N=8 !種類
DATA 7,3,2,6,1,5,10,3 !重さ
DATA 8,4,3,10,7,9,5,2 !価値
LET A=20
DIM W(N),V(N)
MAT READ W
MAT READ V
LET VMAX=0
FOR P=0 TO 2^N-1 !全パターン
   LET WW=0
   LET VV=0
   LET B=P
   LET i=1
   DO WHILE B>0
      LET WW=WW+MOD(B,2)*W(i)
      LET VV=VV+MOD(B,2)*V(i)
      LET B=INT(B/2)
      LET i=i+1
   LOOP
   IF WW<=A AND VV>VMAX THEN LET VMAX=VV
NEXT P
PRINT "価値=";VMAX
END


●貧欲法
「その場での最善」を選択することを繰り返す。シンプルで高速である。

LET N=8 !種類
DATA 7,3,2,6,1,5,10,3 !重さ
DATA 8,4,3,10,7,9,5,2 !価値
LET A=20
DIM W(N),V(N)
MAT READ W
MAT READ V
LET VMAX=0
DO WHILE A>0
   LET Vi=0
   FOR i=1 TO N
      IF W(i)<=A AND V(i)>Vi THEN !価値が最も大きいもの
         LET Vi=V(i)
         EXIT FOR !最初に見つかったもの
      END IF
   NEXT i
   IF i>N THEN EXIT DO !条件を満たすものが既にない場合
   LET VMAX=VMAX+Vi
   LET A=A-W(i) !除外して次へ
   LET V(i)=0 !※最小値
LOOP
PRINT "価値=";VMAX
END


●動的計画法(Dynamic Programming、DP)

LET N=8 !種類
DATA 7,3,2,6,1,5,10,3 !重さ
DATA 8,4,3,10,7,9,5,2 !価値
LET A=20
DIM W(N),V(N)
MAT READ W
MAT READ V
DIM DP(0 TO A)
FOR i=1 TO N
   LET j=A
   DO WHILE j>=W(i)
      LET DP(j)=MAX(DP(j),DP(j-W(i))+V(i))
      LET j=j-1
   LOOP
NEXT i
MAT PRINT DP; !DP(A)
END


●遺伝的アルゴリズム

RANDOMIZE

LET N=8 !種類
DATA 7,3,2,6,1,5,10,3 !重さ
DATA 8,4,3,10,7,9,5,2 !価値
LET A=20

DIM W(N),V(N)
MAT READ W
MAT READ V

FUNCTION F(X,W()) !適応度
   LET FF=0
   LET ii=1
   LET XX=X
   DO WHILE XX>0 !10進法から2進法へ
      LET FF=FF+MOD(XX,2)*W(ii)
      LET XX=INT(XX/2)
      LET ii=ii+1
   LOOP
   LET F=FF
END FUNCTION

LET M=4 !個体数 ※Mは2以上

DIM X(M) !個体
FOR i=1 TO M !第0世代
   LET X(i)=INT(RND*2^N) !0から2^N-1まで
NEXT i
MAT PRINT X; !debug

DIM NX(M) !次の世代
FOR t=1 TO 10 !世代交代によって進化させる
   !選択淘汰(Selection)
   !※エリート選択による適応度がベスト1,2(一番大きな数から順に2つ)の2個体
   LET T1=-999 !1番目 値は-∞
   LET T2=T1
   FOR i=1 TO M
      LET WK=F(X(i),V)
      IF F(X(i),W)>A THEN LET WK=0 !制限を越えるなら解ではないので、0とする
      IF WK>T1 THEN
         LET T2=T1 !降格
         LET X2=X1
         LET T1=WK !ベスト1
         LET X1=i
      ELSE
         IF WK>T2 THEN
            LET T2=WK !ベスト2
            LET X2=i
         END IF
      END IF
   NEXT i
   LET NX(1)=X(X1)
   LET NX(2)=X(X2)

   !上記の2個体を親として、各々の染色体について交叉(Cross Over)させた2個体
   !※親Aa,Bb → 子Ab,Ba
   LET P=2^INT(N/2)
   LET NX(3)=INT(NX(1)/P)*P+MOD(NX(2),P)
   LET NX(4)=INT(NX(2)/P)*P+MOD(NX(1),P)

   FOR i=1 TO M !次の世代へ
      LET X(i)=NX(i)

      !各々の染色体について0.05の確率で遺伝子を変異させる
      !※上位と下位を入れ替える(1点逆位) Aa → aA
      IF RND<0.05 THEN
         LET P=3 ! !突然変異(Mutation) 1~[N/2]
         LET X(i)=INT(X(i)/2^P)+MOD(X(i),2^P)*2^(N-P)
      END IF
   NEXT i
NEXT t
MAT PRINT X; !debug

PRINT BSTR$(X(1),2) !進化の結果
PRINT "重さ=";F(X(1),W)
PRINT "価値=";F(X(1),V)

END


 

Re: 01ナップサック問題

 投稿者:山中和義  投稿日:2013年 6月 7日(金)13時42分51秒
  > No.3073[元記事へ]

> 問題
> 重さと価値がそれぞれW[i],V[i]であるようなN個の品物がある。
> これらの品物から、重さの総和がAを超えないように選んだとき、
> 価値の総和の最大値を求めよ。

●分枝限定法

LET N=8 !種類
DATA 7,3,2,6,1,5,10,3 !重さ
DATA 8,4,3,10,7,9,5,2 !価値
LET A=20

DIM W(N),V(N)
MAT READ W
MAT READ V
PUBLIC NUMERIC VMAX
LET VMAX=0
CALL try(1,A, 0, N,A,W,V)
END

EXTERNAL SUB try(P,R, V0, N,A,W(),V()) !バックトラック法で検索する
FOR i=0 TO MIN(1,INT(R/W(P))) !詰め込む(枝刈り) ※ビットパターン
   LET RR=R-W(P)*i !残り
   LET VV=V0+V(P)*i !価値
   IF RR>0 AND P<N THEN !n種類まで(深さ優先)
      CALL try(P+1,RR, VV, N,A,W,V)
   ELSE
      IF VV>=VMAX THEN !ここまでの結果を得る
         LET VMAX=VV
         PRINT "価値=";VMAX
      END IF
   END IF
NEXT i
END SUB


 

らくだの分配

 投稿者:山中和義  投稿日:2013年 6月 9日(日)20時15分16秒
  白百合学園中学(2013年)の入試問題より
父親から17頭のらくだと遺言「長男に1/2、二男に1/3、三男に1/9ずつ与える」が遺された。
そこに賢者が現れ、自分のラクダ1頭を加えて、長男に9頭、二男に6頭、三男に2頭ときれいに分配した。
賢者はとても感謝され、しかも自分のらくだも戻って、めでたしめでたし!

参考サイト http://www.nichinoken.co.jp/column/shikakumaru/2013/1306_sa.html

●賢者な3兄弟
賢者が現れなくても分けられた!?

らくだが17頭のとき、1/2,1/3,1/9ずつ与えるなら、
17/2=8.5
17/3≒5.66
17/9≒1.88
端数を切り上げて(または四捨五入して)、9,6,2頭ずつで分けた。

別解
らくだが17頭のとき、1/2,1/3,1/9ずつ与えるなら、
比率1/2:1/3:1/9=9/18:6/18:2/18=9:6:2から、9,6,2頭ずつで分けた。
(終り)

●父親の遺言
らくだの頭数を1頭を加えてmとする。x,y,zは正整数で、x≦y≦z≦mとする。
1/x+1/y+1/z=(m-1)/m ∴1/x+1/y+1/z=1-1/m ∴1/x+1/y+1/z+1/m=1
を満たし、x,y,zの最小公倍数がm(x,y,zがmの約数)になるx,y,zの組を求めると、

らくだが、3頭なら
1/4  1/4  1/4

らくだが、5頭なら
1/2  1/6  1/6
1/3  1/3  1/6

らくだが、7頭なら
1/2  1/4  1/8

らくだが、9頭なら
1/2  1/5  1/5

らくだが、11頭なら
1/2  1/3  1/12
1/2  1/4  1/6
1/3  1/3  1/4

らくだが、17頭なら
1/2  1/3  1/9

らくだが、19頭なら
1/2  1/4  1/5

らくだが、23頭なら
1/2  1/3  1/8

らくだが、41頭なら
1/2  1/3  1/7

以上、12通り。



OPTION ARITHMETIC RATIONAL !有理数モード
LET N=4 !変数の個数
PUBLIC NUMERIC C !解の個数
LET C=0
DIM D(N)
CALL try(1,D, 1,1,N) !1≦x≦y≦z≦w、1/x+1/y+1/z+1/w=1
!!!PRINT C
END

EXTERNAL SUB try(P,D(), A,B,N)
OPTION ARITHMETIC RATIONAL !有理数モード
IF P=N THEN !最後の変数wなら
   LET W=1/B
   !!IF W=INT(W) AND W>=A THEN
   IF W=INT(W) THEN
      LET D(N)=W
      LET C=C+1 !個数
      PRINT C
      MAT PRINT D; !解
   END IF
ELSE
   FOR i=MAX(A,INT(1/B)+1) TO INT((N-P+1)/B) !x
      LET D(P)=i
      LET BB=B-1/i !1-1/x
      IF BB>0 THEN CALL try(P+1,D, i,BB,N) !次の変数yへ
   NEXT i
END IF
END SUB


実行結果

1
2  3  7  42

2
2  3  8  24

3
2  3  9  18

4
2  3  10  15  ←不適 28頭に2頭を補い分配することを意味する。∵(m-1)/m=(2m-2)/(2m)より

5
2  3  12  12

6
2  4  5  20

7
2  4  6  12

8
2  4  8  8

9
2  5  5  10

10
2  6  6  6

11
3  3  4  12

12
3  3  6  6

13
3  4  4  6  ←不適 10頭に2頭を補い分配することを意味する。

14
4  4  4  4



類題
1/x+1/y+1/z+1/w=1を満たすx≦y≦z≦wなる正整数の組を求めよ。
答え
1≦x≦y≦z≦wから、1/x<1/x+1/y+1/z+1/w=1≦1/x+1/x+1/x+1/x=4/x ∴2≦x≦4
X=2のとき
1/y+1/z+1/w=1-1/2=1/2
x=2≦y≦z≦wから、1/y<1/y+1/z+1/w=1/2≦1/y+1/y+1/y=3/y ∴3≦y≦6
 y=3のとき
  1/z+1/w=1-1/2-1/3=1/6
  y=3≦z≦wから、1/z<1/z+1/w=1/6≦1/z+1/z=2/z ∴7≦z≦12
  z=7のとき
   1/w=1-1/2-1/3-1/7=1/42 ∴w=42 ゆえに、(x,y,z,w)=(2,3,7,42)
  z=8のとき
   1/w=1-1/2-1/3-1/8=1/24 ∴w=24 ゆえに、(x,y,z,w)=(2,3,8,24)
  z=9のとき
   1/w=1-1/2-1/3-1/9=1/18 ∴w=18 ゆえに、(x,y,z,w)=(2,3,9,18)
  z=10のとき
   1/w=1-1/2-1/3-1/10=1/15 ∴w=15 ゆえに、(x,y,z,w)=(2,3,10,15)
  z=11のとき
   1/w=1-1/2-1/3-1/11=5/66 これは単位分数でないので、不適である。
  z=12のとき
   1/w=1-1/2-1/3-1/12=1/12 ∴w=12 ゆえに、(x,y,z,w)=(2,3,12,12)
 y=4のとき
  ・・・
 y=5のとき
  ・・・
 y=6のとき
  ・・・
X=3のとき
 ・・・
X=4のとき
 ・・・
(終り)

参考サイト http://www2.ocn.ne.jp/~mizuryu/renzoku.html No.291
参考サイト http://oeis.org/A002966
 

将棋パズルの最少手数解は?

 投稿者:GAI  投稿日:2013年 6月12日(水)06時40分52秒
  ttp://www.lcv.ne.jp/~hhase/memo/m03_02a.html
のページに将棋盤のパズル:飛角の入れ替え
という2月15日(土)の記事があります。
以前このパズルに挑戦したとき、99手かかる手数を見つけてこれが最少手数であろうと

1八飛、2八銀、3九金、4九玉、5九金、6九銀、7八金、6八銀左、7九角、8八金、

9八金、7八銀、6九金、5九銀、6八角、7九金、8八金、7九角、6八銀、5九玉、

6九玉、4九金寄、5九金、4九銀、3八金、3九銀、4八銀右、3九金、3八飛、2八金、

1八金、3九銀、2八銀、4八飛、3八銀、4九金、3九金、4九飛、5九銀、4八銀、

6八角、7九玉、6九飛、4九金、3九銀左、5九角、4八角、6八玉、5九玉、7九飛、

6九銀、6八銀、6九飛、7九銀、7八金、6八金、8八金、7八金左、8八銀、7九飛、

6九金、6八金寄、7八飛、7九銀、9八飛、8八銀、7八金寄、7九金寄、6九玉、

5九金、4九銀、3八銀右、3九角、4八銀、4九金、5九銀、6八銀、5九金、4八角、

4九銀、3九銀、3八銀右、3九角、4八銀、4九銀、2八金、3八金、2八角、3九銀、

4八金寄、3八銀左、4九金左、5九玉、6九金、7九銀右、6八金寄、7八銀、7九銀、8八飛
まで、99手。


確信していたのですが、ここにこれを51手で達成できると記載されていて衝撃を受けています。
その手順をどうしても知りたくて調査願えませんでしょうか?
 

勘違いでした。

 投稿者:GAI  投稿日:2013年 6月18日(火)06時27分54秒
  1八飛、2八銀、3九金、4九玉、5九金、6九銀、7八金、6八銀左、7九角、8八金、

9八金、7八銀、6九金、5九銀、6八角、7九金、8八金、7九角、6八銀、5九玉、

6九玉、4九金寄、5九金、4九銀、3八金、3九銀、4八銀右、3九金、3八飛、2八金、

1八金、3九銀、2八銀、4八飛、3八銀、4九金、3九金、4九飛、5九銀、4八銀、

6八角、7九玉、6九飛、4九金、3九銀左、5九角、4八角、6八玉、5九玉、7九飛、

6九銀、6八銀、6九飛、7九銀、7八金、6八金、8八金、7八金左、8八銀、7九飛、

6九金、6八金寄、7八飛、7九銀、9八飛、8八銀、7八金寄、7九金寄、6九玉、

5九金、4九銀、3八銀右、3九角、4八銀、4九金、5九銀、6八銀、5九金、4八角、

4九銀、3九銀、3八銀右、3九角、4八銀、4九銀、2八金、3八金、2八角、3九銀、

4八金寄、3八銀左、4九金左、5九玉、6九金、7九銀右、6八金寄、7八銀、7九銀、8八飛
まで、99手。



この手順は初期条件が王の上に香車があり、両端の従来の香車の上の香車がないものでの手順でした。
見た目同じものだと勘違いして投稿してしまいました。

 

整数をべき乗数の和と差で表す

 投稿者:山中和義  投稿日:2013年 6月18日(火)10時16分49秒
 
問題
すべての整数(非負整数、自然数)nは、1から始まる2つ以上の連続する自然数の和と差で表すことができる。
すなわち、2以上の整数kが存在して、
 式 n=±1±2±3±4±5± … ±k
で表される。
答え
0= 1+2 -3
1=-1+2
2=-1+2 -3+4
3=-1+2 -3+4 -5+6
4=-1+2 -3+4 -5+6 -7+8
 :

負数-1,-2,-3,…は、+,-の記号を反転させる。
(終り)

答え(帰納的な表現による冗長性のある解)
0= 1+2 -3
1=-1+2
となる。
n=(±1±2± … ±k)とすると、
恒等式
 -(k+1)
 +(k+2)
 =1
より、
n+1=(±1±2± … ±k) + { -(k+1)+(k+2) }

負数-1,-2,-3,…は、+,-の記号を反転させる。
(終り)


問題
すべての整数(非負整数、自然数)nは、1から始まる2つ以上の連続する平方数(2乗数)の和と差で表すことができる。
すなわち、2以上の整数kが存在して、
 式 n=±1^2±2^2±3^2±4^2±5^2± … ±k^2
で表される。
答え
0=1^2+2^2-3^2+4^2-5^2-6^2+7^2
1=1^2-2^2+3^2-4^2-5^2+6^2
2=-1^2-2^2-3^2+4^2
3=-1^2+2^2
4=-1^2-2^2+3^2
となる。

n=(±1^2±2^2± … ±k^2)とすると、
恒等式
 +(k+1)^2-(k+2)^2
 -(k+3)^2+(k+4)^2
 =4
より、
n+4=(±1^2+ … ±k^2) + { (k+1)^2-(k+2)^2-(k+3)^2+(k+4)^2 }
(終り)

参考サイト http://blue.kakiko.com/mmrmmr/htm/eqtn21.html


問題
すべての整数(非負整数、自然数)nは、1から始まる2つ以上の連続する立方数(3乗数)の和と差で表すことができる。
すなわち、2以上の整数kが存在して、
 式 n=±1^3±2^3±3^3±4^3±5^3± … ±k^3
で表される。
答え
-(x+1)^3+(x+2)^3+(x+3)^3-(x+4)^3
+(x+5)^3-(x+6)^3-(x+7)^3+(x+8)^3
=48

http://blue.kakiko.com/mmrmmr/htm/eqtn22.htmlより、OK!
(終り)


同様に、

問題
すべての整数(非負整数、自然数)nは、1から始まる2つ以上の連続する4乗数の和と差で表すことができる。
すなわち、2以上の整数kが存在して、
 式 n=±1^4±2^4±3^4±4^4±5^4± … ±k^4
で表される。
答え
 個数が半分で、1次式になるものを見つけて、
 残り半分は、+,-の記号を反転したものを加える。
で、恒等式を見つけると、
+(x+1)^4 -(x+2)^4 -(x+3)^4 +(x+4)^4 -(x+5)^4 +(x+6)^4 +(x+7)^4 -(x+8)^4
-(x+9)^4+(x+10)^4+(x+11)^4-(x+12)^4+(x+13)^4-(x+14)^4-(x+15)^4+(x+16)^4
=1536

http://blue.kakiko.com/mmrmmr/htm/eqtn23.htmlより、無理なのか!?


1,4,48,1536,…
参考サイト http://oeis.org/A011266



最適解のひとつを求めるプログラム

OPTION ARITHMETIC RATIONAL !多桁整数

LET M=3 !べき乗
LET X=48 !0からXまで

DIM F(0 TO X) !出現回数
MAT F=ZER
FOR P=2 TO 2^32-1 !組み合わせ(ビットパターン)
   LET R=0 !最上位の1の位置
   LET w=P

   LET A=0 !n=±1^m±2^m±3^m± … ±k^m
   LET B=0
   LET K=1 !10進法から2進法へ
   DO WHILE w>0
      LET s=MOD(w,2)
      IF s=1 THEN LET R=K
      LET A=A+(2*s-1)*K^M !0,1 → -1,1
      LET B=B+(1-2*s)*K^M !0,1 → 1,-1
      LET w=INT(w/2) !次の桁へ
      LET K=K+1
   LOOP
   IF (A>=0 AND A<=X) THEN CALL PrintOut(A,P,1) !範囲内なら結果を表示する
   IF (B>=0 AND B<=X) THEN CALL PrintOut(B,P,-1)

   IF P=2^R-1 THEN !2のべき乗でひと区切りする
      FOR i=0 TO X !すべてが見つかったなら
         IF F(i)=0 THEN EXIT FOR
      NEXT i
      IF i>X THEN EXIT FOR !終了!!!
   END IF
NEXT P
PRINT P; 2^R !debug
MAT PRINT F; !debug

SUB PrintOut(N,P,S) !式 n=±1^m±2^m±3^m± … ±k^m を表示する
   LET F(N)=F(N)+1 !出現回数

   IF F(N)=1 THEN !最初なら、式を表示する
      PRINT STR$(N);"=";

      LET w=P !ビットパターン
      LET K=1
      DO WHILE w>0 !10進法から2進法へ
         IF MOD(w,2)=0 THEN !±
            IF S=1 THEN PRINT "-"; ELSE PRINT "+";
         ELSE
            IF S=1 THEN PRINT "+"; ELSE PRINT "-";
         END IF
         PRINT STR$(K); !k^m
         IF M>1 THEN PRINT "^";STR$(M);

         LET w=INT(w/2) !次の桁へ
         LET K=K+1
      LOOP
      PRINT
   END IF
END SUB

END

 

Re: 将棋パズルの最少手数解は?

 投稿者:山中和義  投稿日:2013年 6月24日(月)09時30分28秒
  > No.3076[元記事へ]

GAIさんへのお返事です。

> http://www.lcv.ne.jp/~hhase/memo/m03_02a.html
> のページに将棋盤のパズル:飛角の入れ替え
> という2月15日(土)の記事があります。
> 以前このパズルに挑戦したとき、99手かかる手数を見つけてこれが最少手数であろうと
> 確信していたのですが、ここにこれを51手で達成できると記載されていて衝撃を受けています。
> その手順をどうしても知りたくて調査願えませんでしょうか?

現状、51手は見つかっていません。
8パズル、16パズルと同等な計算時間が必要で、制限(枝刈り)なしでは深さが51は手も足もでません。

(貧欲法、欲張り法)
角が左に移動する最適解を求めて、飛車が右に移動する最適解を求めると、

59 手
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: 角飛銀金金銀玉
  × 銀金銀金×

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: 角銀金 金銀飛
  ×銀金玉金銀×

 

Re: 将棋パズルの最少手数解は?

 投稿者:山中和義  投稿日:2013年 6月25日(火)11時22分9秒
  > No.3080[元記事へ]

GAIさんへのお返事です。

(貧欲法、欲張り法)
55手

飛車を右へ(最適解は22手)  25 手

  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: 金銀金金金 飛
   ×銀玉銀銀角×


角を左へ  30 手

  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: 角銀金 金銀飛
   ×銀金玉金銀×

 

Re: 将棋パズルの最少手数解は?

 投稿者:GAI  投稿日:2013年 6月25日(火)13時45分44秒
  > No.3081[元記事へ]

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

> 55手
>
試行錯誤での挑戦ですか?
私も将棋の駒を動かしながらやっていますが、なかなか手数が縮まらなくて苦戦しています。
51手まであと-4手ですね。
 

Re: 将棋パズルの最少手数解は?

 投稿者:山中和義  投稿日:2013年 6月26日(水)06時55分48秒
  > No.3082[元記事へ]

GAIさんへのお返事です。

> 試行錯誤での挑戦ですか?

次の流れになるもので検索すると、プログラムで2分程度で見つかりました。

飛車を右へ
  0: 飛銀金 金銀角
   ×銀金玉金銀×

  ↓

 xx: 金銀○○○ 飛
   ×銀○○銀角×

角を左へ

  ↓

 39: 金銀角金金銀飛
   ×銀 玉金銀×
 39: 金銀角玉金銀飛
   ×銀 金金銀×

  ↓ 12手

 51: 角銀金 金銀飛
   ×銀金玉金銀×


52 手
飛車を右へ

  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: 金銀金 角銀飛
   ×銀玉金銀金×
 32: 金銀金金角銀飛
   ×銀玉 銀金×
 33: 金銀金金 銀飛
   ×銀玉角銀金×
 34: 金銀金金銀銀飛
   ×銀玉角 金×
 35: 金銀金金銀銀飛
   ×銀玉角金 ×
 36: 金銀金金 銀飛
   ×銀玉角金銀×
 37: 金銀金 金銀飛
   ×銀玉角金銀×
 38: 金銀 金金銀飛
   ×銀玉角金銀×
 39: 金銀角金金銀飛
   ×銀玉 金銀×
 40: 金銀角金金銀飛 ←←←
   ×銀 玉金銀×
 41: 金 角金金銀飛
   ×銀銀玉金銀×
 42: 金銀角金金銀飛
   × 銀玉金銀×
 43: 金銀 金金銀飛
   ×角銀玉金銀×
 44: 金銀銀金金銀飛
   ×角 玉金銀×
 45: 金 銀金金銀飛
   ×角銀玉金銀×
 46:  金銀金金銀飛
   ×角銀玉金銀×
 47: 角金銀金金銀飛
   × 銀玉金銀×
 48: 角 銀金金銀飛
   ×金銀玉金銀×
 49: 角銀銀金金銀飛
   ×金 玉金銀×
 50: 角銀銀金金銀飛
   × 金玉金銀×
 51: 角銀 金金銀飛 ←←←
   ×銀金玉金銀×
 52: 角銀金 金銀飛
   ×銀金玉金銀×


あと1手!!!
 

Re: 将棋パズルの最少手数解は?

 投稿者:GAI  投稿日:2013年 6月27日(木)06時50分49秒
  > No.3083[元記事へ]

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

>
> あと1手!!!
>

この手数を更に減らすことは不可能だと思います。
何度挑戦しても、この作戦以外駒を動かす有効な効率のいい手は有り得ません。
ここは、出題者が最終局面を51手にて達成できたと勘違いして解釈したとしか思えません。
手の数と局面を混同して判断した。
ただ角から移動することは一度も検討してはいないが・・・
 

Re: 将棋パズルの最少手数解は?

 投稿者:山中和義  投稿日:2013年 6月27日(木)10時08分54秒
  > No.3084[元記事へ]

GAIさんへのお返事です。

> この手数を更に減らすことは不可能だと思います。

いろいろやってみました。確かに52手が最少です。


> ただ角から移動することは一度も検討してはいないが・・・

同様な流れ(決り手)になるもので検索すると、5分程度で見つかりました。

角を左へ
  0: 飛銀金 金銀角
   ×銀金玉金銀×

  ↓

 xx: 角飛銀金玉銀金
   × 銀金銀金×

飛車を右へ

  ↓

 40: 角銀金金飛銀金
   ×銀金玉 銀×
 40: 角銀金玉飛銀金
   ×銀金金 銀×

  ↓ 11手

 51: 角銀金 金銀飛
   ×銀金玉金銀×


51 手
角を左へ

  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: 角銀飛金玉銀金
   ×銀金 銀金×
 32: 角銀飛 玉銀金
   ×銀金金銀金×
 33: 角銀 飛玉銀金
   ×銀金金銀金×
 34: 角銀金飛玉銀金
   ×銀金 銀金×
 35: 角銀金飛 銀金
   ×銀金玉銀金×
 36: 角銀金飛銀銀金
   ×銀金玉 金×
 37: 角銀金飛銀銀金
   ×銀金玉金 ×
 38: 角銀金飛 銀金
   ×銀金玉金銀×
 39: 角銀金 飛銀金
   ×銀金玉金銀×
 40: 角銀金金飛銀金 ←←←
   ×銀金玉 銀×
 41: 角銀金金飛 金
   ×銀金玉銀銀×
 42: 角銀金金飛金
   ×銀金玉銀銀×
 43: 角銀金金飛金銀
   ×銀金玉銀 ×
 44: 角銀金金飛 銀
   ×銀金玉銀金×
 45: 角銀金金 飛銀
   ×銀金玉銀金×
 46: 角銀金金金飛銀
   ×銀金玉銀 ×
 47: 角銀金金金飛
   ×銀金玉銀銀×
 48: 角銀金金金 飛
   ×銀金玉銀銀×
 49: 角銀金金金銀飛
   ×銀金玉 銀×
 50: 角銀金金 銀飛
   ×銀金玉金銀×
 51: 角銀金 金銀飛
   ×銀金玉金銀×


上記の流れを見つける専用(枝刈りの部分)のプログラムです。
前出の飛車を移動させて、その後角を移動させる場合も同じようなものになります。

!パズル - 将棋駒の入れ替え

!7×2 飛車と角を入れ替える
! 飛銀金 金銀角 → 角銀金 金銀飛
! ×銀金玉金銀×   ×銀金玉金銀×
!答え 51手

LET t0=TIME

PUBLIC NUMERIC xSIZE,ySIZE !盤の大きさ
LET xSIZE=7
LET ySIZE=2

DECLARE STRING INIT$ !初期の状態
LET INIT$="飛銀金 金銀角×銀金玉金銀×"

PUBLIC STRING GOAL$ !完成の状態
LET GOAL$="角銀金 金銀飛×銀金玉金銀×"

PUBLIC NUMERIC LIM !手数の上限 →最少手数
LET LIM=52

!---------- ↓↓↓↓↓ ---------- 盤面の正当性を確認する
IF LEN(INIT$)<>ySIZE*xSIZE THEN
   PRINT "盤の大きさ(xSIZE,ySIZE)と駒の数(INIT$)が合いません。"
   STOP
END IF
IF LEN(GOAL$)<>ySIZE*xSIZE THEN
   PRINT "盤の大きさ(xSIZE,ySIZE)と駒の数(GOAL$)が合いません。"
   STOP
END IF

FOR p=1 TO ySIZE*xSIZE !盤を走査して空白を見つける
   IF INIT$(p:p)=" " THEN EXIT FOR
NEXT p
IF p>ySIZE*xSIZE THEN
   PRINT "空白がありません。"
   STOP
END IF
!---------- ↑↑↑↑↑ ----------

PUBLIC STRING KO$(5) !駒の種類と移動可能範囲 ※8近傍 動きは将棋と同じ
!DATA "×○××歩××××"
DATA "○○○×銀×○×○"
DATA "○○○○金○×○×"
DATA "○○○○玉○○○○"
DATA "×○×○飛○×○×"
DATA "○×○×角×○×○"
FOR i=1 TO UBOUND(KO$)
   READ KO$(i)
NEXT i

PUBLIC STRING STK$(0 TO 200) !局面の記録 ※スタック
FOR i=0 TO 200
   LET STK$(i)=""
NEXT i

PUBLIC NUMERIC C !解の個数
LET C=0
LET STK$(0)=INIT$
CALL backtrack(1,p) !1手目
IF C=0 THEN PRINT "解なし"

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

END


EXTERNAL SUB backtrack(L,p) !1手ずつ打っていき、行き詰まれば元に戻ってやり直す
LET bd$=stk$(L-1) !現在の局面

!---------- ↓↓↓↓↓ ---------- 枝刈り
IF L<=30 THEN !飛車の移動
   FOR i=1 TO ySIZE*xSIZE !誘導
      IF bd$(i:i)="角" THEN EXIT FOR
   NEXT i
   IF L>15 AND (i=13 OR i=7) THEN EXIT SUB
   IF L>20 AND (i=5 OR i=13 OR i=7) THEN EXIT SUB
   IF L>24 AND NOT(i=1 OR i=9 OR i=3 OR i=11) THEN EXIT SUB
   IF L>27 AND NOT(i=1 OR i=9) THEN EXIT SUB

   IF bd$(9:9)="角" AND bd$(1:1)="銀" THEN EXIT SUB !禁じ手

   IF bd$(1:1)="角" THEN !決り手
      PRINT L
      IF NOT(bd$(6:7)="銀金" AND bd$(13:13)="金") THEN EXIT SUB !決り手
   END IF
ELSE !角の移動
   IF NOT(bd$(1:1)="角") THEN EXIT SUB

   FOR i=1 TO ySIZE*xSIZE !誘導
      IF bd$(i:i)="飛" THEN EXIT FOR
   NEXT i
   IF L>35 AND (i=1 OR i=2 OR i=9 OR i=3 OR i=10) THEN EXIT SUB

   IF L>40 AND NOT(bd$(2:3)="銀金" AND bd$(9:10)="銀金") THEN EXIT SUB !決り手

   IF bd$(6:6)="飛" AND bd$(7:7)="金" THEN EXIT SUB !禁じ手
END IF
!---------- ↑↑↑↑↑ ----------

LET px=MOD(p-1,xSIZE)+1 !水平・垂直の座標へ
LET py=INT((p-1)/xSIZE)+1

FOR d=1 TO 9 !隣接する駒を探す
   IF d=5 THEN
   ELSE
      LET mx=px + MOD(d-1,3)-1 !移動元の座標 ※dを水平・垂直の差分dx,dyへ
      LET my=py + INT((d-1)/3)-1
      IF (mx>=1 AND mx<=xSIZE) AND (my>=1 AND my<=ySIZE) THEN !盤内か確認する

         LET mp=(my-1)*xSIZE + mx !連番へ
         LET t$=bd$(mp:mp)
         IF t$="×" OR t$=" " THEN
         ELSE

            FOR a=1 TO UBOUND(KO$) !駒の属性を得る
               IF t$=KO$(a)(5:5) THEN EXIT FOR
            NEXT a
            IF KO$(a)(10-d:10-d)="×" THEN !移動可能範囲なら
            ELSE

               LET w$=bd$
               LET w$(p:p)=t$ !移動させる
               LET w$(mp:mp)=" "

               IF w$=GOAL$ THEN !完成なら、手順を記録しておく
                  LET C=C+1
                  PRINT L;"手"
                  FOR i=0 TO L-1
                     PRINT STR$(i);": ";STK$(i)
                  NEXT i
                  PRINT STR$(L);": ";w$

                  LET LIM=L !上限を狭める
               ELSE
                  FOR t=L TO 0 STEP -1 !最近の局面から順に新しい手かどうか確認する
                     IF STK$(t)=w$ THEN EXIT FOR
                  NEXT t
                  IF t<0 THEN
                     LET STK$(L)=w$ !記録して、次の局面へ
                     IF L<LIM THEN CALL backtrack(L+1,mp) !上限まで
                  END IF
               END IF

            END IF

         END IF

      END IF
   END IF
NEXT d
END SUB

 

Re: 将棋パズルの最少手数解は?

 投稿者:GAI  投稿日:2013年 6月28日(金)08時38分33秒
  > No.3085[元記事へ]

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

やはり正解は51手が可能なんですね。
(飛車から移動しようとすると52手が最少にしかならない!)
この初期画面から100人に挑戦させたとすると、70~80パーセントの人は
直線的に動く飛車から移動させようとするのではと思われます。
また右から左方向より、左から右方向が人間にとって自然な移動方向と感じる習慣があるのではないかと思われます。(このことも狙ってあえて初期画面を飛車と角行の位置を入れ替えたものからスタートさせるものに設定しているとも訝れるところです。)
いずれにしても、このパズルは思いのほか奥が深いものになっている。
この正解を入手するには、やはりコンピュータによる検索がかかせません。
この検索を可能とするプログラムが考えられることも私にとっては驚きです。
本来の将棋の力は上達しませんでしたが、大ゴマを取られないように逃げ回る技術は向上したと思われます。
 

正方形による分割

 投稿者:山中和義  投稿日:2013年 6月29日(土)13時32分59秒
  問題
1辺の長さが1の正方形を、8個の小正方形に分割したい。
小正方形の大きさは、それぞれ異なってもよい。どのように分割すればいいだろうか?

答え
┌┬┬┬┐    ┌─┬┬─┐
├┴┴┼┤    │ ├┤ │
│  ├┤    ├─┴┼┬┤
│  ├┤    │  ├┴┤
└──┴┘1通り  │  │ │
         └──┴─┘変形を含めて5通り
(終り)

参考サイト
 私的数学塾 http://www004.upp.so-net.ne.jp/s_honma/index.htm 内
  クイズ&パズル
   分割パズル http://www004.upp.so-net.ne.jp/s_honma/relax/distribution.htm

 正方形の分割 http://www.geocities.co.jp/Berkeley-Labo/6317/seihoukei.htm

考察
1個の正方形にいくつかの正方形を加えて、(ひと回り大きな)正方形にするには、、
一般に、
 ┌┬┬┐ (n+1)^2=1*n^2+(2n+1)*1^2 個数は2(n+1)個
 ├┴┼┤ n=1,2,3,4,…として、個数は4,6,8,10,…
 │ ├┤
 └─┴┘
   n 1
となる。
また、1個の正方形をいくつかの正方形に分割するには、最少個数は、
 ┌┬┐
 ├┼┤
 └┴┘
のように、4個なので、増減は4-1=+3個となる。
これより、3の剰余を考えて、4,6,8は分割可能より、
   3k: 0 3  ⑥ 9  …
3k+1: 1 ④ 7  10 …
3k+2: 2 5  ⑧ 11 …
なので、
4と6以上では、少なくともひと通りは分割することができる。
(終り)


2,3,5個での分割が存在しないことを考察(代数的解釈)してみる。

その1

考察
小正方形の数が2個の場合
最小の小正方形の大きさを1として考える。
Aは2以上の整数、Nは正の整数とする。
自然数2の分割に着目して、次の方程式、不定方程式を得る。
(1) 2*1^2=N^2 ∴N=±√2 不適である。
(2) 1*1^2+1*A^2=N^2 ∴N^2-A^2=1 ∴(A,N)=(±1,±0)なので、不適である。

同様に、
小正方形の数が3個の場合
(1) 3*1^2=N^2 ∴N=±√3 不適である。
(2) 2*1^2+1*A^2=N^2
 ∴(N+A)(N-A)=2 ∴(N+A,N-A)=(±1,±2)、(±2,±1) 複号同順
 ∴(N,A)=(±3/2,干1/2)、(±3/2,±1/2)
 整数解ではないので、不適である。
(3) 1*1^2+2*A^2=N^2 ∴N^2-2*A^2=1 ∴(N,A)=(±1,0)、(±3,±2)、(±17,±12)、…
 3と2、17と12、…との関係は、不適である。
(4) 1*1^2+1*A^2+1*B^2=N^2 ∴(N,A,B)=(±9,±4,±8)
 9と8との関係は、不適である。

小正方形の数が4個の場合
(1) 4*1^2=N^2
(2) 3*1^2+1*A^2=N^2
(3) 1*1^2+3*A^2=N^2
(4) 2*1^2+2*A^2=N^2
(5) 2*1^2+1*A^2+1*B^2=N^2
(6) 1*1^2+2*A^2+1*B^2=N^2
(7) 1*1^2+1*A^2+2*B^2=N^2
(8) 1*1^2+1*A^2+1*B^2+1*C^2=N^2

小正方形の数が5個の場合
 :

(終り)


!正の整数m,nは、m≧nとする。
!m*n=Σ[k=1,n]a[k]*k^2、係数a[k]は非負整数

!a[k]は、大きさk×kの小正方形の個数

DIM A(100)
FOR M=1 TO 10
   FOR N=M TO M !n×n
   !!FOR N=1 TO M
      PRINT "m*n="; M;N
      CALL try(1,M,N,M*N,A)
      PRINT
   NEXT N
NEXT M
END

EXTERNAL SUB try(K,M,N,R,A()) !バックトラック法で検索する
FOR i=0 TO INT(R/K^2) !k^2の候補
   LET A(K)=i !a[k]*k^2
   LET W=R-i*K^2
   IF W=0 THEN !残りがない場合
      IF A(1)>0 THEN !※最小正方形(1^2)を含むもの
         LET S=0 !結果を表示する
         FOR J=1 TO K
            LET S=S+A(J)
            IF A(J)>0 THEN PRINT "+";STR$(A(J));"*";STR$(J);"^2"; !※係数0は除く
            !!PRINT "+";STR$(A(J));"*";STR$(J);"^2";
         NEXT J
         PRINT " (";STR$(S);")"
      END IF
   ELSE
      IF K<=N THEN CALL try(K+1,M,N,W,A) !次へ
   END IF
NEXT i
END SUB



その2

 電子回路の電圧と正方形分割の関係
  http://6317.teacup.com/basic/bbs/1338

 合成抵抗の問題
  抵抗値が1Ωの抵抗がたくさんある。
  この抵抗をいくつか使って、抵抗値が有理数A/BΩになるものをつくれ。

  参考サイト http://www.junko-k.com/collo/collo266.htm

  http://6317.teacup.com/basic/bbs/3025
  http://6317.teacup.com/basic/bbs/3027
  http://6317.teacup.com/basic/bbs/3028

  http://6317.teacup.com/basic/bbs/3029
   http://6317.teacup.com/basic/bbs/3030


合成抵抗値が有理数A/BΩになるものは、A×Bの大きさの長方形を分割することを意味する。
元が正方形の場合は、1/1=1Ωになる配線が答えになる。


2個のときは、
・直列・並列型
 2型
 ─R─R─

 1+1型
 ┬R┬ ※上記の逆数が現れる
 └R┘
の2通り。具体的な値は、2, 1/2
よって、存在しない。
実際の分割は、
 □□ B
  └A┘

 □
 □
となる。

3個のときは、
・直列・並列型
 3型
 ─R─R─R─   □□□

 2+1型
 ┬R┬R─   □■■
 └R┘     □■■ ※■の固まりはひとつの正方形(2×2)とみなす。

 ┬R─R┬ ※これ以降は上記の逆数が現れる
 └  R┘

 1+1+1型
 ┬R┬
 ├R┤
 └R┘
の4通り。具体的な値は、3, 3/2, 2/3, 1/3
よって、存在しない。

4個のときは、
・直列・並列型
 4型
 ─R─R─R─R─

 3+1型
 ┬R┬R─R─
 └R┘

 ┬R─R┬R─
 └   R┘

 ┬R─R─R┬
 └      R┘

 2+2型
 ┬R─R┬
 └R─R┘

 ┬R┬R┬ ※これ以降は上記の逆数が現れる
 └R┴R┘

 2+1+1型
 ┬R┬R─
 ├R┤
 └R┘

 ┬R┬R┬
 ├R┘ │
 └   R┘

 ┬R─R┬
 ├   R┤
 └   R┘

 1+1+1+1型
 ┬R┬
 ├R┤
 ├R┤
 └R┘
の10通り。
具体的な値は、4, 5/2, 5/3, 3/4, 1, 1, 4/3, 3/5, 2/5, 1/4
よって、2通りだが対称なものなので、1通り。

5個のときは、
・直列・並列型
 5型
 ─R─R─R─R─R─

 4+1型
 ┬R┬R─R─R─
 └R┘

 ┬R─R┬R─R─
 └  R┘

 ┬R─R─R┬R─
 └    R┘

 ┬R─R─R─R┬
 └      R┘

 3+2型
 ┬R┳R┬R─ ×2
 └R┻R┘

 ┬R─R┳R┬ ×2
 └  R┻R┘

 3+1+1型
 ┬R┬R─R─
 ├R┤
 └R┘

 ┬R┬R┬R─
 ├R┘ │
 └  R┘

 ┬R┬R─R┬
 ├R┘  │
 └    R┘

 ┬R─R┬R─ ※これ以降は上記の逆数が現れる
 ├  R┤
 └  R┘

 ┬R─R┬R┬
 ├  R┘ │
 └    R┘

 ┬R─R─R┬
 ├    R┤
 └    R┘

 2+2+1型
 ┬R┳R┬ ×2
 ├R╋R┘
 └R┘

 ┬R┳R┬ ×2
 ├R┻R┤
 └  R┘

 2+1+1+1型
 ┬R┬R─
 ├R┤
 ├R┤
 └R┘

 ┬R┬R┬
 ├R┤ │
 ├R┘ │
 └  R┘

 ┬R┬R┬
 ├R┘ │
 ├  R┤
 └  R┘

 ┬R─R┬
 ├  R┤
 ├  R┤
 └  R┘

 1+1+1+1+!型
 ┬R┬
 ├R┤
 ├R┤
 ├R┤
 └R┘
の24通り。
具体的な値は、
 5, 7/2, 8/3, 7/4, 4/5, 2, 2, 6/5, 7/6, 7/3, 8/5, 5/7,
 7/5, 5/8, 3/7, 6/7, 5/6, 1/2, 1/2, 5/4, 4/7, 3/8, 2/7, 1/5
よって、存在しない。

・ブリッジ型
 ┬R┬R┬
 │ R │
 └R┴R┘
の1通り。具体的な値は、1
実際の分割は、
 ┌──┬─┐
 │  │ │
 ├─┬┤ │
 │ ├┴─┤
 │ │  │
 └─┴──┘
となる。
平衡状態なので、中央の抵抗が無視されるので、
 ┬R─R┬
 └R─R┘
と同等となるので、不適となる。


1,2,3,4,5,6,…個で 1,2,4,10,24,66,…通り  参考サイト http://oeis.org/A000084
 

合成抵抗の図形的解釈(面積図、直線の傾き、積み木)

 投稿者:山中和義  投稿日:2013年 7月 1日(月)20時45分43秒
  > No.3087[元記事へ]

・直列
1Ωと2Ωの抵抗を直列につないだときの合成抵抗は、計算式では1+2=3Ωである。

オームの法則R=E/Iより、X軸方向を電流、Y軸方向を電圧と考えると、
1Ωは、直線y=xから、傾き1/1と読み取れる。
また、長方形(または正方形)で考えると、右斜めの対角線となる。

 ┌┐
 ││ 2[V]
 ├┤
 └┘ 1[V]
 1[A]
と長方形(または正方形)になるように大きさを調整して、縦に並べる。
また、図から
 電圧は、比1:2 V=V1+V2
 電流は、等しく流れる。
が読み取れる。


・並列
1Ωと2Ωの抵抗を並列につないだときの合成抵抗は、1/(1/1+1/2)=2/3Ωである。

1Ωは、y=(2/2)x
2Ωは、y=(2/1)x
 ┌─┬┐
 │ ││ 2[V]
 └─┴┘
 2[A]+1[A]=3[A]
と横に並べる。
また、図から
 電圧は、等しく
 電流は、比1/1:1/2=2:1で流れる。 I=I1+I2
が読み取れる。


練習問題
   ┌┴┐
   │ R1 1Ω
 2Ω R3 │
   │ R2 3Ω
   └┬┘
答え
 ┌─┬┐ 1[V]
 │ ├┤
 │ ││ 3[V]
 │ ││
 └─┴┘
 2[A]+1[A]=3[A]
なので、縦4横3の長方形の対角線の傾きから、4/3Ω
(終り)


・ブリッジ回路
    │
   /\
  1Ω  3Ω
  /   \
 ──1Ω──
  \   /
  3Ω  1Ω
   \/
    │
答え
 ┌─┬┐
 │ ││
 ├┬┤│ 3[V]
 │├┴┤
 ││ │ 2[V]
 └┴─┘
 1[A]+2[A]
なので、縦5横3の長方形の対角線の傾きから、5/3Ω
(終り)
 

フェルマーからメルセンヌへの問い

 投稿者:GAI  投稿日:2013年 7月 3日(水)06時29分38秒
  直角三角形で斜辺の長さが平方数、また直角を挟む2辺の和も平方数
であるような直角三角形は存在しますか?
もし存在すれば、最小のものはどんな長さになっているか?

これってプログラム的に見つかりますか?
手紙を送ったのが1643年らしいのでもちろんコンピュータはありませんが・・・
 

Re: フェルマーからメルセンヌへの問い

 投稿者:山中和義  投稿日:2013年 7月 3日(水)14時46分30秒
  > No.3090[元記事へ]

GAIさんへのお返事です。

> 直角三角形で斜辺の長さが平方数、また直角を挟む2辺の和も平方数
> であるような直角三角形は存在しますか?
> もし存在すれば、最小のものはどんな長さになっているか?
>
> これってプログラム的に見つかりますか?

考察
直角三角形の直角を挟む2辺の長さをa,b、斜辺の長さをcとする。
題意より、
a^2+b^2=c^2なので、a,b,cはピタゴラス数である。
よって、a=m^2-n^2、b=2mn、c=m^2+n^2と表される。
3番目の式c=m^2+n^2=C^2なので、m,n,Cはピタゴラス数である。
よって、m=x^2-y^2、n=2xy、C=x^2+y^2と表される。
これより、組(x,y)→組(m,n,C)→組(a,b,c)を求めて、a+bが平方数なら、題意を満たす。
(終り)


OPTION ARITHMETIC RATIONAL !多桁整数

FOR x=2 TO 2000 !0<y<x
   FOR y=1+MOD(x,2) TO x-1 STEP 2
      IF GCD(x,y)=1 THEN !x-yが奇数、xとyは互いに素

         LET m=x^2-y^2
         LET n=2*x*y
         IF n>m THEN SWAP m,n !0<n<m
         IF MOD(m-n,2)=1 AND GCD(m,n)=1 THEN !奇数、互いに素

            LET a=m^2-n^2
            LET b=2*m*n

            LET w=a+b
            LET t=INTSQR(w) !a+bは平方数
            IF t*t=w THEN

               LET c=m^2+n^2
               PRINT x;y; m;n !debug
               PRINT a;b;c
               PRINT t; x^2+y^2 !√(a+b), c=C^2

            END IF

         END IF

      END IF
   NEXT y
NEXT x

END



x=1469  y=84    m=2150905  n=246792
a=4565486027761  b=1061652293520  c=4687298610289
a+b=2372159^2  c=2165017^2

 

回路に流れる電流の大きさは?

 投稿者:GAI  投稿日:2013年 7月10日(水)12時55分43秒
        ---- A----
     |          |
     |      ---------
     |     |    |    |
     |     E----C----B---------
     |     |    |              |
     |     |     --------------|
    112(V) |              |    |
     |     |--------------|    |
     |     |    |    |    |    |
     |     J----I----G----F----D
     |     |    |         |    |
      ---- K--------------H----

上記の回路図で

A-B
A-C
A-E
B-C
C-E
B-D
C-D
C-F
E-F
E-G
E-I
E-J
D-F
F-G
G-I
I-J
D-H
F-H
J-K
I-K
H-K

間に各1(Ω)の抵抗が配置されており、A,K間に112(V)の電圧がかかったとき、上記のそれぞれの2点間に流れる電流の大きさが知りたいのですが・・・
 

Re: 回路に流れる電流の大きさは?

 投稿者:山中和義  投稿日:2013年 7月10日(水)22時53分38秒
  > No.3092[元記事へ]

GAIさんへのお返事です。

> A-B
> A-C
> A-E
> B-C
> C-E
> B-D
> C-D
> C-F
> E-F
> E-G
> E-I
> E-J
> D-F
> F-G
> G-I
> I-J
> D-H
> F-H
> J-K
> I-K
> H-K

下図のことですか?
 ルジンの問題
 http://ja.wikipedia.org/wiki/%E3%83%AB%E3%82%B8%E3%83%B3%E3%81%AE%E5%95%8F%E9%A1%8C



赤字の数字を節点番号として、
・□を1[Ω]の抵抗として結線する。
・節点1と節点11の間に、112[V]をかける。
の電気回路を考えると、
各節点の電位は、
 節点1: 112 [V]
 節点2: 85 [V]
 節点3: 77 [V]
 節点4: 66 [V]
 節点5: 62 [V]
 節点6: 60 [V]
 節点7: 53 [V]
 節点8: 42 [V]
 節点9: 37 [V]
 節点10: 33 [V]
 節点11: 0 [V]
となるので、各抵抗に黒字の数字の電流が流れます。

参考サイト http://www-lab15.kuee.kyoto-u.ac.jp/~t-naka/resistor/resistor3.html


補足 算出方法
節点1~11、電圧源の順に、節点電位法で、連立方程式Ax=bを立てる。
A=
  3 -1 -1  0 -1  0  0  0  0  0  0  1
 -1  3 -1 -1  0  0  0  0  0  0  0  0
 -1 -1  5 -1 -1 -1  0  0  0  0  0  0
  0 -1 -1  4  0 -1  0 -1  0  0  0  0
 -1  0 -1  0  6 -1 -1  0 -1 -1  0  0
  0  0 -1 -1 -1  5 -1 -1  0  0  0  0
  0  0  0  0 -1 -1  3  0 -1  0  0  0
  0  0  0 -1  0 -1  0  3  0  0 -1  0
  0  0  0  0 -1  0 -1  0  4 -1 -1  0
  0  0  0  0 -1  0  0  0 -1  3 -1  0
  0  0  0  0  0  0  0 -1 -1 -1  0 -1
  1  0  0  0  0  0  0  0  0  0 -1  0
b=
  0  0  0  0  0  0  0  0  0  0  0  112

連立方程式を解いて、
x= 112  85  77  66  62  60  53  42  37  33  0 -112

 

Re: 回路に流れる電流の大きさは?

 投稿者:GAI  投稿日:2013年 7月12日(金)17時13分21秒
  > No.3093[元記事へ]

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


> 補足 算出方法
> 節点1~11、電圧源の順に、節点電位法で、連立方程式Ax=bを立てる。
> A=
>   3 -1 -1  0 -1  0  0  0  0  0  0  1
>  -1  3 -1 -1  0  0  0  0  0  0  0  0
>  -1 -1  5 -1 -1 -1  0  0  0  0  0  0
>   0 -1 -1  4  0 -1  0 -1  0  0  0  0
>  -1  0 -1  0  6 -1 -1  0 -1 -1  0  0
>   0  0 -1 -1 -1  5 -1 -1  0  0  0  0
>   0  0  0  0 -1 -1  3  0 -1  0  0  0
>   0  0  0 -1  0 -1  0  3  0  0 -1  0
>   0  0  0  0 -1  0 -1  0  4 -1 -1  0
>   0  0  0  0 -1  0  0  0 -1  3 -1  0
>   0  0  0  0  0  0  0 -1 -1 -1  0 -1
>   1  0  0  0  0  0  0  0  0  0 -1  0
> b=
>   0  0  0  0  0  0  0  0  0  0  0  112
>
> 連立方程式を解いて、
> x= 112  85  77  66  62  60  53  42  37  33  0 -112
>

節点電位法について少し勉強してみたら
抵抗の行列を各接点について機械的に自己コンダクタンスの和と相互コンダクタンスの和(マイナスを機械的につける)を数値化することで、節点電位ベクトルと節点電流ベクトルとで行列に組み込み、
抵抗行列の逆行列を利用してまさに機械的に各節点の電流が求められるなんてすばらしい方法があるもんなんですね!
(最後の行での1 0 0 ・・・-1 0 が必要になる役割がいまいち理解できてないが・・・)
なんて電気は数学の法則どうりに自分をコントロールしながら動いているんだろう。
こんな方法を思いついている人は数学者なんですか、物理学者なんですか?
もし物理専門の人だったら、数学をいかに使ったら良いかを数学専門の人より遥かに理解していることになると思う。
やっぱり数学はどの様な利用価値があるかを見せつけられないとお友達には成り難い。
いろいろ勉強になります。
 

Re: 回路に流れる電流の大きさは?

 投稿者:山中和義  投稿日:2013年 7月12日(金)20時13分42秒
  > No.3094[元記事へ]

GAIさんへのお返事です。

> (最後の行での1 0 0 ・・・-1 0 が必要になる役割がいまいち理解できてないが・・・)

電圧源ですから、連立方程式Ax=bの意味は、
  ┌  │  ┐┌ ┐ ┌ ┐
  │G │±1││V │=│I │
 ───┼─────────
  │±1│-Zp││Ip│ │Ep│
  └  │  ┘└ ┘ └ ┘


電流源で考えると、すなわち、112[A]を流すと、
 連立方程式は
  ┌ ┐┌ ┐ ┌ ┐
  │G││V │=│I │
  └ ┘└ ┘ └ ┘

A=
  3 -1 -1  0 -1  0  0  0  0  0  0
 -1  3 -1 -1  0  0  0  0  0  0  0
 -1 -1  5 -1 -1 -1  0  0  0  0  0
  0 -1 -1  4  0 -1  0 -1  0  0  0
 -1  0 -1  0  6 -1 -1  0 -1 -1  0
  0  0 -1 -1 -1  5 -1 -1  0  0  0
  0  0  0  0 -1 -1  3  0 -1  0  0
  0  0  0 -1  0 -1  0  3  0  0 -1
  0  0  0  0 -1  0 -1  0  4 -1 -1
  0  0  0  0 -1  0  0  0 -1  3 -1
  0  0  0  0  0  0  0 -1 -1 -1  0
b=
  112  0  0  0  0  0  0  0  0  0 -112

x=
  112  85  77  66  62  60  53  42  37  33  0
となります。

 

分母の有理化

 投稿者:山中和義  投稿日:2013年 7月15日(月)07時15分53秒
  分母の有理化には、恒等式 a^2-b^2=(a+b)(a-b) を使う。
3項以内なら、何回か適用すれば求まるが、計算の手間も左右される。

簡略化されるパターン

a-b=kなら、1/(√a±√b)=(√a干√b)/k  例 1/(√2+√3)
(考察)
1/(√a±√b)
=(√a干√b)/{(√a±√b)(√a干√b)}
=(√a干√b)/(a-b)
=(√a干√b)/k
(終り)

参考
a^2+b^2=kなら、1/(a±bi)=(a干bi)/k
(考察)
1/(a±bi)
=(a干bi)/{(a±bi)(a干bi)}
=(a干bi)/(a^2+b^2)
=(a干bi)/k
(終り)


√a+√b+√(a+b)の型  例 1/(√2+√3+√5)
(考察)
{(√a+√b)+√(a+b)}{(√a+√b)-√(a+b)}
=(√a+√b)^2-{√(a+b)}^2
=2√(ab)
より、
1/{√a+√b+√(a+b)}=√(ab){√a+√b-√(a+b)}/(2ab)=(b√a+a√b-√{ab(a+b)})/(2ab)
(終り)


√a+√b+√c+√d、ab=cdの型  例 1/(1+√6+√2+√3)
(考察)
{(√a+√b)+(√c+√d)}{(√a+√b)-(√c+√d)}
=(√a+√b)^2-(√c+√d)^2
=a+b+2√(ab)-{c+d+2√(cd)}
=a+b-c-d
より、
1/(√a+√b+√c+√d)=(√a+√b-√c-√d)/(a+b-c-d)
(終り)


√a+√b+√c+√d、a+b=c+dの型  例 1/(√2+√5+2+√3)
(考察)
{(√a+√b)+(√c+√d)}{(√a+√b)-(√c+√d)}
=(√a+√b)^2-(√c+√d)^2
=a+b+2√(ab)-{c+d+2√(cd)}
=2{√(ab)-√(cd)}
より、
1/(√a+√b+√c+√d)
={√(ab)+√(cd)}(√a+√b-√c-√d)/{2(ab-cd)}
={a√b+b√a-√(abc)-√(abd) +√(acd)+√(bcd)-c√d-c√d}/{2(ab-cd)}
(終り)


一般的に、

1/(√5+√3)=(√5-√3)/{(√5+√3)(√5-√3)}=(√5-√3)/2
答え
(√3+√5)(A+B√3+C√5+D√15)=k(0以外の整数)と表されるなら、
1/(√3+√5)=(A+B√3+C√5+D√15)/kとなる。
(√3+√5)(A+B√3+C√5+D√15)
=(A√3+3B+C√15+3D√5) + (A√5+B√15+5C+5D√3)
=(3B+5C)+(A+5D)√3+(A+3D)√5+(B+C)√15
なので、連立方程式 3B+5C=k、A+5D=0、A+3D=0、B+C=0 を解く。
(終り)


OPTION ARITHMETIC RATIONAL !有理数モード

!LET N=2
!DATA 3,5 !√3+√5
!DATA 1,1 !係数部分

!LET N=3
!DATA 1,2,3 !1+√2+√3
!DATA 1,1,1 !係数部分

!LET N=3
!DATA 2,3,5 !-√2+√3+√5
!DATA -1,1,1 !係数部分

LET N=3
DATA 1,3,5 !2+√3+√5=2√1+√3+√5
DATA 2,1,1 !係数部分

!LET N=3
!DATA 9,5,7 !3-√5-√7
!DATA 1,-1,-1 !係数部分

!LET N=4
!DATA 1,6,2,3 !1+√6+√2+√3
!DATA 1,1,1,1 !係数部分

!LET N=4
!DATA 5,4,3,2 !√5+2+√3+√2=√5+√4+√3+√2
!DATA 1,1,1,1 !係数部分


DIM R(N),C(N) !√a、√b、√c、… のn個
MAT READ R
MAT READ C

DIM RR(2^N) !√a、√b、√c、√ab、√bc、√ca、√abc、…
MAT RR=ZER
LET S=0
FOR i=0 TO 2^N-1 !組合せ ※2進法N桁
   LET t=i

   LET w=1
   FOR J=1 TO N
      IF MOD(t,2)=1 THEN LET w=w*R(J)
      LET t=INT(t/2)
   NEXT J
   CALL SqNormalize(w, p,q) !√wをp√qと変形する

   FOR J=1 TO S !新しい値なら
      IF q=RR(J) THEN EXIT FOR
   NEXT J
   IF J>S THEN !登録する
      LET S=S+1
      LET RR(S)=q
   END IF

NEXT i
PRINT S !debug
MAT PRINT RR; !debug


!連立方程式Ax=bを立てる
! (√a+√b+√c)(A√1+B√a+C√b+D√c+E√ab+F√bc+G√ca+H√abc)
!=( A~Hの線形結合 )√1+( … )√a+( … )√b+( … )√c+( … )√ab+( … )√bc+( … )√ca+( … )√abc
!=k(整数)
!とする恒等式から、係数A~Hを求める。
DIM A(S,S),x(S),b(S)

MAT A=ZER
FOR i=1 TO N !左側の括弧
   FOR J=1 TO S !右側の括弧
      LET w=R(i)*RR(J) !展開する
      CALL SqNormalize(w, p,q) !√wをp√qと変形する

      FOR K=1 TO S !√qの位置を探す
         IF q=RR(K) THEN EXIT FOR
      NEXT K
      IF K>S THEN
         PRINT "論理エラー"; i;J; w; p;q
         STOP
      ELSE !見つかったなら
         LET A(K,J)=A(K,J)+C(i)*p
      END IF
   NEXT J
NEXT i
MAT PRINT A; !debug

MAT b=ZER
LET b(1)=1 !( … )√1の係数を1と仮定する

DIM iA(S,S) !連立方程式を解く
MAT iA=INV(A)
MAT x=iA*b
MAT PRINT x; !debug


!結果を表示する
LET G=1
FOR i=1 TO S
   IF x(i)<>0 THEN LET G=GCD(G,x(i))
NEXT i
PRINT G !分母

FOR i=1 TO S !√の項
   IF x(i)<>0 THEN PRINT x(i)/G; "√";STR$(RR(i))
NEXT i

END


EXTERNAL SUB SqNormalize(n, p,q) !平方根の中をできるだけ小さな正の整数に直す
!※n=p^2*q、n,p,q≧0とすると、√n=p*√qと変形できる。
OPTION ARITHMETIC RATIONAL !有理数モード
LET q=1 !※√0=0*√1とする ※n=0なら、1行下のFOR文でp=0は設定される
FOR p=INTSQR(n) TO 1 STEP -1 !約数p^2の候補を大きい方から
   LET q=n/p^2
   IF q=INT(q) THEN EXIT FOR !qは自然数より
NEXT p
END SUB


 

Re: 分母の有理化

 投稿者:山中和義  投稿日:2013年 7月16日(火)11時42分38秒
  > No.3096[元記事へ]

問題
1/(4^(1/3)+2^(1/3)-1) の分母を有理化して下さい。

前回の手法で解いてみると、

答え
x=2^(1/3)とおくと、x^3=2
与式=1/(x^2+x-1)=ax^2+bx+c、a,b,c∈Qの形に書ける。
∴(x^2+x-1)(ax^2+bx+c)=1
そこで、x^3=2に注意して左辺を展開すると、(-a+b+c)x^2+(2a-b+c)x+(2a+2b-c)=1
このとき、1,x,x^2はQ上1次独立だから、
 -a +b+c=0
 2a -b+c=0
 2a+2b-c=1
この連立方程式を解いて、(a,b,c)=(2/11,3/11,-1/11)
よって、1/(4^(1/3)+2^(1/3)-1)=(2*4^(1/3)+3*2^(1/3)-1)/11
(終り)

この解答でのポイントは、
 (x^2+x-1)(ax^2+bx+c)=1 となる2次式 ax^2+bx+c を求める
ということである。

この2次式を、別の方法(ユークリッドの互除法)で求めてみる。

まず、簡単なもので考察してみる。

問題
1/√2 の分母を有理化して下さい。
答え
x=√2とおくと、x^2=2
これより、1/x=x/2
(終り)

問題
1/(√2+1) の分母を有理化して下さい。
答え
x=√2とおくと、x^2-2=0
また、x^2-2=(x-1)(x+1)-1
これより、0=(x-1)(x+1)-1 ∴1/(x+1)=x-1
(終り)

整式の変形のポイントは、
g=x^2-2、f=x+1(1番目の問題ではxである)と考えると、g=Qf+R
これより、g=0なので、1/f=-Q/R
(終り)


一般的に、
整式f,gが互いに素のとき、af+bg=(f,g)となる整式a,bが存在する。
これより、g=0なので、1/f=a/(f,g)

以上より、解答は、

答え
x=2^(1/3)とおくと、x^3-2=0
x^3-2=(x^2+x-1)(x-1)+2x-3 ← 式1
x^2+x-1=(2x-3)(x/2+5/4)+11/4 ∴4(x^2+x-1)=(2x-3)(2x+5)+11 ← 式2
式1、式2より、2x-3 を消去して、
11=(2x^2+3x-1)(x^2+x-1)-(2x+5)(x^3-2)
∴与式=(2x^2+3x-1)/11
(終り)


!多項式に対する拡張ユークリッド互除法

!多項式f(x)=A[m]x^m+ … +A[1]x+A[0]、g(x)=B[n]x^n+ … +B[1]x+B[0]、m≧nとして、
!f(x)S(x)+g(x)T(x)=gcd(f(x),g(x))=C(x)となるS(x),T(x),C(x)を求める。

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

!DATA 3 !次数
!DATA -15,11,-5,1 !-15+11x-5x^2+x^3
!DATA 3 !次数
!DATA 5,3,-1,1 !5+3x-x^2+x^3

!DATA 4 !次数
!DATA 0,0,-9,-15,6 !6x^4-15x^3-9x^2=3x^2(x-3)(2x+1)
!DATA 3 !次数
!DATA 0,3,-4,1 !x^3-4x^2+3x=x(x-1)(x-3)

DATA 2 !次数
DATA -1,1,1 !f(x)=-1+x+x^2
DATA 3 !次数
DATA -2,0,0,1 !g(x)=-2+x^3

!DATA 0,17, 0,29 !12*17+(-7)*29=1

!DATA 2 !次数 1/(7+5*2^(1/3)+3*4^(1/3)) x=2^(1/3)とすると、7+5x+3x^2
!DATA 7,5,3
!DATA 3 !次数
!DATA -2,0,0,1 !g(x)=-2+x^3

!DATA 2 !次数 1/(5*3^(2/3)+2*3^(1/3)+1) x=2^(1/3)とすると、1+2x+5x^2
!DATA 1,2,5
!DATA 3 !次数
!DATA -3,0,0,1 !g(x)=-3+x^3

!DATA 2 !次数 1/(1+64^(1/5)-4^(1/5)) x=2^(1/5)とすると、1+2x-x^2
!DATA 1,2,-1
!DATA 5 !次数
!DATA -2,0,0,0,0,1 !g(x)=-2+x^5


READ M !次数
DIM A(0 TO M) !係数
MAT READ A

READ N !次数
DIM B(0 TO N) !係数
MAT READ B

DIM S(0 TO MAX_DEGREE),T(0 TO MAX_DEGREE),C(0 TO MAX_DEGREE)
CALL PolynomialExtendedGCD(M,A,N,B, ss,S,tt,T,cc,C) !拡張ユークリッド互除法

LET G=C(0) !既約
FOR i=1 TO cc
   LET G=GCD(G,C(i))
NEXT i
LET G=G*SGN(C(cc)) !C(x)の最高次数の係数は正
MAT S=(1/G)*S
MAT T=(1/G)*T
MAT C=(1/G)*C


CALL PolynomialDisplay(ss,S) !結果を表示する
PRINT
CALL PolynomialDisplay(tt,T)
PRINT
CALL PolynomialDisplay(cc,C)
PRINT

END


!拡張ユークリッド互除法
! f(x)=A[m]x^m+ … +A[1]x+A[0]、g(x)=B[n]x^n+ … +B[1]x+B[0]、m≧nとして、
! f(x)S(x)+g(x)T(x)=k*gcd(f(x),g(x))=C(x)となるS(x),T(x),C(x)を求める。

EXTERNAL SUB PolynomialExtendedGCD(aa,A(),bb,B(), ss,S(),tt,T(),cc,C()) !拡張ユークリッド互除法
OPTION ARITHMETIC RATIONAL !有理数モード
IF bb=0 AND B(0)=0 THEN !!--- IF b=0 THEN
!!--- s=1 ※f(x)*1+0*0=f(x)とする
   LET S(0)=1
   LET ss=0
   !!--- t=0
   LET T(0)=0
   LET tt=0
   !!--- c=a
   MAT C=A
   LET cc=aa
ELSE
!!--- q=INT(a/b), r=MOD(a,b)
   DIM Q(0 TO MAX_DEGREE),R(0 TO MAX_DEGREE)
   IF aa=0 AND bb=0 THEN !定数項のみ
      LET Q(0)=INT(A(0)/B(0))
      LET qq=0
      LET R(0)=MOD(A(0),B(0))
      LET rr=0
   ELSE
      CALL PolynomialQuotientRemainder(aa,A,bb,B, qq,Q,rr,R)
   END IF

   !!--- CALL ExGCD(b,r, u,v,c) !k=n-1,…,3,2 まで続ける
   !!--- s=v
   CALL PolynomialExtendedGCD(bb,B,rr,R, tt,T,ss,S,cc,C)

   !!--- t=u-v*q
   DIM W(0 TO MAX_DEGREE)
   CALL PolynomialMultiply(ss,S,qq,Q, ww,W)
   MAT T=T-W
   LET tt=ww
END IF
END SUB


!補助ルーチン

!演算関連

EXTERNAL SUB PolynomialMultiply(aa,A(),bb,B(), ss,S()) !乗算 S=A*B ※S≠A、S≠B
OPTION ARITHMETIC RATIONAL !有理数モード
MAT S=ZER
FOR i=aa TO 0 STEP -1
   LET k=A(i)
   IF k=0 THEN !係数が0以外なら
   ELSE
      FOR j=bb TO 0 STEP -1
         LET S(i+j)=S(i+j)+k*B(j) !すべての係数をかける
      NEXT j
   END IF
NEXT i
LET ss=aa+bb!次数 ※その補正
END SUB


EXTERNAL SUB PolynomialQuotientRemainder(aa,A(),bb,B(), qq,Q(),rr,R()) !除算 ※被除数=商*除数+余り
OPTION ARITHMETIC RATIONAL !有理数モード
IF bb=0 AND B(0)=0 THEN !除数が0なら
   PRINT "0で割ることはできません。"
   STOP
ELSE
   MAT Q=ZER !商
   MAT R=A !余り
   FOR t=aa TO bb STEP -1 !被除数の次数が除数のより大きいなら
      IF R(t)=0 THEN !係数が0以外なら
      ELSE
         LET k=R(t)/B(bb) !商の係数、その次数
         LET w=t-bb
         LET Q(w)=k !商

         FOR i=bb TO 0 STEP -1 !余り ※R=A-k*B
            LET R(w+i)=R(w+i)-k*B(i)
         NEXT i
      END IF
   NEXT t
   LET qq=MAX(aa-bb,0) !次数
   IF aa>=bb THEN LET i=MAX(bb-1,0) ELSE LET i=aa !次数
   FOR rr=i TO 1 STEP -1 !※その補正
      IF R(rr)<>0 THEN EXIT FOR
   NEXT rr
END IF
END SUB


!表示関連

EXTERNAL SUB PolynomialDisplay(aa,A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
OPTION ARITHMETIC RATIONAL !有理数モード
CALL mono_disp(A(aa),aa) !最初の項
FOR i=aa-1 TO 0 STEP -1 !次項
   LET w=A(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 OR aa=0 THEN CALL mono_disp(w,i)
NEXT i
END SUB

EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
OPTION ARITHMETIC RATIONAL !有理数モード
IF k<>0 THEN !x^nで
   IF ak=0 OR ak=1 THEN !係数が0,1なら
   ELSEIF ak=-1 THEN !係数が-1なら
      PRINT "-"; !符号
   ELSE
      PRINT STR$(ak);"*";
   END IF
END IF
IF k=0 THEN !次数が0なら
   PRINT STR$(ak);
ELSE
   IF ak<>0 THEN !係数が0以外なら
      PRINT "X";
      IF k<>1 THEN PRINT "^";STR$(k); !次数が1以外なら
   END IF
END IF
END SUB


実行結果
+2/11*X^2+3/11*X-1/11
-2/11*X-5/11
1


数値計算による検算

PRINT 1/(4^(1/3)+2^(1/3)-1)
LET X=2^(1/3)
PRINT (2*X^2+3*X-1)/11
END


 

Re: 分母の有理化

 投稿者:山中和義  投稿日:2013年 7月17日(水)11時12分36秒
  > No.3097[元記事へ]

・√2の共役は、-√2
・x=3^(1/3)の共役は、x*(-1±√(-3))/2、すなわち、ωx,ω^2x
・√2+√3の共役は、√2-√3, -√2+√3, -√2-√3
・共役たちの和や積といった対称式は有理数である。

分母の有理化は共役たちを分母分子に掛ける方法がある。

●平方根の場合
1項のとき
x*(-x)=-x^2より、1/x=(-x)/(-x^2)


2項のとき
(x+y)(x-y)(-x+y)(-x-y)
=(x+y)(x-y)(-(x-y))(-(x+y))
=(x^2-y^2)^2
より、1/(x+y)=(x-y)(-x+y)(-x-y)/(x^2-y^2)^2

符号の決め方は2^2=4通りだが、重複を除けば、
(x+y)(x-y)
=(x+y)(x-y)
=(x^2-y^2)
より、1/(x+y)=(x-y)/(x^2-y^2)


3項のとき
符号の決め方は、
 (x+y+z)(x+y-z)(x-y+z)(x-y-z)(-x+y+z)(-x+y-z)(-x-y+z)(-x-y-z)
の2^3=8通りだが、重複を除けば、4通り


!分母の有理化 - 共役たちを分母分子に掛ける方法
!例 1/(√2+√3+√5)
!http://www.osaka-c.ed.jp/shijonawate/pdf/yuumeimondai/suutosiki_3.pdf

OPTION ARITHMETIC RATIONAL !有理数モード

!LET N=2 !項数
!DATA 3,5 !√3-√5
!DATA 1,-1 !係数部分

!LET N=3 !項数
!DATA 7,5,3 !√7+√5+√3
!DATA 1,1,1 !係数部分

!LET N=3 !項数
!DATA 3,2, 1 !√3+√2-1
!DATA 1,1,-1 !係数部分

LET N=3 !項数
DATA 2,3,5 !√2+√3+√5
DATA 1,1,1 !係数部分

!LET N=4 !項数
!DATA 5, 1,3,2 !√5-2+√3+√2
!DATA 1,-2,1,1 !係数部分


DIM R(N),C(N) !√a、√b、√c、… のn個
MAT READ R
MAT READ C


!分子の計算

DIM R1(2^N),C1(2^N) !√a、√b、√c、√ab、√bc、√ca、√abc、… の高々2^n個
LET R1(1)=1 !定数1
LET C1(1)=1
LET S1=1 !個数

LET F=0 !元の分母の符号パターン
FOR i=1 TO N
   LET F=F*2+(SGN(C(i))+1)/2
NEXT i
PRINT F !debug

DIM P(N)
FOR i=0 TO 2^N-1 !符号パターン(共役な数)を発生させる
   IF i=F THEN !同じならスキップする
   ELSE
      LET t=i
      FOR J=N TO 1 STEP -1 !2進法n桁
         LET P(J)=MOD(t,2)*2-1
         LET t=INT(t/2)
      NEXT J
      !!!MAT PRINT P; !debug

      DIM WW(2^N),W(2^N) !積 (+√a+√b+√c)(+√a+√b-√c)(+√a-√b+√c) …
      DIM WC(N) !共役な数の係数
      FOR J=1 TO N
         LET WC(J)=ABS(C(J))*P(J)
      NEXT J
      CALL SqMultiply(S1,R1,C1,N,R,WC, M,WW,W) !乗算
      MAT R1=WW !次へ
      MAT C1=W
      LET S1=M

   END IF
NEXT i
PRINT S1 !debug
MAT PRINT R1; !debug
MAT PRINT C1; !debug


!分母の計算

DIM R2(2^N),C2(2^N) !√a、√b、√c、√ab、√bc、√ca、√abc、… の高々2^n個
MAT R2=R1 !分子の値
MAT C2=C1
LET S2=S1

CALL SqMultiply(S2,R2,C2,N,R,C, M,WW,W) !乗算
MAT R2=WW
MAT C2=W
LET S2=M

PRINT S2 !debug
MAT PRINT R2; !debug
MAT PRINT C2; !debug


!結果を表示する

LET G=C1(1) !分母
FOR i=2 TO S1
   IF C1(i)<>0 THEN LET G=GCD(G,C1(i))
NEXT i
FOR i=1 TO N !√1の位置を探す
   IF R2(i)=1 THEN EXIT FOR
NEXT i
LET G=GCD(G,C2(i))*SGN(C2(i)) !既約分数
PRINT C2(i)/G

FOR i=1 TO S1 !分子
   IF C1(i)<>0 THEN PRINT C1(i)/G; "√";STR$(R1(i)) !√の項
NEXT i

END


!補助ルーチン

!演算関連

!積 (p√a+q√b+ … +r√c)(s√x+t√y+ … +u√z) を求める
! aa個の平方根、ar[]=a,b,…c、a[]=p,q,…r
! bb個の平方根、br[]=x,y,…z、b[]=s,t,…u
EXTERNAL SUB SqMultiply(aa,AR(),A(),bb,BR(),B(), cc,CR(),C()) !乗算 C=A*B ※A≠C、B≠C
OPTION ARITHMETIC RATIONAL !有理数モード
LET cc=0 !個数
FOR x=1 TO aa
   FOR y=1 TO bb
      LET K=A(x)*B(y) !係数の部分
      CALL SqNormalize(AR(x)*BR(y), P,Q) !平方根の中の部分

      FOR J=1 TO cc !新しい値なら
         IF Q=CR(J) THEN EXIT FOR
      NEXT J
      IF J>cc THEN !リストに登録する
         LET cc=cc+1
         LET CR(cc)=Q !√q
         LET C(cc)=P*K
      ELSE !既出なら、和を求める(同類項をまとめる)
         LET C(J)=C(J)+P*K
      END IF
   NEXT y
NEXT x
END SUB

EXTERNAL SUB SqNormalize(n, p,q) !平方根の中をできるだけ小さな正の整数に直す
!※n=p^2*q、n,p,q≧0とすると、√n=p*√qと変形できる。
OPTION ARITHMETIC RATIONAL !有理数モード
LET q=1 !※√0=0*√1とする ※n=0なら、1行下のFOR文でp=0は設定される
FOR p=INTSQR(n) TO 1 STEP -1 !約数p^2の候補を大きい方から
   LET q=n/p^2
   IF q=INT(q) THEN EXIT FOR !qは自然数より
NEXT p
END SUB


実行結果
7
4
2  3  5  30  0  0  0  0

144  96  0 -48  0  0  0  0

4
1  6  10  15  0  0  0  0

576  0  0  0  0  0  0  0

12
3 √2
2 √3
-1 √30



●立方根の場合

> 1/(4^(1/3)+2^(1/3)-1) の分母を有理化して下さい。

x=2^(1/3)とおくと、x^3=2
4^(1/3)+2^(1/3)-1=x^2+x-1(=f(x)とおく)
また、与式=1/f(x)=f(y)f(z)/(f(x)f(y)f(z))と変形できる。

対称式 f(x)f(y)f(z)=(x^2+x-1)(y^2+y-1)(z^2+z-1) は、
x,y,zの基本対称式 x+y+z,xy+yz+zx,xyz の多項式で表わせる。
今、y=ωx,z=ω^2xとすると、x,y,zはx^3-2=0の解だから、x+y+z=0,xy+yz+zx=0,xyz=2

これより、分母=f(x)f(y)f(z)=f(x)f(ωx)f(ω^2x)=定数

実際に計算すると、
f(ωx)f(ω^2x)=2x^2+3x-1
f(x)f(ωx)f(ω^2x)=11

∴1/f(x)=(2x^2+3x-1)/11

 

Re: 分母の有理化

 投稿者:山中和義  投稿日:2013年 7月18日(木)20時47分57秒
  > No.3098[元記事へ]

Q上の最小多項式から求める方法

1/(√3+√5)
答え
x=√3+√5とおくと、x^4-16x^2+4=0 ∴最小多項式f(x)=x^4-16x^2+4

f(x)=xQ(x)+Rより、f(x)=0なので、1/x=-Q(x)/R
具体的に、R=4、Q(x)=x^3-16xとなる。

よって、与式=-Q(√3+√5)/R=-(2√3-2√5)/4=(-√3+√5)/2
(終り)

考察
n次式f(x)=(x-α[1])(x-α[2])(x-α[3])…(x-α[n])=xQ(x)+R=0として、
「共役たちを分母分子に掛ける方法」を考える。
x=0を代入 または 解と係数の関係 より、R=f(0)=α[1]α[2]α[3]…α[n]
これは分母に相当する。
xQ(x)+R=0より、R/x=-Q(x) ∴α[1]α[2]α[3]…α[n]/α[1]=α[2]α[3]…α[n]
これは分子に相当する。
(終り)


!分母の有理化 - Q上の最小多項式

OPTION ARITHMETIC RATIONAL !有理数モード

!LET N=2 !x=√3+√5
!DATA 3,5
!DATA 1,1
!DATA 4 !f(x)=4-16x^2+x^4
!DATA 4,0,-16,0,1

!LET N=2 !x=3+√2
!DATA 1,2
!DATA 3,1
!DATA 2 !f(x)=7-6x+x^2
!DATA 7,-6,1

!LET N=3 !x=√2+√3+√5
!DATA 2,3,5
!DATA 1,1,1
!DATA 8 !f(x)=576-960x^2+352x^4-40x^6+x^8
!DATA 576,0,-960,0,352,0,-40,0,1

LET N=4
DATA 2,3,5,6 !x=√2+√3+√5+√6
DATA 1,1,1,1
DATA 8 !f(x)=x^8-64x^6-96x^5+808x^4+1152x^3-2304x^2-1152x+144
DATA 144,-1152,-2304,1152,808,-96,-64,0,1


DIM R(N),C(N) !xを読み込む
MAT READ R
MAT READ C

READ M !f(x)の次数
READ B !分子Rを読み込む
DIM A(0 TO M-1) !分母Q(x)を読み込む
MAT READ A

DIM RR(2^N),CC(2^N) !高々2^n個
CALL SqValueOfFunction(N,R,C, M-1,A, S,RR,CC) !関数Q(x)の値

!結果を表示する
FOR i=1 TO S !√の項
   IF CC(i)<>0 THEN PRINT -CC(i)/B; "√";STR$(RR(i)) !-Q(x)/R
NEXT i

END


!補助ルーチン

!演算関連

!x=αのとき、f(α)の値を求める
! x=p√a+q√b+ … +r√c ※n個の平方根、r[]=a,b,…c、c[]=p,q,…r
! f(x)=A[m]x^m+A[m-1]x^(m-1)+ … +A[2]x^2+A[1]x+A[0]
EXTERNAL SUB SqValueOfFunction(N,R(),C(), M,A(), S,RR(),CC())
OPTION ARITHMETIC RATIONAL !有理数モード
LET RR(1)=1 !f=a[m]
LET CC(1)=A(M)
LET S=1
DIM WW(2^N),W(2^N)
FOR i=M-1 TO 0 STEP -1 !ホーナー法
   CALL SqMultiply(S,RR,CC,N,R,C, T,WW,W) !f=f*x+a[i]
   FOR J=1 TO T !√1を探す
      IF WW(J)=1 THEN EXIT FOR
   NEXT J
   IF J>T THEN LET T=T+1
   LET W(J)=W(J)+A(i)

   MAT RR=WW !次へ
   MAT CC=W
   LET S=T
NEXT i
END SUB


!積 (p√a+q√b+ … +r√c)(s√x+t√y+ … +u√z) を求める
! aa個の平方根、ar[]=a,b,…c、a[]=p,q,…r
! bb個の平方根、br[]=x,y,…z、b[]=s,t,…u
EXTERNAL SUB SqMultiply(aa,AR(),A(),bb,BR(),B(), cc,CR(),C()) !乗算 C=A*B ※A≠C、B≠C
OPTION ARITHMETIC RATIONAL !有理数モード
LET cc=0 !個数
FOR x=1 TO aa
   IF A(x)=0 THEN !係数が0以外なら
   ELSE
      FOR y=1 TO bb
         LET K=A(x)*B(y) !係数
         CALL SqNormalize(AR(x)*BR(y), P,Q) !√wをp√qと変形する

         FOR J=1 TO cc !新しい値なら
            IF Q=CR(J) THEN EXIT FOR
         NEXT J
         IF J>cc THEN !リストに登録する
            LET cc=cc+1
            LET CR(cc)=Q !√q
            LET C(cc)=P*K
         ELSE !既出なら、和を求める(同類項をまとめる)
            LET C(J)=C(J)+P*K
         END IF
      NEXT y
   END IF
NEXT x
END SUB

EXTERNAL SUB SqNormalize(n, p,q) !平方根の中をできるだけ小さな正の整数に直す
!※n=p^2*q、n,p,q≧0とすると、√n=p*√qと変形できる。
OPTION ARITHMETIC RATIONAL !有理数モード
LET q=1 !※√0=0*√1とする ※n=0なら、1行下のFOR文でp=0は設定される
FOR p=INTSQR(n) TO 1 STEP -1 !約数p^2の候補を大きい方から
   LET q=n/p^2
   IF q=INT(q) THEN EXIT FOR !qは自然数より
NEXT p
END SUB


 

不具合?

 投稿者:SECOND  投稿日:2013年 7月19日(金)15時57分44秒
  !Ver 7.6.5 まで、無かった症状です。

FOR i=1 TO 100
   PRINT i
NEXT i
pause "BASIC766 起動後、最初の実行は、プログラム終了まで テキスト表示なし。"

END

!無関係な、ついでですが、
!※BITNOT, BITAND, BITOR, BITXOR のシリーズに BITSHT (シフト)を加えて頂けないでしょうか。
!※16進数で、0xff などの記法を許すようにできないでしょうか。
 

Re: 不具合?

 投稿者:白石和夫  投稿日:2013年 7月19日(金)16時30分30秒
  > No.3100[元記事へ]

ご報告ありがとうございました。
次バージョンでの修正を検討します。

16進数の記述はBVAL関数で代替可能です。
Full BASIC規格との互換性を損なうような拡張は控えたいと思います。

BITSHIFT関数の拡張は規格内で可能ですが,
DEF SHIFTLEFT(n)=n*2
DEF SHIFTRIGHT(n)=IP(n/2)
のようにすれば,間に合うことが多いと思います。
(ROTATEは難しいかも?)
 

!Page-2

 投稿者:SECOND  投稿日:2013年 7月20日(土)00時21分29秒
  !Page-2 の始め

!********************************************
! Encorder side R/W file
!********************************************

! read origin data  with bits L
FUNCTION INP_E( L)
   DO WHILE By< L
      IF siz<=i9 THEN
         LET INP_E=Hy
         LET Hy=0
         LET By=0
         EXIT FUNCTION
      END IF
      LET i9=i9+1
      LET Hy=Hy+ORD(db$(i9:i9))*2^By
      LET By=By+8
   LOOP
   !----
   LET INP_E=bitand(Hy,2^L-1)
   LET Hy=IP(Hy*2^(-L))
   LET By=By-L
END FUNCTION

! JPG の符号化データー中、0xff は、制御コード marker の接頭文字として
! 機能させるので、データーとしての 0xff は、0x00 を後付する規則がある。
! このプログラムで、必要はないが、同じ書式とした。

! write huffman code  with byte
SUB WRT_D( D)
   LET huf$=huf$& CHR$(D)
   IF D=255 THEN LET huf$=huf$& CHR$(0)
END SUB

!********************************************
! Decorder Side R/W file
!********************************************

! read huffman code  with byte
FUNCTION INP_D
   IF LEN(huf$)<=i9 THEN EXIT FUNCTION
   LET i9=i9+1
   LET INP_D=ORD(huf$(i9:i9))
END FUNCTION

! write origin data  with bits L
SUB OUT_D( D, L)
   LET Hy=Hy+D*2^By          !By: staying bits in register Hy
   LET By=By+L
   DO WHILE 8<=By
      IF siz<=o9 THEN EXIT SUB
      LET o9=o9+1
      LET out$=out$& CHR$(bitand(Hy,255))
      LET Hy=IP(Hy*2^(-8))
      LET By=By-8
   LOOP
END SUB

!********************************************
SUB Decode0
   LET i9=0                  !input byte pointer
   !
   !---read tree =DHT( Define Huffman Table)
   MAT DH=ZER
   MAT DV=ZER
   LET lmx=INP_D             !huffman code max.length
   FOR i=1 TO lmx
      LET DH(i)=INP_D        !DH(i) 各コード長の数( tree 各階層の終端数)
      LET DH(0)=DH(0)+DH(i)  !DH(0) 全コードの数( tree 分岐路の総数)
   NEXT i
   FOR i=0 TO DH(0)-1
      LET DV(i)=INP_D
   NEXT i
   !
   !---make huffman.code table & decorder table
   MAT B=ZER              !code table
   MAT L=ZER              !code length
   CALL makeH0            !Code table B() L()<-- DH()
   CALL makeD0            !Decorder table A()<-- B() L() DH() DV()
   CALL list_DHT
   CALL list_HT
   CALL list_A
   !
   !---read huffman code
   LET siz=INP_D+256*INP_D+65536*INP_D+16777216*INP_D  !output data size
   LET o9=0                                            !output byte pointer
   LET out$=""                                         !output byte buffer
   LET By=0               !remainder in output bit register
   LET Hy=0               !output bit register
   !---
   LET BC=0               !remainder in input register
   LET Hx=0               !input register
   CALL R_BLK0
END SUB

SUB R_BLK0
   DO WHILE o9< siz
      CALL DEC1_NS
      CALL OUT_D(V_,xL)
   LOOP
END SUB

!==========================================================
! decorder
! 区切れなく連続する bit の流れから、A() で復号。
! L_ ← 検出された登録ハフマンコードの bit長
! V_ ← 検出された登録ハフマンコードに対応する座標( 8bit値)
!----------------------------------------------------------
SUB DEC1_NS
   LET NA=0
   DO
      IF BC< BST THEN CALL DEC1_IN
      LET W=Hx*SHb                     !bits width BST
      !----
      LET NA=A(NA+IP(W))               !line adr.  NA=0 table end
      IF 32768<=NA THEN EXIT DO        !DU0L LLLL VVVV VVVV
      LET BC=BC-BST
      LET Hx=FP(W)
   LOOP
   LET L_=MOD(IP(NA/256),128)          ! U0L LLLL
   LET V_=MOD(NA,256)                  !          VVVV VVVV
   IF lmx< L_ THEN PRINT "unused code"
   !----
   LET W=MOD(L_,BST)
   IF W=0 THEN LET W=BST
   LET BC=BC-W
   LET Hx=FP(Hx*2^W)
END SUB

SUB DEC1_IN
   LET W=INP_D
   IF W=255 THEN
      LET M=INP_D
      IF M<>0 THEN LET w=1/0   !EXTYPE=3001, ffxx marker, abnormally break
   END IF                      !BC:    ┌┐buffer remain
   LET Hx=Hx+W*2^(-8-BC)       !Hw:  xx.xxxxxxxxx bits(BST).~b(-?)
   LET BC=BC+8                 !W:       └──→ next input space
END SUB                        !BST:└┘decord pitch

!======================================
! B()L()<-- DH() for decorder table A()
!--------------------------------------
SUB makeH0
   LET i=0               !コード生成 順番(短い順)
   LET Hx=0
   FOR L_=1 TO lmx       !lmx= 最大 bit 長
      FOR P=1 TO DH(L_)
         LET L(i)=L_
         LET B(i)=Hx     !コード(生成順), 座標DV(頻度降順) と同順。
         LET i=i+1
         LET Hx=Hx+1
      NEXT P
      LET Hx=Hx*2
   NEXT L_
   LET B(256)=0
END SUB

!=============================================
! make decorder table A()<-- B() L() DH() DV()
!---------------------------------------------
SUB makeD0
   FOR LH=lmx TO 1 STEP -1
      IF DH(LH)<>0 THEN EXIT FOR
   NEXT LH                          !bit length max. in huffman table
   LET LM=CEIL(LH/BST)*BST          !bit length max. bound by BST
   !---
   LET i=0                          !start huffman table adr.
   LET LA=0                         !line adr.
   LET NC=0                         !next start Decord code
   LET P=BST                        !start Decord code width
   DO
      LET D_=NC                                      !start Decord code
      LET D_=D_*SHb                                  !shr(U_,BST)
      LET D9=2^P                                     ! over Decord code
      LET NC=-1
      LET LB=LA+(D9-D_)                              !1st nest adr.
      DO
         CALL SERCH
         IF 0< L_ THEN
            LET A(LA)= BVAL("8000",16)+L_*256+DV(i)  !D00L LLLL VVVV VVVV   !b15=end. +L.+V.
         ELSEIF P=LM THEN
            LET A(LA)= BVAL("C000",16)+LH*256        !DU0L LLLL VVVV VVVV   !b15=end. b14=Unused. +L.
         ELSE
            IF NC=-1 THEN LET NC=D_
            LET A(LA)=LB                             !0nnn nnnn nnnn nnnn   !nest adr.
            LET LB=LB+SHb                            !next nest adr.
         END IF
         LET D_=D_+1
         LET LA=LA+1
      LOOP UNTIL D9<=D_
      LET P=P+BST
   LOOP UNTIL LM< P
   !---
   LET A(LA)=0                                       !(0),table stop mark
END SUB

SUB SERCH
   FOR i=i TO DH(0)-1
      LET L_=L(i)
      IF L_<=P THEN LET w=IP( D_*2^(L_-P)) ELSE EXIT FOR
      IF w<=B(i) THEN
         IF w=B(i) THEN EXIT SUB ELSE EXIT FOR
      END IF
   NEXT i
   LET L_=-1
END SUB

!=========================================
! print Decoder table. Process_list<-- A()
!-----------------------------------------
SUB list_A
   PRINT
   PRINT "******  Decoder table A() ******"
   PRINT "下表は、BST 幅( 現在は "& STR$(BST)& "bit)づつ区切って読込み"
   PRINT "配列 A() をたどって、不明な長さ(len.)の Code を、"
   PRINT "特定( 復号)していく仕組み。 座標<>""--"" で終点。"
   PRINT "----------------------------------------------"
   LET L4=MAX(LM,4)
   PRINT "Line  A()   Code"& REPEAT$(" ",L4-4)& " len. 座標"
   !---
   LET LA=0             !line adr.
   LET NC=0
   LET P=BST
   DO
      LET D_=NC         !next start Decord code
      LET D_=D_*SHb
      LET D9=2^P        !over Decord code
      LET NC=-1
      DO
         LET W=A(LA)
         !! IF W=0 THEN EXIT DO
         IF 32768<=W THEN               !DU0L LLLL VVVV VVVV
            LET L_=MOD( IP(W/256),128)  ! U0L LLLL
            LET V_=MOD(W,256)           !          VVVV VVVV
            LET w1$=USING$("##",MOD(L_,32))& "  "& RIGHT$("0"& BSTR$(V_,16),2)
            IF 64< L_ THEN LET w1$(3:6)="  -- Unused"
         ELSE                           !0nnn nnnn nnnn nnnn
            IF NC=-1 THEN LET NC=D_
            LET L_=0
            LET V_=0
            LET w1$=" -  -- Line"& STR$(W)
         END IF
         LET w$=USING$( "####",LA)& right$("     "& BSTR$(W,16),6)& "  "
         LET w$=w$& right$("0000000"& BSTR$(D_,2),P)& REPEAT$(" ",L4+2-P)& w1$
         PRINT w$
         !---
         LET D_=D_+1
         LET LA=LA+1
      LOOP UNTIL D9<=D_
      LET P=P+BST                       !next Decord code width
   LOOP UNTIL LM< P  !W=0
   !---
   PRINT USING$( "####",LA)& right$("     "& BSTR$( A(LA),16),6)  !verify end
   PRINT "decoder table end"
END SUB

!=========================
! print huffman code table
!-------------------------
SUB list_HT
   PRINT
   PRINT "huffman code"
   PRINT " 頻度 座標 len. コード(";
   IF MOD(B(256),2)=1 THEN PRINT "座標順)" ELSE PRINT "生成順、頻度降順)"
   LET sum=0
   FOR i=0 TO 255
      IF L(i)<>0 THEN
         IF MOD(B(256),2)=1 THEN                            !1=Sort at value. Encorder 用
            LET V_=i
            LET w$=RIGHT$("    "& BSTR$(SV(i),16),5)& "  "  !times
            LET sum=sum+L(i)*SV(i)
         ELSE                                               !0=Sort at length. Decorder 用
            LET V_=DV(i)
            LET w$=RIGHT$("    "& BSTR$(S_(i),16),5)& "  "  !times
            LET sum=sum+L(i)*S_(i)
         END IF
         LET w$=w$& right$("0"& BSTR$(V_,16),2)& "  "       !value
         LET w$=w$& right$(" "& STR$(L(i)),2)& "   "        !huffman code length
         LET w$=w$& right$("0000000"& BSTR$(B(i),2),L(i))   !huffman code
         PRINT w$
      END IF
   NEXT i
   PRINT " 合計( 頻度 * bit)=";sum
END SUB

!===================
! print huffman tree
!-------------------
SUB list_TREE
   PRINT
   PRINT "huffman tree  ****1行が長い時( ~ 数1000桁 )、右端で折り返さない注意!****"
   PRINT "                0,00: 7,01 などの意味 → 縦0階,横00番:縦7階,横01番 に2分岐"
   !---disp.nest
   FOR Le=Le0 TO 0 STEP -1
      LET w$=right$(" "& BSTR$(Le,16),2)& "|"
      FOR Ad=0 TO SE+1
         IF Tr(Le,Ad,1)>0 OR Tr(Le,Ad,3)>0 THEN
            LET w$=w$&
&& right$(" "& BSTR$(Tr(Le,Ad,0),16),2)& ","& right$("0"& BSTR$(Tr(Le,Ad,1),16),2)& ":"&
&& right$(" "& BSTR$(Tr(Le,Ad,2),16),2)& ","& right$("0"& BSTR$(Tr(Le,Ad,3),16),2)& "|"
         ELSE
            LET w$=w$& "----"& right$(" "& BSTR$(Le,16),2)& "-----|"
         END IF
      NEXT Ad
      PRINT w$
   NEXT Le
   !---hor.scale
   LET w$=""
   FOR Ad=0 TO SE+1
      LET w$=w$& "     "& right$("0"& BSTR$(Ad,16),2)& "     "   !Care tail SP.
   NEXT Ad
   !---hor.frequency
   LET w$=w$& crlf$& "頻度 "
   FOR Ad=0 TO SE+1
      IF 0< S_(Ad) THEN LET w1$=left$( BSTR$(S_(Ad),16)& "     ",6) ELSE LET w1$="unused "
      LET w$=w$& w1$& "      "
   NEXT Ad
   !---hor.value
   LET w$=w$& crlf$& "座標 "
   FOR Ad=0 TO SE+1
      IF 0< S_(Ad) THEN LET w1$=right$("0"& BSTR$(DV(Ad),16),2)& "    " ELSE LET w1$="unused"
      LET w$=w$& w1$& "      "
   NEXT Ad
   !---hor.rank
   LET w$=w$& crlf$& "len. "
   FOR Ad=0 TO SE+1
      LET w$=w$& right$(" "& BSTR$(Tr(0,Ad,0),16),2)& "          "
   NEXT Ad
   PRINT w$
END SUB

END
 

ハフマン・コードによる、符号化と復号化

 投稿者:SECOND  投稿日:2013年 7月20日(土)00時23分20秒
  !----------------------------------------------------------------------
! 入力データーの、ハフマン・コードによる、符号化と復号化、往復の処理。
!
!JPG での、ハフマン・コードの使われ方を見ると、
!画像データー(DCT出力)そのものを、符号化するのでなく、
!ZRL( ZeroRunLength 各データー直前0の数)と、データーbit長 の2つの
!数量を、4bit づつ 8bit にまとめた2次元の値( ZRL・bit長 )、
!この作成された 8bit値 の方を、ハフマン符号化している。
!
!肝心な画像データー(DCT出力)は、bit長ごとに、グループ分け、されるものの、
!ほぼ、特に正の数は、そのままの数値で、ハフマン符号の後に付加される。
!が、bit長 を予め知らせるフォームになるので、例えば、
!
!X= 3bit長以下のデーターの場合、
!Y= 2^3= 8通り(0~7) ではなく、15通り(-7~0~7) 識別される事ができる。
!
! if X=0 then   !符号化側、L=bit長
!   L=0
! else
!   L=len( bstr$( abs(X),2))
!   if X< 0 then Y= X +(2^L-1) else Y=X
! end if
!
!      3bit長                                  3bit長
!  !-----------  2bit長             2bit長 -----------
!  ! 0  0  0  0  -----              -----   1  1  1  1
! Y=! 0  0  1  1   0  0  --      --   1  1   0  0  1  1
!  ! 0  1  0  1   0  1   0       1   0  1   0  1  0  1
!  !-----------  -----  --  --  --  -----  -----------
! X= -7 -6 -5 -4  -3 -2  -1   0   1   2  3   4  5  6  7
!
! Y を元の X に戻すには、
!
! if L=0 then   !復号化側、L=bit長
!   X=0
! else
!   if Y< 2^(L-1) then X= Y -(2^L-1) else X=Y
! end if
!---------------------------------------------------------------------

!---------------------------------------------------------------------
!■このプログラムでは、次の様に、2次元の値( ZRL・bit長 ) の部分を、
! 直接の入力データーに置換え、それだけに 単純化して符号化、復号化する。
!
!● 符号化
! 文字入力データー  → その値の頻度 の測定 →
! → ハフマン符号木と、符号木定義表( DHT DefineHuffmanTable)の作成 →
! → ハフマン・コード表の作成 → データー値の符号化。
!● 復号化
! 符号木定義表( DHT DefineHuffmanTable) → ハフマン・コード表の復元 →
! → デコーダー・テーブル作成 → データー値の復号化。
!
!■出力のテキスト中で、"座標" は、
!  上の JPG での 作成された 8bit値、2次元の値だった部分です。
!  このプログラムでは、1次元の座標にして、
! "座標" が、直接の入力データー(文字入力データー)の意味になります。
!
!------------------------------------------------------------------------

DEBUG ON
OPTION ARITHMETIC NATIVE
OPTION BASE 0
OPTION CHARACTER byte
!
!------------------- テスト・データー ---------------------
! 注意。大きなファイルは、長い時間かかります。このプログラムと同じフォルダーに置きます。
!
!LET fl$="README.TXT"
!LET fl$="REVISION.TXT"
!LET fl$="BASIC.KW1"
LET fl$="BASIC.KW2"
!----------------------------------------------------------
!
LET xL=8                      !入力データーを区切る処理単位、1文字の bit 幅(1~8)の設定
!
!---encorder & decorder       !**DHT( DefineHuffmanTable )の実体は、配列 DH() DV()
!                             !    DH(i)= (i)bit長ハフマンコードの数、DV()= 頻度降順の座標
DIM DH(32),DV(255)            !  DH()DV() だけで、ハフマン符号木は、再生される。
DIM B(255+1)                  !huffman.code table :DH()DV() から作成。 MAKE_H2,MAKE_H0 で実行。
DIM L(255)                    !huffman.code length:DH()DV() から作成。 MAKE_H2,MAKE_H0 で実行。
!
!---encorder                  !**DHT を作るための配列類。
DIM SV(256)                   !SV(座標)= 頻度 → 頻度0の座標を除き順を詰める為 S_() DV() に分解。
DIM S_(256)                   !S_(j)=j番目の頻度、DV(j)= その座標。 MAKE_DHT で作成。
DIM F_(256),Tr(32,256,3)      !Tr(,,):ハフマン符号木、F_():作業用。   TREE3 で使用。
!
!---decorder
DIM A(2000)                   !huffman decorder table
LET BST=2                     !huffman decorder's bit step:速さで選ぶ。1,2,3,,,
LET SHb=2^BST                 !huffman decorder:シフトに使用。n*SHb=(shl n,BST)  n/SHb=(shr n,BST)
!
!---lister
LET crlf$=CHR$(13)& CHR$(10)
!
FILE SPLITNAME (fl$) path$, name$, ext$
!
PRINT "-------------------------"
PRINT "Encorder Side"
CALL load( fl$, db$)                         !db$ ←全ファイル
PRINT "原文 db$:";LEN(db$)
CALL Encode0
PRINT "-------------------------"
PRINT "符号化 終了 huf$:";LEN(huf$)
CALL save( name$& ext$& "符号化.huf", huf$)
!
PRINT
PRINT "-------------------------"
PRINT "Decorder Side"
CALL load( name$& ext$& "符号化.huf", huf$)  !huf$ ←全ファイル
PRINT "huf$:";LEN(huf$)
CALL Decode0
PRINT "-------------------------"
PRINT "復号化 終了 out$:";LEN(out$)
CALL save( name$& ext$& "復号化"& ext$, out$)
!
PRINT
PRINT "-------------------------"
PRINT " db$:";LEN(db$) ;"bytes 原文"
PRINT "huf$:";LEN(huf$);"bytes 符号化"
PRINT "out$:";LEN(out$);"bytes 復号化 ";
IF db$=out$ THEN PRINT "一致" ELSE PRINT "一致しない"

!------- full write binary
SUB save(f$,d$)             !d$ → 全ファイル
   OPEN #1: NAME f$
   ERASE#1
   PRINT #1: d$;
   CLOSE #1
END SUB

!------- full read binary
SUB load(f$,d$)             !d$ ← 全ファイル
   OPTION CHARACTER BYTE
   OPEN #1: NAME f$, ACCESS INPUT
   SET #1: ENDOFLINE CHR$(13)
   ASK #1: FILESIZE s9
   LET d$=""
   DO
      LINE INPUT #1,IF MISSING THEN EXIT DO :w9$
      LET d$=d$& w9$& CHR$(13)
   LOOP
   CLOSE #1
   IF s9< LEN(d$) THEN LET d$=d$(1:LEN(d$)-1)
END SUB

!==================
SUB Encode0
   LET siz=LEN(db$)                  !source DATA length
   !  ---analize source, --> frequency= SV( each data )
   MAT SV=ZER
   CALL F_BLK0
   !
   !---make tree =DHT( Define Huffman Table )
   MAT DH=ZER
   MAT DV=ZER
   CALL MAKE_DHT                     !lmx DH() <-- S_() DV() <-- SV()
   CALL list_TREE
   CALL list_DHT
   !
   !---make huffman encorder table
   MAT B=ZER                         !huffman.code table
   MAT L=ZER                         !huffman.code length
   CALL MAKE_H2                      !huffman.code table B()L() <-- DH()DV()
   CALL list_HT                      !listing huffman.code table B()L()
   !
   !---output DHT( Define Huffman Table)
   LET huf$=CHR$(lmx)                !huffman code max.length
   FOR i=1 TO lmx
      LET huf$=huf$& CHR$( DH(i))    !DH(i) 各コード長の数( tree 各階層の終端数)
   NEXT i
   FOR i=0 TO DH(0)-1                !DH(0) 全コードの数( tree 分岐路の総数)
      LET huf$=huf$& CHR$( DV(i))
   NEXT i
   !
   !---output huffman coded source
   LET huf$=huf$& dword$(siz)        !source DATA length
   LET Hw=0                          !output bit_stream_buffer
   LET BC=0                          !remainder bits in Hw
   CALL W_BLK0
   CALL W_FLUSH
END SUB

!---------
SUB F_BLK0
   LET i9=0                          !input buffer pointer
   LET By=0                          !input register remainder bit
   LET Hy=0                          !input register
   DO WHILE i9< siz OR 0< By
      LET V_=INP_E(xL)
      LET SV(V_)=SV(V_)+1
   LOOP
END SUB

!---------
SUB W_BLK0
   LET i9=0                          !input buffer pointer
   LET By=0                          !input register remainder bit
   LET Hy=0                          !input register
   DO WHILE i9< siz OR 0< By
      LET V_=INP_E(xL)
      CALL W_HUFF( L(V_),B(V_))      !L() huffman bit length,  B() huffman code
   LOOP
END SUB

!=============================================
! write bit stream
! L= データーのbit長、W= データー値(may be 0)
! 一定幅でない 入力データーを、
! 区切れのない連続の
!   bit の流れ( MSB~LSB, MSB~LSB,,) にして出力
!---------------------------------------------
SUB W_HUFF( L, W )
   LET Hw=Hw+W*2^(8-BC-L)       !Hw: b7~b(-?) 左詰め bit_stream buffer < 100h
   LET BC=BC+L
   DO WHILE 8<=BC               !BC:┌─────┐ stored data width  b7~b(-?)
      CALL WRT_D( IP(Hw))       !Hw: xxxxxxxx.xxx
      LET Hw=FP(Hw)*256         !   └───┘     output parts  b7~b0
      LET BC=BC-8               !BC:┌ ┐
   LOOP                         !Hw: xxx00000.0・・・
END SUB                         !      └───→  next data space

!---------------------------------------------
! write flush
! write bit stream の後、バッファ:Hx  内の残存
! bit を、byte 境界に合わせるため、不足 bit を
! "1" で埋めて書き出し、Hx を空にする。
!---------------------------------------------
SUB W_FLUSH
   IF 0< BC THEN CALL W_HUFF( 8-BC, 2^(8-BC)-1)  !write flush
END SUB

!======================================================
! DHT( Define Huffman Table segmet)
! 復号側に、符号化側で使用した符号木を、再現させる数表
! 構成:
! DH()= 符号木の 階層ごとの枝の数
! DV()= 出現頻度順に並べた 座標
!------------------------------------------------------
SUB MAKE_DHT
!  --- monitor SV()
   PRINT
   PRINT "頻度表"
   PRINT "座標= 横から縦の順。0~0xff データー値"
   CALL msg_x( SV, 0,255, "","      ")   !SV( 0~255)
   PRINT "total=";Tx
   !
   !--- make S_()DV()<-- SV()
   LET SE=-1
   FOR i=0 TO 255
      IF SV(i)<>0 THEN
         LET SE=SE+1
         LET S_(SE)=SV(i)
         LET DV(SE)=i
      END IF
   NEXT i
   PRINT
   PRINT "上の表を、頻度数と、座標の2つの表に分解し、同順の対にする。"
   PRINT "---------------------------------"
   PRINT "表中、頻度数0を外して詰めたもの"
   CALL msg_x( S_, 0,SE, "","      ")    !S_(0~SE)
   PRINT "座標"
   CALL msg_x( DV, 0,SE, "    ","00")    !DV(0~SE)
   !
   !--- sort DV() by S_()
   CALL Qsort(0,SE)
   PRINT "---------------------------------"
   PRINT "頻度の多い順に置換え (座標と対)"
   CALL msg_x( S_, 0,SE, "","      ")    !S_(0~SE)
   PRINT "座標"
   CALL msg_x( DV, 0,SE, "    ","00")    !DV(0~SE)
   !
   !--- make huffman tree, DH()
   CALL TREE3
END SUB

SUB list_DHT
   PRINT
   PRINT "len.(コード長) 1~"& STR$(lmx)& " の各個数 ( Define Huffman Table )"
   CALL msg_x( DH, 1,lmx , " ","00")     !DH(1~lmx)
   PRINT " 頻度順の、座標"
   CALL msg_x( DV, 0,Tx-1, " ","00")     !DV(0~Tx-1)
END SUB

SUB msg_x( M(), S,E, s$,n$)   !16 進数 表示
   LET Tx=0
   LET w$=""
   FOR i=S TO E
      LET Tx=Tx+M(i)
      LET w$=w$& s$& RIGHT$(n$& BSTR$(M(i),16), LEN(n$))
      IF MOD(i-S,16)=15 THEN LET w$=w$& crlf$
   NEXT i
   IF MOD(i-S,16)=0 THEN PRINT w$; ELSE PRINT w$
END SUB

!---------------------------------------------------------------------------
! make huffman tree
!
! 値と頻度がセットになっているデーター個数に、同数のハフマン符号を作る。
!
!1)頻度が最小の2個を選び、1組にして、その頻度の和を、新たな1個の頻度に変更。
!2)1個少なくなった全体に、再び1)の操作を行い、全体が1組(1個)になるまで繰返す。
!
!最後の1組は、その中に2組、その2組も、各々同様に、
!最初に有ったデーター個数に至るまで、経路が木の枝のように分かれる。
!
!その経路の数は、最初に有ったデーター個数と、過不足なく同数。
!
!最後の1組から、データー1個に至る直前までの、途中の組(分岐点)をたどる時、
!各々の組の2つの枝に、0,1 の番号を付け、最後の1組から並べると、ハフマン符号ができる。
!
!1つの経路のたどる分岐点の数は、頻度が大きいデーターほど、後からつながれていて、
!より少ないので、ハフマン符号は、より短い 011・・となる。


!プログラムは、出来た枝から、直接、ハフマン符号を作らず、
!各層における枝の数を、収めた 配列テーブル DH() を作成して終っている。
!
!SUB MAKE_H2 で、DH() から、ココで作成された木構造を、011・・の形(ハフマン符号)
!へ再生する事で、符号化に使用している。復号側も、SUB makeH0 で、DH() から再生。
!
!プログラムは、ハフマン符号木の最後尾に、使わない枝( 空席)も、1つ追加している。
!下の文中、 !←(+1) 符号木の最下に、空席を1つ作る。 …の行、2つ。
!              SE+1 を、SE にすると、空席は無くなる。
!---------------------------------------------------------------------------
SUB TREE3
   MAT Tr=ZER
   FOR i=0 TO SE
      LET F_(i)=S_(i)               !数値を壊すので、コピー F_(i)で実行
   NEXT i
   LET F_(SE+1)=0                   !← 空席用
   !---minimum pair
   DO
      LET w=1e10
      FOR i=0 TO SE+1               !←(+1) 符号木の最下に、空席を1つ作る。
         IF F_(i)< w THEN
            LET w=F_(i)
            LET Ad1=i               !minimum1   !頻度最小の分岐アドレスAd1
         END IF
      NEXT i
      LET w=1e10
      FOR i=0 TO SE+1               !←(+1) 符号木の最下に、空席を1つ作る。
         IF F_(i)< w AND i<>Ad1 THEN
            LET w=F_(i)
            LET Ad2=i               !minimum2   !頻度最小の分岐アドレスAd2
         END IF
      NEXT i
      IF w=1e10 THEN EXIT DO        !分岐の組が無くなるまで
      !---
      LET F_(Ad1)=F_(Ad1)+F_(Ad2)   !次の頻度最小の組探しは、2分岐合計を1つにし、
      LET F_(Ad2)=2e10              !他方を外して行なう
      !---
      FOR Le1=lmx TO 1 STEP -1      !アドレスAd1の最上 節点レベルLe1 を探す(最初のLe1=0)
         IF Tr(Le1,Ad1,1)>0 OR Tr(Le1,Ad1,3)>0 THEN EXIT FOR
      NEXT Le1
      FOR Le2=lmx TO 1 STEP -1      !アドレスAd2の最上 節点レベルLe2 を探す(最初のLe2=0)
         IF Tr(Le2,Ad2,1)>0 OR Tr(Le2,Ad2,3)>0 THEN EXIT FOR
      NEXT Le2
      LET Le0=MAX( Le1,Le2 )+1      !両者何れよりも1つ上の節点レベル(Le0,Ad1)に、
      !---
      LET Tr(Le0,Ad1,0)=Le1         !分岐先( 節点レベル,アドレス)として2組記入
      LET Tr(Le0,Ad1,1)=Ad1
      LET Tr(Le0,Ad1,2)=Le2
      LET Tr(Le0,Ad1,3)=Ad2
      IF lmx< Le0 THEN LET lmx=Le0  !最大段数 lmx の設定、更新
   LOOP
   !---make DH()
   LET k=0
   CALL bitl(Le0,Ad1)               !全分岐路の 分岐段数 を求める。
   FOR Ad=0 TO SE
      LET DH(Tr(0,Ad,0))=DH(Tr(0,Ad,0))+1   !分岐段数 が同じ Tr(0,Ad,0) の
   NEXT Ad                                  !総数を、段数毎に、DH() に集計
   LET DH(0)=Ad
END SUB

SUB bitl(Le,Ad)                     !最上 節点(Le0,Ad1)より全分岐路を、底まで辿る
   IF 0< Le THEN
      LET k=k+1
      CALL bitl( Tr(Le,Ad,0), Tr(Le,Ad,1) )  !分岐先 1
      CALL bitl( Tr(Le,Ad,2), Tr(Le,Ad,3) )  !分岐先 2
      LET k=k-1
   ELSE
      LET Tr(0,Ad,0)=k              !最上 節点から底までの 分岐段数 kを書く
   END IF
END SUB

!-----------------------------
! Quick Sort S_() DV() by S_()
!-----------------------------
SUB Qsort(L,R)                      !降順にセット。
   local i,j
   LET i=L
   LET j=R
   LET Tx=S_(IP((L+R)/2))
   DO
      DO WHILE S_(i) >Tx            ![>]降順 [< ]昇順
         LET i=i+1
      LOOP
      DO WHILE Tx >S_(j)            ![>]降順 [< ]昇順
         LET j=j-1
      LOOP
      IF j< i THEN EXIT DO          !等号付 j<=i は、暴走。
      SWAP S_(i),S_(j)
      SWAP DV(i),DV(j)
      LET i=i+1
      LET j=j-1
   LOOP UNTIL j< i                  !等号付 j<=i は、低速。
   IF L< j THEN CALL Qsort(L,j)
   IF i< R THEN CALL Qsort(i,R)
END SUB

!===================================
! make encorder table B()L()<-- DH()
!-----------------------------------
SUB MAKE_H2
   LET i=0               !コード生成 順番(短い順)
   LET Hx=0
   FOR L_=1 TO lmx       !lmx= 最大 bit 長
      FOR N=1 TO DH(L_)
         LET V_=DV(i)    !座標DV(頻度降順)
         LET L(V_)=L_
         LET B(V_)=Hx    !コード(座標V_)
         LET i=i+1
         LET Hx=Hx+1
      NEXT N
      LET Hx=Hx*2
   NEXT L_
   LET B(256)=1
END SUB

!
Page-2 へ続く
 

Re: 分母の有理化

 投稿者:山中和義  投稿日:2013年 7月21日(日)11時26分35秒
  > No.3099[元記事へ]

最小多項式を求める方法

最小多項式 f(x)=(x-α[1])(x-α[2])(x-α[3])…(x-α[n]) なので、解と係数の関係より、

個数が少ない場合は、

  LET a= SQR(3)+SQR(5)
  LET b= SQR(3)-SQR(5)
  LET c=-SQR(3)+SQR(5)
  LET d=-SQR(3)-SQR(5)
  PRINT 1 !x^4
  PRINT -(a+b+c+d) !x^3
  PRINT a*b+a*c+a*d +b*c+b*d +c*d !x^2
  PRINT -(a*b*c+a*b*d+a*c*d +b*c*d) !x^1
  PRINT a*b*c*d !x^0
  END

とすればよいでしょう。

多い場合は、「解の積」を機械的に生成するように改良します。

!Q上の最小多項式を求める

!最小多項式 f(x)=(x-α[1])(x-α[2])(x-α[3])…(x-α[n]) なので、
!解と係数の関係より、展開式 f(x)=c[n]x^n+c[n-1]x^(n-1)+ … +c[1]x+c[0] を計算する。

!x=√2+√3+√5+√6の場合、f(x)=x^8-64x^6-96x^5+808x^4+1152x^3-2304x^2-1152x+144

LET M=3 !線形独立な平方根の個数 ∵√6=√2√3より、√6は除く

LET N=2^M !共役の個数
DIM A(N)
LET A(1)= SQR(2)+SQR(3)+SQR(5) +SQR(6) !√6の符号 ∵√6=√2√3より
LET A(2)= SQR(2)+SQR(3)-SQR(5) +SQR(6)
LET A(3)= SQR(2)-SQR(3)+SQR(5) -SQR(6)
LET A(4)= SQR(2)-SQR(3)-SQR(5) -SQR(6)
LET A(5)=-SQR(2)+SQR(3)+SQR(5) -SQR(6)
LET A(6)=-SQR(2)+SQR(3)-SQR(5) -SQR(6)
LET A(7)=-SQR(2)-SQR(3)+SQR(5) +SQR(6)
LET A(8)=-SQR(2)-SQR(3)-SQR(5) +SQR(6)

DIM c(0 TO N) !係数 ※基本対称式
MAT c=ZER
FOR p=0 TO 2^N-1 !組み合わせで「解の積」を機械的に生成する
   LET t=p
   LET r=0 !ビット列の1の個数
   LET W=1 !r個の積、C(n,r)通り
   LET K=1
   DO WHILE t>0
      IF MOD(t,2)=1 THEN
         LET r=r+1
         LET W=W*(-A(K))
      END IF
      LET t=INT(t/2)
      LET K=K+1
   LOOP

   LET c(N-r)=c(N-r)+W !x^(N-r)の係数
NEXT p
MAT PRINT c; !1,x,…,x^(n-1),x^nの係数

END


実行結果
144 -1152 -2304.00000000003  1152  808.000000000003 -95.9999999999994 -64  .00000000000003  1

 

Re: 分母の有理化

 投稿者:山中和義  投稿日:2013年 7月26日(金)18時47分57秒
  > No.3104[元記事へ]

最小多項式を求める方法のつづき

> 1/(4^(1/3)+2^(1/3)-1) の分母を有理化して下さい。

Q上の最小多項式から求める方法

x=4^(1/3)+2^(1/3)-1のとき、Q上の最小多項式を求めると、f(x)=x^3+3x^2-3x-11
よって、1/x=-(x^2+3x-3)/(-11)=(x^2+3x-3)/11
xを代入して、
分子
={4^(1/3)+2^(1/3)-1}^2 +3{4^(1/3)+2^(1/3)-1} -3
=2*2^(1/3)+4^(1/3)+1 +2*2-2*2^(1/3)-2*4^(1/3)  +3*4^(1/3)+3*2^(1/3)-3  -3
=2*4^(1/3)+3*2^(1/3)-1
(終り)


!x=4^(1/3)+2^(1/3)-1の場合、f(x)=x^3+3x^2-3x-11

OPTION ARITHMETIC COMPLEX !複素数モード
LET i=COMPLEX(0,1) !虚数単位


DEF G(y)=y^2+y-1
LET y=2^(1/3)
LET w=EXP(2*PI*i/3) !y^3-1=0(y≠1)の解のひとつ

LET N=3 !共役の個数
DIM A(N)
LET A(1)=G(y)
LET A(2)=G(w*y)
LET A(3)=G(w^2*y)


DIM c(0 TO N) !係数 ※基本対称式
MAT c=ZER
FOR p=0 TO 2^N-1 !組み合わせで「解の積」を機械的に生成する
   LET R=0 !ビット列の1の個数
   LET S=1 !r個の積、C(n,r)通り
   LET t=p !ビットパターン ※2進法n桁
   LET K=1
   DO WHILE t>0
      IF MOD(t,2)=1 THEN !ビットが1なら
         LET R=R+1
         LET S=S*(-A(K))
      END IF
      LET t=INT(t/2) !次へ
      LET K=K+1
   LOOP

   LET c(N-R)=c(N-R)+S !x^(n-r)の係数
NEXT p
MAT PRINT c; !1,x,…,x^(n-1),x^nの係数

END


実行結果
(-11  7.86122469204065E-15) (-3 -1.2583792514953E-15) ( 3 -1.55431223447522E-15)  1


> x=√2+√3+√5+√6の場合、f(x)=x^8-64x^6-96x^5+808x^4+1152x^3-2304x^2-1152x+144

前出の最小多項式を求める方法のプログラムは、上記のように記述すると、


!x=√2+√3+√5+√6の場合、f(x)=x^8-64x^6-96x^5+808x^4+1152x^3-2304x^2-1152x+144

OPTION ARITHMETIC COMPLEX !複素数モード
LET i=COMPLEX(0,1) !虚数単位

DEF G(x1,x2,x3)=x1+x2+x3+x1*x2 !∵√6=√2√3より、√6は除く
LET x1=SQR(2)
LET x2=SQR(3)
LET x3=SQR(5)
LET w=EXP(2*PI*i/2) !x^2-1=0(x≠1)の解のひとつ、すなわちω=-1

LET N=2^3 !共役の個数
DIM A(N)
LET A(1)=G(  x1,   x2,   x3)
LET A(2)=G(  x1,   x2, w*x3)
LET A(3)=G(  x1, w*x2,   x3)
LET A(4)=G(  x1, w*x2, w*x3)
LET A(5)=G(w*x1,   x2,   x3)
LET A(6)=G(w*x1,   x2, w*x3)
LET A(7)=G(w*x1, w*x2,   x3)
LET A(8)=G(w*x1, w*x2, w*x3)


DIM c(0 TO N) !係数 ※基本対称式
MAT c=ZER
FOR p=0 TO 2^N-1 !組み合わせで「解の積」を機械的に生成する
   LET R=0 !ビット列の1の個数
   LET S=1 !r個の積、C(n,r)通り
   LET t=p !ビットパターン ※2進法n桁
   LET K=1
   DO WHILE t>0
      IF MOD(t,2)=1 THEN !ビットが1なら
         LET R=R+1
         LET S=S*(-A(K))
      END IF
      LET t=INT(t/2) !次へ
      LET K=K+1
   LOOP

   LET c(N-R)=c(N-R)+S !x^(n-r)の係数
NEXT p
MAT PRINT c; !1,x,…,x^(n-1),x^nの係数

END


実行結果

( 143.999999999999  4.55231300086593E-13) (-1152  2.87033774599169E-12) (-2304 -3.24149828525186E-14) ( 1152 -1.22630932501458E-12) ( 808 -4.23419558502279E-14) (-96  1.31570129478226E-13) (-64  7.00144567739066E-15) (-2.66453525910038E-15 -2.63649535642436E-15)  1


 

Re: 分母の有理化

 投稿者:山中和義  投稿日:2013年 7月27日(土)20時12分49秒
  > No.3098[元記事へ]

> 分母の有理化は共役たちを分母分子に掛ける方法がある。

> ●立方根の場合
> > 1/(4^(1/3)+2^(1/3)-1) の分母を有理化して下さい。
>
> x=2^(1/3)とおくと、x^3=2
> 4^(1/3)+2^(1/3)-1=x^2+x-1(=f(x)とおく)
> また、与式=1/f(x)=f(y)f(z)/(f(x)f(y)f(z))と変形できる。
>
> 対称式 f(x)f(y)f(z)=(x^2+x-1)(y^2+y-1)(z^2+z-1) は、
> x,y,zの基本対称式 x+y+z,xy+yz+zx,xyz の多項式で表わせる。
> 今、y=ωx,z=ω^2xとすると、x,y,zはx^3-2=0の解だから、x+y+z=0,xy+yz+zx=0,xyz=2
>
> これより、分母=f(x)f(y)f(z)=f(x)f(ωx)f(ω^2x)=定数
>
> 実際に計算すると、
> f(ωx)f(ω^2x)=2x^2+3x-1
> f(x)f(ωx)f(ω^2x)=11
>
> ∴1/f(x)=(2x^2+3x-1)/11

考察
1/f(x)=(f(ωx)f(ω^2x))/(f(x)f(ωx)f(ω^2x)) と変形すると、分母が有理化される。
(終り)


OPTION ARITHMETIC COMPLEX !複素数モード
LET i=COMPLEX(0,1) !虚数単位

LET w=EXP(2*PI*i/3) !y^3-1=0(y≠1)の解のひとつ、すなわちω=(-1+(√3)i)/2

DATA 2 !f(x)=x^2+x-1
DATA -1,1,1

DATA 3 !g(x)=x^3-2
DATA -2,0,0,1


READ ff !f(x)を読み込む
DIM F(0 TO ff)
MAT READ F

READ gg !g(x)を読み込む
DIM G(0 TO gg)
MAT READ G


!分子 f(ωx)f(ω^2x) の計算

DIM A(0 TO ff),B(0 TO ff) !f(ωx)、f(ω^2x)
FOR k=0 TO ff
   LET A(k)=F(k)*w^k
   LET B(k)=F(k)*(w^2)^k
NEXT k
LET aa=ff
LET bb=ff

DIM S(0 TO 2*ff)
CALL PolynomialMultiply(aa,A,bb,B, ss,S)
PRINT ss
MAT PRINT S;

DIM Q(0 TO 2*ff),R(0 TO 2*ff)
CALL PolynomialQuotientRemainder(ss,S,gg,G, qq,Q,rr,R) !x=2^(1/3)を考慮する

PRINT rr !結果を表示する
MAT PRINT R;


!分母 f(x)f(ωx)f(ω^2x) の計算

CALL PolynomialMultiply(ff,F,rr,R, ss,S) !f(x)×分子
PRINT ss
MAT PRINT S;

CALL PolynomialQuotientRemainder(ss,S,gg,G, qq,Q,rr,R)

PRINT rr !結果を表示する
MAT PRINT R;


END


!補助ルーチン

!f(x)=A[aa]x^aa+ … +A[1]x+A[0]、g(x)=B[bb]x^bb+ … +B[1]x+B[0]

!演算関連

EXTERNAL SUB PolynomialMultiply(aa,A(),bb,B(), ss,S()) !乗算 S=A*B ※S≠A、S≠B
OPTION ARITHMETIC COMPLEX !複素数モード
MAT S=ZER
FOR i=aa TO 0 STEP -1
   LET k=A(i)
   FOR j=bb TO 0 STEP -1
      LET S(i+j)=S(i+j)+k*B(j) !すべての係数をかける
   NEXT j
NEXT i
LET ss=aa+bb!次数 ※その補正
END SUB


EXTERNAL SUB PolynomialQuotientRemainder(aa,A(),bb,B(), qq,Q(),rr,R()) !除算 ※被除数=商*除数+余り
OPTION ARITHMETIC COMPLEX !複素数モード
IF bb=0 AND ABS(B(0))<1E-12 THEN !除数が0なら ※※複素数による近似
   PRINT "0で割ることはできません。"
   STOP
ELSE
   MAT Q=ZER !商
   MAT R=A !余り
   FOR t=aa TO bb STEP -1 !被除数の次数が除数のより大きいなら
      IF ABS(R(t))<1E-12 THEN !係数が0以外なら ※※複素数による近似
      ELSE
         LET k=R(t)/B(bb) !商の係数、その次数
         LET w=t-bb
         LET Q(w)=k !商

         FOR i=bb TO 0 STEP -1 !余り ※R=A-k*B
            LET R(w+i)=R(w+i)-k*B(i)
         NEXT i
      END IF
   NEXT t
   LET qq=MAX(aa-bb,0) !次数
   IF aa>=bb THEN LET t=MAX(bb-1,0) ELSE LET t=aa !次数
   FOR rr=t TO 1 STEP -1 !※その補正
      IF ABS(R(rr))>=1E-12 THEN EXIT FOR ! ※※複素数による近似
      LET R(rr)=0 ! ※※複素数による近似
   NEXT rr
END IF
END SUB


実行結果

4
1 ( 1 -3.33066907387547E-16) ( 2 -1.22124532708767E-15) (-1  9.99200722162641E-16) ( 1 -1.23905334777075E-15)

2
(-1  1.99840144432528E-15) ( 3 -2.81117360292904E-15) ( 2 -1.22124532708767E-15)  0  0

4
( 1 -1.99840144432528E-15) (-4  4.80957504725432E-15) ( 0  4.08473168483914E-16) ( 5 -4.03241893001671E-15) ( 2 -1.22124532708767E-15)

0
( 11 -1.00632393043587E-14)  0  0  0  0

 

多項式の計算

 投稿者:山中和義  投稿日:2013年 8月 1日(木)06時59分48秒
  多項式を使って数学の問題を解く


!問題
!3次曲線 y=x^3+x^2-5x-7 が直線Lと3点A,B,Cで交わっている。
!A,Bのx座標がそれぞれ -1, 2であるとき、
!直線Lの方程式および3点A,B,Cの座標を求めよ。

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

DATA 3 !y=x^3+x^2-5x-7
DATA -7,-5,1,1

READ ff !yを読み込む
DIM F(0 TO ff)
MAT READ F


LET gg=2 !解と係数の関係より、a,bを解とする2次方程式を得る
DIM G(0 TO gg)
LET a=-1 !2点A,B
LET b=2
LET G(2)=1
LET G(1)=-(a+b)
LET G(0)=a*b


DIM Q(0 TO MAX_DEGREE),R(0 TO MAX_DEGREE)
CALL PolynomialQuotientRemainder(ff,F,gg,G, qq,Q,rr,R)
PRINT qq !点C x+2=0
MAT PRINT Q;
PRINT rr !直線L y=-x-3
MAT PRINT R;

PRINT a; PolynomialValue(a,ff,F) !3点A,B,C
PRINT b; PolynomialValue(b,ff,F)
PRINT -Q(0); PolynomialValue(-Q(0),ff,F)

END


!POLY.LIB

!f(x)=A[aa]x^aa+ … +A[2]x^2+A[1]x+A[0]、g(x)=B[bb]x^bb+ … +B[2]x^2+B[1]x+B[0]

EXTERNAL FUNCTION PolynomialValue(a,ff,F()) !多項式の値 f(a)
OPTION ARITHMETIC RATIONAL !有理数モード
LET t=F(ff)
FOR i=ff-1 TO 0 STEP -1 !ホーナー法
   LET t=t*a+F(i)
NEXT i
LET PolynomialValue=t
END FUNCTION


EXTERNAL SUB PolynomialDifferential(K,ff,F(), cc,C()) !k階微分
OPTION ARITHMETIC RATIONAL !有理数モード
MAT C=ZER
FOR i=K TO ff
   LET C(i-K)=PERM(i,K)*F(i)
NEXT i
LET cc=MAX(ff-K,0)
END SUB


EXTERNAL SUB PolynomialPowerN(aa,A(), N, bb,B()) !べき乗展開(多項定理による)
OPTION ARITHMETIC RATIONAL !有理数モード
DIM P(aa+1) !{p,q,…,r}の並び
MAT B=ZER
CALL PolyPowN(N,aa+1,1,P, aa,A,N, B)
LET bb=aa*N
END SUB

EXTERNAL SUB PolyPowN(m,d,s,P(), aa,A(),N, B()) !自然数mをd分割する
OPTION ARITHMETIC RATIONAL !有理数モード
IF d=1 THEN
   LET P(s)=m

   !{p,q,…,r}で多項式を展開する
   LET c=PermFactorialM(P,aa+1) !前半部分 (p+q+ … +r)!/(p!*q!* … *r!)

   LET x=0 !後半部分を加味する
   FOR i=0 TO aa
      LET c=c*A(i)^P(i+1) !係数
      LET x=x+i*P(i+1) !べき乗
   NEXT i

   LET B(x)=B(x)+c !記録する

ELSEIF d>1 THEN
   FOR i=0 TO m
      LET P(s)=m-i
      CALL PolyPowN(i,d-1,s+1,P, aa,A,N, B) !次へ
   NEXT i
END IF
END SUB

EXTERNAL FUNCTION PermFactorialM(B(),M) !同じものを含む順列の「場合の数」
OPTION ARITHMETIC RATIONAL !有理数モード
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


EXTERNAL SUB PolynomialComposition(aa,A(),bb,B(), ss,S()) !合成関数 f(g(x))
OPTION ARITHMETIC RATIONAL !有理数モード
DIM W(0 TO aa*bb)
LET S(0)=A(aa) !s=a[aa]
LET ss=0
FOR i=aa-1 TO 0 STEP -1 !ホーナー法
   CALL PolynomialMultiply(ss,S,bb,B, ww,W) !s=s*X+a[i]
   LET W(0)=W(0)+A(i)
   MAT S=W !次へ
   LET ss=ww
NEXT i
END SUB


EXTERNAL SUB PolynomialGCD(aa,A(),bb,B(), cc,C()) !最大公約数
OPTION ARITHMETIC RATIONAL !有理数モード
IF aa=0 AND bb=0 THEN !定数項のみなら
   MAT C=ZER
   LET C(0)=GCD(A(0),B(0))
   LET cc=0
ELSE
   DIM TA(0 TO MAX_DEGREE),TB(0 TO MAX_DEGREE) !作業変数
   MAT TA=A
   LET taa=aa
   MAT TB=B
   LET tbb=bb
   DO WHILE NOT(tbb=0 AND TB(0)=0) !--- DO WHILE b<>0
      DIM Q(0 TO MAX_DEGREE),R(0 TO MAX_DEGREE)
      CALL PolynomialQuotientRemainder(taa,TA,tbb,TB, qq,Q,rr,R) !--- LET R=MOD(a,b)
      MAT TA=TB !--- LET a=b
      LET taa=tbb
      MAT TB=R !--- LET b=R
      LET tbb=rr
   LOOP !--- LOOP
   LET G=TA(0) !既約
   FOR i=1 TO taa
      LET G=GCD(G,TA(i))
   NEXT i
   MAT C=(1/G)*TA !--- LET GCD=a
   LET cc=taa
END IF
END SUB


EXTERNAL SUB PolynomialLCM(aa,A(),bb,B(), cc,C()) !最小公倍数
OPTION ARITHMETIC RATIONAL !有理数モード
DIM G(0 TO MAX_DEGREE)
CALL PolynomialGCD(aa,A,bb,B, gg,G) !LCM=A*B/Gより
DIM Q(0 TO MAX_DEGREE),R(0 TO MAX_DEGREE)
CALL PolynomialQuotientRemainder(bb,B,gg,G, qq,Q,rr,R)
IF NOT(rr=0 AND R(0)=0) THEN !余りが0以外なら
   PRINT "論理エラー"
   STOP
END IF
CALL PolynomialMultiply(aa,A,qq,Q, cc,C)
END SUB


!拡張ユークリッド互除法
! f(x)=A[m]x^m+ … +A[1]x+A[0]、g(x)=B[n]x^n+ … +B[1]x+B[0]、m≧nとして、
! f(x)S(x)+g(x)T(x)=gcd(f(x),g(x))=C(x)となるS(x),T(x),C(x)を求める。
EXTERNAL SUB PolynomialExtendedGCD(aa,A(),bb,B(), ss,S(),tt,T(),cc,C()) !拡張ユークリッド互除法
OPTION ARITHMETIC RATIONAL !有理数モード
CALL Poly_ExGCD(aa,A,bb,B, ss,S,tt,T,cc,C)
LET G=C(0) !既約
FOR i=1 TO cc
   LET G=GCD(G,C(i))
NEXT i
LET G=G*SGN(C(cc)) !C(x)の最高次数の係数は正とする
MAT S=(1/G)*S
MAT T=(1/G)*T
MAT C=(1/G)*C
END SUB

!f(x)S(x)+g(x)T(x)=k*gcd(f(x),g(x))=C(x)となるS(x),T(x),C(x)を求める。
EXTERNAL SUB Poly_ExGCD(aa,A(),bb,B(), ss,S(),tt,T(),cc,C()) !拡張ユークリッド互除法
OPTION ARITHMETIC RATIONAL !有理数モード
IF bb=0 AND B(0)=0 THEN !!--- IF b=0 THEN
!!--- s=1 !※f(x)*1+0*0=f(x)とする
   MAT S=ZER
   LET S(0)=1
   LET ss=0
   !!--- t=0
   MAT T=ZER
   LET T(0)=0
   LET tt=0
   !!--- c=a
   MAT C=A
   LET cc=aa
ELSE
!!--- q=INT(a/b), r=MOD(a,b)
   DIM Q(0 TO MAX_DEGREE),R(0 TO MAX_DEGREE)
   IF aa=0 AND bb=0 THEN !定数項のみ
      MAT Q=ZER
      LET Q(0)=INT(A(0)/B(0))
      LET qq=0
      MAT R=ZER
      LET R(0)=MOD(A(0),B(0))
      LET rr=0
   ELSE
      CALL PolynomialQuotientRemainder(aa,A,bb,B, qq,Q,rr,R)
   END IF

   !!--- CALL ExGCD(b,r, u,v,c) !k=n-1,…,3,2 まで続ける
   !!--- s=v
   CALL PolynomialExtendedGCD(bb,B,rr,R, tt,T,ss,S,cc,C)

   !!--- t=u-v*q
   DIM W(0 TO MAX_DEGREE)
   CALL PolynomialMultiply(ss,S,qq,Q, ww,W)
   MAT T=T-W
   LET tt=ww
END IF
END SUB


!補助ルーチン

!演算関連

EXTERNAL SUB PolynomialMultiply(aa,A(),bb,B(), ss,S()) !乗算 S=A*B ※S≠A、S≠B
OPTION ARITHMETIC RATIONAL !有理数モード
MAT S=ZER
FOR i=aa TO 0 STEP -1
   LET k=A(i)
   IF k=0 THEN !係数が0以外なら
   ELSE
      FOR j=bb TO 0 STEP -1
         LET S(i+j)=S(i+j)+k*B(j) !すべての係数をかける
      NEXT j
   END IF
NEXT i
LET ss=aa+bb!次数 ※その補正
END SUB


EXTERNAL SUB PolynomialQuotientRemainder(aa,A(),bb,B(), qq,Q(),rr,R()) !除算 ※被除数=商*除数+余り
OPTION ARITHMETIC RATIONAL !有理数モード
IF bb=0 AND B(0)=0 THEN !除数が0なら
   PRINT "0で割ることはできません。"
   STOP
ELSE
   MAT Q=ZER !商
   MAT R=A !余り
   FOR t=aa TO bb STEP -1 !被除数の次数が除数のより大きいなら
      IF R(t)=0 THEN !係数が0以外なら
      ELSE
         LET k=R(t)/B(bb) !商の係数、その次数
         LET w=t-bb
         LET Q(w)=k !商

         FOR i=bb TO 0 STEP -1 !余り ※R=A-k*B
            LET R(w+i)=R(w+i)-k*B(i)
         NEXT i
      END IF
   NEXT t
   LET qq=MAX(aa-bb,0) !次数
   IF aa>=bb THEN LET t=MAX(bb-1,0) ELSE LET t=aa !次数
   FOR rr=t TO 1 STEP -1 !※その補正
      IF R(rr)<>0 THEN EXIT FOR
   NEXT rr
END IF
END SUB


!表示関連

EXTERNAL SUB PolynomialDisplay(aa,A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
OPTION ARITHMETIC RATIONAL !有理数モード
CALL mono_disp(A(aa),aa) !最初の項
FOR i=aa-1 TO 0 STEP -1 !次項
   LET w=A(i)
   IF w>0 THEN PRINT "+";
   IF w<>0 OR aa=0 THEN CALL mono_disp(w,i)
NEXT i
END SUB

EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
OPTION ARITHMETIC RATIONAL !有理数モード
IF k<>0 THEN !x^nで
   IF ak=0 OR ak=1 THEN !係数が0,1なら
   ELSEIF ak=-1 THEN !係数が-1なら
      PRINT "-"; !符号
   ELSE
      PRINT STR$(ak);"*";
   END IF
END IF
IF k=0 THEN !次数が0なら
   PRINT STR$(ak);
ELSE
   IF ak<>0 THEN !係数が0以外なら
      PRINT "X";
      IF k<>1 THEN PRINT "^";STR$(k); !次数が1以外なら
   END IF
END IF
END SUB


実行結果

1
2  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

1
-3 -1  0  0

-1 -2
2 -5
-2 -1


※サブルーチン部分は、POLY.LIB として共有利用してください。



●例

!問題
!2個のサイコロを投げるとき、目の和が8となる場合の数は、
!多項式 (x+x^2+x^3+x^4+x^5+x^6)^2 を展開したときの、x^8の係数を調べればよい。

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

DATA 6 !(x+x^2+x^3+x^4+x^5+x^6)^2
DATA 0,1,1,1,1,1,1
LET N=2 !べき乗

READ aa
DIM A(0 TO aa)
MAT READ A

DIM B(0 TO aa*N) !展開した多項式
CALL PolynomialPowerN(aa,A, N, bb,B)
PRINT bb
MAT PRINT B;

END

MERGE "POLY.LIB"


実行結果

12
0  0  1  2  3  4  5  6  5  4  3  2  1



●例

!問題
!3次方程式f(x)=x^3+x^2-4x+1=0の1つの解をαとする。
!他の2つの解は、-α^2-2α+2, α^2+α-3と表される。

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

DATA 3 !f(x)=x^3+x^2-4x+1=0
DATA 1,-4,1,1
DATA 2 !-α^2-2α+2
DATA 2,-2,-1
DATA 2 !α^2+α-3
DATA -3,1,1

READ ff !f(x)を読み込む
DIM F(0 TO ff)
MAT READ F

READ gg !g(α)を読み込む
DIM G(0 TO gg)
MAT READ G

DIM S(0 TO MAX_DEGREE)
CALL PolynomialComposition(ff,F,gg,G, ss,S) !f(-α^2-2α+2)を求める
PRINT ss
MAT PRINT S;

DIM Q(0 TO MAX_DEGREE),R(0 TO MAX_DEGREE)
CALL PolynomialQuotientRemainder(ss,S,ff,F, qq,Q,rr,R) !f(α)=0を考慮する
PRINT qq
MAT PRINT Q;
PRINT rr !余りが0となる
MAT PRINT R;


PRINT

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

READ hh !h(α)を読み込む
DIM H(0 TO hh)
MAT READ H

CALL PolynomialComposition(ff,F,hh,H, ss,S) !f(α^2+α-3)を求める
PRINT ss
MAT PRINT S;

CALL PolynomialQuotientRemainder(ss,S,ff,F, qq,Q,rr,R) !f(α)=0を考慮する
PRINT qq
MAT PRINT Q;
PRINT rr !余りが0となる
MAT PRINT R;

END

MERGE "POLY.LIB"


実行結果

6
5 -24  16  20 -5 -6 -1

3
5 -4 -5 -1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

0
0  0  0  0  0  0  0


6
-5  17  9 -15 -5  3  1

3
-5 -3  2  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

0
0  0  0  0  0  0  0


 

Re: 多項式の計算

 投稿者:山中和義  投稿日:2013年 8月 1日(木)11時04分34秒
  > No.3107[元記事へ]

続き

> 多項式を使って数学の問題を解く

●例

!問題
!3次方程式 x^3-6x^2+11x-6=0 の解から、2を減じた解をもつ3次方程式を作れ。

!定理(解より一定数を減ずる)
!F(X)=0の解を、α,β,γとする。
!このとき、α-p,β-p,γ-pを解とする方程式は、F(X+p)=0

!Y=F(X)のグラフを、X軸方向に、-pだけ平行移動すればよい。

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

DATA 3 !x^3-6x^2+11x-6=0
DATA -6,11,-6,1

READ ff
DIM F(0 TO ff)
MAT READ F

LET aa=1 !x+2
DIM A(0 TO aa)
LET A(1)=1
LET A(0)=2

DIM T(0 TO MAX_DEGREE)
CALL PolynomialComposition(ff,F,aa,A, tt,T) !F(X+2)
PRINT tt
MAT PRINT T;


!問題
!3次方程式 x^3-6x^2+11x-6=0 の解を、2倍した解をもつ3次方程式を作れ。

!定理(解に一定数を乗ずる)
!F(X)=0の解を、α,β,γとする。
!このとき、kα,kβ,kγを解とする方程式は、F(X/k)=0

LET bb=1 !x/2
DIM B(0 TO bb)
LET B(1)=1/2
LET B(0)=0

CALL PolynomialComposition(ff,F,bb,B, tt,T) !F(X/2)
MAT T=(1/T(tt))*T !最高次数の係数を1にする
PRINT tt
MAT PRINT T;

END

MERGE "POLY.LIB"


実行結果

3
0 -1  0  1

3
-48  44 -12  1



●例

!問題
!αが方程式 x^3+3x-1=0 の解であるとき、1/(α^2+α+2)をαの多項式で表せ。

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

DATA 3 !x^3+3x-1
DATA -1,3,0,1
READ ff
DIM F(0 TO ff)
MAT READ F

DATA 2 !x^2+x+2
DATA 2,1,1
READ gg
DIM G(0 TO gg)
MAT READ G

DIM S(0 TO MAX_DEGREE),T(0 TO MAX_DEGREE),C(0 TO MAX_DEGREE)
CALL PolynomialExtendedGCD(ff,F,gg,G, ss,S,tt,T,cc,C) !sf+tg=(f,g)
PRINT ss
MAT PRINT S;
PRINT tt
MAT PRINT T; !s*0+tg=(f,g)より、1/g=t/(f,g)
PRINT cc !(f,g)
MAT PRINT C;

END

MERGE "POLY.LIB"


実行結果

2
-1/7 -2/7  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

3
3/7 -1/7  2/7  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

0
1  0  0


 

Re: 多項式の計算

 投稿者:山中和義  投稿日:2013年 8月 8日(木)11時10分8秒
  > No.3108[元記事へ]

続き

●例
多項式補間 - n個の点を通る(n-1)次の多項式


OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

DATA 5 !n個の点
DATA 0, 1, 3, 6, 7 !X座標
DATA 0.8, 3.1, 4.5, 3.9, 2.8 !Y座標

READ N
DIM X(0 TO N-1),Y(0 TO N-1) !(x[i],y[i])
MAT READ X
MAT READ Y


DIM P(0 TO N-1) !(展開された)多項式
CALL PolynomialInterpolationL(N,X,Y, pp,P)
PRINT pp
MAT PRINT P;

FOR t=0 TO 7 STEP 0.5
   LET s=P(N-1) !ホーナー法
   FOR i=N-2 TO 0 STEP -1
      LET s=s*t+P(i)
   NEXT i
   PRINT USING "-%.##   -##.##########": t, s
NEXT t

END

!POLY.LIB

!多項式補間

EXTERNAL SUB PolynomialInterpolationN(N,X(),Y(), pp,P()) !ニュートン補間
OPTION ARITHMETIC RATIONAL !有理数モード
!f(x)=a[0]+a[1](x-x[0])+a[2](x-x[0])(x-x[1])+ … +a[n-2](x-x[0])(x-x[1]) … (x-x[n-2])
DIM A(0 TO N-1) !係数
DIM W(0 TO N-1)
FOR i=0 TO N-1
   LET W(i)=Y(i)
   FOR J=i-1 TO 0 STEP -1
      LET W(J)=(W(J+1)-W(J))/(X(i)-X(J))
   NEXT J
   LET A(i)=W(0)
NEXT i
!!!MAT PRINT A; !debug

MAT P=ZER !f(x)=(…((a[n-1](x-x[n-2])+a[n-2])(x-x[n-3))+a[n-3]) … +a[1])(x-x[0])+a[0]
LET P(0)=A(N-1)
LET pp=0
FOR i=N-2 TO 0 STEP -1 !ホーナー法 s=s*(X-x[i])+a[i]
   FOR J=pp TO 0 STEP -1
      LET P(J+1)=P(J+1)+P(J) !s*X
      LET P(J)=-P(J)*X(i) !-s*x[i]
   NEXT J
   LET P(0)=P(0)+A(i) !+a[i]
   LET pp=pp+1
NEXT i
CALL Poly_DegUpdt(pp,P) !※その補正
END SUB


EXTERNAL SUB PolynomialInterpolationL(N,X(),Y(), pp,P()) !ラグランジュ補間
OPTION ARITHMETIC RATIONAL !有理数モード
MAT P=ZER
DIM W(0 TO N-1)
FOR i=0 TO N-1 !Σy[i]Π{(X-x[j])/(x[i]-x[j])}
   MAT W=ZER !分子側
   LET W(0)=1
   LET ww=0
   FOR J=0 TO N-1
      IF i<>J THEN
         FOR K=ww TO 0 STEP -1 !展開する w=w*(X-x[j])
            LET W(K+1)=W(K+1)+W(K) !w*X
            LET W(K)=-W(K)*X(J) !-w*x[j]
         NEXT K
         LET ww=ww+1
      END IF
   NEXT J

   LET s=1 !分母側
   FOR J=0 TO N-1
      IF i<>J THEN LET s=s*(X(i)-X(J))
   NEXT J

   MAT W=(Y(i)/s)*W !Σ
   MAT P=P+W
NEXT i
LET pp=N-1 !次数
CALL Poly_DegUpdt(pp,P) !※その補正
END SUB


EXTERNAL SUB Poly_DegUpdt(aa,A()) !次数を補正する
OPTION ARITHMETIC RATIONAL !有理数モード
FOR i=aa TO 1 STEP -1
   IF A(i)<>0 THEN EXIT FOR
NEXT i
LET aa=i
END SUB


実行結果

4
4/5  4453/1400 -25829/25200  1937/12600 -239/25200

0.00      .8000000000
0.50     2.1527405754
1.00     3.1000000000
1.50     3.7357366071
2.00     4.1396825397
2.50     4.3773437500
3.00     4.5000000000
3.50     4.5447048611
4.00     4.5342857143
4.50     4.4773437500
5.00     4.3682539683
5.50     4.1871651786
6.00     3.9000000000
6.50     3.4584548611
7.00     2.8000000000

 

約数の個数

 投稿者:山中和義  投稿日:2013年 8月16日(金)19時37分23秒
  問題
約数の個数がC個になる最小の数Nを求める。
例
 約数の個数が100個になる最小の数が45360である。
 約数の個数が200個になる最小の数は498960である。

考察
C=a*b*c*…として、n=p^(a-1)*q^(b-1)*r^(c-1)* …

個数Cを約数の積に分解する。並びは大きい順とする。
 例 48の場合
 48=24*2=16*3=12*4=12*2*2=8*6=8*3*2=6*4*2=4*4*3=4*3*2*2=3*2*2*2*2
次に、素数を小さい順に割り当てて、約数をC個もつ数を生成する。
 12*2*2の場合、2^11*3^1*5^1
(終り)

個数Cが奇数の場合、Nは平方数である。

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


OPTION ARITHMETIC RATIONAL !多桁の整数

DATA 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97 !素数
DIM P(20)
MAT READ P

FOR C=1 TO 1000 !個数
   LET N=2^(C-1) !仮の最小
   CALL try(1,P,1,C, N)
   PRINT STR$(C);":"; N
NEXT C

END

EXTERNAL SUB try(i,P(),S,F, N) !約数の積に分解する 例 12の場合、12=6*2=4*3=3*2*2
OPTION ARITHMETIC RATIONAL !多桁の整数
FOR D=1 TO INT(F/2) !約数の候補
   IF MOD(F,D)=0 THEN !大きい順に F/1,F/2,F/3,…,3,2
      LET FD=F/D
      LET W=S*P(i)^(FD-1) !6*2のとき、2^5*3^1とする
      IF W<N THEN !W≧Nなら、これ以降は可能性はない
         IF D=1 THEN !分解が完了なら
            LET N=W !最小のもの
         ELSE
            CALL try(i+1,P,W,D, N) !次へ
         END IF
      END IF
   END IF
NEXT D
END SUB


実行結果

1 : 1
2 : 2
3 : 4
4 : 6
5 : 16
6 : 12
7 : 64
8 : 24
9 : 36
10 : 48
11 : 1024
12 : 60
13 : 4096
14 : 192
15 : 144
16 : 120
17 : 65536
18 : 180
19 : 262144
20 : 240
21 : 576
22 : 3072
23 : 4194304
24 : 360
25 : 1296
26 : 12288
27 : 900
28 : 960
29 : 268435456
30 : 720
31 : 1073741824
32 : 840
33 : 9216
34 : 196608
35 : 5184
36 : 1260
37 : 68719476736
38 : 786432
39 : 36864
40 : 1680
41 : 1099511627776
42 : 2880
43 : 4398046511104
44 : 15360
45 : 3600
46 : 12582912
47 : 70368744177664
48 : 2520
49 : 46656
50 : 6480

 

Re: 約数の個数

 投稿者:GAI  投稿日:2013年 8月17日(土)07時58分54秒
  > No.3110[元記事へ]

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

私的数学塾で投稿していた任意の約数の個数に対する最小数を見つけるプログラムを見せてもらいまして、こんな効率よい組み方が可能であると感心いたしました。
(思ったよりもスッキリと少ないステップで記述できるんですね。)
自分はまだプログラムを作るときの全体の構成方法や、細かい部分を実行させるためのテクニックが(どんな変数を導入して、なにを変化させていけばいいのかが見えてきません。)
圧倒的に不足しています。
掲載されたプログラムをじっくり分析させてもらって、その流れを辿っていきたいと思います。
是非外部副プログラムを使って、仕事の割り当てをしていくコツを身につけたいです。
丸一日かけても見えなかった線がこうして示されたことで、どこで迷っていたかが認識できるようになりました。
プログラムの掲載ありがとうございました。(一日でもはやく、山中さんのようになりたい!)
 

教えて下さい

 投稿者:GAI  投稿日:2013年 8月17日(土)15時19分59秒
  プログラムを分析していたら、例えばC=24で
24=24*1
  =12*2
  =8*3
  =6*4
  =6*2*2
  =4*3*2
  =3*2*2*2
というように、24をいろいろな積で表すすべての可能性に分解してそれから構成される数N
(上からN=8388608,6144,1152,864,480,360,420)
を調べ、この中の最小で360を決めているように読めました。
そこで今度はN=96なら、これを幾つかの積で表す場合
手動で行ってみるとかなり面倒なことになり
96=96*1
  =48*2
  =32*3
  =24*4
  =16*6
  =12*8
  =24*2*2
  =16*3*2
  =12*4*2
  =8*6*2
  =8*4*3
  =6*4*4
  =12*2*2*2
  =8*3*2*2
  =6*4*2*2
  =4*4*3*2
  =6*2*2*2*2
  =4*3*2*2*2
  =3*2*2*2*2*2

と全部で19タイプであらわすことができました。
たぶんこの分解方法の総数はA034836で与えられるのであろうが、例96のように具体的にどう分解されるかをみるときには、どのようなプログラムになるのでしょうか?
例の約数の個数で使われた副プログラムのアイデアが上手く使えそうなのですが、未だ作りかえる技術を持ちません。
重ね重ねよろしくお願いします。
 

Re: 教えて下さい

 投稿者:山中和義  投稿日:2013年 8月17日(土)20時15分7秒
  > No.3112[元記事へ]

GAIさんへのお返事です。

> そこで今度はN=96なら、これを幾つかの積で表す場合
> 手動で行ってみるとかなり面倒なことになり
> 96=96*1
>   =48*2
>   =32*3
>   =24*4
>   =16*6
>   =12*8
>   =24*2*2
>   =16*3*2
>   =12*4*2
>   =8*6*2
>   =8*4*3
>   =6*4*4
>   =12*2*2*2
>   =8*3*2*2
>   =6*4*2*2
>   =4*4*3*2
>   =6*2*2*2*2
>   =4*3*2*2*2
>   =3*2*2*2*2*2
>
> と全部で19タイプであらわすことができました。

前回と同様に外部ルーチンで、NをN/DとDに分解します。
再帰呼び出しで、DをNとして分解を続けます。


OPTION ARITHMETIC RATIONAL !多桁の整数

DIM F(20) !約数の積

PRINT " 1" !1のとき
PRINT "1: 1 個"

FOR N=2 TO 100 !2以上の自然数
   LET C=0
   CALL try(1,F,N, C)
   PRINT STR$(N);":"; C;"個"
NEXT N

END

EXTERNAL SUB try(i,F(),N, C) !約数の積に分解する 例 12の場合、12=6*2=4*3=3*2*2
OPTION ARITHMETIC RATIONAL !多桁の整数
FOR D=1 TO INT(N/2) !約数の候補
   IF MOD(N,D)=0 THEN !大きい順に F/1,F/2,F/3,…,3,2
      LET F(i)=N/D
      IF i=1 OR (i>1 AND F(i-1)>=F(i)) THEN

         IF D=1 THEN !分解が完了なら
            LET C=C+1

            PRINT F(1); !結果を表示する
            FOR K=2 TO i
               PRINT "*";F(K);
            NEXT K
            PRINT
         ELSE
            CALL try(i+1,F,D, C) !次へ
         END IF

      END IF
   END IF
NEXT D
END SUB


実行結果

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


http://oeis.org/A034836 は、3つに分解できる個数なので、

96  ← 96 * 1 * 1
48 * 2  ← 48 * 2 * 1
32 * 3  ← 32 * 3 * 1
24 * 4  ←  24 * 4 * 1
24 * 2 * 2
16 * 6  ← 16 * 6 * 1
16 * 3 * 2
12 * 8  ← 12 * 8 * 1
12 * 4 * 2
12 * 2 * 2 * 2  ← NG
8 * 6 * 2
8 * 4 * 3
8 * 3 * 2 * 2  ← NG
6 * 4 * 4
6 * 4 * 2 * 2  ← NG
6 * 2 * 2 * 2 * 2  ← NG
4 * 4 * 3 * 2  ← NG
4 * 3 * 2 * 2 * 2  ← NG
3 * 2 * 2 * 2 * 2 * 2  ← NG
96: 19 個

の7個は、NGとなります。
 

Re: 教えて下さい

 投稿者:GAI  投稿日:2013年 8月17日(土)20時52分7秒
  > No.3113[元記事へ]

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


ありがとうございます。

A034836は
勘違いしておりました。



http://oeis.org/A001055
が示したいところでした。
 

Re: 教えて下さい

 投稿者:山中和義  投稿日:2013年 8月18日(日)10時21分6秒
  > No.3113[元記事へ]

GAIさんへのお返事です。

効率を考えると、約数の検索範囲は、1から√nまでとするのがよいでしょう。
処理時間はO(n/2)がO(√n)になるので、大きなnについてはかなり期待できます。
ただし、分解式の出現する順番は、降順(1番目の数)になりません。


!問題
!自然数Nを正の約数の積に分解する
!例 48の場合
! 48
! 24 * 2
! 16 * 3
! 12 * 4
! 12 * 2 * 2
! 8 * 6
! 8 * 3 * 2
! 6 * 4 * 2
! 6 * 2 * 2 * 2
! 4 * 4 * 3
! 4 * 3 * 2 * 2
! 3 * 2 * 2 * 2 * 2
!計 12個

!参考サイト http://oeis.org/A001055

OPTION ARITHMETIC RATIONAL !多桁の整数

DIM F(20) !約数の積

FOR N=1 TO 100 !自然数
   LET C=0
   CALL try(1,F,N, C)
   PRINT STR$(N);":"; C;"個"
NEXT N

END

EXTERNAL SUB try(i,F(),N, C) !約数の積に分解する 例 12の場合、12=6*2=4*3=3*2*2
OPTION ARITHMETIC RATIONAL !多桁の整数
FOR D=1 TO INTSQR(N) !約数の候補
   IF MOD(N,D)=0 THEN
      LET W=N/D
      IF i=1 OR (i>1 AND F(i-1)>=W) THEN !並びは大きい順に ※1番目は無条件

         LET F(i)=W
         IF D=1 THEN !分解が完了なら
            LET C=C+1

            PRINT F(1); !結果を表示する
            FOR K=2 TO i
               PRINT "*";F(K);
            NEXT K
            PRINT
         ELSE
            CALL try(i+1,F,D, C) !次へ
         END IF

      END IF

      IF D>1 AND D*D<>N THEN !平方数以外なら、もう一方も
         IF i=1 OR (i>1 AND F(i-1)>=D) THEN

            LET F(i)=D
            CALL try(i+1,F,W, C) !次へ

         END IF
      END IF

   END IF
NEXT D
END SUB


実行結果(一部)

96
48 * 2
32 * 3
3 * 2 * 2 * 2 * 2 * 2
24 * 4
24 * 2 * 2
4 * 3 * 2 * 2 * 2
4 * 4 * 3 * 2
16 * 6
16 * 3 * 2
6 * 2 * 2 * 2 * 2
6 * 4 * 4
6 * 4 * 2 * 2
12 * 8
12 * 4 * 2
12 * 2 * 2 * 2
8 * 6 * 2
8 * 4 * 3
8 * 3 * 2 * 2
96: 19 個

 

トレースしてみて

 投稿者:GAI  投稿日:2013年 8月19日(月)12時27分2秒
  > No.3113[元記事へ]

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


> 前回と同様に外部ルーチンで、NをN/DとDに分解します。
> 再帰呼び出しで、DをNとして分解を続けます。
>
>
> OPTION ARITHMETIC RATIONAL !多桁の整数
>
> DIM F(20) !約数の積
>
> PRINT " 1" !1のとき
> PRINT "1: 1 個"
>
> FOR N=2 TO 100 !2以上の自然数
>    LET C=0
>    CALL try(1,F,N, C)
>    PRINT STR$(N);":"; C;"個"
> NEXT N
>
> END
>
> EXTERNAL SUB try(i,F(),N, C) !約数の積に分解する 例 12の場合、12=6*2=4*3=3*2*2
> OPTION ARITHMETIC RATIONAL !多桁の整数
> FOR D=1 TO INT(N/2) !約数の候補
>    IF MOD(N,D)=0 THEN !大きい順に F/1,F/2,F/3,…,3,2
>       LET F(i)=N/D
>       IF i=1 OR (i>1 AND F(i-1)>=F(i)) THEN
>
>          IF D=1 THEN !分解が完了なら
>             LET C=C+1
>
>             PRINT F(1); !結果を表示する
>             FOR K=2 TO i
>                PRINT "*";F(K);
>             NEXT K
>             PRINT
>          ELSE
>             CALL try(i+1,F,D, C) !次へ
>          END IF
>
>       END IF
>    END IF
> NEXT D
> END SUB
>


このプログラムのトレースをとって動きの変化を追ってみました。
(N=24で固定して見てみました。)
例のtry(i+1,F,D,C)
を効率よく繰り返し使用されていくことが見えてきました。
重要な部分が
EXTERNAL SUB try(i,F(),N,C)
に対し、Nの部分がDへ変化している所なんですね。
ただしIFの構文が何重にも重なっているので、これが次に何処に跳んでいくのかを探すのが大変でした。
SUB try の中に更にtry が入り込んでいるところや、変数の多さ(N,C,K,D,I)に何が今変化しており、なんの値が何を意味していたのか、現在どんな部分の調査をしているのかを確認するのに目が回る思いでした。
全体を通して感じることは、これだけの変数をどこでどの様に配置しておけば良いのかや、IFの条件を
どんな関数や論理式でチェックしておけばいいのかをどの様に判断されているのだろう?
もちろんプログラムだから他の方法でも考えられるだろうが、これだけコンパクトにまとめることは不可能ではないかと感じました。
ただし、人間ならたちどころにこれは考えなくてもいいと判断できる所でも、なんと忠実に長大な処理をした上でその不可能性をやっている所がおもしろいです。
(逆に人間は一瞬でそのあたりの判断が下せる能力とは、どんな部分で行っているのでしょうね。)
近頃マービン・ミンスキーという人工知能の研究者が著した”心の社会学”という本を読んでみて、人間の心が如何なるシステムを取り得るかをこれだけ詳しく考察しているんだと驚いてしまいました。
再帰プログラムという考え方はいろいろ使えそうですね。
 

最小多項式を求める

 投稿者:山中和義  投稿日:2013年 8月20日(火)11時36分53秒
  > No.3105[元記事へ]

問題
(1-2^(1/3)+4^(1/3))^3を簡単にしなさい。

答え
α=1-2^(1/3)+4^(1/3)を解にもつ3次方程式f(x)(最小多項式)を求めると、f(x)=x^3-3*x^2+9*x-9
f(α)=0より、α^3=3α^2-9α+9
αに数値を代入して、整理すると、
3(1-2^(1/3)+4^(1/3))^2 -9(1-2^(1/3)+4^(1/3)) +9
=3{1+4^(1/3)+2*2^(1/3)-2*2^(1/3)-2*2+2*4^(1/3)} -9(1-2^(1/3)+4^(1/3)) +9
=9*(2^(1/3)-1)
(終り)

別解
x=2^(1/3)とおく。
与式
=(1-x+x^2)^3
={(1+x)(1-x+x^2)/(1+x)}^3
=(x^3+1)^3/(x+1)^3 ∵a^3+b^3=(a+b)(a^2-ab+b^2)より
=27/(x+1)^3 ∵x^3=2より
=27/(x^3+3x^2+3x+1)
=9/(x^2+x+1) ∵x^3=2より
=9(x-1)/{(x-1)(x^2+x+1)}
=9(x-1)/(x^3-1) ∵a^3-b^3=(a+b)(a^2+ab+b^2)より
=9(x-1) ∵x^3=2より
(終り)

別解
x=2^(1/3)とおく。
与式
=(1-x+x^2)^3
=x^6-3x^5+6x^4-7x^3+6x^2-3x+1
=(x^2-3^2+6x-5)(x^3-2)+(9x-9)
≡9x-9 mod (x^3-2)
(終り)



!Q上の最小多項式を求める

!最小多項式 f(x)=(x-α[1])(x-α[2])(x-α[3])…(x-α[n]) なので、
!展開式 f(x)=c[n]x^n+c[n-1]x^(n-1)+ … +c[1]x+c[0] を計算する。

OPTION ARITHMETIC COMPLEX !複素数モード
LET i=COMPLEX(0,1) !虚数単位


!x=1-2^(1/3)+4^(1/3)の場合、f(x)=x^3-3*x^2+9*x-9
DEF G(y)=1-y+y^2
LET y=2^(1/3)
LET w=EXP(2*PI*i/3) !y^3-1=0(y≠1)の解のひとつ、すなわち ω=(-1+(√3)i)/2

LET N=3 !解の個数(共役の個数)
DIM A(N) !α[1],α[2],…,α[n]
LET A(1)=G(    y)
LET A(2)=G(  w*y)
LET A(3)=G(w^2*y)


!(x-α[1])(x-α[2]) … (x-α[n])を展開する
DIM C(0 TO N) !係数
LET C(1)=1 !X-α[1] !n個の解について
LET C(0)=-A(1)
FOR K=2 TO N !ホーナー法による
   LET C(K)=0
   FOR J=K-1 TO 0 STEP -1 !展開する w=w*(X-α[k])
      LET C(J+1)=C(J+1)+C(J)
      LET C(J)=-C(J)*A(K)
   NEXT J
NEXT K

MAT PRINT C; !1,x,…,x^(n-1),x^nの係数

END


実行結果

(-9  7.79216101365332E-15) ( 9 -4.88498130835069E-15) (-3 -8.88178419700125E-16)  1



例
!x=2^(1/3)+√(-2)の場合、f(x)=x^6+6x^4-4x^3+12x^2+24x+12
DEF G(x1,x2)=x1+x2
LET x1=2^(1/3)
LET x2=SQR(-2)
LET w=EXP(2*PI*i/3) !x^3-1=0(x≠1)の解のひとつ、すなわち (-1+(√3)i)/2

LET N=3*2 !共役の個数
DIM A(N)
LET A(1)=G(    x1,  x2)
LET A(2)=G(  w*x1,  x2)
LET A(3)=G(w^2*x1,  x2)
LET A(4)=G(    x1, -x2)
LET A(5)=G(  w*x1, -x2)
LET A(6)=G(w^2*x1, -x2)


例
!x=3^(1/2)+2^(1/3)の場合、f(x)=x^6-9x^4-4x^3+27x^2-36x-23
DEF G(x1,x2)=x1+x2
LET x1=3^(1/2)
LET x2=2^(1/3)
LET v=EXP(2*PI*i/2) !x^2-1=0(x≠1)の解のひとつ、すなわち -1
LET w=EXP(2*PI*i/3) !x^3-1=0(x≠1)の解のひとつ、すなわち (-1+(√3)i)/2

LET N=2*3 !共役の個数
DIM A(N)
LET A(1)=G(  x1,     x2)
LET A(2)=G(v*x1,   w*x2)
LET A(3)=G(  x1, w^2*x2)
LET A(4)=G(v*x1,     x2)
LET A(5)=G(  x1,   w*x2)
LET A(6)=G(v*x1, w^2*x2)

 

Re: 最小多項式を求める

 投稿者:山中和義  投稿日:2013年 8月21日(水)11時40分28秒
  > No.3117[元記事へ]

> 問題
> (1-2^(1/3)+4^(1/3))^3を簡単にしなさい。
>
> 答え
> α=1-2^(1/3)+4^(1/3)を解にもつ3次方程式f(x)(最小多項式)を求めると、f(x)=x^3-3*x^2+9*x-9

次の問題に置き換えて、3次方程式(最小多項式)を得る。

問題
αが方程式 x^3-2=0 の解であるとき、α^2-α+1を解とする3次方程式を求めよ。

答え
求める3次方程式をf(x)=x^3+Ax^2+Bx+Cとする。
y=α^2-α+1とすると、
  y^3=α^6-3α^5+6α^4-7α^3+6α^2-3α+1≡9α-9 mod (α^3-2)
 Ay^2=A(α^4-2α^3+3α^2-2α+1)≡A(3α^2-3) mod (α^3-2)
   By≡B(α^2-α+1) mod (α^3-2)
    C≡C mod (α^3-2)
より、
 f(y)=(-9-3A+B+C)+(9-B)α+(3A+B)α^2 mod (α^3-2)
また、yは解なので、f(y)=0である。
よって、連立方程式
 -9-3A+B+C=0
 9-B=0
 3A+B=0
を解くと、A=-3、B=9、C=-9
(終り)


OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

!DATA 3 !x^3+3x^2-1
!DATA -1,0,3,1
DATA 3 !x^3-2
DATA -2,0,0,1

READ ff
DIM F(0 TO ff)
MAT READ F

!DATA 2 !α^2+α+1
!DATA 1,1,1
DATA 2 !α^2-α+1
DATA 1,-1,1

READ gg
DIM G(0 TO gg)
MAT READ G

LET N=3 !n次方程式

DIM A(0 TO N,0 TO N) !1,A,B,C,… の係数
MAT A=ZER

FOR J=N TO 0 STEP -1

   DIM W(0 TO MAX_DEGREE) !べき乗を展開する
   CALL PolynomialPowerN(gg,G,J, ww,W)
   CALL PolynomialDisplay(ww,W)
   PRINT

   DIM Q(0 TO MAX_DEGREE),R(0 TO MAX_DEGREE) !剰余を考える
   CALL PolynomialQuotientRemainder(ww,W,ff,F, qq,Q,rr,R)
   CALL PolynomialDisplay(rr,R)
   PRINT

   FOR K=0 TO N !係数を得る
      LET A(N-K,N-J)=R(N-K)
   NEXT K

NEXT J
LET A(N,0)=1
MAT PRINT A; !debug


DIM b(0 TO N)
MAT b=ZER
LET b(N)=1

DIM x(0 TO N),iA(0 TO N,0 TO N) !Ax=bを解く
MAT iA=INV(A)
MAT x=iA*b
MAT PRINT x; !1,A,B,C,…

END

MERGE "POLY.LIB"


実行結果

X^6-3*X^5+6*X^4-7*X^3+6*X^2-3*X+1
9*X-9
X^4-2*X^3+3*X^2-2*X+1
3*X^2-3
X^2-X+1
X^2-X+1
1
1
-9 -3  1  1
9  0 -1  0
0  3  1  0
1  0  0  0

1 -3  9 -9

 

Re: 最小多項式を求める

 投稿者:山中和義  投稿日:2013年 8月23日(金)09時42分22秒
  > No.3118[元記事へ]

> 問題
> (1-2^(1/3)+4^(1/3))^3を簡単にしなさい。
>
> 答え
> α=1-2^(1/3)+4^(1/3)を解にもつ3次方程式f(x)(最小多項式)を求めると、f(x)=x^3-3*x^2+9*x-9

参考サイト http://www.rkmath.rikkyo.ac.jp/~kida/intbasis.pdf 3.最小多項式 より

●解と係数の関係を用いる

問題
αが方程式 x^3-2=0 の解であるとき、α^2-α+1を解とする3次方程式を求めよ。

答え
まず、次の問題を解いて関係式を得る。

 類題
 αが方程式 x^3-2=0 の解であるとき、y=α^2 を解とする3次方程式を求めよ。
 答え
 0=α^3-2=α(α^2)-2より、αy=2 ∴α^2y^2=2^2 ∴y(y^2)=4 ∴y^3-4=0
 (終り)

α[1]^2,α[2]^2,α[3]^2をy^3-4=0の解とすると、解と係数の関係より、
α[1]^2 +α[2]^2 +α[3]^2=0
α[1]^2α[2]^2 +α[2]^2α[3]^2 +α[3]^2α[1]^2=0
α[1]^2 α[2]^2 α[3]^2=4


また、α[1],α[2],α[3]をx^3-2=0の解とすると、解と係数の関係より、
α[1]+α[2]+α[3]=0
α[1]α[2]+α[2]α[3]+α[3]α[1]=0
α[1]α[2]α[3]=2


y[i]=α[i]^2-α[i]+1(i=1,2,3)に対して、

y[1]+y[2]+y[3]
=(α[1]^2-α[1]+1)+(α[2]^2-α[2]+1)+(α[3]^2-α[3]+1)
=(α[1]^2+α[2]^2+α[3]^2) -(α[1]+α[2]+α[3]) +3
=0-0+3
=3

y[1]y[2]
=(α[1]^2-α[1]+1)(α[2]^2-α[2]+1)
=α[1]^2α[2]^2 -α[1]α[2](α[1]+α[2]) +(α[1]^2+α[2]^2) +α[1]α[2] -(α[1]+α[2]) +1
=α[1]^2α[2]^2 -α[1]α[2](-α[3]) +(-α[3]^2) +α[1]α[2] -(-α[3]) +1
=α[1]^2α[2]^2 +2 -α[3]^2 +α[1]α[2] +α[3] +1
=α[1]^2α[2]^2 -α[3]^2 +α[1]α[2] +α[3] +3
なので、
y[1]y[2]+y[2]y[3]+y[3]y[1]
=0-0+0+0+3*3
=9

y[1]y[2]y[3]
=(α[1]^2α[2]^2 -α[3]^2 +α[1]α[2] +α[3] +3)(α[3]^2-α[3]+1)
= α[1]^2α[2]^2α[3]^2-α[1]^2α[2]^2α[3]+α[1]^2α[2]^2
 -α[3]^4+α[3]^3-α[3]^2
 +α[1]α[2]α[3]^2-α[1]α[2]α[3]+α[1]α[2]
 +α[3]^3-α[3]^2+α[3]
 +3α[3]^2-3α[3]+3
= 4-2α[1]α[2]+α[1]^2α[2]^2
 -2α[3]+2-α[3]^2
 +2α[3]-2+α[1]α[2]
 +2-α[3]^2+α[3]
 +3α[3]^2-3α[3]+3
=9-α[1]α[2]+α[1]^2α[2]^2+α[3]^2-2α[3]
=9+(-α[1]α[2]α[3]^2+α[1]^2α[2]^2α[3]^2+α[3]^4-2α[3]^3)/α[3]^2
=9+(-2α[3]+4+2α[3]-2*2)/α[3]^2
=9+0/α[3]^2
=9

よって、解と係数の関係より、y^3-3y^2+9y-9=0



●正則(線形)表現を用いる

!問題
!αが方程式 x^3-2=0 の解であるとき、α^2-α+1を解とする3次方程式を求めよ。
!答え x^3-3x^2+9x-9

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20

DATA 3 !x^3-2
DATA -2,0,0,1

READ ff
DIM F(0 TO ff)
MAT READ F

DATA 2 !y=α^2-α+1
DATA 1,-1,1

READ gg
DIM G(0 TO gg)
MAT READ G

LET N=ff !n次方程式

DIM A(N,N) !s(α^k)に対応する行列
MAT A=ZER

FOR J=0 TO N-1

   DIM S(0 TO MAX_DEGREE)
   MAT S=ZER !基底 1,α,α^2,…
   LET S(J)=1
   LET ss=J

   DIM W(0 TO MAX_DEGREE) !y倍
   CALL PolynomialMultiply(gg,G,ss,S, ww,W)
   CALL PolynomialDisplay(ww,W)
   PRINT

   DIM Q(0 TO MAX_DEGREE),R(0 TO MAX_DEGREE) !剰余を考える
   CALL PolynomialQuotientRemainder(ww,W,ff,F, qq,Q,rr,R)
   CALL PolynomialDisplay(rr,R)
   PRINT

   FOR K=0 TO N-1 !係数を得る
      LET A(J+1,K+1)=R(K)
   NEXT K

NEXT J
MAT PRINT A; !debug


!n次正方行列Aの固有多項式(eigenpolynomial)ΦA(t)=det(tE-A)=t^n+c1*t^(n-1)+ … + cn を求める。

DIM c(0 TO N) !多項式 X^N+c(1)*X^(N-1)+c(2)*X^(N-2)+ … +c(N-1)*X+c(N) の係数

!Frame法、Leverrier-Faddeev法
! adj(s*I-A)=s^(n-1)*I+s^(n-2)*β[1]+ … +s*β[n-2]+β[n-1]
! det(s*I-A)=s^n+α[1]*s^(n-1)+ … + α[n-1]*s+α[n]
!のとき
! β[0]=I、k=1~nについて
!  X[k]=A*β[k-1]
!  α[k]=-trace(X[k])/k
!  β[k]=X[k]+α[k]*I
!の逐次計算でα[k]、β[k]が求まる。

DIM X(N,N),cE(N,N) !作業用
MAT X=IDN !adj(s*I-A)
FOR k=1 TO N
   MAT X=A*X
   LET c(k)=-tr(X)/k !det(s*I-A)
   MAT cE=(c(k))*IDN
   MAT X=X+cE
NEXT k
LET c(0)=1

MAT PRINT c;


FUNCTION tr(A(,)) !行列Aのトレース
   LET t=0
   FOR i=1 TO N
      LET t=t+A(i,i)
   NEXT i
   LET tr=t
END FUNCTION

END

MERGE "POLY.LIB"


実行結果

X^2-X+1
X^2-X+1
X^3-X^2+X
-X^2+X+2
X^4-X^3+X^2
X^2+2*X-2
1 -1  1
2  1 -1
-2  2  1

1 -3  9 -9

 

Re: 最小多項式を求める

 投稿者:山中和義  投稿日:2013年 8月25日(日)10時46分22秒
  > No.3119[元記事へ]

つづき

> 問題
> (1-2^(1/3)+4^(1/3))^3を簡単にしなさい。
>
> 答え
> α=1-2^(1/3)+4^(1/3)を解にもつ3次方程式f(x)(最小多項式)を求めると、f(x)=x^3-3*x^2+9*x-9

参考サイト http://www.rkmath.rikkyo.ac.jp/~kida/intbasis.pdf 3.最小多項式 より

●終結式を用いる


!問題
!αが方程式 x^3-2=0 の解であるとき、α^2-α+1を解とする3次方程式を求めよ。
!答え
!終結式 resultant(y^3-2,x-(y^2-y+1),y) を求める。よって、x^3-3x^2+9x-9
!(終り)

OPTION ARITHMETIC RATIONAL !有理数モード

PUBLIC NUMERIC MAX_DEGREE !最高次数
LET MAX_DEGREE=20


!終結式 resultant(y^3-2,x-(y^2-y+1),y) を行列式(シルベスター行列式)で表現する。
!  [ 1   0   0    -2     0  ]
!  [ 0   1   0     0    -2  ]
!  [-1   1   x-1   0     0  ]
!  [ 0  -1   1     x-1   0  ]
!  [ 0   0  -1     1     x-1]

LET M=3 !1番目の多項式の次数
DATA 0,1 !y^3の係数(xの次数、係数列)
DATA 0,0 !y^2
DATA 0,0 !y
DATA 0,-2 !1

LET N=2 !2番目の多項式の次数
DATA 0,-1 !y^2の係数(xの次数、係数列)
DATA 0,1 !y
DATA 1,-1,1 !1


LET P=M+N !P×Pの正方行列
DIM aa(0 TO P*P-1) !各要素の次数 ※要素番号は連番(0~p*p-1)
DIM A(0 TO P*P-1,0 TO MAX_DEGREE) !各要素の多項式
MAT aa=ZER
MAT A=ZER

CALL MtxSet(M,1, aa,A) !1番目の多項式
CALL MtxSet(N,N+1, aa,A) !2番目

SUB MtxSet(L,K, aa(),A(,)) !行列式を組み立てる
   FOR q=1 TO L+1 !列位置
      READ w !次数
      LET t=(K-1)*P+(q-1) !開始位置 k行1桁
      FOR J=0 TO w
         READ r !係数列
         FOR i=1 TO P-L !1列ずつずらす
            LET tt=(i-1)*(P+1)
            IF J=0 THEN LET aa(t+tt)=w
            LET A(t+tt,J)=r
         NEXT i
      NEXT J
   NEXT q
END SUB


DIM S(0 TO MAX_DEGREE)
CALL PolynomialMatrixDET(P, aa,A, ss,S)
PRINT ss
MAT PRINT S;

END


!行列(要素が1変数多項式)の計算

!m行n列 aa(i),A(i,*)
!    1    2         n
! 1: A(0) A(1)   … A(n-1)
! 2: A(n) A(n+1) …
!     :
! m:             … A(m*n-1)
!
!Aは2次元とする。1次は要素番号i、2次は多項式の係数を表す。
!要素番号は連番(0~m*n-1)とする。
!aaは多項式の次数とする。

EXTERNAL SUB PolynomialMatrixZER(n, aa(),A(,)) !零行列 MAT A=ZER
OPTION ARITHMETIC RATIONAL !有理数モード
MAT A=ZER !定数 0
MAT aa=ZER
END SUB


EXTERNAL SUB PolynomialMatrixIDN(n, aa(),A(,)) !単位行列 MAT A=IDN
OPTION ARITHMETIC RATIONAL !有理数モード
MAT A=ZER !定数 0
MAT aa=ZER
FOR i=1 TO n !対角線について
   LET A((i-1)*n+(i-1),0)=1 !定数 1
NEXT i
END SUB


!演算関連

EXTERNAL SUB PolynomialMatrixMultiply(m,p,n, aa(),A(,),bb(),B(,), cc(),C(,)) !積 C=A*B
OPTION ARITHMETIC RATIONAL !有理数モード
DIM W(0 TO MAX_DEGREE),S(0 TO MAX_DEGREE)
MAT C=ZER
FOR y=1 TO m !y行
   FOR x=1 TO n !x列
      MAT W=ZER
      LET ww=0

      FOR i=1 TO p !積の和 w=Σa[y,i]b[i,x]
         LET yy=(y-1)*p+(i-1)
         LET xx=(i-1)*n+(x-1)
         CALL PolyMtxMul(aa(yy),A,yy, bb(xx),B,xx, ss,S)
         MAT W=W+S
         LET ww=MAX(ww,ss)
      NEXT i
      CALL Poly_DegUpdt(ww,W) !※次数の補正

      LET i=(y-1)*n+(x-1) !c[y,x]=w
      FOR J=0 TO ww !copy it
         LET C(i,J)=W(J)
      NEXT J
      LET cc(i)=ww
   NEXT x
NEXT y
END SUB

EXTERNAL SUB PolyMtxMul(aa,A(,),y, bb,B(,),x, ss,S()) !乗算 S=A*B
OPTION ARITHMETIC RATIONAL !有理数モード
MAT S=ZER
FOR i=aa TO 0 STEP -1
   LET k=A(y,i)
   IF k=0 THEN !係数が0以外なら
   ELSE
      FOR j=bb TO 0 STEP -1
         LET S(i+j)=S(i+j)+k*B(x,j) !すべての係数をかける
      NEXT j
   END IF
NEXT i
LET ss=aa+bb!次数
CALL Poly_DegUpdt(ss,S) !※その補正
END SUB


EXTERNAL SUB PolynomialMatrixTR(n, aa(),A(,), ss,S()) !行列Aのトレース
OPTION ARITHMETIC RATIONAL !有理数モード
MAT S=ZER
LET ss=0
FOR i=1 TO N !対角線の和
   LET t=(i-1)*n+(i-1)
   FOR J=0 TO aa(t)
      LET S(J)=S(J)+A(t,J)
   NEXT J
   LET ss=MAX(ss,aa(t)) !次数
NEXT i
CALL Poly_DegUpdt(ss,S) !※その補正
END SUB


EXTERNAL SUB PolynomialMatrixDET(n, aa(),A(,), ss,S()) !行列式Aの値
OPTION ARITHMETIC RATIONAL !有理数モード

!n次正方行列Aの固有多項式 ΦA(t)=det(tE-A)=t^n+c[1]*t^(n-1)+ … + c[n] を求める。
!
!Frame法、Leverrier-Faddeev法
! adj(s*I-A)=s^(n-1)*I+s^(n-2)*β[1]+ … +s*β[n-2]+β[n-1]
! det(s*I-A)=s^n+α[1]*s^(n-1)+ … + α[n-1]*s+α[n]
!のとき
! β[0]=I、k=1~nについて
!  X[k]=A*β[k-1]
!  α[k]=-trace(X[k])/k
!  β[k]=X[k]+α[k]*I
!の逐次計算でα[k]、β[k]が求まる。
!
!DET(A)=(-1)^n*c[n]となる。

DIM xx(0 TO n^2-1),X(0 TO n^2-1,0 TO MAX_DEGREE) !adj(s*I-A)
CALL PolynomialMatrixIDN(n, xx,X) !MAT X=IDN

LET k=1
DO
   DIM ww(0 TO n^2-1),W(0 TO n^2-1,0 TO MAX_DEGREE)
   CALL PolynomialMatrixMultiply(n,n,n, aa,A,xx,X, ww,W) !MAT X=A*X

   CALL PolynomialMatrixTR(n, ww,W, ss,S) !LET c(k)=-tr(X)/k !det(s*I-A)
   MAT S=(-1/k)*S

   IF k=N THEN EXIT DO

   MAT X=W !MAT cE=(c(k))*IDN、 MAT X=X+cE
   MAT xx=ww
   FOR i=1 TO n !対角線について
      LET t=(i-1)*n+(i-1)
      FOR J=0 TO MAX(xx(t),ss)
         LET X(t,J)=X(t,J)+S(J)
      NEXT J
      LET xx(t)=MAX(xx(t),ss) !次数
      CALL Poly_MtxDegUpdt(xx(t),X,t) !※その補正
   NEXT i

   LET k=k+1
LOOP
IF MOD(n,2)=1 THEN MAT S=(-1)*S !(-1)^n*c(n)
END SUB

EXTERNAL SUB Poly_MtxDegUpdt(ss,S(,),t) !次数を補正する
OPTION ARITHMETIC RATIONAL !有理数モード
FOR J=ss TO 1 STEP -1
   IF S(t,J)<>0 THEN EXIT FOR
NEXT J
LET ss=J
END SUB


!POLY.LIB より

EXTERNAL SUB Poly_DegUpdt(aa,A()) !次数を補正する
OPTION ARITHMETIC RATIONAL !有理数モード
FOR i=aa TO 1 STEP -1
   IF A(i)<>0 THEN EXIT FOR
NEXT i
LET aa=i
END SUB

 

GIC回路

 投稿者:SECOND  投稿日:2013年 8月26日(月)02時25分24秒
  ! GIC回路
!
!抵抗、コンデンサーだけでも、増幅器を使用して、コイルのような誘導性の
!インピーダンスや、そのベクトル角が、180°になるような負性抵抗も作成できる。
!
! ※電圧増幅器の出力抵抗 Zo は、行列 5x5 で解く場合に使用する。
!
!   電圧増幅率Gの、出力端子を、節点(V2,V4) として選んでいるため、
!   増幅器内部の出力抵抗 Zoを、素子として必要とする。0Ωは不可。
!   (0Ωでは、その節点の自己アドミタンス、相互アドミタンス共に ∞)
!   行列 5x5 では、Zo<>0Ω の影響を、簡素な行列要素で、反映できる。
!
!   行列 3x3 の節点は、増幅器出力を避けているため、Zo=0Ωでもよい。
!   例題の行列 3x3 は、Zo=0Ω での行列要素になっている。
!   行列 3x3 で、Zo<>0Ω にすると、3素子の合成が、行列要素になって煩雑。

OPTION ARITHMETIC COMPLEX
DIM A(5,5)
!-------------------------------------------------------------------------------
! Generalized Impedance Converter   行列 3x3

!
!                        ┌──┐
!                  (0ohm)│   +├──────────┐
!                    ┌Zo┤G  │                    │
!      1A            │  │   -├┐                  │
!      →            │  └──┘│                  │
!  Zin ──┬──Z1─┴──Z2─┬┴─Z3──┬─Z4──┴─Z5──┐
! (Zin==V1)│                  │┌──┐  │                  │
!          │                  └┤-   │  │                  ▽
!          │                    │  G├Zo┘
!          └──────────┤+   │(0Ω)
!                                └──┘
!         ↑V1                 ↑V2                 ↑V3
!
!         | 1/Z1               G/Z1                 -G/Z1      ||V1| | 1|
!         |-G/Z3               1/Z2+1/Z3+G/Z2+G/Z3  -G/Z2      ||V2|=| 0|
!         |-G/Z4               G/Z4                  1/Z4+1/Z5 ||V3| | 0|
!-----
SUB mat3x3(Z1,Z2,Z3,Z4,Z5)
   LET A(1,1)= 1/Z1
   LET A(1,2)= G/Z1
   LET A(1,3)=-G/Z1
   !
   LET A(2,1)=-G/Z3
   LET A(2,2)= 1/Z2+1/Z3+G/Z2+G/Z3
   LET A(2,3)=-G/Z2
   !
   LET A(3,1)=-G/Z4
   LET A(3,2)= G/Z4
   LET A(3,3)= 1/Z4+1/Z5
END SUB

!-------------------------------------------------------------------------------
! Generalized Impedance Converter   行列 5x5

!
!                        ┌──┐
!                        │   +├──────────┐
!                    ┌Zo┤G  │                    │
!      1A            │  │   -├┐                  │
!      →            │  └──┘│                  │
!  Zin ──┬──Z1─┴──Z2─┬┴─Z3──┬─Z4──┴─Z5──┐
! (Zin==V1)│                  │┌──┐  │                  │
!          │                  └┤-   │  │                  ▽
!          │                    │  G├Zo┘
!          └──────────┤+   │
!                                └──┘
!         ↑V1      ↑V2       ↑V3       ↑V4      ↑V5
!
!    | 1/Z1    -1/Z1            0           0               0         ||V1| | 1|
!    |-1/Z1     1/Z1+1/Z2+1/Zo  G/Zo-1/Z2   0              -G/Zo      ||V2|=| 0|
!    | 0       -1/Z2            1/Z2+1/Z3  -1/Z3            0         ||V3| | 0|
!    |-G/Zo     0               G/Zo-1/Z3   1/Z3+1/Z4+1/Zo -1/Z4      ||V4| | 0|
!    | 0        0               0          -1/Z4            1/Z4+1/Z5 ||V5| | 0|
!-----
SUB mat5x5(Z1,Z2,Z3,Z4,Z5,Zo)
   LET A(1,1)= 1/Z1
   LET A(1,2)=-1/Z1
   LET A(1,3)= 0
   LET A(1,4)= 0
   LET A(1,5)= 0
   !
   LET A(2,1)=-1/Z1
   LET A(2,2)= 1/Z1+1/Z2+1/Zo
   LET A(2,3)= G/Zo-1/Z2
   LET A(2,4)= 0
   LET A(2,5)=-G/Zo
   !
   LET A(3,1)= 0
   LET A(3,2)=-1/Z2
   LET A(3,3)= 1/Z2+1/Z3
   LET A(3,4)=-1/Z3
   LET A(3,5)= 0
   !
   LET A(4,1)=-G/Zo
   LET A(4,2)= 0
   LET A(4,3)= G/Zo-1/Z3
   LET A(4,4)= 1/Z3+1/Z4+1/Zo
   LET A(4,5)=-1/Z4
   !
   LET A(5,1)= 0
   LET A(5,2)= 0
   LET A(5,3)= 0
   LET A(5,4)=-1/Z4
   LET A(5,5)= 1/Z4+1/Z5
END SUB

!-------------------------------------------------------------------------------
OPTION ANGLE DEGREES
SET TEXT background "opaque"
SET COLOR MIX(15) .4,.4,.4

DEF sc$(i)=mid$("0.01 0.1   1  10 100  1K 10K100K  1M 10M100M", 4*(i+2)+1,4)

!
+---------------------------------------------------------+
! グラフの上下限 (0.01~100M 間、10 の整数乗で、自由に変更) |
!+---------------------------------------------------------+
LET fL=0.01                !下限 周波数(Hz)
LET fH=10E6                !上限 周波数(Hz)
LET zL=0.01                !下限 インピーダンス(Ω)
LET zH=100E6               !上限 インピーダンス(Ω)
!
LET stp=10^(1/12)          !10^(1/ 周波数10倍毎ステップ数=12 )

DATA 100,1000,1000000, 0    !テストする増幅率G

!※ Zo=0 は 行列 3x3 、Zo<>0 は 行列 5x5  が使用される。

!+---------------------------------------------------------+
!     Z1~Z5 <1 は、コンデンサー (F)                     |
!1≦ Z1~Z5      は、抵抗器       (ohm) として計算         |
!                                                          |
!           ( Z1  ,Z2  ,Z3  ,Z4  ,Z5  , Zo,  m$ )          |
!+---------------------------------------------------------+
CALL GIC_Zin( 1e3 ,1e-6,1e3 ,1e3 ,1e3 ,  0, "行列 3x3  Z2 ←1/jωC  Zin=誘導性(L)")
pause
CALL GIC_Zin( 1e3 ,1e-6,1e3 ,1e3 ,1e3 , 10, "行列 5x5  Z2 ←1/jωC  Zin=誘導性(L)")
pause
CALL GIC_Zin( 1e3 ,1e3 ,1e-6,1e3 ,1e3 ,  0, "行列 3x3  Z3 ←1/jωC  Zin=容量性(C)")
pause
CALL GIC_Zin( 1e3 ,1e3 ,1e-6,1e3 ,1e3 , 10, "行列 5x5  Z3 ←1/jωC  Zin=容量性(C)")
pause
CALL GIC_Zin( 1e3 ,1e-6,1e3 ,1e-6,1e3 ,  0, "行列 3x3  Z2,Z4 ←1/jωC  Zin=負性(R)")
pause
CALL GIC_Zin( 1e3 ,1e-6,1e3 ,1e-6,1e3 , 10, "行列 5x5  Z2,Z4 ←1/jωC  Zin=負性(R)")


SUB GIC_Zin( u1,u2,u3,u4,u5, Zo,m$)
   CLEAR
   CALL SCALE
   LET w$="Zo="& STR$(Zo)& "Ω "& m$
   PLOT TEXT ,AT logfL+1.1, logzL-.9*by :w$            !最下端
   RESTORE
   IF Zo=0 THEN MAT A=ZER(3,3) ELSE MAT A=ZER(5,5)
   DO
      READ G
      IF G=0 THEN EXIT DO
      PRINT w$
      PRINT "G=";STR$(G)
      PRINT "        周波数            V1/1       θ           設計式による値(Zo=0Ω)"
      !----
      LET f=fL
      DO
         LET ω=2*PI*f
         IF u1< 1 THEN LET Z1=1/COMPLEX(0,ω*u1) ELSE LET Z1=u1
         IF u2< 1 THEN LET Z2=1/COMPLEX(0,ω*u2) ELSE LET Z2=u2
         IF u3< 1 THEN LET Z3=1/COMPLEX(0,ω*u3) ELSE LET Z3=u3
         IF u4< 1 THEN LET Z4=1/COMPLEX(0,ω*u4) ELSE LET Z4=u4
         IF u5< 1 THEN LET Z5=1/COMPLEX(0,ω*u5) ELSE LET Z5=u5
         IF Zo=0 THEN CALL mat3x3(Z1,Z2,Z3,Z4,Z5) ELSE CALL mat5x5(Z1,Z2,Z3,Z4,Z5,Zo)
         MAT A=INV(A)
         LET Zv=ABS(A(1,1))          !A(1,1)= △11/△= V1/(1A) なので、A(1,1)==Zin
         LET Za=arg(A(1,1))
         !
         !---------------- 比較の為、設計式による計算値 (電圧増幅器の出力抵抗 Zo=0)
         !
         !LET Zin=Z1*Z3*Z5/(Z2*Z4)  ← 電圧増幅率 G= ∞ の場合
         !
         ! G が小さい場合
         !           1/Z2*1/Z4 + (1/Z2+1/Z3)*(1/Z4+1/Z5)*(1+G)/G^2
         !Zin= Z1 * ───────────────────────
         !           1/Z3*1/Z5 + (1/Z2+1/Z3)*(1/Z4+1/Z5)*(1+G)/G^2
         !
         LET w=(1/Z2+1/Z3)*(1/Z4+1/Z5)*(1+G)/G^2
         LET Zin=Z1*(1/Z2*1/Z4 +w)/(1/Z3*1/Z5 +w)
         !
         LET Zv00=ABS(Zin)
         LET Za00=arg(Zin)
         !----------------
         !
         ! リスト
         PRINT USING "###,###,###.#Hz #,###,###,###Ω ####.#度 #,###,###,###Ω ####.#度": f, Zv, Za, Zv00, Za00
         ! グラフ
         IF fL< f THEN
            SET LINE COLOR "black"
            PLOT LINES:  LOG10(f_),LOG10(Zv_);  LOG10(f),LOG10(Zv)   !Z[Ω]
            SET LINE COLOR "red"
            PLOT LINES:  LOG10(f_),Za_/90+zct;  LOG10(f),Za/90+zct   !位相[度]
         END IF
         LET f_=f
         LET Zv_=Zv
         LET Za_=Za
         LET f=f*stp
      LOOP UNTIL fH< f
      PRINT
   LOOP
END SUB

SUB SCALE
   LET logfL=LOG10(fL)
   LET logfH=LOG10(fH)
   LET logzL=LOG10(zL)
   LET logzH=LOG10(zH)
   LET zct=INT((logzH+logzL)/2)
   !
   ASK bitmap SIZE i,j
   LET bx=(logfH-logfL)*40/(i-80)   !左右 40pixel の border( 目盛りの余白)
   LET by=(logzH-logzL)*24/(j-48)   !上下 24pixel の border( 目盛りの余白)
   SET WINDOW logfL-bx, logfH+bx, logzL-by, logzH+by
   DRAW grid0
   SET TEXT COLOR "red"
   FOR i=-2 TO 2
      PLOT TEXT ,AT logfH+.1*bx, zct+i-by/3, USING "+###°" :i*90  !y軸 右
   NEXT i
   SET TEXT COLOR "black"
   FOR i=logfL TO logfH
      PLOT TEXT ,AT i-bx/2  , logzH+by/3 :sc$(i)& "Hz"  !x軸 上
   NEXT i
   FOR i=logzL TO logzH
      PLOT TEXT ,AT logfL-bx, i-by/3     :sc$(i)& "Ω"  !y軸 左
   NEXT i
END SUB

END
 

Σ[n=0,∞]1/n! を用いて

 投稿者:山中和義  投稿日:2013年 8月30日(金)11時16分49秒
  問題
Σ[n=0,∞]1/n!=1/0!+1/1!+1/2!+1/3!+1/4!+ … =e=2.71828… である。
そこで、
 X=Σ[n=0,∞]1/(2n)!=1+1/2!+1/4!+1/6!+ …
 Y=Σ[n=0,∞]1/(3n)!=1+1/3!+1/6!+1/9!+ …
 Z=Σ[n=0,∞]1/(4n)!=1+1/4!+1/8!+1/12!+ …
の値を求めよ。

考察
まず、実際に数値計算してみる。

!Σ1/(k*n)!の計算
LET k=2
LET s=0
FOR n=30*k TO 1 STEP -1 !例 1/6!+1/4!+1/2!=((((0+1)/(6*5)+1)/(4*3)+1)/(2*1)
   IF MOD(n,k)=0 THEN LET s=s+1
   LET s=s/n
NEXT n
PRINT s+1 !1/0!を加味する
END


k=2のとき、1.54308063481525
k=3のとき、1.16805831337592
k=4のとき、1.04169147034169


次に、
x^2-1=(x-1)(x+1)より、1,-1
x^3-1=(x-1)(x^2+x+1)より、1,ω,ω^2
x^4-1=(x-1)(x+1)(x^2+1)より、1,-1(=i^2),i,-i(=i^3)
1のn乗根(x^n-1=0の解)または 1の原始n乗根 に着目する。

1+(-1)=0、1+ω+ω^2=0、1+i+i^2+i^3=0 なので、


OPTION ARITHMETIC COMPLEX !複素数モード
LET i=COMPLEX(0,1) !虚数単位
LET w=COMPLEX(-1/2,SQR(3)/2) !ω(1の虚数立方根の一つ)

PRINT (EXP(1)+EXP(-1))/2 !X
PRINT (EXP(1)+EXP(w)+EXP(w^2))/3 !Y
PRINT (EXP(1)+EXP(i)+EXP(i^2)+EXP(i^3))/4 !Z

END

実行結果

1.54308063481524
( 1.16805831337592 -1.85037170770859E-17)
1.04169147034169



cosθ=(EXP(iθ)+EXP(-iθ))/2より、
EXP(ω)=EXP((-1+i√3)/2)=EXP(-1/2)*EXP(i*(√3)/2)=EXP(i*(√3)/2)/SQR(EXP(1))
EXP(ω^2)=EXP((-1-i√3)/2)=EXP(-1/2)*EXP(-i*(√3)/2)=EXP(-i*(√3)/2)/SQR(EXP(1))
EXP(ω)+EXP(ω^2)
={EXP(i*(√3)/2)+EXP(-i*(√3)/2)}/SQR(EXP(1))
=2*COS((√3)/2)/SQR(EXP(1))

また、
EXP(i)+EXP(-i)=EXP(i*1)+EXP(-i*1)=2*COS(1)

なので、実数の範囲で表現すると、


PRINT ( EXP(1)+2*COS(SQR(3)/2)/SQR(EXP(1)) )/3 !Y
PRINT ( EXP(1)+EXP(-1)+2*COS(1) )/4 !Z
END

実行結果

1.16805831337592
1.04169147034169



一般的に、


OPTION ARITHMETIC COMPLEX !複素数モード
LET i=COMPLEX(0,1) !虚数単位

LET k=5 !Σ1/(k*n)!

LET a=EXP(2*PI*i/k) !1の原始k乗根のひとつ
LET s=0
FOR m=0 TO k-1
   LET s=s+EXP(a^m)
NEXT m
PRINT s/k

END


と考えられる。

 

数独

 投稿者:永野護  投稿日:2013年 8月30日(金)12時23分6秒
  お世話になります。
以下は数独を解くプログラムです。これを十進BASICで書き換えるとどのようになるのでしょうか。なおデータ入力部は不要です。
/* 数独を解くプログラム  Motonaga Asao  2006/11/18 */
/*                                      2006/11/19 */
/*                                      2006/11/21 */
/*                                      2006/12/16 */
/*                                      2009/01/12 */
#include <stdio.h>

#define True -1
#define False 0

#define N 9
#define N3 3

/* 盤の出力 */
int PrintBan(int Ban[N][N])
{
    int i,j;
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++) printf("%5d",Ban[i][j]);
        putchar('\n');
    }
    putchar('\n');
    return 0;
}

/* 空いた枡を見つける */
int findBlank(int *x,int *y,int Ban[N][N])
{
    int i,j;
    for(i=0;i<N;i++)
        for(j=0;j<N;j++)
            if (Ban[i][j] == 0)
            {
                *x=i; *y=j;
                return True;
            }
    return False;
}

/* kを枡(x,y)に置けるか ? */
int isOkeru(int x,int y,int k,int Ban[N][N])
{
    int i,j;

    for(i=0;i<N;i++) if (Ban[i][y] == k) return False; /* 横に同じ数はないか */
    for(j=0;j<N;j++) if (Ban[x][j] == k) return False; /* 縦に同じ数はないか */
    for(i=0;i<N3;i++)                                  /* blockに同じ数はないか */
        for(j=0;j<N3;j++)
            if (Ban[N3*(x/N3)+i][N3*(y/N3)+j] == k) return False;
    return True;
}

/* これが問題のバックトラック */
int Try(int Ban[N][N])
{
    int x,y,k;
    if (findBlank(&x,&y,Ban)) /* 盤に空いた枡(x,y)があるか */
    for(k=1;k<=N;k++)
    {
        if(isOkeru(x,y,k,Ban)) /* 枡(x,y)にkを置けるか */
        {
            Ban[x][y] = k; /* 置けるなら置く */
            Try(Ban);      /* 次を確かめる */
            Ban[x][y] = 0; /* 枡(x,y)にkを置けないとして別の置き方はないか */
        }
    }
    else
    {
        printf("Solution\n"); /* 解が見つかった */
        PrintBan(Ban);
    }
    return 0;
}

int main(int argc,char *argv[])
{
    int i,j,Ban[N][N];
    FILE *stream;

    if (argc != 2)
    {
        printf("\nusage : Sudoku filename\n\n");
        return 1;
    }
    if((stream = fopen(argv[1],"r")) == NULL)
    {
        printf("%s がありません。\n",argv[1]);
        return 1;
    }
    for (i=0;i<N;i++)
        for(j=0;j<N;j++) fscanf(stream,"%d",&Ban[i][j]);
    fclose(stream);
    printf("Problem\n");
    PrintBan(Ban);
    Try(Ban);
    return 0;
}

 

Re: 数独

 投稿者:山中和義  投稿日:2013年 8月30日(金)19時31分51秒
  > No.3123[元記事へ]

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

> 数独を解くプログラムです。これを十進BASICで書き換えるとどのようになるのでしょうか。

ほとんど機械的に同等な命令に置き換えてみました。


!数独を解くプログラム  Motonaga Asao  2009/01/12

LET N=9
LET N3=3

!盤の出力
SUB PrintBan(Ban(,))
   local i,j
   FOR i=0 TO N-1
      FOR j=0 TO N-1
         PRINT USING "###": Ban(i,j);
      NEXT j
      PRINT
   NEXT i
   PRINT
END SUB

!空いた枡を見つける
SUB findBlank(x,y,Ban(,), RET)
   local i,j
   FOR i=0 TO N-1
      FOR j=0 TO N-1
         IF Ban(i,j)=0 THEN
            LET x=i
            LET y=j
            LET RET=-1
            EXIT SUB
         END IF
      NEXT j
   NEXT i
   LET RET=0
END SUB

!kを枡(x,y)に置けるか ?
SUB isOkeru(x,y,k,Ban(,), RET)
   local i,j
   FOR i=0 TO N-1
      IF Ban(i,y)=k THEN
         LET RET=0 ! 横に同じ数はないか
         EXIT SUB
      END IF
   NEXT i
   FOR j=0 TO N-1
      IF Ban(x,j)=k THEN
         LET RET=0 !縦に同じ数はないか
         EXIT SUB
      END IF
   NEXT j
   FOR i=0 TO N3-1 !blockに同じ数はないか
      FOR j=0 TO N3-1
         IF Ban(N3*INT(x/N3)+i,N3*INT(y/N3)+j)=k THEN
            LET RET=0
            EXIT SUB
         END IF
      NEXT j
   NEXT i
   LET RET=-1
END SUB

!これが問題のバックトラック
SUB Try(Ban(,))
   local x,y,k
   CALL findBlank(x,y,Ban, RET) !盤に空いた枡(x,y)があるか
   IF RET<>0 THEN
      FOR k=1 TO N
         CALL isOkeru(x,y,k,Ban, RET) !枡(x,y)にkを置けるか
         IF RET<>0 THEN
            LET Ban(x,y)=k !置けるなら置く
            CALL Try(Ban) !次を確かめる
            LET Ban(x,y)=0 !枡(x,y)にkを置けないとして別の置き方はないか
         END IF
      NEXT k
   ELSE
      PRINT "Solution" !解が見つかった
      CALL PrintBan(Ban)
   END IF
END SUB


DATA 0,0,0, 0,7,0, 9,4,0 !初期配置
DATA 0,7,0, 0,9,0, 0,0,5
DATA 3,0,0, 0,0,5, 0,7,0

DATA 0,8,7, 4,0,0, 1,0,0
DATA 4,6,3, 0,8,0, 0,0,0
DATA 0,0,0, 0,0,7, 0,8,0

DATA 8,0,0, 7,0,0, 0,0,0
DATA 7,0,0, 0,0,0, 0,2,8
DATA 0,5,0, 2,6,8, 0,0,0

DIM Ban(0 TO N-1,0 TO N-1)
MAT READ Ban

PRINT "Problem"
CALL PrintBan(Ban)
CALL Try(Ban)

END


実行結果

Problem
  0  0  0  0  7  0  9  4  0
  0  7  0  0  9  0  0  0  5
  3  0  0  0  0  5  0  7  0
  0  8  7  4  0  0  1  0  0
  4  6  3  0  8  0  0  0  0
  0  0  0  0  0  7  0  8  0
  8  0  0  7  0  0  0  0  0
  7  0  0  0  0  0  0  2  8
  0  5  0  2  6  8  0  0  0

Solution
  2  1  5  8  7  6  9  4  3
  6  7  8  3  9  4  2  1  5
  3  4  9  1  2  5  8  7  6
  5  8  7  4  3  2  1  6  9
  4  6  3  9  8  1  7  5  2
  1  9  2  6  5  7  3  8  4
  8  2  6  7  4  3  5  9  1
  7  3  4  5  1  9  6  2  8
  9  5  1  2  6  8  4  3  7

 

数独

 投稿者:永野護  投稿日:2013年 8月31日(土)17時24分38秒
  丁寧な回答に感謝します。お忙しい折お手数をおかけしました。
大変助かりました。
敬具
 

グラフィックデモ

 投稿者:しばっち  投稿日:2013年 8月31日(土)21時18分15秒
  RANDOMIZE
LET N=40
DIM X(N),Y(N),DX(N),DY(N)
CALL GINIT(XSIZE,YSIZE)
FOR I=1 TO N
   LET X(I)=RND*XSIZE
   LET Y(I)=RND*YSIZE
   LET DX(I)=RND*5-2.5
   LET DY(I)=RND*5-2.5
NEXT I
DO
   FOR I=1 TO N
      LET X(I)=X(I)+DX(I)
      LET Y(I)=Y(I)+DY(I)
      LET DY(I)=DY(I)+.1
      IF X(I)<0 OR X(I)>XSIZE THEN LET DX(I)=-DX(I)
      IF Y(I)<0 OR Y(I)>YSIZE THEN LET DY(I)=-DY(I)
   NEXT I
   CALL BOXFULL(0,0,XSIZE-1,YSIZE-1,0)
   FOR I=1 TO N
      IF Y(I)<0 AND DY(I)<0 THEN
         LET Y(I)=RND*YSIZE
         LET DY(I)=RND*5-2.5
      END IF
      CALL LINE(X(I),Y(I),X(I)-DX(I),Y(I)-DY(I),7)
   NEXT I
   WAIT DELAY 1/100
LOOP
END

EXTERNAL  SUB GINIT(XSIZE,YSIZE)
ASK BITMAP SIZE XSIZE,YSIZE
SET WINDOW  0 , XSIZE , YSIZE, 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

EXTERNAL SUB BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA: X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB
 

グラフィックデモ

 投稿者:しばっち  投稿日:2013年 8月31日(土)21時18分51秒
  LET N1=20
LET N2=40
RANDOMIZE
DIM X(N1),Y(N1),DX(N1),DY(N1)
DIM X2(N2),Y2(N2),DX2(N2),DY2(N2)
CALL GINIT(XSIZE,YSIZE)
FOR I=1 TO N1
   LET X(I)=RND*XSIZE
   LET Y(I)=RND*YSIZE
   LET THETA=ANGLE(X(I)-XSIZE/2,Y(I)-YSIZE/2)
   LET DX(I)=COS(THETA)
   LET DY(I)=SIN(THETA)
NEXT I
FOR I=1 TO N2
   LET X2(I)=RND*XSIZE
   LET Y2(I)=RND*YSIZE
   LET THETA=ANGLE(X2(I)-XSIZE/2,Y2(I)-YSIZE/2)
   LET DX2(I)=COS(THETA)
   LET DY2(I)=SIN(THETA)
NEXT I
DO
   CALL BOXFULL(0,0,XSIZE-1,YSIZE-1,0)
   FOR I=1 TO N1
      LET X(I)=X(I)+DX(I)
      LET Y(I)=Y(I)+DY(I)
      LET DX(I)=DX(I)+DX(I)/10
      LET DY(I)=DY(I)+DY(I)/10
      IF X(I)<0 OR X(I)>XSIZE OR Y(I)<0 OR Y(I)>YSIZE THEN
         LET X(I)=XSIZE/2+RND*50-25
         LET Y(I)=YSIZE/2+RND*50-25
         LET THETA=ANGLE(X(I)-XSIZE/2,Y(I)-YSIZE/2)
         LET DX(I)=COS(THETA)
         LET DY(I)=SIN(THETA)
      END IF
      CALL LINE(X(I),Y(I),X(I)-DX(I),Y(I)-DY(I),7)
   NEXT I
   FOR I=1 TO N2
      LET X2(I)=X2(I)+DX2(I)
      LET Y2(I)=Y2(I)+DY2(I)
      LET DX2(I)=DX2(I)+DX2(I)/50
      LET DY2(I)=DY2(I)+DY2(I)/50
      IF X2(I)<0 OR X2(I)>XSIZE OR Y2(I)<0 OR Y2(I)>YSIZE THEN
         LET X2(I)=XSIZE/2+RND*50-25
         LET Y2(I)=YSIZE/2+RND*50-25
         LET THETA=ANGLE(X2(I)-XSIZE/2,Y2(I)-YSIZE/2)
         LET DX2(I)=COS(THETA)
         LET DY2(I)=SIN(THETA)
      END IF
      CALL PSET(X2(I),Y2(I),7)
   NEXT I
   WAIT DELAY 1/100
LOOP
END

EXTERNAL  SUB PSET(X,Y,C)
SET POINT COLOR C
PLOT POINTS: X , Y
END SUB

EXTERNAL  SUB GINIT(XSIZE,YSIZE)
ASK BITMAP SIZE XSIZE,YSIZE
SET WINDOW  0 , XSIZE , YSIZE, 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

EXTERNAL SUB BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA: X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB
 

メビウスの帯

 投稿者:しばっち  投稿日:2013年 9月 2日(月)20時00分1秒
  SAMPLEフォルダ内 Lorenz_attractor.BAS を改造してみた
マウスでドラッグすると回転の向きや速度が変化します
右クリックで終了します

RANDOMIZE
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
LET ZTH=0          ! z軸のまわりの回転角
LET XTH=0          ! x軸のまわりの回転角初期値
LET YTH=0          ! y軸のまわりの回転角初期値
DIM M(4,4),POINT(4),ROTX(4,4),ROTY(4,4),X1(0 TO 360),Y1(0 TO 360),Z1(0 TO 360),X2(0 TO 360),Y2(0 TO 360),Z2(0 TO 360)
MAT M=ROTATE(ZTH)
SET POINT STYLE 1
LET LMIN=1E+10
LET LMAX=-1E+10
LET  A=INT(RND*7)+1
DO
   LET  B=INT(RND*7)+1
LOOP UNTIL A<>B
LET  R=INT(RND*10)+3
FOR I=0 TO 360
   LET ALPHA=I*2
   LET  X1(I)=(A+R*SIN(ALPHA/2))*COS(ALPHA)
   LET  Z1(I)=(A+R*SIN(ALPHA/2))*SIN(ALPHA)
   LET  Y1(I)=A+R*COS(ALPHA/2)
   LET  X2(I)=(B+R*SIN(ALPHA/2))*COS(ALPHA)
   LET  Z2(I)=(B+R*SIN(ALPHA/2))*SIN(ALPHA)
   LET  Y2(I)=B+R*COS(ALPHA/2)
   LET XMIN=MIN(XMIN,X1(I))
   LET XMAX=MAX(XMAX,X1(I))
   LET YMIN=MIN(YMIN,Y1(I))
   LET YMAX=MAX(YMAX,Y1(I))
   LET ZMIN=MIN(ZMIN,Z1(I))
   LET ZMAX=MAX(ZMAX,Z1(I))
   LET XMIN=MIN(XMIN,X2(I))
   LET XMAX=MAX(XMAX,X2(I))
   LET YMIN=MIN(YMIN,Y2(I))
   LET YMAX=MAX(YMAX,Y2(I))
   LET ZMIN=MIN(ZMIN,Z2(I))
   LET ZMAX=MAX(ZMAX,Z2(I))
NEXT I
FOR I=0 TO 359  !'重心計算
   LET MX=MX+X1(I)+X2(I)
   LET MY=MY+Y1(I)+Y2(I)
   LET MZ=MZ+Z1(I)+Z2(I)
NEXT I
LET RANGE=MAX(XMAX-XMIN,MAX(YMAX-YMIN,ZMAX-ZMIN))
LET XDT=RND-.5 !'回転初期値
LET YDT=RND-.5
LET MX=MX/360/2
LET MY=MY/360/2
LET MZ=MZ/360/2
LOCATE VALUE NOWAIT(1),RANGE  0 TO 2,AT 1 : SCALE
LOCATE VALUE NOWAIT(2),RANGE -3 TO 5,AT 1 : SPEED
LOCATE VALUE NOWAIT(3),RANGE -RANGE TO RANGE,AT 0 : XMOVE
LOCATE VALUE NOWAIT(4),RANGE -RANGE TO RANGE,AT 0 : YMOVE
LOCATE VALUE NOWAIT(5),RANGE -RANGE TO RANGE,AT 0 : ZMOVE
DO
   LOCATE VALUE NOWAIT(1): SCALE
   LOCATE VALUE NOWAIT(2): SPEED
   LOCATE VALUE NOWAIT(3): XMOVE
   LOCATE VALUE NOWAIT(4): YMOVE
   LOCATE VALUE NOWAIT(5): ZMOVE
   MAT ROTX=IDN ! x軸のまわりの回転
   LET ROTX(2,2)=COS(XTH)
   LET ROTX(2,3)=SIN(XTH)
   LET ROTX(3,2)=-SIN(XTH)
   LET ROTX(3,3)=COS(XTH)
   MAT ROTY=IDN ! y軸のまわりの回転
   LET ROTY(1,1)=COS(YTH)
   LET ROTY(1,3)=-SIN(YTH)
   LET ROTY(3,1)=SIN(YTH)
   LET ROTY(3,3)=COS(YTH)
   MAT M=M *  ROTX * ROTY
   SET DRAW MODE HIDDEN
   CLEAR
   FOR I=0 TO 359
      CALL PLOT(X1(I),Y1(I),Z1(I))
      CALL PLOT(X2(I),Y2(I),Z2(I))
      CALL PLOT(X2(I+1),Y2(I+1),Z2(I+1))
      CALL PLOT(X1(I+1),Y1(I+1),Z1(I+1))
      CALL PLOT(X1(I),Y1(I),Z1(I))
      PLOT LINES
   NEXT I
   IF FL=0 THEN
      SET WINDOW LMIN*1.5,LMAX*1.5,LMIN*1.5,LMAX*1.5
      LET WW=(LMAX-LMIN)*1.5
   END IF
   LET FL=1
   SET DRAW MODE EXPLICIT
   MOUSE POLL X,Y,L,R
   IF R<>0 THEN STOP
   LET XTH=0
   LET YTH=0
   IF L<>0 THEN
      DO WHILE L<>0
         MOUSE POLL X,Y,L,R
      LOOP
      LET XDT=-(Y-Y0)/WW*5 !'移動量
      LET YDT= (X-X0)/WW*5
      LET XDT=MAX(-5,MIN(5,XDT))
      LET YDT=MAX(-5,MIN(5,YDT))
   ELSE
      LET XTH=XTH+XDT*SPEED
      LET YTH=YTH+YDT*SPEED
   END IF
   LET X0=X
   LET Y0=Y
LOOP

SUB PLOT(X,Y,Z)
   LET POINT(1)=X-MX+XMOVE
   LET POINT(2)=Y-MY+YMOVE
   LET POINT(3)=Z-MZ+ZMOVE
   MAT POINT=POINT*M
   IF FL=0 THEN
      LET LMIN=MIN(LMIN,POINT(1)) !'描画範囲
      LET LMAX=MAX(LMAX,POINT(1))
      LET LMIN=MIN(LMIN,POINT(2))
      LET LMAX=MAX(LMAX,POINT(2))
   ELSE
      PLOT LINES:POINT(1)*SCALE,POINT(2)*SCALE;
   END IF
END SUB
END
 

ケーリーツリー

 投稿者:しばっち  投稿日:2013年 9月 2日(月)20時00分44秒
  RANDOMIZE
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
PUBLIC NUMERIC K,XX(2730),YY(2730),ZZ(2730) !' 2+8*(4^(LEV-1)-1)/3
LET ZTH=0          ! z軸のまわりの回転角
LET XTH=0          ! x軸のまわりの回転角初期値
LET YTH=0          ! y軸のまわりの回転角初期値
DIM M(4,4),POINT(4),ROTX(4,4),ROTY(4,4)
MAT M=ROTATE(ZTH)
SET POINT STYLE 1
LET LMIN=1E+10
LET LMAX=-1E+10
LET LL=2^9  !'TREEの大きさ
INPUT  PROMPT "LEVEL(2<=LEV<=6)=":LEV
CALL TREE(LEV,0,0,0,0,LL,0,LL)
FOR I=1 TO K
   LET MX=MX+XX(I)
   LET MY=MY+YY(I)
   LET MZ=MZ+ZZ(I)
   LET XMIN=MIN(XMIN,XX(I))
   LET XMAX=MAX(XMAX,XX(I))
   LET YMIN=MIN(YMIN,YY(I))
   LET YMAX=MAX(YMAX,YY(I))
   LET ZMIN=MIN(ZMIN,ZZ(I))
   LET ZMAX=MAX(ZMAX,ZZ(I))
NEXT I
LET RANGE=MAX(XMAX-XMIN,MAX(YMAX-YMIN,ZMAX-ZMIN))
LET XDT=RND-.5
LET YDT=RND-.5
LET MX=MX/K
LET MY=MY/K
LET MZ=MZ/K
LOCATE VALUE NOWAIT(1),RANGE  0 TO 2,AT 1 : SCALE
LOCATE VALUE NOWAIT(2),RANGE -3 TO 5,AT 1 : SPEED
LOCATE VALUE NOWAIT(3),RANGE -RANGE TO RANGE,AT 0 : XMOVE
LOCATE VALUE NOWAIT(4),RANGE -RANGE TO RANGE,AT 0 : YMOVE
LOCATE VALUE NOWAIT(5),RANGE -RANGE TO RANGE,AT 0 : ZMOVE
DO
   LOCATE VALUE NOWAIT(1): SCALE
   LOCATE VALUE NOWAIT(2): SPEED
   LOCATE VALUE NOWAIT(3): XMOVE
   LOCATE VALUE NOWAIT(4): YMOVE
   LOCATE VALUE NOWAIT(5): ZMOVE
   MAT ROTX=IDN ! x軸のまわりの回転
   LET ROTX(2,2)=COS(XTH)
   LET ROTX(2,3)=SIN(XTH)
   LET ROTX(3,2)=-SIN(XTH)
   LET ROTX(3,3)=COS(XTH)
   MAT ROTY=IDN ! y軸のまわりの回転
   LET ROTY(1,1)=COS(YTH)
   LET ROTY(1,3)=-SIN(YTH)
   LET ROTY(3,1)=SIN(YTH)
   LET ROTY(3,3)=COS(YTH)
   MAT M=M *  ROTX * ROTY
   SET DRAW MODE HIDDEN
   CLEAR
   FOR I=1 TO K STEP 2
      CALL  PLOTLINE(XX(I),YY(I),ZZ(I),XX(I+1),YY(I+1),ZZ(I+1))
   NEXT I
   IF FL=0 THEN
      SET WINDOW -LMAX*1.2,LMAX*1.2,-LMAX*1.2,LMAX*1.2
      LET WW=(LMAX-LMIN)*1.2
   END IF
   LET FL=1
   SET DRAW MODE EXPLICIT
   MOUSE POLL X,Y,L,R
   IF R<>0 THEN STOP
   LET XTH=0
   LET YTH=0
   IF L<>0 THEN
      LET X0=X
      LET Y0=Y
      DO WHILE L<>0
         MOUSE POLL X,Y,L,R
      LOOP
      LET XDT=-(Y-Y0)/WW*5
      LET YDT= (X-X0)/WW*5
      LET XDT=MAX(-2,MIN(2,XDT))
      LET YDT=MAX(-2,MIN(2,YDT))
   ELSE
      LET XTH=XTH+XDT*SPEED
      LET YTH=YTH+YDT*SPEED
   END IF
   LET X0=X
   LET Y0=Y
LOOP

SUB PLOT(X,Y,Z)
   LET POINT(1)=X-MX+XMOVE
   LET POINT(2)=Y-MY+YMOVE
   LET POINT(3)=Z-MZ+ZMOVE
   MAT POINT=POINT*M
   IF FL=0 THEN
      LET LMIN=MIN(LMIN,POINT(1))
      LET LMAX=MAX(LMAX,POINT(1))
      LET LMIN=MIN(LMIN,POINT(2))
      LET LMAX=MAX(LMAX,POINT(2))
   ELSE
      PLOT LINES:POINT(1)*SCALE,POINT(2)*SCALE;
   END IF
END SUB

SUB PLOTLINE(X1,Y1,Z1,X2,Y2,Z2)
   PLOT LINES
   CALL PLOT(X1,Y1,Z1)
   CALL PLOT(X2,Y2,Z2)
   PLOT LINES
END SUB
END

EXTERNAL  SUB TREE(N,XS,YS,ZS,XE,YE,ZE,L)
OPTION ARITHMETIC NATIVE
IF N>0 THEN
   LET K=K+1
   LET XX(K)=XS
   LET YY(K)=YS
   LET ZZ(K)=ZS
   LET K=K+1
   LET XX(K)=XE
   LET YY(K)=YE
   LET ZZ(K)=ZE
   LET X=XE-XS
   LET Y=YE-YS
   LET Z=ZE-ZS
   IF X<>0 THEN
      CALL TREE(N-1,XE,YE,ZE,XE,YE,ZE+L/2,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE,YE,ZE-L/2,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE,YE+L/2,ZE,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE,YE-L/2,ZE,L/2)
   END IF
   IF Y<>0 THEN
      CALL TREE(N-1,XE,YE,ZE,XE+L/2,YE,ZE,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE-L/2,YE,ZE,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE,YE,ZE+L/2,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE,YE,ZE-L/2,L/2)
   END IF
   IF Z<>0 THEN
      CALL TREE(N-1,XE,YE,ZE,XE+L/2,YE,ZE,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE-L/2,YE,ZE,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE,YE+L/2,ZE,L/2)
      CALL TREE(N-1,XE,YE,ZE,XE,YE-L/2,ZE,L/2)
   END IF
END IF
END SUB
 

ヒルベルト曲線

 投稿者:しばっち  投稿日:2013年 9月 2日(月)20時01分25秒
  OPTION ARITHMETIC NATIVE
PUBLIC NUMERIC K,LL,XO,YO,ZO,XX(4096),YY(4096),ZZ(4096)  !'8^LEV
OPTION ANGLE DEGREES
INPUT  PROMPT "LEVEL(1<=LEVEL=<4)=":LEV
LET ZTH=0          ! z軸のまわりの回転角
LET XTH=0          ! x軸のまわりの回転角初期値
LET YTH=0          ! y軸のまわりの回転角初期値
LET LL=5 !'移動量
DIM M(4,4),POINT(4),ROTX(4,4),ROTY(4,4)
DIM A(3),B(3),C(3),D(3),E(3),F(3),G(3),H(3)
MAT M=ROTATE(ZTH)
SET POINT STYLE 1
MAT READ A,B,C,D,E,F,G,H  !'位置ベクトル
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
LET K=1
CALL RECURSIVE(LEV,A,E,F,B,C,G,H,D)
FOR I=1 TO K
   LET MX=MX+XX(I)
   LET MY=MY+YY(I)
   LET MZ=MZ+ZZ(I)
   LET XMIN=MIN(XMIN,XX(I))
   LET XMAX=MAX(XMAX,XX(I))
   LET YMIN=MIN(YMIN,YY(I))
   LET YMAX=MAX(YMAX,YY(I))
   LET ZMIN=MIN(ZMIN,ZZ(I))
   LET ZMAX=MAX(ZMAX,ZZ(I))
NEXT I
LET MX=MX/K
LET MY=MY/K
LET MZ=MZ/K
LET RANGE=MAX(XMAX-XMIN,MAX(YMAX-YMIN,ZMAX-ZMIN))
LET XDT=RND-.5
LET YDT=RND-.5
LET LMIN=1E+10
LET LMAX=-1E+10
LOCATE VALUE NOWAIT(1),RANGE  0 TO 2,AT 1 : SCALE
LOCATE VALUE NOWAIT(2),RANGE -3 TO 5,AT 1 : SPEED
LOCATE VALUE NOWAIT(3),RANGE -RANGE TO RANGE,AT 0 : XMOVE
LOCATE VALUE NOWAIT(4),RANGE -RANGE TO RANGE,AT 0 : YMOVE
LOCATE VALUE NOWAIT(5),RANGE -RANGE TO RANGE,AT 0 : ZMOVE
DO
   LOCATE VALUE NOWAIT(1): SCALE
   LOCATE VALUE NOWAIT(2): SPEED
   LOCATE VALUE NOWAIT(3): XMOVE
   LOCATE VALUE NOWAIT(4): YMOVE
   LOCATE VALUE NOWAIT(5): ZMOVE
   MAT ROTX=IDN ! x軸のまわりの回転
   LET ROTX(2,2)=COS(XTH)
   LET ROTX(2,3)=SIN(XTH)
   LET ROTX(3,2)=-SIN(XTH)
   LET ROTX(3,3)=COS(XTH)
   MAT ROTY=IDN ! y軸のまわりの回転
   LET ROTY(1,1)=COS(YTH)
   LET ROTY(1,3)=-SIN(YTH)
   LET ROTY(3,1)=SIN(YTH)
   LET ROTY(3,3)=COS(YTH)
   MAT M=M *  ROTX * ROTY
   SET DRAW MODE HIDDEN
   CLEAR
   FOR I=1 TO K
      CALL PLOT(XX(I),YY(I),ZZ(I))
   NEXT   I
   PLOT LINES
   IF FL=0 THEN
      SET WINDOW LMIN*2,LMAX*2,LMIN*2,LMAX*2
      LET WW=(LMAX-LMIN)*2
   END IF
   LET FL=1
   SET DRAW MODE EXPLICIT
   MOUSE POLL X,Y,L,R
   IF R<>0 THEN STOP
   LET XTH=0
   LET YTH=0
   IF L<>0 THEN
      DO WHILE L<>0
         MOUSE POLL X,Y,L,R
      LOOP
      LET XDT=-(Y-Y0)/WW*5
      LET YDT= (X-X0)/WW*5
      LET XDT=MAX(-5,MIN(5,XDT))
      LET YDT=MAX(-5,MIN(5,YDT))
   ELSE
      LET XTH=XTH+XDT*SPEED
      LET YTH=YTH+YDT*SPEED
   END IF
   LET X0=X
   LET Y0=Y
LOOP

SUB PLOT(X,Y,Z)
   LET POINT(1)=X-MX+XMOVE
   LET POINT(2)=Y-MY+YMOVE
   LET POINT(3)=Z-MZ+ZMOVE
   MAT POINT=POINT*M
   IF FL=0 THEN
      LET LMIN=MIN(LMIN,POINT(1))
      LET LMAX=MAX(LMAX,POINT(1))
      LET LMIN=MIN(LMIN,POINT(2))
      LET LMAX=MAX(LMAX,POINT(2))
   ELSE
      PLOT LINES:POINT(1)*SCALE,POINT(2)*SCALE;
   END IF
END SUB
END

EXTERNAL  SUB MOVE(A(),B())
OPTION ARITHMETIC NATIVE
LET  XO=XO+LL*(B(1)-A(1))
LET  YO=YO+LL*(B(2)-A(2))
LET  ZO=ZO+LL*(B(3)-A(3))
LET K=K+1
LET XX(K)=XO
LET YY(K)=YO
LET ZZ(K)=ZO
END SUB

EXTERNAL  SUB RECURSIVE(N,A(),E(),F(),B(),C(),G(),H(),D()) !'ヒルベルト曲線
OPTION ARITHMETIC NATIVE
IF N>0 THEN
   CALL RECURSIVE(N-1,A,B,C,D,H,G,F,E)
   CALL MOVE(A,E)
   CALL RECURSIVE(N-1,A,D,H,E,F,G,C,B)
   CALL MOVE(E,F)
   CALL RECURSIVE(N-1,A,D,H,E,F,G,C,B)
   CALL MOVE(F,B)
   CALL RECURSIVE(N-1,F,B,A,E,H,D,C,G)
   CALL MOVE(B,C)
   CALL RECURSIVE(N-1,F,B,A,E,H,D,C,G)
   CALL MOVE(C,G)
   CALL RECURSIVE(N-1,C,B,F,G,H,E,A,D)
   CALL MOVE(G,H)
   CALL RECURSIVE(N-1,C,B,F,G,H,E,A,D)
   CALL MOVE(H,D)
   CALL RECURSIVE(N-1,H,G,F,E,A,B,C,D)
END IF
END SUB
 

シェルピンスキーの三角形

 投稿者:しばっち  投稿日:2013年 9月 2日(月)20時02分5秒
  RANDOMIZE
OPTION ARITHMETIC NATIVE
PUBLIC NUMERIC K,XX(4096),YY(4096),ZZ(4096)  !'4^LEV
OPTION ANGLE DEGREES
LET ZTH=0          ! z軸のまわりの回転角
LET XTH=0          ! x軸のまわりの回転角初期値
LET YTH=0          ! y軸のまわりの回転角初期値
DIM M(4,4),POINT(4),ROTX(4,4),ROTY(4,4)
MAT M=ROTATE(ZTH)
SET POINT STYLE 1
LET LMIN=1E+10
LET LMAX=-1E+10
INPUT  PROMPT "LEVEL(1<=LEV=<6)=":LEV
CALL RECURSIVE(LEV,0,0,0,128)
LET LL=128/2^LEV
FOR I=1 TO K
   LET MX=MX+XX(I)+2*LL*COS(0)
   LET MX=MX+XX(I)+2*LL*COS(120)
   LET MX=MX+XX(I)+2*LL*COS(240)
   LET MX=MX+XX(I)
   LET MY=MY+YY(I)
   LET MY=MY+YY(I)
   LET MY=MY+YY(I)
   LET MY=MY+YY(I)+2*LL
   LET MZ=MZ+ZZ(I)+2*LL*SIN(0)
   LET MZ=MZ+ZZ(I)+2*LL*SIN(120)
   LET MZ=MZ+ZZ(I)+2*LL*SIN(240)
   LET MZ=MZ+ZZ(I)
   LET XMIN=MIN(XMIN,XX(I))
   LET XMAX=MAX(XMAX,XX(I))
   LET YMIN=MIN(YMIN,YY(I))
   LET YMAX=MAX(YMAX,YY(I))
   LET ZMIN=MIN(ZMIN,ZZ(I))
   LET ZMAX=MAX(ZMAX,ZZ(I))
NEXT I
LET RANGE=MAX(XMAX-XMIN,MAX(YMAX-YMIN,ZMAX-ZMIN))
LET XDT=RND-.5
LET YDT=RND-.5
LET MX=MX/4/K
LET MY=MY/4/K
LET MZ=MZ/4/K
LOCATE VALUE NOWAIT(1),RANGE  0 TO 2,AT 1 : SCALE
LOCATE VALUE NOWAIT(2),RANGE -3 TO 5,AT 1 : SPEED
LOCATE VALUE NOWAIT(3),RANGE -RANGE TO RANGE,AT 0 : XMOVE
LOCATE VALUE NOWAIT(4),RANGE -RANGE TO RANGE,AT 0 : YMOVE
LOCATE VALUE NOWAIT(5),RANGE -RANGE TO RANGE,AT 0 : ZMOVE
DO
   LOCATE VALUE NOWAIT(1): SCALE
   LOCATE VALUE NOWAIT(2): SPEED
   LOCATE VALUE NOWAIT(3): XMOVE
   LOCATE VALUE NOWAIT(4): YMOVE
   LOCATE VALUE NOWAIT(5): ZMOVE
   MAT ROTX=IDN ! x軸のまわりの回転
   LET ROTX(2,2)=COS(XTH)
   LET ROTX(2,3)=SIN(XTH)
   LET ROTX(3,2)=-SIN(XTH)
   LET ROTX(3,3)=COS(XTH)
   MAT ROTY=IDN ! y軸のまわりの回転
   LET ROTY(1,1)=COS(YTH)
   LET ROTY(1,3)=-SIN(YTH)
   LET ROTY(3,1)=SIN(YTH)
   LET ROTY(3,3)=COS(YTH)
   MAT M=M *  ROTX * ROTY
   SET DRAW MODE HIDDEN
   CLEAR
   FOR I=1 TO K
      CALL  TETRAHEDRON(XX(I),YY(I),ZZ(I),LL)
   NEXT I
   IF FL=0 THEN
      SET WINDOW -LMAX,LMAX,-LMAX,LMAX
      LET WW=LMAX*2
   END IF
   LET FL=1
   SET DRAW MODE EXPLICIT
   MOUSE POLL X,Y,L,R
   IF R<>0 THEN STOP
   LET XTH=0
   LET YTH=0
   IF L<>0 THEN
      DO WHILE L<>0
         MOUSE POLL X,Y,L,R
      LOOP
      LET XDT=-(Y-Y0)/WW*5
      LET YDT= (X-X0)/WW*5
      LET XDT=MAX(-2,MIN(2,XDT))
      LET YDT=MAX(-2,MIN(2,YDT))
   ELSE
      LET XTH=XTH+XDT*SPEED
      LET YTH=YTH+YDT*SPEED
   END IF
   LET X0=X
   LET Y0=Y
LOOP

SUB PLOT(X,Y,Z)
   LET POINT(1)=X-MX+XMOVE
   LET POINT(2)=Y-MY+YMOVE
   LET POINT(3)=Z-MZ+ZMOVE
   MAT POINT=POINT*M
   IF FL=0 THEN
      LET LMIN=MIN(LMIN,POINT(1))
      LET LMAX=MAX(LMAX,POINT(1))
      LET LMIN=MIN(LMIN,POINT(2))
      LET LMAX=MAX(LMAX,POINT(2))
   ELSE
      PLOT LINES:POINT(1)*SCALE,POINT(2)*SCALE;
   END IF
END SUB

SUB PLOTLINE(X1,Y1,Z1,X2,Y2,Z2)
   PLOT LINES
   CALL PLOT(X1,Y1,Z1)
   CALL PLOT(X2,Y2,Z2)
   PLOT LINES
END SUB

SUB TETRAHEDRON(X,Y,Z,L) !'4面体
   CALL PLOT(X+2*L*COS(0),Y,Z+2*L*SIN(0))
   CALL PLOT(X+2*L*COS(120),Y,Z+2*L*SIN(120))
   CALL PLOT(X+2*L*COS(240),Y,Z+2*L*SIN(240))
   CALL PLOT(X+2*L*COS(0),Y,Z+2*L*SIN(0))
   CALL PLOTLINE(X+2*L*COS(0),Y,Z+2*L*SIN(0),X,Y+2*L,Z)
   CALL PLOTLINE(X+2*L*COS(120),Y,Z+2*L*SIN(120),X,Y+2*L,Z)
   CALL PLOTLINE(X+2*L*COS(240),Y,Z+2*L*SIN(240),X,Y+2*L,Z)
END SUB
END

EXTERNAL  SUB RECURSIVE(LEV,X,Y,Z,L) !'シェルピンスキー三角形
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
IF LEV=0 THEN
   LET K=K+1
   LET XX(K)=X
   LET YY(K)=Y
   LET ZZ(K)=Z
ELSE
   CALL RECURSIVE(LEV-1,X,Y+L,Z,L/2)
   CALL RECURSIVE(LEV-1,X+L*COS(0),Y,Z+L*SIN(0),L/2)
   CALL RECURSIVE(LEV-1,X+L*COS(120),Y,Z+L*SIN(120),L/2)
   CALL RECURSIVE(LEV-1,X+L*COS(240),Y,Z+L*SIN(240),L/2)
END IF
END SUB
 

リサージュ曲線

 投稿者:しばっち  投稿日:2013年 9月 2日(月)20時03分13秒
  最近、話題の3Dプリンター。その出力形式「STLファイル(バイナリー)」の書き出しをつけてみた(持ってないけど...)

ビューワ
http://www.vector.co.jp/soft/winnt/art/se379971.html
http://www.vector.co.jp/soft/win95/art/se280377.html

3Dソフト
http://www.123dapp.com/design

3Dモデルデータサイト
http://www.thingiverse.com/categories

RANDOMIZE
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
LET ZTH=0          ! z軸のまわりの回転角
LET XTH=0          ! x軸のまわりの回転角初期値
LET YTH=0          ! y軸のまわりの回転角初期値
LET N=360 !'周期
LET LL=5  !'チューブ太さ
LET NN=8  !'チューブ分割数
LET RR=100  !'半径
DIM M(4,4),POINT(4),ROTX(4,4),ROTY(4,4)
DIM XX(0 TO N+1),YY(0 TO N+1),ZZ(0 TO N+1)
DIM XN(0 TO NN),YN(0 TO NN),ZN(0 TO NN),XM(0 TO NN),YM(0 TO NN),ZM(0 TO NN)
MAT M=ROTATE(ZTH)
SET POINT STYLE 1
LET A=INT(RND*20)+1
LET B=INT(RND*20)+1
LET C=INT(RND*20)+1
LET D=INT(RND*360)
FOR I=0 TO N+1
   LET XX(I)=RR*COS(A*I)
   LET YY(I)=RR*SIN(B*I)
   LET ZZ(I)=RR*COS(C*I+D)
   LET XMIN=MIN(XMIN,XX(I))
   LET XMAX=MAX(XMAX,XX(I))
   LET YMIN=MIN(YMIN,YY(I))
   LET YMAX=MAX(YMAX,YY(I))
   LET ZMIN=MIN(ZMIN,ZZ(I))
   LET ZMAX=MAX(ZMAX,ZZ(I))
NEXT I
LET RANGE=MAX(XMAX-XMIN,MAX(YMAX-YMIN,ZMAX-ZMIN))
LET XDT=RND-.5
LET YDT=RND-.5
LET LMIN=1E+10
LET LMAX=-1E+10
LOCATE VALUE NOWAIT(1),RANGE  0 TO 2,AT 1 : SCALE
LOCATE VALUE NOWAIT(2),RANGE -3 TO 5,AT 1 : SPEED
LOCATE VALUE NOWAIT(3),RANGE -RANGE TO RANGE,AT 0 : XMOVE
LOCATE VALUE NOWAIT(4),RANGE -RANGE TO RANGE,AT 0 : YMOVE
LOCATE VALUE NOWAIT(5),RANGE -RANGE TO RANGE,AT 0 : ZMOVE
DO
   LOCATE VALUE NOWAIT(1): SCALE
   LOCATE VALUE NOWAIT(2): SPEED
   LOCATE VALUE NOWAIT(3): XMOVE
   LOCATE VALUE NOWAIT(4): YMOVE
   LOCATE VALUE NOWAIT(5): ZMOVE
   MAT ROTX=IDN ! x軸のまわりの回転
   LET ROTX(2,2)=COS(XTH)
   LET ROTX(2,3)=SIN(XTH)
   LET ROTX(3,2)=-SIN(XTH)
   LET ROTX(3,3)=COS(XTH)
   MAT ROTY=IDN ! y軸のまわりの回転
   LET ROTY(1,1)=COS(YTH)
   LET ROTY(1,3)=-SIN(YTH)
   LET ROTY(3,1)=SIN(YTH)
   LET ROTY(3,3)=COS(YTH)
   MAT M=M *  ROTX * ROTY
   SET DRAW MODE HIDDEN
   CLEAR
   FOR I=0 TO N
      CALL PLOT(XX(I),YY(I),ZZ(I))
   NEXT I
   PLOT LINES
   IF FL=0 THEN
      SET WINDOW LMIN*2,LMAX*2,LMIN*2,LMAX*2
      LET WW=(LMAX-LMIN)*2
   END IF
   LET FL=1
   SET DRAW MODE EXPLICIT
   MOUSE POLL X,Y,L,R
   IF R<>0 THEN EXIT DO
   LET XTH=0
   LET YTH=0
   IF L<>0 THEN
      DO WHILE L<>0
         MOUSE POLL X,Y,L,R
      LOOP
      LET XDT=-(Y-Y0)/WW*5
      LET YDT= (X-X0)/WW*5
      LET XDT=MAX(-5,MIN(5,XDT))
      LET YDT=MAX(-5,MIN(5,YDT))
   ELSE
      LET XTH=XTH+XDT*SPEED
      LET YTH=YTH+YDT*SPEED
   END IF
   LET X0=X
   LET Y0=Y
LOOP

FILE GETSAVENAME F$,"STLファイル|*.stl"
IF F$="" THEN STOP
IF POS(UCASE$(F$),".STL")=0 THEN LET F$=F$ & ".stl"
OPEN #1:NAME F$ !'STLファイル書き出し(バイナリー形式)
ERASE #1
PRINT #1:REPEAT$(CHR$(0),80);
PRINT #1:MKL$(2*NN*N);
FOR I=0 TO N
   LET  XA=XX(I+1)-XX(I)
   LET  YA=YY(I+1)-YY(I)
   LET  ZA=ZZ(I+1)-ZZ(I)
   LET  VX=YY(I+1)*ZZ(I)-ZZ(I+1)*YY(I)
   LET  VY=ZZ(I+1)*XX(I)-XX(I+1)*ZZ(I)
   LET  VZ=XX(I+1)*YY(I)-YY(I+1)*XX(I)
   LET  SS=SQR(VX^2+VY^2+VZ^2)
   IF SS=0 THEN
      LET  VX=(YY(I+1)+1)*(ZZ(I)+1)-(ZZ(I+1)+1)*(YY(I)+1)
      LET  VY=(ZZ(I+1)+1)*(XX(I)+1)-(XX(I+1)+1)*(ZZ(I)+1)
      LET  VZ=(XX(I+1)+1)*(YY(I)+1)-(YY(I+1)+1)*(XX(I)+1)
      LET  SS=SQR(VX^2+VY^2+VZ^2)
   END IF
   LET  VX=VX/SS
   LET  VY=VY/SS
   LET  VZ=VZ/SS
   LET  TX=XA+VX*LL
   LET  TY=YA+VY*LL
   LET  TZ=ZA+VZ*LL
   FOR K=0 TO NN-1
      CALL ROTATE(TX,TY,TZ,XA,YA,ZA,K*360/NN,XO,YO,ZO)
      LET XN(K)=XO+XX(I)
      LET YN(K)=YO+YY(I)
      LET ZN(K)=ZO+ZZ(I)
   NEXT K
   IF I>0 THEN
      FOR K=0 TO NN-1
         LET X1=XM(K)
         LET Y1=YM(K)
         LET Z1=ZM(K)
         IF K=NN-1 THEN
            LET X2=XM(0)
            LET Y2=YM(0)
            LET Z2=ZM(0)
         ELSE
            LET X2=XM(K+1)
            LET Y2=YM(K+1)
            LET Z2=ZM(K+1)
         END IF
         IF K=NN-1 THEN
            LET X3=XN(0)
            LET Y3=YN(0)
            LET Z3=ZN(0)
         ELSE
            LET X3=XN(K+1)
            LET Y3=YN(K+1)
            LET Z3=ZN(K+1)
         END IF
         LET X4=XN(K)
         LET Y4=YN(K)
         LET Z4=ZN(K)
         CALL VECTORNORMAL(X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,XS,YS,ZS)
         PRINT #1:MKS$(XS);
         PRINT #1:MKS$(YS);
         PRINT #1:MKS$(ZS);
         PRINT #1:MKS$(X1);
         PRINT #1:MKS$(Y1);
         PRINT #1:MKS$(Z1);
         PRINT #1:MKS$(X2);
         PRINT #1:MKS$(Y2);
         PRINT #1:MKS$(Z2);
         PRINT #1:MKS$(X3);
         PRINT #1:MKS$(Y3);
         PRINT #1:MKS$(Z3);
         PRINT #1:CHR$(0);CHR$(0);
         CALL VECTORNORMAL(X1,Y1,Z1,X3,Y3,Z3,X4,Y4,Z4,XS,YS,ZS)
         PRINT #1:MKS$(XS);
         PRINT #1:MKS$(YS);
         PRINT #1:MKS$(ZS);
         PRINT #1:MKS$(X1);
         PRINT #1:MKS$(Y1);
         PRINT #1:MKS$(Z1);
         PRINT #1:MKS$(X3);
         PRINT #1:MKS$(Y3);
         PRINT #1:MKS$(Z3);
         PRINT #1:MKS$(X4);
         PRINT #1:MKS$(Y4);
         PRINT #1:MKS$(Z4);
         PRINT #1:CHR$(0);CHR$(0);
      NEXT  K
   END IF
   MAT XM=XN
   MAT YM=YN
   MAT ZM=ZN
NEXT I
CLOSE #1

SUB PLOT(X,Y,Z)
   LET POINT(1)=X+XMOVE
   LET POINT(2)=Y+YMOVE
   LET POINT(3)=Z+ZMOVE
   MAT POINT=POINT*M
   IF FL=0 THEN
      LET LMIN=MIN(LMIN,POINT(1))
      LET LMAX=MAX(LMAX,POINT(1))
      LET LMIN=MIN(LMIN,POINT(2))
      LET LMAX=MAX(LMAX,POINT(2))
   ELSE
      PLOT LINES:POINT(1)*SCALE,POINT(2)*SCALE;
   END IF
END SUB
END

EXTERNAL  SUB ROTATE(XX,YY,ZZ,X0,Y0,Z0,TH,NX,NY,NZ)
OPTION ARITHMETIC NATIVE
OPTION ANGLE DEGREES
!'(X0,Y0,Z0) 原点を通る回転軸
!'点 P(XX,YY,ZZ) TH度回転  P'(NX,NY,NZ)
DIM A(3,3)
LET  S=SQR(X0*X0+Y0*Y0+Z0*Z0)
LET  X=X0/S
LET  Y=Y0/S
LET  Z=Z0/S
LET  A(1,1)=X*X*(1-COS(TH))+COS(TH)
LET  A(1,2)=X*Y*(1-COS(TH))+Z*SIN(TH)
LET  A(1,3)=X*Z*(1-COS(TH))-Y*SIN(TH)
LET  A(2,1)=Y*X*(1-COS(TH))-Z*SIN(TH)
LET  A(2,2)=Y*Y*(1-COS(TH))+COS(TH)
LET  A(2,3)=Y*Z*(1-COS(TH))+X*SIN(TH)
LET  A(3,1)=Z*X*(1-COS(TH))+Y*SIN(TH)
LET  A(3,2)=Z*Y*(1-COS(TH))-X*SIN(TH)
LET  A(3,3)=Z*Z*(1-COS(TH))+COS(TH)
LET  NX=XX*A(1,1)+YY*A(1,2)+ZZ*A(1,3)
LET  NY=XX*A(2,1)+YY*A(2,2)+ZZ*A(2,3)
LET  NZ=XX*A(3,1)+YY*A(3,2)+ZZ*A(3,3)
END SUB

EXTERNAL  SUB VECTORNORMAL(X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,XX,YY,ZZ) !'法線ベクトル
OPTION ARITHMETIC NATIVE
LET  XX=(Y3-Y2)*(Z1-Z3)-(Z3-Z2)*(Y1-Y3)
LET  YY=(Z3-Z2)*(X1-X3)-(X3-X2)*(Z1-Z3)
LET  ZZ=(X3-X2)*(Y1-Y3)-(Y3-Y2)*(X1-X3)
LET  S=SQR(XX^2+YY^2+ZZ^2)
IF S<>0 THEN
   LET  XX=XX/S
   LET  YY=YY/S
   LET  ZZ=ZZ/S
END IF
END SUB

EXTERNAL  FUNCTION MKS$(X) !'IEEE754 32bit 浮動小数型
OPTION ARITHMETIC NATIVE
OPTION CHARACTER BYTE
OPTION BASE 0
DIM B(32)
IF X<0 THEN LET  B(0)=1
IF X<>0 THEN
   IF ABS(X)<1 THEN
      DO WHILE 2^(N+1)>ABS(X)
         LET  N=N-1
      LOOP
      LET  N=N+1
   ELSE
      DO WHILE 2^(N+1)<ABS(X)
         LET  N=N+1
      LOOP
   END IF
   LET  NN=N
   LET  N=N+127
   FOR I=1 TO 8
      IF BITAND(N,2^(8-I))<>0 THEN LET  B(I)=1
   NEXT I
   LET  T=(ABS(X)-2^NN)/2^NN
   FOR I=9 TO 31
      LET  T=T*2
      IF T>=1 THEN
         LET  B(I)=1
         LET  T=T-INT(T)
      END IF
   NEXT I
END IF
LET  AA$=CHR$(B(0)*128+B(1)*64+B(2)*32+B(3)*16+B(4)*8+B(5)*4+B(6)*2+B(7))
LET  BB$=CHR$(B(8)*128+B(9)*64+B(10)*32+B(11)*16+B(12)*8+B(13)*4+B(14)*2+B(15))
LET  CC$=CHR$(B(16)*128+B(17)*64+B(18)*32+B(19)*16+B(20)*8+B(21)*4+B(22)*2+B(23))
LET  DD$=CHR$(B(24)*128+B(25)*64+B(26)*32+B(27)*16+B(28)*8+B(29)*4+B(30)*2+B(31))
LET  MKS$=DD$&CC$&BB$&AA$
END FUNCTION

EXTERNAL  FUNCTION MKL$(A) !'long整数型
OPTION ARITHMETIC NATIVE
OPTION CHARACTER BYTE
DECLARE STRING A$,B$,C$,D$
IF A<0 THEN LET  A=A+2^32
LET  A$=CHR$(MOD(A,256))
LET  B$=CHR$(MOD(INT(A/256),256))
LET  C$=CHR$(MOD(INT(A/65536),256))
LET  D$=CHR$(MOD(INT(A/16777216),256))
LET  MKL$=A$&B$&C$&D$
END FUNCTION
 

テンソル積について

 投稿者:永野護  投稿日:2013年10月31日(木)09時16分34秒
  島村様、わかりやすい回答ありがとうございました。
敬具
 

Re: プログラムの解釈

 投稿者:山中和義  投稿日:2013年10月31日(木)10時05分55秒
  > No.3184[元記事へ]

GAIさんへのお返事です。

> 順列を生成するプログラム

アルゴリズムの本にあります。

サブルーチン perm の処理
先頭から(n-1)までを固定して、その並びから始まる最小のものを用意する(される)。
  n
  ↓
1  i      m
□□□□□□□□□
  └┘ ← この範囲を右へ1つローテイトさせる
  └─┘
  └──┘
    :
  └─────┘
とする。
再帰呼出しされるごとに、辞書式順序で先頭から(n-1)までが確定されていく。


REM 1~nの順列を辞書式順序で生成する。
DECLARE EXTERNAL SUB perm
DIM a(100)
INPUT n
MAT a=ZER(n)
FOR i=1 TO n !並び 1,2,3,4,…,n
   LET a(i)=i
NEXT i
CALL perm(a,1)
END
EXTERNAL SUB perm(a(),n)
LET m=UBOUND(a)
!----- debug -----
PRINT REPEAT$(" ",(m+1)*(n-1)); !階層
FOR i=1 TO m !並びを表示する
   PRINT STR$(a(i));
NEXT i
PRINT
!----- debug -----
IF n=m THEN !すべて並んだなら
!!MAT PRINT a;
ELSE
   FOR i=n TO m !ローテイトする範囲を設定する
      LET t=a(i) !右へ1つローテイト
      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) !左へ1つローテイトで元に戻す
      FOR j=n TO i-1
         LET a(j)=a(j+1)
      NEXT j
      LET a(i)=t

   NEXT i

END IF
END SUB



n=4の場合の実行結果

   n=1 n=2 n=3 n=4
? 4
1234
     1234
          1234
               1234
               1243
          1324
               1324
               1342
          1423
               1423
               1432
     2134
          2134
               2134
               2143
          2314
               2314
               2341
          2413
               2413
               2431
     3124
          3124
               3124
               3142
          3214
               3214
               3241
          3412
               3412
               3421
     4123
          4123
               4123
               4132
          4213
               4213
               4231
          4312
               4312
               4321

 

Re: プログラムの解釈

 投稿者:山中和義  投稿日:2013年10月31日(木)11時13分40秒
  > No.3186[元記事へ]

つづき

> GAIさんへのお返事です。
>
> > 順列を生成するプログラム


nからiの範囲をローテイトさせる必要がなく、nとiを入れ替えのみで可能です。
ただし、辞書式順序にはなりませんが、代入処理が少ないためやや高速です。


REM 1~nの順列を辞書式順序でなく生成する。
DECLARE EXTERNAL SUB perm
DIM a(100)
INPUT n
MAT a=ZER(n)
FOR i=1 TO n !並び 1,2,3,4,…,n
   LET a(i)=i
NEXT i
CALL perm(a,1)
END
EXTERNAL SUB perm(a(),n)
LET m=UBOUND(a)
!----- debug -----
PRINT REPEAT$(" ",(m+1)*(n-1)); !階層
FOR i=1 TO m !並びを表示する
   PRINT STR$(a(i));
NEXT i
PRINT
!----- debug -----
IF n=m THEN !すべて並んだなら
!!MAT PRINT a;
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


実行結果

? 4
1234
     1234
          1234
               1234
               1243
          1324
               1324
               1342
          1432
               1432
               1423
     2134
          2134
               2134
               2143
          2314
               2314
               2341
          2431
               2431
               2413
     3214
          3214
               3214
               3241
          3124
               3124
               3142
          3412
               3412
               3421
     4231
          4231
               4231
               4213
          4321
               4321
               4312
          4132
               4132
               4123


 

Re: プログラムの解釈

 投稿者:SECOND  投稿日:2013年11月 1日(金)05時39分39秒
  > No.3184[元記事へ]

!左ローテイト1つだけの方法・・・速度は、右左ローテイトより速く、SWAP より遅い。

!●アルゴリズム

! n 番目から、右終点 m 番までを1組に、順列の CALL を受ける。
! n+1 番目から、右終点 m 番までを、次の組として、その順列を、自身へ CALL する。
! これを、rotate left n~m で、先頭を、一順させる ・・・が、プログラムの、ほぼ全部。
!
! 以上の行き着く先は、n+1=m で、組の長さが1になって始めて終端する。
!
! そこでは、各階層での先頭が履歴として、配列 a() の中に、木構造の経路の様に並び、
! 1つの順列パターンとなるので、それをプリントして RETURN する。
!
! CALL から戻ったら、
! n+1 番目から、右終点 m 番までの残りも、左ローテイトして先頭へ移し、同様に繰返す。
!
! n 番目から、右終点 m 番の、配列部分は、一順した後、必ず元へ戻るように終了させる。
! 元へ戻っていないと、各階層での CALL~RETURN で、配列が保存されず、一順管理も破綻する。
!------------------------------------------------------------------------------------

LET m=3
DIM a(m)
!
FOR i=1 TO m
   LET a(i)=i
NEXT i
CALL perm(a,1)    !( m 個の数列,  n の初期値)

SUB perm(a(),n)
   local i
   IF n=m THEN
      MAT PRINT USING REPEAT$("## ",m): a
   ELSE
      FOR i=n TO m
         CALL perm(a,n+1)
         !--------                !rotate Left 1
         LET t=a(n)               !  ┌── → ──┐
         FOR j=n TO m-1           ! a(n)・・←・・a(m)
            LET a(j)=a(j+1)
         NEXT j
         LET a(m)=t
         !--------
      NEXT i
   END IF
END SUB

END
 

順列

 投稿者:しばっち  投稿日:2013年11月 3日(日)00時12分36秒
  PUBLIC NUMERIC B(10),S
DO
   INPUT PROMPT "N,R=":N,R
LOOP UNTIL N>=R
PRINT PERM(N,R)
SELECT CASE R
CASE 2
   CALL PERM2(N)
CASE 3
   CALL PERM3(N)
CASE 4
   CALL PERM4(N)
CASE 5
   CALL PERM5(N)
CASE ELSE
   DIM A(N)
   CALL PERMN(1,N,R,A)
END SELECT
END

EXTERNAL SUB PERM2(N)
FOR I=1 TO N
   FOR J=1 TO N
      IF I<>J THEN
         LET S=S+1
         PRINT S;":";I;J
      END IF
   NEXT J
NEXT I
END SUB

EXTERNAL SUB PERM3(N)
FOR I=1 TO N
   FOR J=1 TO N
      FOR K=1 TO N
         IF I<>J AND J<>K AND I<>K THEN
            LET S=S+1
            PRINT S;":";I;J;K
         END IF
      NEXT K
   NEXT J
NEXT I
END SUB

EXTERNAL SUB PERM4(N)
FOR I=1 TO N
   FOR J=1 TO N
      FOR K=1 TO N
         FOR L=1 TO N
            IF I<>J AND I<>K AND I<>L AND J<>K AND J<>L AND K<>L THEN
               LET S=S+1
               PRINT S;":";I;J;K;L
            END IF
         NEXT L
      NEXT K
   NEXT J
NEXT I
END SUB

EXTERNAL SUB PERM5(N)
FOR I=1 TO N
   FOR J=1 TO N
      FOR K=1 TO N
         FOR L=1 TO N
            FOR M=1 TO N
               IF I<>J AND I<>K AND I<>L AND I<>M AND J<>K AND J<>L AND J<>M AND K<>L AND K<>M AND L<>M THEN
                  LET S=S+1
                  PRINT S;":";I;J;K;L;M
               END IF
            NEXT M
         NEXT L
      NEXT K
   NEXT J
NEXT I
END SUB

EXTERNAL  SUB PERMN(NN,M,N,A())
IF N<NN THEN
   MAT B=ZER
   FOR J=1 TO N
      IF B(A(J))<>0 THEN EXIT SUB
      LET B(A(J))=1
   NEXT J
   LET S=S+1
   PRINT S;":";
   FOR J=1 TO N
      PRINT A(J);
   NEXT J
   PRINT
ELSE
   FOR I=1 TO M
      LET A(NN)=I
      CALL PERMN(NN+1,M,N,A)
   NEXT I
END IF
END SUB
 

Re: プログラムの解釈

 投稿者:SECOND  投稿日:2013年11月 3日(日)17時02分28秒
  > No.3188[元記事へ]

! m 個から r 個、取る場合は、以下の様に速めに終らせます。
!------------
LET m=4
LET r=2   !m 個から r 個
!
DIM a(m)
FOR i=1 TO m
   LET a(i)=i
NEXT i
CALL perm( a,1)     !CALL perm_fast( a,1) !速い

SUB perm(a(),n)
   local i
   IF n >r THEN     !● r で、速めに終らせる。
      MAT PRINT USING REPEAT$("## ",r)& " 配列の残り(無視)→"& REPEAT$("## ",m-r) :a
   ELSE
      FOR i=n TO m
         CALL perm(a,n+1)
         !--------                !rotate Left 1
         LET t=a(n)               !  ┌── → ──┐
         FOR j=n TO m-1           ! a(n)・・←・・a(m)
            LET a(j)=a(j+1)
         NEXT j
         LET a(m)=t
         !--------
      NEXT i
   END IF
END SUB


!-------------------- swap を使った速い方も、同様に・・
SUB perm_fast( a(),n)
   local i
   IF n<=r THEN
      FOR i=n TO  m
         swap a(n), a(i)
         CALL perm_fast( a,n+1)
         swap a(n), a(i)
      NEXT i
   ELSE
      MAT PRINT USING REPEAT$("## ",r)& " 配列の残り(無視)→"& REPEAT$("## ",m-r) :a
   END IF
END SUB

END
 

アニメーション

 投稿者:SECOND  投稿日:2013年11月 5日(火)06時41分50秒
  !クリックは、Graphic WINDOW 内の任意な場所で、
! 左押し→ 反転開始、動いている時に押し続けると 一時停止。
! 右押し→ プログラム終了。
!-------------------------
SET bitmap SIZE 501,501
!                    !401x401 501x501 641x641
SET TEXT font "",10  !  8      10      11
LET pxw=          6  !  5       6       7    !Pixels /問題座標x単位
LET pyw=          9  !  7       9      11    !Pixels /  〃 y単位
!
ASK PIXEL SIZE(0,0;1,1) bmx,bmy
LET px=1/pxw                                 !問題座標x幅 /Pixel
LET py=1/pyw                                 !  〃 y幅 /Pixel
LET ss=7                                     !  〃 x幅 /1人
DIM u( ss*3*pxw, 7*pyw+1)
DIM v( ss*8*pxw, 7*pyw+1), n$(0 TO 7)
MAT READ n$
DATA "head","neck","shoulder","abdomen","back","thigh","shin","   "
!
CALL act(0)
PLOT TEXT,AT ss*2, 17.0: "Right click to STOP"
PLOT TEXT,AT ss*2, 15.4: " Left click to TURN/PAUSE"
CALL act(1)
DO
   mouse poll mx,my,ml,mr
   IF ml=1 THEN
      IF bak_t=1 THEN CALL act(2) ELSE CALL act(1)
   END IF
   WAIT DELAY 0
LOOP UNTIL mr=1

SUB act(t)
   FOR st=1 TO 3 STEP 2
      SET AREA COLOR 0
      IF st=1 THEN LET k=16 ELSE LET k=44
      SET WINDOW -(ss*st+2), bmx/pxw-px-(ss*st+2), -(bmy/pyw-py)+k,k
      IF st=1 THEN LET i=i1 ELSE LET i=i3
      IF st=1 THEN LET w$=w1$ ELSE LET w$=w3$
      IF t=0 THEN CALL init08
      IF t=1 THEN CALL left7
      IF t=2 THEN CALL right8
      IF st=1 THEN LET i1=i ELSE LET i3=i
      IF st=1 THEN LET w1$=w$ ELSE LET w3$=w$
   NEXT st
   LET bak_t=t
END SUB

SUB init08
   PLOT AREA:      0,7  ;     0,-7   ;  ss*8-px,-7   ;  ss*8-px,7              !clear image part
   PLOT LINES:     0,0  ;     0, 7   ; ss*st-px, 7   ; ss*st-px,0  ;     0,0   !left upper around
   PLOT LINES: ss*st,0  ; ss*st, 7   ;  ss*8-px, 7   ;  ss*8-px,0  ; ss*st,0   !right upper around
   PLOT LINES:     0,-py;     0,-7-py;  ss*8-px,-7-py;  ss*8-px,-py !;     0,-py !all under around
   LET w$=""
   FOR i=0 TO 7
      LET j=MOD(i*st,8)         !← st=1/st=3 で doll の直線整列 散在を切換えている。
      DRAW doll WITH SHIFT( i*ss+1, j-7)
      LET w$=w$& n$(j)& " "
   NEXT i
   PLOT LINES: 0,-9; ss*8,-9; ss*8,-7.6; 0,-7.6; 0,-9   !text box
   LET i=0
   LET j=0
END SUB

SUB right8
   MAT u=ZER( ss*st*pxw, 7*pyw+1)
   ASK PIXEL ARRAY(i*ss,j+7) u  !  right upper image
   CALL move(u, 0, 1,  8)       !↑   ( u(,), dx,dy, n)
   CALL move(u,-1, 0,  8)       !←
   CALL move(u, 0,-1,  8)       !↓
   ASK PIXEL ARRAY(i*ss,j+7) v  !  all upper image
   CALL move(v, 1/7,0, st*7)    !→   ( v(,), dx,dy, n)
   PLOT AREA: px,py-9; ss*8-px,py-9; ss*8-px,-py-7.6; px,-py-7.6   !clear text box
END SUB

SUB left7
   MAT u=ZER( ss*st*pxw, 7*pyw+1)
   ASK PIXEL ARRAY(ss*i,j+7) v  !  all upper image
   CALL move(v, -1/7,0, st*7)   !←   ( v(,), dx,dy, n)
   ASK PIXEL ARRAY(ss*i,j+7) u  !  left upper image
   CALL move(u, 0, 1,  8)       !↑   ( u(,), dx,dy, n)
   CALL move(u, 1, 0,  8)       !→
   CALL move(u, 0,-1,  8)       !↓
   PLOT TEXT,AT .8,-9: w$       !write text box
END SUB

SUB move( v(,), dx,dy, n)
   LET w=SIZE(v,1)/(ss*pxw)
   FOR k=1 TO n
      MAT PLOT CELLS ,IN  ss*(i+dx),7+j+dy; ss*(w+i+dx)-px,j+dy: v
      IF 0< dy THEN PLOT AREA: ss*i,j        ; ss*(i+w )-px,j        ; ss*(i+w )-px,j+dy-py; ss*i,j+dy-py
      IF dy< 0 THEN PLOT AREA: ss*i,j+7+dy+py; ss*(i+w )-px,j+7+dy+py; ss*(i+w )-px,j+7 ; ss*i,j+7
      IF 0< dx THEN PLOT AREA: ss*i,j        ; ss*(i+dx)-px,j        ; ss*(i+dx)-px,j+7 ; ss*i,j+7
      IF dx< 0 THEN PLOT AREA: ss*(i+w+dx),j ; ss*(i+w )-px,j        ; ss*(i+w )-px,j+7 ; ss*(i+w+dx),j+7
      CALL bwait(0)
      LET i=i+dx
      LET j=j+dy
   NEXT k
END SUB

PICTURE doll
   FOR h=0 TO 6
      SET AREA COLOR 23+h
      IF h< 2 THEN
         PLOT AREA: 1,h; 2-px,h; 2-px,(h+1)-py; 1,(h+1)-py
         PLOT AREA: 3,h; 4-px,h; 4-px,(h+1)-py; 3,(h+1)-py
      ELSEIF h< 4 THEN
         PLOT AREA: 1,h; 4-px,h; 4-px,(h+1)-py; 1,(h+1)-py
         PLOT AREA: 0,h; 1-px*3,h; 1-px*3,(h+1)-py; 0,(h+1)-py
         PLOT AREA: 5,h; 4+px*2,h; 4+px*2,(h+1)-py; 5,(h+1)-py
      ELSEIF h=4 THEN
         PLOT AREA: 0,h; 5-px,h; 5-px,(h+1)-py; 0,(h+1)-py
      ELSEIF h=5 THEN
         PLOT AREA: 2,5; 3-px,5; 3-px,6-py; 2,6-py
      ELSEIF h=6 THEN
         PLOT AREA: 1,h; 4-px,h; 4-px,(h+1)-py; 1,(h+1)-py
      END IF
   NEXT h
END PICTURE

SUB bwait(t)               !default local value 't'
   DO
      mouse poll mx,my,ml,mr
      IF 0< mr THEN STOP
      IF 0< ml THEN LET t=.1
      IF t<=0 THEN EXIT SUB
      LET t=t-.1
      WAIT DELAY .1
   LOOP
END SUB

END
 

N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月16日(土)19時15分17秒
  http://members3.jcom.home.ne.jp/zakii/enumeration/10_balls_boxes.htm

!'N個の異なる球をR個の異なる箱に分ける(空箱なし)
DO
   INPUT PROMPT "N,R=":N,R
LOOP UNTIL N>=R
PUBLIC STRING A$(10)
PUBLIC NUMERIC B(10),S
DIM AA(N)
PRINT FACT(R)*S2(N,R)
SELECT CASE N
CASE 2
   FOR I=1 TO R
      FOR J=1 TO R
         LET B(I)=1
         LET B(J)=1
         LET FL=0
         FOR II=1 TO R
            IF B(II)=0 THEN LET FL=1
         NEXT II
         IF FL=0 THEN
            LET A$(I)=A$(I)&"1"
            LET A$(J)=A$(J)&" 2"
            LET S=S+1
            PRINT S;":";
            FOR II=1 TO R
               PRINT "[";LTRIM$(A$(II));"]";
               LET A$(II)=""
            NEXT II
            PRINT
         END IF
         MAT B=ZER
      NEXT J
   NEXT I
CASE 3
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            LET B(I)=1
            LET B(J)=1
            LET B(K)=1
            LET FL=0
            FOR II=1 TO R
               IF B(II)=0 THEN LET FL=1
            NEXT II
            IF FL=0 THEN
               LET A$(I)=A$(I)&"1"
               LET A$(J)=A$(J)&" 2"
               LET A$(K)=A$(K)&" 3"
               LET S=S+1
               PRINT S;":";
               FOR II=1 TO R
                  PRINT "[";LTRIM$(A$(II));"]";
                  LET A$(II)=""
               NEXT II
               PRINT
            END IF
            MAT B=ZER
         NEXT K
      NEXT J
   NEXT I
CASE 4
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               LET B(I)=1
               LET B(J)=1
               LET B(K)=1
               LET B(L)=1
               LET FL=0
               FOR II=1 TO R
                  IF B(II)=0 THEN LET FL=1
               NEXT II
               IF FL=0 THEN
                  LET A$(I)=A$(I)&"1"
                  LET A$(J)=A$(J)&" 2"
                  LET A$(K)=A$(K)&" 3"
                  LET A$(L)=A$(L)&" 4"
                  LET S=S+1
                  PRINT S;":";
                  FOR II=1 TO R
                     PRINT "[";LTRIM$(A$(II));"]";
                     LET A$(II)=""
                  NEXT II
                  PRINT
               END IF
               MAT B=ZER
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE ELSE
   CALL PN(1,N,R,AA)
END SELECT
END

EXTERNAL  SUB PN(NN,M,R,AA())
IF M<NN THEN
   FOR II=1 TO M
      LET B(AA(II))=1
   NEXT II
   LET FL=0
   FOR II=1 TO R
      IF B(II)=0 THEN LET FL=1
   NEXT II
   IF FL=0 THEN
      FOR II=1 TO M
         LET A$(AA(II))=A$(AA(II))&" "&STR$(II)
      NEXT II
      LET S=S+1
      PRINT S;":";
      FOR II=1 TO R
         PRINT "[";LTRIM$(A$(II));"]";
         LET A$(II)=""
      NEXT II
      PRINT
   END IF
   MAT B=ZER
ELSE
   FOR I=1 TO R
      LET AA(NN)=I
      CALL PN(NN+1,M,R,AA)
   NEXT I
END IF
END SUB

EXTERNAL FUNCTION S2(N,K) !'第2スターリング数
IF K<1 OR K>N THEN
   LET S2=0
   EXIT FUNCTION
END IF
IF K=N OR K=1 THEN
   LET S2=1
   EXIT FUNCTION
END IF
LET S2=K*S2(N-1,K)+S2(N-1,K-1)
END FUNCTION

N,R=5,3
150
1 :[1 2 3][4][5]
2 :[1 2 3][5][4]
3 :[1 2 4][3][5]
4 :[1 2][3 4][5]
5 :[1 2 5][3][4]

中略

144 :[4 5][3][1 2]
145 :[4][3 5][1 2]
146 :[4][3][1 2 5]
147 :[5][3 4][1 2]
148 :[5][3][1 2 4]
149 :[4][5][1 2 3]
150 :[5][4][1 2 3]
 

N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月16日(土)19時15分55秒
  !'N個の異なる球をR個の異なる箱に分ける(空箱あり)
INPUT PROMPT "N,R=":N,R
PUBLIC STRING A$(10)
PUBLIC NUMERIC S
DIM AA(N)
PRINT R^N
SELECT CASE N
CASE 2
   FOR I=1 TO R
      FOR J=1 TO R
         LET A$(I)=A$(I)&"1"
         LET A$(J)=A$(J)&" 2"
         LET S=S+1
         PRINT S;":";
         FOR II=1 TO R
            PRINT "[";LTRIM$(A$(II));"]";
            LET A$(II)=""
         NEXT II
         PRINT
      NEXT J
   NEXT I
CASE 3
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            LET A$(I)=A$(I)&"1"
            LET A$(J)=A$(J)&" 2"
            LET A$(K)=A$(K)&" 3"
            LET S=S+1
            PRINT S;":";
            FOR II=1 TO R
               PRINT "[";LTRIM$(A$(II));"]";
               LET A$(II)=""
            NEXT II
            PRINT
         NEXT K
      NEXT J
   NEXT I
CASE 4
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               LET A$(I)=A$(I)&"1"
               LET A$(J)=A$(J)&" 2"
               LET A$(K)=A$(K)&" 3"
               LET A$(L)=A$(L)&" 4"
               LET S=S+1
               PRINT S;":";
               FOR II=1 TO R
                  PRINT "[";LTRIM$(A$(II));"]";
                  LET A$(II)=""
               NEXT II
               PRINT
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE 5
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               FOR M=1 TO R
                  LET A$(I)=A$(I)&"1"
                  LET A$(J)=A$(J)&" 2"
                  LET A$(K)=A$(K)&" 3"
                  LET A$(L)=A$(L)&" 4"
                  LET A$(M)=A$(M)&" 5"
                  LET S=S+1
                  PRINT S;":";
                  FOR II=1 TO R
                     PRINT "[";LTRIM$(A$(II));"]";
                     LET A$(II)=""
                  NEXT II
                  PRINT
               NEXT M
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE ELSE
   CALL PN(1,N,R,AA)
END SELECT
END

EXTERNAL  SUB PN(NN,M,R,AA())
IF M<NN THEN
   FOR II=1 TO M
      LET A$(AA(II))=A$(AA(II))&" "&STR$(II)
   NEXT II
   LET S=S+1
   PRINT S;":";
   FOR II=1 TO R
      PRINT "[";LTRIM$(A$(II));"]";
      LET A$(II)=""
   NEXT II
   PRINT
ELSE
   FOR I=1 TO R
      LET AA(NN)=I
      CALL PN(NN+1,M,R,AA)
   NEXT I
END IF
END SUB

N,R=5,3
243
1 :[1 2 3 4 5][][]
2 :[1 2 3 4][5][]
3 :[1 2 3 4][][5]
4 :[1 2 3 5][4][]
5 :[1 2 3][4 5][]
6 :[1 2 3][4][5]
7 :[1 2 3 5][][4]

中略

236 :[4][5][1 2 3]
237 :[4][][1 2 3 5]
238 :[5][4][1 2 3]
239 :[][4 5][1 2 3]
240 :[][4][1 2 3 5]
241 :[5][][1 2 3 4]
242 :[][5][1 2 3 4]
243 :[][][1 2 3 4 5]
 

N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月16日(土)19時16分27秒
  !'N個の異なる球をR個の同じ箱に分ける(空箱なし)
DO
   INPUT PROMPT "N,R=":N,R
LOOP UNTIL N>=R
PRINT S2(N,R)
PUBLIC STRING A$(10),B$(10,1000)
PUBLIC NUMERIC C(10),S
DIM AA(N)
SELECT CASE N
CASE 2
   FOR I=1 TO R
      FOR J=1 TO R
         LET C(I)=1
         LET C(J)=1
         LET FG=0
         FOR II=1 TO R
            IF C(II)=0 THEN LET FG=1
         NEXT II
         IF FG=0 THEN
            LET A$(I)=A$(I)&"1"
            LET A$(J)=A$(J)&" 2"
            FOR II=1 TO S
               LET FL=CHECK(R,A$,B$,II)
               IF FL<>0 THEN EXIT FOR
            NEXT II
            IF FL=0 THEN
               LET S=S+1
               FOR II=1 TO R
                  LET B$(II,S)=A$(II)
               NEXT II
               PRINT S;":";
               FOR II=1 TO R
                  PRINT "[";LTRIM$(A$(II));"]";
               NEXT II
               PRINT
            END IF
            MAT A$=NUL$
         END IF
         LET C(I)=0
         LET C(J)=0
      NEXT J
   NEXT I
CASE 3
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            LET C(I)=1
            LET C(J)=1
            LET C(K)=1
            LET FG=0
            FOR II=1 TO R
               IF C(II)=0 THEN LET FG=1
            NEXT II
            IF FG=0 THEN
               LET A$(I)=A$(I)&"1"
               LET A$(J)=A$(J)&" 2"
               LET A$(K)=A$(K)&" 3"
               FOR II=1 TO S
                  LET FL=CHECK(R,A$,B$,II)
                  IF FL<>0 THEN EXIT FOR
               NEXT  II
               IF FL=0 THEN
                  LET S=S+1
                  FOR II=1 TO R
                     LET B$(II,S)=A$(II)
                  NEXT II
                  PRINT S;":";
                  FOR II=1 TO R
                     PRINT "[";LTRIM$(A$(II));"]";
                  NEXT II
                  PRINT
               END IF
               MAT A$=NUL$
            END IF
            LET C(I)=0
            LET C(J)=0
            LET C(K)=0
         NEXT K
      NEXT J
   NEXT I
CASE 4
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               LET C(I)=1
               LET C(J)=1
               LET C(K)=1
               LET C(L)=1
               LET FG=0
               FOR II=1 TO R
                  IF C(II)=0 THEN LET FG=1
               NEXT II
               IF FG=0 THEN
                  LET A$(I)=A$(I)&"1"
                  LET A$(J)=A$(J)&" 2"
                  LET A$(K)=A$(K)&" 3"
                  LET A$(L)=A$(L)&" 4"
                  FOR II=1 TO S
                     LET FL=CHECK(R,A$,B$,II)
                     IF FL<>0 THEN EXIT FOR
                  NEXT II
                  IF FL=0 THEN
                     LET S=S+1
                     FOR II=1 TO R
                        LET B$(II,S)=A$(II)
                     NEXT II
                     PRINT S;":";
                     FOR II=1 TO R
                        PRINT "[";LTRIM$(A$(II));"]";
                     NEXT II
                     PRINT
                  END IF
                  MAT A$=NUL$
               END IF
               LET C(I)=0
               LET C(J)=0
               LET C(K)=0
               LET C(L)=0
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE ELSE
   CALL PN(1,N,R,AA)
END SELECT
END

EXTERNAL  SUB PN(NN,M,R,AA())
IF M<NN THEN
   FOR II=1 TO M
      LET C(AA(II))=1
   NEXT II
   LET FG=0
   FOR II=1 TO R
      IF C(II)=0 THEN LET FG=1
   NEXT II
   IF FG=0 THEN
      FOR II=1 TO M
         LET A$(AA(II))=A$(AA(II))&" "&STR$(II)
      NEXT II
      FOR II=1 TO S
         LET FL=CHECK(R,A$,B$,II)
         IF FL<>0 THEN EXIT FOR
      NEXT II
      IF FL=0 THEN
         LET S=S+1
         FOR II=1 TO R
            LET B$(II,S)=A$(II)
         NEXT II
         PRINT S;":";
         FOR II=1 TO R
            PRINT "[";LTRIM$(A$(II));"]";
         NEXT II
         PRINT
      END IF
      MAT A$=NUL$
   END IF
   MAT C=ZER
ELSE
   FOR I=1 TO R
      LET AA(NN)=I
      CALL PN(NN+1,M,R,AA)
   NEXT I
END IF
END SUB

EXTERNAL  FUNCTION S2(N,R) !'第2スターリング数
FOR J=0 TO R
   LET V=V+COMB(R,J)*(-1)^J*(R-J)^N
NEXT J
LET S2=V/FACT(R)
END FUNCTION

EXTERNAL  FUNCTION CHECK(R,A$(),B$(,),II)
SELECT CASE R
CASE 2
   FOR I=1 TO R
      FOR J=1 TO R
         IF I<>J THEN
            IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) THEN
               LET CHECK=1
               EXIT FUNCTION
            END IF
         END IF
      NEXT J
   NEXT I
CASE 3
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            IF I<>J AND J<>K AND I<>K THEN
               IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) THEN
                  LET CHECK=1
                  EXIT FUNCTION
               END IF
            END IF
         NEXT K
      NEXT J
   NEXT I
CASE 4
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               IF I<>J AND I<>K AND I<>L AND J<>K AND J<>L AND K<>L THEN
                  IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) AND LTRIM$(A$(L))=LTRIM$(B$(4,II)) THEN
                     LET CHECK=1
                     EXIT FUNCTION
                  END IF
               END IF
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE 5
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               FOR M=1 TO R
                  IF I<>J AND I<>K AND I<>L AND I<>M AND J<>K AND J<>L AND J<>M AND K<>L AND K<>M AND L<>M THEN
                     IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) AND LTRIM$(A$(L))=LTRIM$(B$(4,II)) AND LTRIM$(A$(M))=LTRIM$(B$(5,II)) THEN
                        LET CHECK=1
                        EXIT FUNCTION
                     END IF
                  END IF
               NEXT M
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE 6
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               FOR M=1 TO R
                  FOR O=1 TO R
                     IF I<>J AND I<>K AND I<>L AND I<>M AND I<>O AND J<>K AND J<>L AND J<>M AND J<>O  THEN
                        IF K<>L AND K<>M AND K<>O AND L<>M AND L<>O AND M<>O THEN
                           IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) AND LTRIM$(A$(L))=LTRIM$(B$(4,II)) AND LTRIM$(A$(M))=LTRIM$(B$(5,II)) AND LTRIM$(A$(O))=LTRIM$(B$(6,II)) THEN
                              LET CHECK=1
                              EXIT FUNCTION
                           END IF
                        END IF
                     END IF
                  NEXT O
               NEXT M
            NEXT L
         NEXT K
      NEXT J
   NEXT I
END SELECT
END FUNCTION

N,R=5,3
25
1 :[1 2 3][4][5]
2 :[1 2 4][3][5]
3 :[1 2][3 4][5]
4 :[1 2 5][3][4]
5 :[1 2][3 5][4]
6 :[1 2][3][4 5]
7 :[1 3 4][2][5]
8 :[1 3][2 4][5]
9 :[1 3 5][2][4]
10 :[1 3][2 5][4]
11 :[1 3][2][4 5]
12 :[1 4][2 3][5]
13 :[1][2 3 4][5]
14 :[1 5][2 3][4]
15 :[1][2 3 5][4]
16 :[1][2 3][4 5]
17 :[1 4 5][2][3]
18 :[1 4][2 5][3]
19 :[1 4][2][3 5]
20 :[1 5][2 4][3]
21 :[1][2 4 5][3]
22 :[1][2 4][3 5]
23 :[1 5][2][3 4]
24 :[1][2 5][3 4]
25 :[1][2][3 4 5]
 

N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月16日(土)19時17分3秒
  !'N個の異なる球をR個の同じ箱に分ける(空箱あり)
DO
   INPUT PROMPT "N,R=":N,R
LOOP UNTIL N>=R AND N>=2
DIM AA(N)
PUBLIC STRING A$(10),B$(10,1000)
PUBLIC NUMERIC S,SS
FOR K=1 TO R
   LET SS=SS+S2(N,K)
NEXT  K
PRINT SS
SELECT CASE N
CASE 2
   FOR I=1 TO R
      FOR J=1 TO R
         LET A$(I)=A$(I)&"1"
         LET A$(J)=A$(J)&" 2"
         FOR II=1 TO S
            LET FL=CHECK(R,A$,B$,II)
            IF FL<>0 THEN EXIT FOR
         NEXT II
         IF FL=0 THEN
            LET S=S+1
            FOR II=1 TO R
               LET B$(II,S)=A$(II)
            NEXT II
            PRINT S;":";
            FOR II=1 TO R
               PRINT "[";LTRIM$(A$(II));"]";
            NEXT II
            PRINT
         END IF
         IF S=SS THEN STOP
         MAT A$=NUL$
      NEXT J
   NEXT I
CASE 3
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            LET A$(I)=A$(I)&"1"
            LET A$(J)=A$(J)&" 2"
            LET A$(K)=A$(K)&" 3"
            FOR II=1 TO S
               LET FL=CHECK(R,A$,B$,II)
               IF FL<>0 THEN EXIT FOR
            NEXT II
            IF FL=0 THEN
               LET S=S+1
               FOR II=1 TO R
                  LET B$(II,S)=A$(II)
               NEXT II
               PRINT S;":";
               FOR II=1 TO R
                  PRINT "[";LTRIM$(A$(II));"]";
               NEXT II
               PRINT
            END IF
            IF S=SS THEN STOP
            MAT A$=NUL$
         NEXT K
      NEXT J
   NEXT I
CASE 4
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               LET A$(I)=A$(I)&"1"
               LET A$(J)=A$(J)&" 2"
               LET A$(K)=A$(K)&" 3"
               LET A$(L)=A$(L)&" 4"
               FOR II=1 TO S
                  LET FL=CHECK(R,A$,B$,II)
                  IF FL<>0 THEN EXIT FOR
               NEXT II
               IF FL=0 THEN
                  LET S=S+1
                  FOR II=1 TO R
                     LET B$(II,S)=A$(II)
                  NEXT II
                  PRINT S;":";
                  FOR II=1 TO R
                     PRINT "[";LTRIM$(A$(II));"]";
                  NEXT II
                  PRINT
               END IF
               IF S=SS THEN STOP
               MAT A$=NUL$
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE ELSE
   CALL PN(1,N,R,AA)
END SELECT
END

EXTERNAL  SUB PN(NN,M,R,AA())
IF M<NN THEN
   FOR II=1 TO M
      LET A$(AA(II))=A$(AA(II))&" "&STR$(II)
   NEXT II
   FOR II=1 TO S
      LET FL=CHECK(R,A$,B$,II)
      IF FL<>0 THEN EXIT FOR
   NEXT II
   IF FL=0 THEN
      LET S=S+1
      FOR II=1 TO R
         LET B$(II,S)=A$(II)
      NEXT II
      PRINT S;":";
      FOR II=1 TO R
         PRINT "[";LTRIM$(A$(II));"]";
      NEXT II
      PRINT
   END IF
   IF S=SS THEN STOP
   MAT A$=NUL$
ELSE
   FOR I=1 TO R
      LET AA(NN)=I
      CALL PN(NN+1,M,R,AA)
   NEXT I
END IF
END SUB

EXTERNAL  FUNCTION S2(N,R) !'第2スターリング数
FOR J=0 TO R
   LET V=V+COMB(R,J)*(-1)^J*(R-J)^N
NEXT J
LET S2=V/FACT(R)
END FUNCTION

EXTERNAL  FUNCTION CHECK(R,A$(),B$(,),II)
SELECT CASE R
CASE 2
   FOR I=1 TO R
      FOR J=1 TO R
         IF I<>J THEN
            IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) THEN
               LET CHECK=1
               EXIT FUNCTION
            END IF
         END IF
      NEXT J
   NEXT I
CASE 3
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            IF I<>J AND J<>K AND I<>K THEN
               IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) THEN
                  LET CHECK=1
                  EXIT FUNCTION
               END IF
            END IF
         NEXT K
      NEXT J
   NEXT I
CASE 4
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               IF I<>J AND I<>K AND I<>L AND J<>K AND J<>L AND K<>L THEN
                  IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) AND LTRIM$(A$(L))=LTRIM$(B$(4,II)) THEN
                     LET CHECK=1
                     EXIT FUNCTION
                  END IF
               END IF
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE 5
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               FOR M=1 TO R
                  IF I<>J AND I<>K AND I<>L AND I<>M AND J<>K AND J<>L AND J<>M AND K<>L AND K<>M AND L<>M THEN
                     IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) AND LTRIM$(A$(L))=LTRIM$(B$(4,II)) AND LTRIM$(A$(M))=LTRIM$(B$(5,II)) THEN
                        LET CHECK=1
                        EXIT FUNCTION
                     END IF
                  END IF
               NEXT M
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE 6
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               FOR M=1 TO R
                  FOR O=1 TO R
                     IF I<>J AND I<>K AND I<>L AND I<>M AND I<>O AND J<>K AND J<>L AND J<>M AND J<>O  THEN
                        IF K<>L AND K<>M AND K<>O AND L<>M AND L<>O AND M<>O THEN
                           IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) AND LTRIM$(A$(L))=LTRIM$(B$(4,II)) AND LTRIM$(A$(M))=LTRIM$(B$(5,II)) AND LTRIM$(A$(O))=LTRIM$(B$(6,II)) THEN
                              LET CHECK=1
                              EXIT FUNCTION
                           END IF
                        END IF
                     END IF
                  NEXT O
               NEXT M
            NEXT L
         NEXT K
      NEXT J
   NEXT I
END SELECT
END FUNCTION

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

N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月16日(土)19時17分32秒
  !'N個の同じ球をR個の異なる箱に分ける(空箱なし)
DO
   INPUT PROMPT "N,R=":N,R
LOOP UNTIL N>=R AND R>1
DIM A(N)
PUBLIC NUMERIC S
PRINT COMB(N-1,R-1)
CALL COMBN(1,N-1,R-1,A)
END

EXTERNAL  SUB COMBN(NN,N,R,A())
IF R<NN THEN
   LET S=S+1
   PRINT S;":[";
   FOR J=1 TO N+1
      PRINT "●";
      FOR L=1 TO R
         IF A(L)=J THEN PRINT "] [";
      NEXT  L
   NEXT J
   PRINT "]"
ELSE
   FOR I=1 TO N-R+NN
      LET A(NN)=I
      IF NN=1 OR A(NN-1)<A(NN) THEN
         CALL COMBN(NN+1,N,R,A)
      END IF
   NEXT I
END IF
END SUB

N,R=5,3
6
1 :[●] [●] [●●●]
2 :[●] [●●] [●●]
3 :[●] [●●●] [●]
4 :[●●] [●] [●●]
5 :[●●] [●●] [●]
6 :[●●●] [●] [●]
 

N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月16日(土)19時18分0秒
  !'N個の同じ球をR個の異なる箱に分ける(空箱あり)
PUBLIC NUMERIC S
INPUT PROMPT "N,R=":N,R
PRINT COMB(N+R-3,R-1)
DIM A(N+R-1)
CALL RECURSIVE(1,N-1,R-1,A)
END

EXTERNAL  SUB RECURSIVE(NN,M,N,A())
IF N<NN THEN
   LET S=S+1
   PRINT S;": [";
   FOR J=1 TO M+1
      PRINT "●";
      FOR L=1 TO N
         IF A(L)=J THEN PRINT "] [";
      NEXT  L
   NEXT J
   PRINT "]"
ELSE
   FOR I=1 TO M
      LET A(NN)=I
      IF NN=1 OR A(NN-1)<=A(NN) THEN
         CALL RECURSIVE(NN+1,M,N,A)
      END IF
   NEXT I
END IF
END SUB

N,R=5,3
10
1 : [●] [] [●●●●]
2 : [●] [●] [●●●]
3 : [●] [●●] [●●]
4 : [●] [●●●] [●]
5 : [●●] [] [●●●]
6 : [●●] [●] [●●]
7 : [●●] [●●] [●]
8 : [●●●] [] [●●]
9 : [●●●] [●] [●]
10 : [●●●●] [] [●]
 

N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月16日(土)19時18分26秒
  !'N個の同じ球をR個の同じ箱に分ける(空箱なし)
PUBLIC NUMERIC S
DO
   INPUT PROMPT "N,R=":N,R
LOOP UNTIL N>=R AND N>=2
DIM A(N)
PRINT P(N,R)
SELECT CASE R
CASE 2
   FOR I=1 TO N
      LET J=N-I
      IF I<=J THEN
         LET S=S+1
         PRINT S;": [";
         FOR II=1 TO N
            PRINT "●";
            IF II=I THEN PRINT "] [";
         NEXT II
         PRINT "]"
      END IF
   NEXT I
CASE 3
   FOR I=1 TO N
      FOR J=I TO N-I
         LET K=N-I-J
         IF I<=J AND J<=K THEN
            LET S=S+1
            PRINT S;": [";
            FOR II=1 TO N
               PRINT "●";
               IF II=I OR II=I+J THEN PRINT "] [";
            NEXT II
            PRINT "]"
         END IF
      NEXT J
   NEXT I
CASE 4
   FOR I=1 TO N
      FOR J=I TO N-I
         FOR K=J TO N-I-J
            LET L=N-I-J-K
            IF I<=J AND J<=K AND K<=L THEN
               LET S=S+1
               PRINT S;": [";
               FOR II=1 TO N
                  PRINT "●";
                  IF II=I OR II=I+J OR II=I+J+K THEN PRINT "] [";
               NEXT II
               PRINT "]"
            END IF
         NEXT K
      NEXT J
   NEXT I
CASE 5
   FOR I=1 TO N
      FOR J=I TO N-I
         FOR K=J TO N-I-J
            FOR L=K TO N-I-J-K
               LET M=N-I-J-K-L
               IF I<=J AND J<=K AND K<=L AND L<=M THEN
                  LET S=S+1
                  PRINT S;": [";
                  FOR II=1 TO N
                     PRINT "●";
                     IF II=I OR II=I+J OR II=I+J+K OR II=I+J+K+L THEN PRINT "] [";
                  NEXT II
                  PRINT "]"
               END IF
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE ELSE
   CALL RECURSIVE(1,R,N,A)
END SELECT
END

EXTERNAL SUB RECURSIVE(NN,N,M,A())
IF NN=N THEN
   LET SS=M
   FOR J=0 TO NN
      LET SS=SS-A(J)
   NEXT J
   IF SS=0 THEN
      IF A(NN-1)<=A(NN) THEN
         LET S=S+1
         PRINT S;": [";
         FOR II=1 TO N
            PRINT "●";
            LET SS=SS+A(II)
            IF II=SS THEN PRINT "] [";
         NEXT II
         PRINT "]"
      END IF
      EXIT SUB
   END IF
ELSE
   FOR I=1 TO M
      LET A(NN)=I
      IF NN=1 OR A(NN-1)<=A(NN) THEN
         CALL RECURSIVE(NN+1,N,M,A)
      END IF
   NEXT I
END IF
END SUB

EXTERNAL  FUNCTION P(N,M) !'分割数
IF M=1 OR N=M THEN
   LET P=1
ELSEIF N>=3 AND 2<=M AND M<=N-1 THEN
   LET P=P(N-M,M)+P(N-1,M-1)
ELSE
   LET P=0
END IF
END FUNCTION

N,R=5,3
2
1 : [●] [●] [●●●]
2 : [●] [●●] [●●]
 

N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月16日(土)19時18分48秒
  !'N個の同じ球をR個の同じ箱に分ける(空箱あり)
PUBLIC NUMERIC S
INPUT PROMPT "N,R=":N,R
DIM A(N)
FOR K=1 TO R
   LET SS=SS+P(N,K)
NEXT K
PRINT SS
SELECT CASE R
CASE 2
   FOR I=0 TO N
      LET J=N-I
      IF I<=J THEN
         LET S=S+1
         PRINT S;": [";
         FOR II=1 TO N
            PRINT "●";
            IF II=I THEN PRINT "] [";
         NEXT II
         PRINT "]"
      END IF
   NEXT I
CASE 3
   FOR I=0 TO N
      FOR J=I TO N-I
         LET K=N-I-J
         IF I<=J AND J<=K THEN
            LET S=S+1
            PRINT S;": [";
            FOR II=1 TO N
               PRINT "●";
               IF II=I OR II=I+J THEN PRINT "] [";
            NEXT II
            PRINT "]"
         END IF
      NEXT J
   NEXT I
CASE 4
   FOR I=0 TO N
      FOR J=I TO N-I
         FOR K=J TO N-I-J
            LET L=N-I-J-K
            IF I<=J AND J<=K AND K<=L THEN
               LET S=S+1
               PRINT S;": [";
               FOR II=1 TO N
                  PRINT "●";
                  IF II=I OR II=I+J OR II=I+J+K THEN PRINT "] [";
               NEXT II
               PRINT "]"
            END IF
         NEXT K
      NEXT J
   NEXT I
CASE 5
   FOR I=0 TO N
      FOR J=I TO N-I
         FOR K=J TO N-I-J
            FOR L=K TO N-I-J-K
               LET M=N-I-J-K-L
               IF I<=J AND J<=K AND K<=L AND L<=M THEN
                  LET S=S+1
                  PRINT S;": [";
                  FOR II=1 TO N
                     PRINT "●";
                     IF II=I OR II=I+J OR II=I+J+K OR II=I+J+K+L THEN PRINT "] [";
                  NEXT II
                  PRINT "]"
               END IF
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE ELSE
   CALL RECURSIVE(1,R,N,A)
END SELECT
END

EXTERNAL SUB RECURSIVE(NN,N,M,A())
IF NN=N THEN
   LET SS=M
   FOR J=0 TO NN
      LET SS=SS-A(J)
   NEXT J
   IF SS=0 THEN
      IF A(NN-1)<=A(NN) THEN
         LET S=S+1
         PRINT S;": [";
         FOR II=1 TO N
            PRINT "●";
            LET SS=SS+A(II)
            IF II=SS THEN PRINT "] [";
         NEXT II
         PRINT "]"
      END IF
      EXIT SUB
   END IF
ELSE
   FOR I=0 TO M
      LET A(NN)=I
      IF NN=1 OR A(NN-1)<=A(NN) THEN
         CALL RECURSIVE(NN+1,N,M,A)
      END IF
   NEXT I
END IF
END SUB

EXTERNAL  FUNCTION P(N,M) !'分割数
IF M=1 OR N=M THEN
   LET P=1
ELSEIF N>=3 AND 2<=M AND M<=N-1 THEN
   LET P=P(N-M,M)+P(N-1,M-1)
ELSE
   LET P=0
END IF
END FUNCTION

N,R=5,3
5
1 : [●●●●●]
2 : [●] [●●●●]
3 : [●●] [●●●]
4 : [●] [●] [●●●]
5 : [●] [●●] [●●]
 

Re: N個の球をR個の箱に分ける

 投稿者:山中和義  投稿日:2013年11月17日(日)10時01分8秒
  > No.3198[元記事へ]

しばっちさんへのお返事です。

> N個の同じ球をR個の異なる箱に分ける(空箱あり)
> N,R=5,3
>  10
>  1 : [●] [] [●●●●]
>  2 : [●] [●] [●●●]
>  3 : [●] [●●] [●●]
>  4 : [●] [●●●] [●]
>  5 : [●●] [] [●●●]
>  6 : [●●] [●] [●●]
>  7 : [●●] [●●] [●]
>  8 : [●●●] [] [●●]
>  9 : [●●●] [●] [●]
>  10 : [●●●●] [] [●]

1番目や3番目の箱が空になる場合はないのですか?

 

Re: N個の球をR個の箱に分ける

 投稿者:しばっち  投稿日:2013年11月17日(日)20時38分51秒
  > No.3201[元記事へ]

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

> しばっちさんへのお返事です。
>
> > N個の同じ球をR個の異なる箱に分ける(空箱あり)
> > N,R=5,3
> >  10
> >  1 : [●] [] [●●●●]
> >  2 : [●] [●] [●●●]
> >  3 : [●] [●●] [●●]
> >  4 : [●] [●●●] [●]
> >  5 : [●●] [] [●●●]
> >  6 : [●●] [●] [●●]
> >  7 : [●●] [●●] [●]
> >  8 : [●●●] [] [●●]
> >  9 : [●●●] [●] [●]
> >  10 : [●●●●] [] [●]
>
> 1番目や3番目の箱が空になる場合はないのですか?


ご指摘有難うございます。こちらの勘違いでした。
取り急ぎ作成しましたので、とりあえずはこれでよろしいでしょうか?

!'N個の同じ球をR個の異なる箱に分ける(空箱あり)
INPUT PROMPT "N,R=":N,R
PRINT COMB(N+R-1,R-1)
SELECT CASE R
CASE 2
   FOR I=0 TO N
      LET J=N-I
      LET S=S+1
      PRINT S;":[";
      FOR II=1 TO I
         PRINT "●";
      NEXT II
      PRINT "][";
      FOR II=1 TO J
         PRINT "●";
      NEXT II
      PRINT "]"
   NEXT I
CASE 3
   FOR I=0 TO N
      FOR J=0 TO N-I
         LET K=N-J-I
         LET S=S+1
         PRINT S;":[";
         FOR II=1 TO I
            PRINT "●";
         NEXT II
         PRINT "][";
         FOR II=1 TO J
            PRINT "●";
         NEXT II
         PRINT "][";
         FOR II=1 TO K
            PRINT "●";
         NEXT II
         PRINT "]"
      NEXT J
   NEXT I
CASE 4
   FOR I=0 TO N
      FOR J=0 TO N-I
         FOR K=0 TO N-I-J
            LET L=N-I-J-K
            LET S=S+1
            PRINT S;":[";
            FOR II=1 TO I
               PRINT "●";
            NEXT II
            PRINT "][";
            FOR II=1 TO J
               PRINT "●";
            NEXT II
            PRINT "][";
            FOR II=1 TO K
               PRINT "●";
            NEXT II
            PRINT "][";
            FOR II=1 TO L
               PRINT "●";
            NEXT II
            PRINT "]"
         NEXT K
      NEXT J
   NEXT I
CASE 5
   FOR I=0 TO N
      FOR J=0 TO N-I
         FOR K=0 TO N-I-J
            FOR L=0 TO N-I-J-K
               LET M=N-I-J-K-L
               LET S=S+1
               PRINT S;":[";
               FOR II=1 TO I
                  PRINT "●";
               NEXT II
               PRINT "][";
               FOR II=1 TO J
                  PRINT "●";
               NEXT II
               PRINT "][";
               FOR II=1 TO K
                  PRINT "●";
               NEXT II
               PRINT "][";
               FOR II=1 TO L
                  PRINT "●";
               NEXT II
               PRINT "][";
               FOR II=1 TO M
                  PRINT "●";
               NEXT II
               PRINT "]"
            NEXT L
         NEXT K
      NEXT J
   NEXT I
END SELECT
END

N,R=5,3
21
1 :[][][●●●●●]
2 :[][●][●●●●]
3 :[][●●][●●●]
4 :[][●●●][●●]
5 :[][●●●●][●]
6 :[][●●●●●][]
7 :[●][][●●●●]
8 :[●][●][●●●]
9 :[●][●●][●●]
10 :[●][●●●][●]
11 :[●][●●●●][]
12 :[●●][][●●●]
13 :[●●][●][●●]
14 :[●●][●●][●]
15 :[●●][●●●][]
16 :[●●●][][●●]
17 :[●●●][●][●]
18 :[●●●][●●][]
19 :[●●●●][][●]
20 :[●●●●][●][]
21 :[●●●●●][][]
 

n個の球をm個の箱に分ける方法

 投稿者:山中和義  投稿日:2013年11月20日(水)21時41分51秒
  問題:n個の球をm個の箱に分ける方法
http://members3.jcom.home.ne.jp/zakii/enumeration/10_balls_boxes.htm

(5) n<mなら0なので、n≧mのとき
同種類のn個の球と区別のつくm個の箱がある。
各箱に球を1個以上配る配り方は何通りあるか。
答え
n個の球を一列に並べて、(n-1)本の仕切り線を考える。
n=6の場合
   1   2   3   4   5 番目
 ○│○│○│○│○│○
(n-1)本の仕切り線から、(m-1)本を重複しないように選べばよい。comb(n-1,m-1)通り。
(終り)


PUBLIC NUMERIC N,M
LET N=5
LET M=3 !※M>1

DIM D(M-1) !仕切り線の位置

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(1,1,D)
PRINT C;"通り"

PRINT COMB(n-1,m-1);"通り"

END


EXTERNAL SUB try(P,S,D())
IF P=M THEN !R本目なら
   LET C=C+1

   !!!MAT PRINT D; !debug
   !PRINT D(1); !各箱の中の球の個数
   !FOR J=2 TO M-1
   !   PRINT D(J)-D(J-1);
   !NEXT J
   !PRINT N-D(M-1)

   PRINT STR$(C); ": "; !結果を表示する
   PRINT "["; !図示する
   FOR X=1 TO N
      PRINT "●";
      FOR J=1 TO M-1
         IF X=D(J) THEN PRINT "] ["; !1番目以降
      NEXT J
   NEXT X
   PRINT "]"
ELSE
   FOR i=S TO N-1 !p本目の仕切り線の位置 D(p)<D(p+1)
      LET D(P)=i
      CALL try(P+1,i+1,D)
   NEXT i
END IF
END SUB



(6)
同種類のn個の球と区別のつくm個の箱がある。
各箱に球を配る配り方(空箱があってよい)は何通りあるか。
答え
n個の球を一列に並べて、(n+1)本の仕切り線を考える。
n=6の場合
 0   1   2   3   4   5   6 番目
 │○│○│○│○│○│○│
(n+1)本の仕切り線から、(m-1)本を重複を許して選べばよい。H(n+1,m-1)通り。
(終り)


PUBLIC NUMERIC N,M
LET N=5
LET M=3 !※M>1

DIM D(M-1) !仕切り線の位置

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(1,0,D)
PRINT C;"通り"

PRINT COMB((N+1)+(M-1)-1,M-1);"通り" !H(N,R)=COMB(N+R-1,R)より

END


EXTERNAL SUB try(P,S,D())
IF P=M THEN !R本目なら
   LET C=C+1

   !!!MAT PRINT D; !debug
   !PRINT D(1); !各箱の中の球の個数
   !FOR J=2 TO M-1
   !   PRINT D(J)-D(J-1);
   !NEXT J
   !PRINT N-D(M-1)

   PRINT STR$(C); ": "; !結果を表示する
   PRINT "["; !図示する
   FOR J=1 TO M-1
      IF D(J)=0 THEN PRINT "] ["; !0番目の仕切り線
   NEXT J
   FOR X=1 TO N
      PRINT "●";
      FOR J=1 TO M-1
         IF X=D(J) THEN PRINT "] ["; !1番目以降
      NEXT J
   NEXT X
   PRINT "]"
ELSE
   FOR i=S TO N !p本目の仕切り線の位置 D(p)≦D(p+1)
      LET D(P)=i
      CALL try(P+1,i,D)
   NEXT i
END IF
END SUB



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

関係図 「k個の球を配る」による
 (5):1,n-m  ※初期値, 残り
 (6):0,n


!(5) n<mなら0なので、n≧mのとき
!同種類のn個の球と区別のつくm個の箱がある。
!各箱に球を1個以上配る配り方は何通りあるか。
!答え
!m個の箱に1個ずつ球を入れる。残り(n-m)個の球について、(6)を議論する。
!(終り)

PUBLIC NUMERIC N,M
LET N=5
LET M=3

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

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(1,N-M,B)
PRINT C;"通り"

PRINT COMB(N-1,M-1);"通り"

PRINT


!(6)
!同種類のn個の球と区別のつくm個の箱がある。
!各箱に球を配る配り方(空箱があってよい)は何通りあるか。
!答え
!1番目の箱にi=0~n個を入れられる。
!2番目の箱にJ=0~(n-i)個を入れられる。
!3番目の箱にK=0~(n-(i+J))個を入れられる。
! :
! :
!(終り)

MAT B=ZER
LET C=0
CALL try(1,N,B)
PRINT C;"通り"

PRINT COMB((N+1)+(M-1)-1,M-1);"通り" !H(N,R)=COMB(N+R-1,R)より

END


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

   LET C=C+1

   MAT PRINT B; !各箱の中の球の個数

   FOR J=1 TO M !図示する
      PRINT "[";
      FOR X=1 TO B(J)
         PRINT "●";
      NEXT X
      PRINT "]";
   NEXT J
   PRINT

   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,B)

      LET B(P)=B(P)-i !restore it
   NEXT i
END IF
END SUB



 

Re: n個の球をm個の箱に分ける方法

 投稿者:山中和義  投稿日:2013年11月21日(木)09時35分48秒
  > No.3203[元記事へ]

問題:n個の球をm個の箱に分ける方法
http://members3.jcom.home.ne.jp/zakii/enumeration/10_balls_boxes.htm

関係図 m進法n桁の数による
    0
  (2) → (1)
  f↓  ↓f
  (4) → (3)
    0
とする手法があるが、m^nが10^9程度になると、場合の数を数え上げるのが困難になる。

そこで、条件に合うm進法n桁の数を生成することを考える。

答え (3)
(7)の結果より、箱の中の球の個数は、[●] [●] [●●●] と [●] [●●] [●●] の2通り。

[●] [●] [●●●] の場合
 箱の番号 1,2,3,3,3 と考えると、
  5!/(1!1!3!)=20通り
 は、3進法5桁(各位の数は1,2,3とする)の並び方となる。例 12333, 13233,13323,…,33321
 1個の並び2!=2通りが重複する(例 ①②333と②①333)ので、20/2=10通り

[●] [●●] [●●] の場合
 1,2,2,3,3 と考えると、5!/(1!2!2!)=30通り
 2個の並び2!=2通りが重複するので、30/2=15通り

よって、10+15=25通りとなる。
(終り)


関係図 同じものを含む順列
 (5):1 → (1)
 (6):0 → (2)

 (7):1 → (3)
 (8):0 → (4)

以上を、プログラムに反映させる。


!(1) n<mなら0なので、n≧mのとき
!相異なるn個の球と区別のつくm個の箱がある。
!各箱に球を1個以上配る配り方は何通りあるか。

PUBLIC NUMERIC N,M
LET N=5
LET M=3

DIM A(N) !n個の球 値は、箱の番号
DIM B(M) !m個の箱 値は、球の個数

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(1,1,N,A,B)
PRINT C;"通り"

PRINT FACT(m)*StirlingS2(n,m);"通り" !検算

PRINT


!(2)
!相異なるn個の球と区別のつくm個の箱がある。
!各箱に球を配る配り方(空箱があってよい)は何通りあるか。

LET C=0
CALL try(1,0,N,A,B)
PRINT C;"通り"

PRINT M^N;"通り" !検算

END


EXTERNAL SUB try(P,S,T,A(),B())
IF P>M THEN !最後の箱まで配って、
   IF T=0 THEN !球を残らず配り終えたなら
      CALL stub(N,M,A,B)
   END IF
ELSE
   FOR i=S TO T !p番目の箱 B(1)≦B(2)≦B(3)≦…≦B(p)
      LET B(P)=i
      CALL try(P+1,S,T-i,A,B) !(5),(6)
   NEXT i
END IF
END SUB


EXTERNAL SUB stub(N,M,A(),B()) !同じ球● を 異なる球① へ
LET K=0 !最初のパターン
FOR J=1 TO M
   FOR X=1 TO B(J)
      LET A(K+X)=J
   NEXT X
   LET K=K+B(J)
NEXT J
MAT PRINT A; !debug

DO
   LET C=C+1

   PRINT STR$(C); ": "; !結果を表示する
   FOR J=1 TO M !j番目の箱
      PRINT "[";
      FOR K=1 TO N
         IF A(K)=J THEN PRINT K; !球の番号
      NEXT K
      PRINT "]";
   NEXT J
   PRINT

   CALL NextPermFactorial(A,N, rc) !次へ
LOOP UNTIL rc<>0
END SUB


EXTERNAL SUB NextPermFactorial(A(),N, rc) !辞書式順序で次の順列を返す ※「異なるn個のもの」と共通
LET i=N-1 !順列を右から左にみて、増加列から減少列に変わる位置iを探す
DO WHILE i>0 AND A(i)>=A(i+1) !0は番人
   LET i=i-1
LOOP
IF i=0 THEN !A(1)>A(2)>A(3)> … >A(N)なら 例. N=4、4,3,2,1
   LET rc=1 !完了(最後の並びである)
   EXIT SUB
END IF

LET j=N !その位置iより右で、A(i)以上で最小の数A(j)を探す
DO WHILE A(i)>=A(j)
   LET j=j-1
LOOP
LET t=A(i) !A(i)とA(j)を交換する
LET A(i)=A(j)
LET A(j)=t

LET i=i+1 !(i+1)からNまでの範囲を逆順にする
LET j=N
DO WHILE i<j
   LET t=A(i) !swap it
   LET A(i)=A(j)
   LET A(j)=t
   LET i=i+1
   LET j=j-1
LOOP
LET rc=0 !未了
END SUB


EXTERNAL FUNCTION StirlingS2(n,m) !第2種スターリング数 ※公式による
LET s=0
FOR k=0 TO m-1 !包除原理より
   LET s=s+(-1)^k*COMB(m,k)*(m-k)^n
NEXT k
LET StirlingS2=s/FACT(m)
END FUNCTION



上記をベースに考える。青色の字は修正、赤色の字は追加して、


!(3) n<mなら0なので、n≧mのとき
!相異なるn個の球と区別のつかないm個の箱がある。
!各箱に球を1個以上配る配り方は何通りあるか。

PUBLIC NUMERIC N,M
LET N=5
LET M=3

DIM A(N) !n個の球 値は、箱の番号
DIM B(M) !m個の箱 値は、球の個数

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(1,1,N,A,B)
PRINT C;"通り"

PRINT StirlingS2(n,m);"通り" !検算

PRINT


!(4)
!相異なるn個の球と区別のつかないm個の箱がある。
!各箱に球を配る配り方(空箱があってよい)は何通りあるか。

LET C=0
CALL try(1,0,N,A,B)
PRINT C;"通り"

LET S=0 !検算
FOR k=1 TO M
   LET S=S+StirlingS2(n,k)
NEXT k
PRINT S;"通り"

END


EXTERNAL SUB try(P,S,T,A(),B())
IF P>M THEN !最後の箱まで配って、
   IF T=0 THEN !球を残らず配り終えたなら
      CALL stub(N,M,A,B)
   END IF
ELSE
   FOR i=S TO T !p番目の箱 B(1)≦B(2)≦B(3)≦…≦B(p)
      LET B(P)=i
      CALL try(P+1,i,T-i,A,B) !(7),(8)
   NEXT i
END IF
END SUB


EXTERNAL SUB stub(N,M,A(),B()) !同じ球● を 異なる球① へ
LET K=0 !最初のパターン(m進法n桁)
FOR J=1 TO M
   FOR X=1 TO B(J)
      LET A(K+X)=J
   NEXT X
   LET K=K+B(J)
NEXT J
MAT PRINT A; !debug

DO
   CALL Filter(N,M,A,B, rc) !箱の中の球の並びで篩う
   IF rc<>0 THEN


      LET C=C+1

      PRINT STR$(C); ": "; !結果を表示する
      FOR J=1 TO M !j番目の箱
         PRINT "[";
         FOR K=1 TO N
            IF A(K)=J THEN PRINT K; !球の番号
         NEXT K
         PRINT "]";
      NEXT J
      PRINT

   END IF
   CALL NextPermFactorial(A,N, rc) !次へ
LOOP UNTIL rc<>0
END SUB


EXTERNAL SUB Filter(N,M,A(),B(), rc) !個数が同じ箱の並びが昇順になっているかどうあ確認する
DIM F(M) !m個の箱 値は、球の番号で最小のもの

LET rc=0 !NG

!中身(球の並び)について、
! [①][②][③4][⑤6] と [①][②][⑤6][③4] を同一とみなす必要がある。
FOR J=1 TO M !j番目の箱
   FOR K=1 TO N !球の番号で最小のもの
      IF A(K)=J THEN EXIT FOR
   NEXT K
   LET F(J)=K !空の場合は、N+1
NEXT J
!!!MAT PRINT F; !debug

FOR K=1 TO N !球の個数が同じものでは
   LET W=-1
   FOR J=1 TO M !j番目の箱
      IF B(J)=K THEN
         IF F(J)<W THEN EXIT FOR !球の番号が昇順のもの
         LET W=F(J)
      END IF
   NEXT J
   IF J<=M THEN EXIT FOR
NEXT K
IF K>N THEN LET rc=-1 !OK
END SUB



EXTERNAL SUB NextPermFactorial(A(),N, rc) !辞書式順序で次の順列を返す ※「異なるn個のもの」と共通
LET i=N-1 !順列を右から左にみて、増加列から減少列に変わる位置iを探す
DO WHILE i>0 AND A(i)>=A(i+1) !0は番人
   LET i=i-1
LOOP
IF i=0 THEN !A(1)>A(2)>A(3)> … >A(N)なら 例. N=4、4,3,2,1
   LET rc=1 !完了(最後の並びである)
   EXIT SUB
END IF

LET j=N !その位置iより右で、A(i)以上で最小の数A(j)を探す
DO WHILE A(i)>=A(j)
   LET j=j-1
LOOP
LET t=A(i) !A(i)とA(j)を交換する
LET A(i)=A(j)
LET A(j)=t

LET i=i+1 !(i+1)からNまでの範囲を逆順にする
LET j=N
DO WHILE i<j
   LET t=A(i) !swap it
   LET A(i)=A(j)
   LET A(j)=t
   LET i=i+1
   LET j=j-1
LOOP
LET rc=0 !未了
END SUB


EXTERNAL FUNCTION StirlingS2(n,m) !第2種スターリング数 ※公式による
LET s=0
FOR k=0 TO m-1 !包除原理より
   LET s=s+(-1)^k*COMB(m,k)*(m-k)^n
NEXT k
LET StirlingS2=s/FACT(m)
END FUNCTION


 

Re: プログラムの解釈

 投稿者:SECOND  投稿日:2013年11月22日(金)19時43分54秒
  > No.3191[元記事へ]

!途中のk番目、1回分だけのプログラムで、
! Permutation(n,r) 全体を処理する方法 6通りほど、まとめてみた

! 先の・・・で、変数名が、mPr と、n= 中間ポインター になっていたが、
!
!●● 通常の変数名、 nPr と、k= 中間ポインター に、全て変更した ●●

!順列 Permutation   nPr  P(n,r)
!---------------------
! 入力数列 a() の準備
!---------------------
LET n=3
LET r=2
DIM a(n)
!
FOR i=1 TO n
   LET a(i)=i
NEXT i

!----------------------------------------------------------
! 出力1行。速度を測るときは、MAT PRINT を削除( 先頭に"!")
!----------------------------------------------------------
SUB output1p
   MAT PRINT USING REPEAT$("## ",r)& " 配列の残り(無視)→"& REPEAT$("## ",n-r) :a
END SUB

!----------------------------------------
!(No_print, n=9,r=9 の所要時間)@P3_500MHz
!-------perm00  27.08 sec.
!-------perm50  25.15 sec.
!-------perm10  19.88 sec.
!-------perm40  15.82 sec.
!-------perm20  12.03 sec.
!-------perm30  9.83 sec.

!(No_print, n=8,r=8 の所要時間)@P3_500MHz
!-------perm00  3.02 sec.
!-------perm50  2.75 sec.
!-------perm10  2.2 sec.
!-------perm40  1.76 sec.
!-------perm20  1.37 sec.
!-------perm30  1.1 sec.

!------------------------------------------------------------
!各文の引数から、a() が消え、k のみになっているが、
!元々 a() は、local(局所変数)でないので、問題を簡単にするため
!------------------------------------------------------------
!
MAT PRINT USING REPEAT$("## ",n) :a    !入力数列 a()表示。
LET t0=TIME
CALL perm00(1)                         !( k の初期値=1)
PRINT "-------perm00 ";TIME-t0;"sec."
PRINT
!
MAT PRINT USING REPEAT$("## ",n) :a    !入力数列 a()表示。先プログラムでの a() 保存 検査
LET t0=TIME
CALL perm50(1)                         !( k の初期値=1)
PRINT "-------perm50 ";TIME-t0;"sec."
PRINT
!
MAT PRINT USING REPEAT$("## ",n) :a    !入力数列 a()表示。先プログラムでの a() 保存 検査
LET t0=TIME
CALL perm10(1)                         !( k の初期値=1)
PRINT "-------perm10 ";TIME-t0;"sec."
PRINT
!
MAT PRINT USING REPEAT$("## ",n) :a    !入力数列 a()表示。先プログラムでの a() 保存 検査
LET t0=TIME
CALL perm40(1)                         !( k の初期値=1)
PRINT "-------perm40 ";TIME-t0;"sec."
PRINT
!
MAT PRINT USING REPEAT$("## ",n) :a    !入力数列 a()表示。先プログラムでの a() 保存 検査
LET t0=TIME
CALL perm20(1)                         !( k の初期値=1)
PRINT "-------perm20 ";TIME-t0;"sec."
PRINT
!
MAT PRINT USING REPEAT$("## ",n) :a    !入力数列 a()表示。先プログラムでの a() 保存 検査
LET t0=TIME
CALL perm30(1)                         !( k の初期値=1)
PRINT "-------perm30 ";TIME-t0;"sec."
PRINT
!
MAT PRINT USING REPEAT$("## ",n) :a    !入力数列 a()表示。先プログラムでの a() 保存 検査

!----------------------------------------
!1回毎に、右左rotate 復元しながら、一巡。
!----------------------------------------
SUB perm00(k)
   local i
   IF r< k THEN
      CALL output1p
   ELSE
      FOR i=k TO n
      !  !--------                !rotate Right 1
         LET t=a(i)               !  ┌── ← ──┐
         FOR j=i-1 TO k STEP -1   ! a(k)・・→・・a(i)
            LET a(j+1)=a(j)
         NEXT j
         LET a(k)=t
         !--------
         CALL perm00(k+1)
         !--------                !rotate Left 1
         LET t=a(k)               !  ┌── → ──┐
         FOR j=k TO i-1           ! a(k)・・←・・a(i)
            LET a(j)=a(j+1)
         NEXT j
         LET a(i)=t
         !--------
      NEXT i
   END IF
END SUB

!------------------------------------------------------------------
! 毎回、右左rotate で復元せず、RETURN までに1巡復元すればよいので、
! rotate 1回( rotate の左右方向は、何れかに固定できればよい)
!------------------------------------------------------------------
SUB perm10(k)
   local i
   IF r< k THEN
      CALL output1p
   ELSE
      FOR i=k TO n
         CALL perm10(k+1)
         !--------                !rotate Left 1
         LET t=a(k)               !  ┌── → ──┐
         FOR j=k TO n-1           ! a(k)・・←・・a(n)
            LET a(j)=a(j+1)
         NEXT j
         LET a(n)=t
         !--------
      NEXT i
   END IF
END SUB

!------------------------------------------------------------------
! 一巡の要求は、先頭k位置だけで、k+1 ~n は、その残りであればよく、
! 先頭位置・巡回位置の、交換(swap)・復元(swap)を、順番に行なう方法。
! rotate のように全桁の移送をしないため、高速になる。
!------------------------------------------------------------------
SUB perm20(k)
   local i
   IF r< k THEN
      CALL output1p
   ELSE
      FOR i=k TO n
         swap a(k),a(i)
         CALL perm20(k+1)
         swap a(k),a(i)
      NEXT i
   END IF
END SUB

!-----------------------------------------------------------------------
! perm20 の高速化。最初の 交換(k,k)・復元(k,k) が無駄で k+1 からに。最速
!-----------------------------------------------------------------------
SUB perm30(k)
   local i
   IF r< k THEN
      CALL output1p
   ELSE
      CALL perm30(k+1)
      FOR i=k+1 TO n
         swap a(k),a(i)
         CALL perm30(k+1)
         swap a(k),a(i)
      NEXT i
   END IF
END SUB

!---------------------------------------------------------
! Perm30 の swap を1回で巡回させ、最後に rotate1回で補修
!---------------------------------------------------------
SUB perm40(k)
   local i
   IF r< k THEN
      CALL output1p
   ELSE
      CALL perm40(k+1)
      FOR i=k+1 TO n
         swap a(k),a(i)
         CALL perm40(k+1)
      NEXT i
      !--------                !rotate Left 1
      LET t=a(k)               !  ┌── → ──┐
      FOR j=k TO n-1           ! a(k)・・←・・a(n)
         LET a(j)=a(j+1)
      NEXT j
      LET a(n)=t
      !--------
   END IF
END SUB

!---------------------------------------------------------------------
! 保存無し 巡回だけなら、Perm40 の様に swap1回にして、別の b() で保存
!---------------------------------------------------------------------
SUB perm50(k)
   local i,b(10)       !b()の添字は、変数不可なので大きめ
   IF r< k THEN
      CALL output1p
   ELSE
      MAT b=a
      CALL perm50(k+1)
      FOR i=k+1 TO n
         swap a(k),a(i)
         CALL perm50(k+1)
      NEXT i
      MAT a=b
   END IF
END SUB

END
 

Re: n個の球をm個の箱に分ける方法

 投稿者:山中和義  投稿日:2013年11月23日(土)21時09分20秒
  > No.3203[元記事へ]

重複組合せ → 組合せ


!(6)
!同種類のn個の球と区別のつくm個の箱がある。
!各箱に球を配る配り方(空箱があってよい)は何通りあるか。
!答え
!順序組分配法 http://izumi-math.jp/F_Nakamura/repeat/repeat.htm
!(終り)

PUBLIC NUMERIC N,M
LET N=5
LET M=3

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

LET t=N !C(n+m-1,n)=C(n+m-1,m-1)
LET N=N+M-1
LET M=t

DIM A(N)
CALL comb(A,1,M)
PRINT C;"通り"

END

!SAMPLEフォルダ内 COMBINAT.BAS より

EXTERNAL SUB comb(a(),k,r) !1~nの集合からr個を選ぶ組合せを生成する
IF r=0 THEN
   LET C=C+1
   FOR i=1 TO N
      IF a(i)=1 THEN PRINT i;
   NEXT i
   PRINT " → ";
   LET k=0 !n個の球 値は、箱の番号
   FOR i=1 TO N
      IF a(i)=1 THEN
         PRINT i-k; !0,1,2,3,…,r-1が加味されているので
         LET k=k+1
      END IF
   NEXT i

   PRINT
ELSE
   FOR i=k TO N-r+1!k以降の数からr個を選択する
      LET a(i)=1 !2進法n桁とみなし、iビット目を1とする
      CALL comb(a,i+1,r-1)
      LET a(i)=0 !元に戻す
   NEXT i
END IF
END SUB


実行結果

1  2  3  4  5  →  1  1  1  1  1
1  2  3  4  6  →  1  1  1  1  2
1  2  3  4  7  →  1  1  1  1  3
1  2  3  5  6  →  1  1  1  2  2
1  2  3  5  7  →  1  1  1  2  3
1  2  3  6  7  →  1  1  1  3  3
1  2  4  5  6  →  1  1  2  2  2
1  2  4  5  7  →  1  1  2  2  3
1  2  4  6  7  →  1  1  2  3  3
1  2  5  6  7  →  1  1  3  3  3
1  3  4  5  6  →  1  2  2  2  2
1  3  4  5  7  →  1  2  2  2  3
1  3  4  6  7  →  1  2  2  3  3
1  3  5  6  7  →  1  2  3  3  3
1  4  5  6  7  →  1  3  3  3  3
2  3  4  5  6  →  2  2  2  2  2
2  3  4  5  7  →  2  2  2  2  3
2  3  4  6  7  →  2  2  2  3  3
2  3  5  6  7  →  2  2  3  3  3
2  4  5  6  7  →  2  3  3  3  3
3  4  5  6  7  →  3  3  3  3  3
21 通り


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


!(6)
!同種類のn個の球と区別のつくm個の箱がある。
!各箱に球を配る配り方(空箱があってよい)は何通りあるか。
!答え
!丸棒分配法 http://izumi-math.jp/F_Nakamura/repeat/repeat.htm
!(終り

PUBLIC NUMERIC N,M
LET N=5
LET M=3

DIM A(N+M-1) !n個の球と(m-1)個の仕切り線
FOR i=1 TO N !最初の並び(同じものを含む順列)
   LET A(i)=1
NEXT i
FOR i=N+1 TO N+M-1
   LET A(i)=2
NEXT i
MAT PRINT A;

LET C=0 !場合の数
DO
   LET C=C+1

   PRINT STR$(C); ": "; !結果を表示する
   PRINT "[";
   FOR K=1 TO N+M-1
      IF A(K)=1 THEN PRINT "●";
      IF A(K)=2 THEN PRINT "][";
   NEXT K
   PRINT "]";
   PRINT

   CALL NextPermFactorial(A,N+M-1, rc) !次へ
LOOP UNTIL rc<>0
PRINT C;"通り"

PRINT COMB(n+m-1,m-1);"通り"

END


EXTERNAL SUB NextPermFactorial(A(),N, rc) !辞書式順序で次の順列を返す ※「異なるn個のもの」と共通
LET i=N-1 !順列を右から左にみて、増加列から減少列に変わる位置iを探す
DO WHILE i>0 AND A(i)>=A(i+1) !0は番人
   LET i=i-1
LOOP
IF i=0 THEN !A(1)>A(2)>A(3)> … >A(N)なら 例. N=4、4,3,2,1
   LET rc=1 !完了(最後の並びである)
   EXIT SUB
END IF

LET j=N !その位置iより右で、A(i)以上で最小の数A(j)を探す
DO WHILE A(i)>=A(j)
   LET j=j-1
LOOP
LET t=A(i) !A(i)とA(j)を交換する
LET A(i)=A(j)
LET A(j)=t

LET i=i+1 !(i+1)からNまでの範囲を逆順にする
LET j=N
DO WHILE i<j
   LET t=A(i) !swap it
   LET A(i)=A(j)
   LET A(j)=t
   LET i=i+1
   LET j=j-1
LOOP
LET rc=0 !未了
END SUB


実行結果

1  1  1  1  1  2  2

1: [●●●●●][][]
2: [●●●●][●][]
3: [●●●●][][●]
4: [●●●][●●][]
5: [●●●][●][●]
6: [●●●][][●●]
7: [●●][●●●][]
8: [●●][●●][●]
9: [●●][●][●●]
10: [●●][][●●●]
11: [●][●●●●][]
12: [●][●●●][●]
13: [●][●●][●●]
14: [●][●][●●●]
15: [●][][●●●●]
16: [][●●●●●][]
17: [][●●●●][●]
18: [][●●●][●●]
19: [][●●][●●●]
20: [][●][●●●●]
21: [][][●●●●●]
21 通り
21 通り


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


!(5) n<mなら0なので、n≧mのとき
!同種類のn個の球と区別のつくm個の箱がある。
!各箱に球を1個以上配る配り方は何通りあるか。

PUBLIC NUMERIC N,M
LET N=5
LET M=3

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

PUBLIC NUMERIC C !場合の数
LET C=0
CALL try(1,N,B)
PRINT C;"通り"

PRINT COMB(n-1,m-1);"通り"

PRINT


!(6)
!同種類のn個の球と区別のつくm個の箱がある。
!各箱に球を配る配り方(空箱があってよい)は何通りあるか。
!答え
!仕切り分配法 http://izumi-math.jp/F_Nakamura/repeat/repeat.htm

! 関係図 「k個の球を配る」による
!  (6):n+m,m → (5)
!(終り)

LET C=0
CALL try(1,N+M,B)
PRINT C;"通り"

PRINT COMB(n+m-1,m-1);"通り"

END


EXTERNAL SUB try(P,T,B())
IF P>M THEN !最後の箱まで配って、
   IF T=0 THEN !球を残らず配り終えたなら
      LET C=C+1

      PRINT STR$(C); ": "; !結果を表示する
      FOR J=1 TO M !図示する
         PRINT "[○";
         FOR X=2 TO B(J)
            PRINT "●";
         NEXT X
         PRINT "]";
      NEXT J
      PRINT
   END IF
ELSE
   FOR i=1 TO T !p番目の箱
      LET B(P)=i
      CALL try(P+1,T-i,B)
   NEXT i
END IF
END SUB


実行結果

1: [○][○][○●●]
2: [○][○●][○●]
3: [○][○●●][○]
4: [○●][○][○●]
5: [○●][○●][○]
6: [○●●][○][○]
6 通り
6 通り

1: [○][○][○●●●●●]
2: [○][○●][○●●●●]
3: [○][○●●][○●●●]
4: [○][○●●●][○●●]
5: [○][○●●●●][○●]
6: [○][○●●●●●][○]
7: [○●][○][○●●●●]
8: [○●][○●][○●●●]
9: [○●][○●●][○●●]
10: [○●][○●●●][○●]
11: [○●][○●●●●][○]
12: [○●●][○][○●●●]
13: [○●●][○●][○●●]
14: [○●●][○●●][○●]
15: [○●●][○●●●][○]
16: [○●●●][○][○●●]
17: [○●●●][○●][○●]
18: [○●●●][○●●][○]
19: [○●●●●][○][○●]
20: [○●●●●][○●][○]
21: [○●●●●●][○][○]
21 通り
21 通り




 

N個の要素をR個の巡回列に分割する

 投稿者:しばっち  投稿日:2013年11月28日(木)20時06分53秒
  http://ja.wikipedia.org/wiki/スターリング数

!'N個の要素をR個の巡回列に分割する
DO
   INPUT PROMPT "N,R=":N,R
LOOP UNTIL N>=R AND N>2
PRINT S1(N,R) !'第1種スターリング数
PUBLIC STRING A$(10),B$(10,1000)
PUBLIC NUMERIC C(10),S
SELECT CASE N
CASE 3
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            LET C(I)=1
            LET C(J)=1
            LET C(K)=1
            LET FG=0
            FOR II=1 TO R
               IF C(II)=0 THEN LET FG=1
            NEXT II
            IF FG=0 THEN
               LET A$(I)=A$(I)&" 1"
               LET A$(J)=A$(J)&" 2"
               LET A$(K)=A$(K)&" 3"
               FOR II=1 TO S
                  LET FL=CHECK(R,A$,B$,II)
                  IF FL<>0 THEN EXIT FOR
                  LET FL=ROTATECHK(R,A$,B$,II)
                  IF FL<>0 THEN EXIT FOR
               NEXT  II
               IF FL=0 THEN
                  LET S=S+1
                  FOR II=1 TO R
                     LET B$(II,S)=A$(II)
                  NEXT II
                  PRINT S;":";
                  FOR II=1 TO R
                     PRINT "[";LTRIM$(A$(II));"]";
                  NEXT II
                  PRINT
               END IF
               MAT A$=NUL$

               LET A$(I)=A$(I)&" 1"
               LET A$(J)=A$(J)&" 3"
               LET A$(K)=A$(K)&" 2"
               FOR II=1 TO S
                  LET FL=CHECK(R,A$,B$,II)
                  IF FL<>0 THEN EXIT FOR
                  LET FL=ROTATECHK(R,A$,B$,II)
                  IF FL<>0 THEN EXIT FOR
               NEXT  II
               IF FL=0 THEN
                  LET S=S+1
                  FOR II=1 TO R
                     LET B$(II,S)=A$(II)
                  NEXT II
                  PRINT S;":";
                  FOR II=1 TO R
                     PRINT "[";LTRIM$(A$(II));"]";
                  NEXT II
                  PRINT
               END IF
               MAT A$=NUL$

            END IF
            LET C(I)=0
            LET C(J)=0
            LET C(K)=0
         NEXT K
      NEXT J
   NEXT I
CASE 4
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               LET C(I)=1
               LET C(J)=1
               LET C(K)=1
               LET C(L)=1
               LET FG=0
               FOR II=1 TO R
                  IF C(II)=0 THEN LET FG=1
               NEXT II
               IF FG=0 THEN
                  LET II=1
                  FOR JJ=2 TO N
                     FOR KK=2 TO N
                        FOR LL=2 TO N
                           IF II<>JJ AND II<>KK AND II<>LL AND JJ<>KK AND JJ<>LL AND KK<>LL THEN
                              LET A$(I)=A$(I)&" "&STR$(II)
                              LET A$(J)=A$(J)&" "&STR$(JJ)
                              LET A$(K)=A$(K)&" "&STR$(KK)
                              LET A$(L)=A$(L)&" "&STR$(LL)
                              FOR Q=1 TO S
                                 LET FL=CHECK(R,A$,B$,Q)
                                 IF FL<>0 THEN EXIT FOR
                                 LET FL=ROTATECHK(R,A$,B$,Q)
                                 IF FL<>0 THEN EXIT FOR
                              NEXT  Q
                              IF FL=0 THEN
                                 LET S=S+1
                                 FOR Q=1 TO R
                                    LET B$(Q,S)=A$(Q)
                                 NEXT  Q
                                 PRINT S;":";
                                 FOR Q=1 TO R
                                    PRINT "[";LTRIM$(A$(Q));"]";
                                 NEXT  Q
                                 PRINT
                              END IF
                              MAT A$=NUL$
                           END IF
                        NEXT LL
                     NEXT KK
                  NEXT JJ
               END IF
               LET C(I)=0
               LET C(J)=0
               LET C(K)=0
               LET C(L)=0
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE 5
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               FOR M=1 TO R
                  LET C(I)=1
                  LET C(J)=1
                  LET C(K)=1
                  LET C(L)=1
                  LET C(M)=1
                  LET FG=0
                  FOR II=1 TO R
                     IF C(II)=0 THEN LET FG=1
                  NEXT II
                  IF FG=0 THEN
                     LET II=1
                     FOR JJ=2 TO N
                        FOR KK=2 TO N
                           FOR LL=2 TO N
                              FOR MM=2 TO N
                                 IF II<>JJ AND II<>KK AND II<>LL AND II<>MM AND JJ<>KK AND JJ<>LL AND JJ<>MM AND KK<>LL AND KK<>MM AND LL<>MM THEN
                                    LET A$(I)=A$(I)&" "&STR$(II)
                                    LET A$(J)=A$(J)&" "&STR$(JJ)
                                    LET A$(K)=A$(K)&" "&STR$(KK)
                                    LET A$(L)=A$(L)&" "&STR$(LL)
                                    LET A$(M)=A$(M)&" "&STR$(MM)
                                    FOR Q=1 TO S
                                       LET FL=CHECK(R,A$,B$,Q)
                                       IF FL<>0 THEN EXIT FOR
                                       LET FL=ROTATECHK(R,A$,B$,Q)
                                       IF FL<>0 THEN EXIT FOR
                                    NEXT  Q
                                    IF FL=0 THEN
                                       LET S=S+1
                                       FOR Q=1 TO R
                                          LET B$(Q,S)=A$(Q)
                                       NEXT  Q
                                       PRINT S;":";
                                       FOR Q=1 TO R
                                          PRINT "[";LTRIM$(A$(Q));"]";
                                       NEXT  Q
                                       PRINT
                                    END IF
                                    MAT A$=NUL$
                                 END IF
                              NEXT MM
                           NEXT LL
                        NEXT KK
                     NEXT JJ
                  END IF
                  LET C(I)=0
                  LET C(J)=0
                  LET C(K)=0
                  LET C(L)=0
                  LET C(M)=0
               NEXT M
            NEXT L
         NEXT K
      NEXT J
   NEXT I
CASE 6
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            FOR L=1 TO R
               FOR M=1 TO R
                  FOR O=1 TO R
                     LET C(I)=1
                     LET C(J)=1
                     LET C(K)=1
                     LET C(L)=1
                     LET C(M)=1
                     LET C(O)=1
                     LET FG=0
                     FOR II=1 TO R
                        IF C(II)=0 THEN LET FG=1
                     NEXT II
                     IF FG=0 THEN
                        LET II=1
                        FOR JJ=2 TO N
                           FOR KK=2 TO N
                              FOR LL=2 TO N
                                 FOR MM=2 TO N
                                    FOR NN=2 TO N
                                       IF II<>JJ AND II<>KK AND II<>LL AND II<>MM AND II<>NN AND JJ<>KK AND JJ<>LL AND JJ<>MM AND JJ<>NN AND KK<>LL AND KK<>MM AND KK<>NN AND LL<>MM AND LL<>NN AND MM<>NN THEN
                                          LET A$(I)=A$(I)&" "&STR$(II)
                                          LET A$(J)=A$(J)&" "&STR$(JJ)
                                          LET A$(K)=A$(K)&" "&STR$(KK)
                                          LET A$(L)=A$(L)&" "&STR$(LL)
                                          LET A$(M)=A$(M)&" "&STR$(MM)
                                          LET A$(O)=A$(O)&" "&STR$(NN)
                                          FOR Q=1 TO S
                                             LET FL=CHECK(R,A$,B$,Q)
                                             IF FL<>0 THEN EXIT FOR
                                             LET FL=ROTATECHK(R,A$,B$,Q)
                                             IF FL<>0 THEN EXIT FOR
                                          NEXT  Q
                                          IF FL=0 THEN
                                             LET S=S+1
                                             FOR Q=1 TO R
                                                LET B$(Q,S)=A$(Q)
                                             NEXT  Q
                                             PRINT S;":";
                                             FOR Q=1 TO R
                                                PRINT "[";LTRIM$(A$(Q));"]";
                                             NEXT  Q
                                             PRINT
                                          END IF
                                          MAT A$=NUL$
                                       END IF
                                    NEXT NN
                                 NEXT MM
                              NEXT LL
                           NEXT KK
                        NEXT JJ
                     END IF
                     LET C(I)=0
                     LET C(J)=0
                     LET C(K)=0
                     LET C(L)=0
                     LET C(M)=0
                     LET C(O)=0
                  NEXT O
               NEXT M
            NEXT L
         NEXT K
      NEXT J
   NEXT I
END SELECT
END

EXTERNAL FUNCTION S1(N,K) !'第1種スターリング数
IF K<1 OR K>N THEN
   LET S1=0
   EXIT FUNCTION
END IF
IF K=N THEN
   LET S1=1
   EXIT FUNCTION
END IF
LET S1=(N-1)*S1(N-1,K)+S1(N-1,K-1)
END FUNCTION

EXTERNAL  FUNCTION CHECK(R,A$(),B$(,),II)
SELECT CASE R
CASE 1
   FOR I=1 TO R
      IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) THEN
         LET CHECK=1
         EXIT FUNCTION
      END IF
   NEXT I
CASE 2
   FOR I=1 TO R
      FOR J=1 TO R
         IF I<>J THEN
            IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) THEN
               LET CHECK=1
               EXIT FUNCTION
            END IF
         END IF
      NEXT J
   NEXT I
CASE 3
   FOR I=1 TO R
      FOR J=1 TO R
         FOR K=1 TO R
            IF I<>J AND J<>K AND I<>K THEN
               IF LTRIM$(A$(I))=LTRIM$(B$(1,II)) AND LTRIM$(A$(J))=LTRIM$(B$(2,II)) AND LTRIM$(A$(K))=LTRIM$(B$(3,II)) THEN
                  LET CHECK=1
                  EXIT FUNCTION
               END IF
            END IF
         NEXT K
      NEXT J
   NEXT I
CASE ELSE
   DIM B(R)
   FOR I=1 TO R
      LET B(I)=I
   NEXT I
   CALL PERM(B,1)
END SELECT

SUB PERM(B(),N)
   LOCAL I,J
   LET M=UBOUND(B)
   IF N=M THEN
      LET FL=0
      FOR K=1 TO M
         IF LTRIM$(A$(B(K)))=LTRIM$(B$(K,II)) THEN LET FL=FL+1
      NEXT K
      IF FL=M THEN
         LET CHECK=1
         EXIT FUNCTION
      END IF
   ELSE
      FOR I=N TO M
         LET T=B(I)
         FOR J=I-1 TO N STEP-1
            LET B(J+1)=B(J)
         NEXT J
         LET B(N)=T
         CALL PERM(B,N+1)
         LET T=B(N)
         FOR J=N TO I-1
            LET B(J)=B(J+1)
         NEXT J
         LET B(I)=T
      NEXT I
   END IF
END SUB
END FUNCTION

EXTERNAL  FUNCTION ROTATECHK(R,A$(),B$(,),II) !'巡回列かどうか
FOR I=1 TO R
   FOR J=1 TO R
      LET AA$=LTRIM$(A$(I))
      LET BB$=LTRIM$(B$(J,II))
      IF LEN(AA$)=LEN(BB$) THEN
         FOR N=3 TO LEN(AA$) STEP 2
            LET C$=""
            LET K=N
            FOR L=1 TO (LEN(AA$)+1)/2
               LET C$=C$&AA$(K:K)&" "
               IF K>=LEN(AA$) THEN LET K=1 ELSE LET K=K+2
            NEXT L
            IF BB$=RTRIM$(C$) THEN
               LET ROTATECHK=1
               EXIT FUNCTION
            END IF
         NEXT N
      END IF
   NEXT J
NEXT I
LET ROTATECHK=0
END FUNCTION

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

スターリング数

 投稿者:山中和義  投稿日:2013年12月 1日(日)10時20分19秒
  n文字の置換のうち、m個の巡回置換の積(積の順序は問わない)で表される全体の個数
例 n=5,m=3の場合
(1 2)(3 4)(5)、(1)(2)(3 4 5)など
答え
n文字の置換は、n!通り。
その中から、m個の巡回置換を探す。

便宜上
 [1 2 3 4 5] =(1)(2)(3 4 5)
 [1 2 4 5 3]
を
 [1 2 4 5 3] =(1)(2)(3 4 5)
と表す。
(終り)


PUBLIC NUMERIC n,m
LET n=5
LET m=3

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

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

PUBLIC NUMERIC s1(100) !n段目 s1(n,k)
MAT s1=ZER(n)
CALL perm(a,1)
MAT PRINT s1;
END

EXTERNAL SUB perm(a(),k) !辞書順序でn-順列(n!通り)を生成する
IF k=n THEN !すべて並んだなら
   PRINT "["; !置換を表示する
   FOR i=1 TO n
      PRINT a(i);
   NEXT i
   PRINT "] = ";

   LET p=0 !巡回置換の個数
   DIM f(n) !篩い
   MAT f=ZER
   FOR i=1 TO n !n文字
      IF f(i)=0 THEN !現れていないなら
         LET p=p+1
         PRINT "("; !巡回置換を表示する
         LET t=i
         DO
            PRINT t;
            LET f(t)=1
            LET t=a(t) !次へ
         LOOP UNTIL t=i !巡回するまで
         PRINT ")";
      END IF
   NEXT i
   IF p=m THEN !m個なら
      LET c=c+1
      PRINT " ←";c
   ELSE
      PRINT
   END IF

   LET s1(p)=s1(p)+1 !n!=Σs1(n,p)
ELSE
   FOR i=k TO n
      LET t=a(i)
      FOR j=i-1 TO k STEP -1
         LET a(j+1)=a(j)
      NEXT j
      LET a(k)=t

      CALL perm(a,k+1)

      LET t=a(k)
      FOR j=k TO i-1
         LET a(j)=a(j+1)
      NEXT j
      LET a(i)=t
   NEXT i
END IF
END SUB


実行結果

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


 

五角形

 投稿者:永野護  投稿日:2013年12月 6日(金)13時13分21秒
  質問です。任意の五角形があるとします。各辺の和が面積と等しい場合があるでしょうか。
もしあるならプログラムを作って求めることができるでしょうか。
よろしくお願いします。
 

Re: 五角形

 投稿者:山中和義  投稿日:2013年12月 6日(金)20時03分52秒
  > No.3209[元記事へ]

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

> 質問です。任意の五角形があるとします。各辺の和が面積と等しい場合があるでしょうか。
> もしあるならプログラムを作って求めることができるでしょうか。

1辺の長さがaの正n角形を考える。
周囲の長さL=na、面積S=na^2/(4tan(π/n))である。
これより、5a=5a^2/(4tan(π/5)) ∴a(a-4tan(π/5))=0 ∴a=4tan(π/5)
二重根号で表すと、a=20/√(25+10√5)

任意の場合は、分かりません。
 

Re: 五角形

 投稿者:しばっち  投稿日:2013年12月 6日(金)21時09分37秒
  > No.3209[元記事へ]

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

> 質問です。任意の五角形があるとします。各辺の和が面積と等しい場合があるでしょうか。
> もしあるならプログラムを作って求めることができるでしょうか。
> よろしくお願いします。

!'これは正多角形の場合です
DIM X(20),Y(20)
OPTION ANGLE DEGREES
FOR N=4 TO 20
   LET RMIN=0
   LET RMAX=100000
   DO
      LET R=(RMIN+RMAX)/2
      FOR I=1 TO N
         LET X(I)=R*COS((I-1)*360/N)
         LET Y(I)=R*SIN((I-1)*360/N)
      NEXT I
      LET RR=SQR((X(2)-X(1))^2+(Y(2)-Y(1))^2)*N !'1辺の長さ*n
      LET S=AREA(N,X,Y) !'面積
      IF S<RR THEN LET RMIN=R ELSE LET RMAX=R
   LOOP UNTIL ABS(RR-S)<1E-6
   PRINT N;"角形"
   PRINT "半径=";R
   FOR I=1 TO N
      PRINT "座標 X=";X(I);"Y=";Y(I)
   NEXT I
   PRINT "面積";S
NEXT N
END

EXTERNAL FUNCTION AREA(N,X(),Y())
LET A=X(N-1)*Y(1)-X(1)*Y(N-1)
FOR I=2 TO N-1
   LET A=A+X(I-1)*Y(I)-X(I)*Y(I-1)
NEXT I
LET AREA=ABS(A)/2
END FUNCTION
 

Re: 五角形

 投稿者:山中和義  投稿日:2013年12月 6日(金)22時13分50秒
  > No.3211[元記事へ]

しばっちさんへのお返事です。

> EXTERNAL FUNCTION AREA(N,X(),Y())
> LET A=X(N-1)*Y(1)-X(1)*Y(N-1)
> FOR I=2 TO N-1
>    LET A=A+X(I-1)*Y(I)-X(I)*Y(I-1)
> NEXT I
> LET AREA=ABS(A)/2
> END FUNCTION

頂点番号は1~Nなので、N番目の頂点が加味されていないようです。

EXTERNAL FUNCTION AREA(N,X(),Y())
LET A=X(N)*Y(1)-X(1)*Y(N)
FOR I=2 TO N
   LET A=A+X(I-1)*Y(I)-X(I)*Y(I-1)
NEXT I
LET AREA=ABS(A)/2
END FUNCTION

 

五角形

 投稿者:永野護  投稿日:2013年12月 7日(土)12時29分17秒
  山中様、しばっち様、丁寧な回答ありがとうございました。
敬具
 

辺の長さが、1,2,3,4,5,6の適当な並べ替え の等角6角形

 投稿者:山中和義  投稿日:2013年12月 9日(月)10時25分39秒
  問題
次の条件をみたす六角形が存在することを示せ。
(1) すべての内角の大きさが120度である。
(2) 辺の長さが、1,2,3,4,5,6の適当な並べ替えである。

考察
多角形なので、辺の並びはじゅず順列で考える。
n-順列から、円順列生成して、裏返しを篩ってじゅず順列とする。

必要条件
z=EXP(2πi/n)=cos(2π/n)+i*sin(2π/n)、iは虚数単位 とする。
これより、z^2-{2cos(2π/n)}z+1=0 ←式1
辺の並びa[1],a[2],a[3],…,a[n]に対して、
多項式 a[1]+a[2]z+a[3]z^2+ … +a[n]z^(n-1) が 式1 で割り切れる。
(終り)


一般的な形で述べると、
nが(s+1)個の相異なる素数(またはどの2つも互いに素な自然数)の積に分解するとき、
辺の長さが1^s, 2^s, …, n^sの並べ替えであるような等角n角形(内角が等しい)が存在する。

n=6=2*3、10=2*5、12=3*4、14=2*7、15=3*5、…

n=14以上は困難である。



OPTION ARITHMETIC COMPLEX !複素平面

PUBLIC NUMERIC n
LET n=6

DIM a(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,2) !円順列、じゅず順列
PRINT C;"通り"

END

EXTERNAL SUB perm(a(),k) !辞書順序でn-順列(n!通り)を生成する
OPTION ARITHMETIC COMPLEX !複素平面
IF k=n THEN !すべて並んだなら
   IF a(2)<a(n) THEN !じゅず順列
      CALL stub(a)
   END IF
ELSE
   FOR i=k TO n
      LET t=a(i) !k≦iとして、kからiまでの範囲を右ローテイト
      FOR j=i-1 TO k STEP -1
         LET a(j+1)=a(j)
      NEXT j
      LET a(k)=t

      CALL perm(a,k+1) !次へ

      LET t=a(k) !k≦iとして、kからiまでの範囲を左ローテイトで元に戻す
      FOR j=k TO i-1
         LET a(j)=a(j+1)
      NEXT j
      LET a(i)=t
   NEXT i
END IF
END SUB

EXTERNAL SUB stub(a())
OPTION ARITHMETIC COMPLEX !複素平面
!z=EXP(2πi/n)として、A[1]+A[2]z+A[3]z^2+A[4]z^3+ … +A[n]z^(n-1)=0かどうか確認する
LET z=EXP(2*PI*COMPLEX(0,1)/n)
DIM P(0 TO n) !多角形の頂点位置を算出する
LET P(0)=0
FOR i=1 TO n
   LET P(i)=P(i-1)+a(i)*z^(i-1)
NEXT i
IF ABS(P(n))<1E-12 THEN !題意を満たすなら

   LET C=C+1
   MAT PRINT a;

   SET WINDOW -5,6,-2,9 !n=6
   !SET WINDOW -13,11,-1,23 !n=10
   CLEAR
   DRAW grid

   MAT PLOT LINES: P !多角形を描く

   WAIT DELAY 2

END IF
END SUB


実行結果

1  4  5  2  3  6

1  5  3  4  2  6

2 通り



 

1~9の数字をいくつか足して、和が9の倍数

 投稿者:山中和義  投稿日:2013年12月10日(火)11時10分27秒
  問題
1~9の数字をいくつか足して、和が9の倍数となるような場合の数を求めたい。
ただし、足す順番は無視するものとする。
(1) 1~9の数字を最大1回だけ使えるときは何通りあるか。

答え
●「払える金額の問題」として数え上げる

その1 組合せ

LET S=0
FOR C1=0 TO 1 !数字1を0,1個
   FOR C2=0 TO 1
      FOR C3=0 TO 1
         FOR C4=0 TO 1
            FOR C5=0 TO 1
               FOR C6=0 TO 1
                  FOR C7=0 TO 1
                     FOR C8=0 TO 1
                        FOR C9=0 TO 1
                           IF MOD(C1*1+C2*2+C3*3+C4*4+C5*5+C6*6+C7*7+C8*8+C9*9,9)=0 THEN LET S=S+1
                        NEXT C9
                     NEXT C8
                  NEXT C7
               NEXT C6
            NEXT C5
         NEXT C4
      NEXT C3
   NEXT C2
NEXT C1
PRINT S; "通り"
END


その2 動的計画法

DATA 9 !種類
DATA 1,2,3,4,5,6,7,8,9 !硬貨
DATA 1,1,1,1,1,1,1,1,1 !枚数

READ N
DIM A(N),B(N)
MAT READ A
MAT READ B

LET T=0
FOR K=1 TO N
   LET T=T+A(K)*B(K)
NEXT K
PRINT "総額="; T; "円"

DIM F(0 TO T)
MAT F=ZER
LET F(0)=1 !0円
FOR K=1 TO N
   FOR i=T TO 0 STEP -1 !今までに支払える金額に対して
      LET Fi=F(i)
      IF Fi>0 THEN
         LET W=i
         FOR C=1 TO B(K) !新しい硬貨を追加する
            LET W=W+A(K)
            LET F(W)=F(W)+Fi
         NEXT C
      END IF
   NEXT i
NEXT K
MAT PRINT F;

LET S=0
FOR i=0 TO T
   IF MOD(i,9)=0 THEN LET S=S+F(i)
NEXT i
PRINT S; "通り"

END



●m進法n桁に対応させて数え上げる
個数がすべて同じなので、「m^n通り」に対応させられる。


LET S=0
FOR i=0 TO 2^9-1 !場合の数の候補
   LET T=i
   LET W=0
   FOR X=1 TO 9 !2進法9桁
      LET W=W+MOD(T,2)*X
      LET T=INT(T/2)
   NEXT X
   IF MOD(W,9)=0 THEN LET S=S+1
NEXT i
PRINT S; "通り"
END



●対称性を利用して数え上げる
1+2+3+4+5+6+7+8=36より、数字9の有無で2つに分けられ、それぞれの場合の数は同じである。
よって、1から8までの数字で考える。
・数字を0個使う場合
 0
 1通り

・数字を1個使う場合
 0通り

・数字を2個使う場合
 最小値1+2=3>0、最大値7+8=15<18なので、倍数は9
 1+8、2+7、3+6、4+5
 4通り

・数字を3個使う場合
 最小値1+2+3=6>0、最大値6+7+8=21<27なので、倍数は9,18
 1+2+6、1+3+5、2+3+4
 3+7+8、4+6+8、5+6+7
 6通り

・数字を4個使う場合
 最小値1+2+3+4=10>9、最大値5+6+7+8=26<27なので、倍数は18
 1+2+7+8、1+3+6+8、1+4+5+8、1+4+6+7、
 2+3+5+8、2+3+6+7、2+4+5+7、3+4+5+6
 8通り

8個の数字からk個選んで9の倍数をつくれる個数をN(k)とすると、N(k)=N(8-k)から、
5,6,7,8個は、6,4,0,1個となる。
これより、1+0+4+6+8+6+4+0+1=30通り

したがって、2*30=60通り


LET n=8 !1から8までの数字
DIM a(n)
MAT a=ZER
PUBLIC NUMERIC S
FOR r=0 TO n !r個を選ぶ
   LET S=0
   CALL comb(a,1,r)
   PRINT S; "通り"
NEXT r
END
EXTERNAL SUB comb(a(),k,r) !1~nの集合からr個を選ぶ組合せを生成する
IF r=0 THEN
   LET w=0
   FOR i=1 TO UBOUND(a)
      LET w=w+a(i)*i
   NEXT i
   IF MOD(w,9)=0 THEN LET S=S+1
ELSE
   FOR i=k TO UBOUND(a)-r+1 !k以降の数からr個を選択する
      LET a(i)=1
      CALL comb(a,i+1,r-1)
      LET a(i)=0
   NEXT i
END IF
END SUB


 

Re: 1~9の数字をいくつか足して、和が9の倍数

 投稿者:山中和義  投稿日:2013年12月10日(火)13時17分1秒
  > No.3215[元記事へ]

問題
1~9の数字をいくつか足して、和が9の倍数となるような場合の数を求めたい。
ただし、足す順番は無視するものとする。
(2) 1~9の数字を最大2回だけ使えるときは何通りあるか。

答え
3進法に着目して、
       1=1
     1+1=2
   3    =3
   3  +1=4
   3+1+1=5
 3+3    =6
 3+3  +1=7
 3+3+1+1=8
と、1~8までの数字が1と3のみで表される。

問題の条件を満たす場合は、2,4,5,6,7,8,9をそれぞれ0個~2個足した式に、
上の8つの式の何れかを加えて(加えられる式がもともと9の倍数の場合は加えないものとする)、
9の倍数にしたものと考えられる。
これは3^7=2187通りとなる。




> 問題
> 1~9の数字をいくつか足して、和が9の倍数となるような場合の数を求めたい。
> ただし、足す順番は無視するものとする。
> (1) 1~9の数字を最大1回だけ使えるときは何通りあるか。

●2進法に着目して数え上げる
1+2+3+4+5+6+7+8=36より、数字9の有無で2つに分けられ、それぞれの場合の数は同じである。
よって、1から8までの数字で考える。
2進法に着目して、
     1=1
   2  =2
   2+1=3
 4    =4
 4  +1=5
 4+2  =6
 4+2+1=7
と、1~7までの数字が1と2と4のみで表される。

問題の条件を満たす場合は、3,5,6,7,8をそれぞれ0個~1個足した式に、
上の7つの式の何れかを加えて(加えられる式がもともと9の倍数の場合は加えないものとする)、
9の倍数にしたものと考えられる。
これは2^5通りとなるが、その中で、
 19=5+6+8≡1 mod 9は、8を使っているので、8を足すことができないので除く。
 10=3+7≡1 mod 9は、8を足すと3+7+8と重複するので除く。
以上から、2^5-2=30通り
したがって、2*30=60通りとなる。

(補足)
最小値0、最大値3+5+6+7+8=29<36なので、倍数は0,9,18,27
9で割って余りが1になるのは、1,10,19,28であるが、1,28はつくれない。
10=3+7,19=5+6+8のみである。

0 ≡ 0
8 = 8 ≡ 8
7 = 7 ≡ 7
7+8 = 15 ≡ 6
6 = 6 ≡ 6
6+8 = 14 ≡ 5
6+7 = 13 ≡ 4
6+7+8 = 21 ≡ 3
5 = 5 ≡ 5
5+8 = 13 ≡ 4
5+7 = 12 ≡ 3
5+7+8 = 20 ≡ 2
5+6 = 11 ≡ 2
5+6+8 = 19 ≡ 1
5+6+7 = 18 ≡ 0
5+6+7+8 = 26 ≡ 8
3 = 3 ≡ 3
3+8 = 11 ≡ 2
3+7 = 10 ≡ 1
3+7+8 = 18 ≡ 0
3+6 = 9 ≡ 0
3+6+8 = 17 ≡ 8
3+6+7 = 16 ≡ 7
3+6+7+8 = 24 ≡ 6
3+5 = 8 ≡ 8
3+5+8 = 16 ≡ 7
3+5+7 = 15 ≡ 6
3+5+7+8 = 23 ≡ 5
3+5+6 = 14 ≡ 5
3+5+6+8 = 22 ≡ 4
3+5+6+7 = 21 ≡ 3
3+5+6+7+8 = 29 ≡ 2

(終り)

 

副プログラムの驚き

 投稿者:nagram  投稿日:2013年12月12日(木)22時02分56秒
  十進BASICでは、副プログラムの実引数に変数を指定すると参照渡しとなり、副プログラム内で仮引数の値が変わると実引数の値も変わります。次のプログラムの出力結果を予想してみて下さい。6でしょうか、4でしょうか。

10 LET a=3
20 CALL example(a,a)
30 PRINT a
40 SUB example(p,q)
50    LET p=p+q
60    LET q=q+1
70 END SUB
80 END

どうでしょうか、この結果を予想できましたか? 50行で、p+qの計算結果が変数qにも代入されているのです。「副プログラムを呼び出すとき複数の実引数に同じ変数を指定すると、それに対応する仮引数は同一の変数としてふるまう」ということです。ヘルプの「変数引数」の項目を読むと「副プログラムの実引数に変数を書いたとき,仮引数は実引数と同じ記憶場所を指す」とあるので納得しますが、直感的には戸惑う結果です。
 

Re: 副プログラムの驚き

 投稿者:山中和義  投稿日:2013年12月13日(金)16時44分43秒
  > No.3217[元記事へ]

nagramさんへのお返事です。

> 仮引数と実引数

10 LET a=3
20 CALL example(a,a)

この20行目を実行することは、
SUB~END SUBの変数p,qをそれぞれ文字a,aに置き換えることに相当します。
すなわち、
40 SUB example(a,a)
50    LET a=a+a !2a→a
60    LET a=a+1 !2a+1→a
70 END SUB

よって、結果は2a+1=2*3+1=7になります。

 

線が歪んでる?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時49分4秒
  http://www.ritsumei.ac.jp/~akitaoka/
http://www.huffingtonpost.jp/2013/08/21/10_optical_illusions_that_will_blow_your_mind_n_3766354.html
http://matome.naver.jp/odai/2134114701850624001
http://www.kecl.ntt.co.jp/IllusionForum/index.html?sl=jastrow

CALL GINIT(600,600)
LET S=1
LET ST=40
FOR Y=0 TO 600 STEP ST
   LET C=7
   FOR X=XX TO 600 STEP ST
      CALL BOXFULL(X,Y,X+ST,Y+ST,C)
      LET C=7-C
   NEXT X
   LET XX=XX+20*S
   IF XX=40 OR XX=0 THEN LET S=-S
NEXT Y
SET LINE WIDTH 3
FOR Y=0 TO 600 STEP ST
   CALL LINE(0,Y,600,Y,1)
NEXT Y
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) .5,.5,.5
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

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 BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA:X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB
 

歪んでる?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時49分50秒
  CALL GINIT(550,550)
CALL TILE(0,0,550,550,7,0,50)
LET A=2
FOR Y=50 TO 500 STEP 50
   IF Y=300 THEN LET A=3-A
   FOR X=50 TO 500 STEP 50
      CALL DIA(X,Y,14,14,A)
      LET A=3-A
      IF X=250 THEN LET A=3-A
   NEXT X
NEXT Y
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) 1,1,1
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) 0,0,0
CLEAR
END SUB

EXTERNAL SUB PSET(X,Y,C)
SET POINT COLOR C
PLOT POINTS:X,Y
END SUB

EXTERNAL  SUB TILE(XS,YS,XE,YE,C1,C2,SIZE)
FOR Y=YS TO YE
   FOR X=XS TO XE
      LET I=INT(X/SIZE)
      LET J=INT(Y/SIZE)
      IF MOD(I+J,2)=0 THEN LET C=C1 ELSE LET C=C2
      CALL PSET(X,Y,C)
   NEXT X
NEXT Y
END SUB

EXTERNAL SUB DIA(X,Y,M,N,P)
SET AREA COLOR 0
PLOT AREA:X-M,Y;X,Y-N;X+M,Y;X,Y+M
SET AREA COLOR 7
SELECT CASE P
CASE 1
   PLOT AREA:X-M,Y;X-M/2,Y-N/2;X,Y;X-M/2,Y+N/2
   PLOT AREA:X,Y;X+M/2,Y-N/2;X+M,Y;X+M/2,Y+N/2
CASE 2
   PLOT AREA:X,Y;X-M/2,Y-N/2;X,Y-N;X+M/2,Y-N/2
   PLOT AREA:X,Y;X+M/2,Y+N/2;X,Y+N;X-M/2,Y+N/2
END SELECT
END SUB
 

歪んでる?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時50分17秒
  CALL GINIT(650,650)
CALL TILE(0,0,649,649,4,7,50)
FOR Y=50 TO 600 STEP 50
   FOR X=50 TO 600 STEP 50
      READ A
      CALL DIA(X,Y,14,14,A)
   NEXT X
NEXT Y
DATA 1,2,1,2,2,1,2,1,1,2,1,2
DATA 1,1,2,1,2,2,1,2,1,1,2,1
DATA 2,1,1,2,1,2,2,1,2,1,1,2
DATA 1,2,1,1,2,1,2,2,1,2,1,1
DATA 2,1,2,1,1,2,1,2,2,1,2,1
DATA 2,2,1,2,1,1,2,1,2,2,1,2
DATA 1,2,2,1,2,1,1,2,1,2,2,1
DATA 2,1,2,2,1,2,1,1,2,1,2,2
DATA 1,2,1,2,2,1,2,1,1,2,1,2
DATA 1,1,2,1,2,2,1,2,1,1,2,1
DATA 2,1,1,2,1,2,2,1,2,1,1,2
DATA 1,2,1,1,2,1,2,2,1,2,1,1
END

EXTERNAL  SUB TILE(XS,YS,XE,YE,C1,C2,SIZE)
FOR Y=YS TO YE
   FOR X=XS TO XE
      LET I=INT(X/SIZE)
      LET J=INT(Y/SIZE)
      IF MOD(I+J,2)=0 THEN LET C=C1 ELSE LET C=C2
      CALL PSET(X,Y,C)
   NEXT X
NEXT Y
END SUB

EXTERNAL SUB PSET(X,Y,C)
SET POINT COLOR C
PLOT POINTS:X,Y
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) 11/255,125/255,62/255
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 DIA(X,Y,M,N,P)
SET AREA COLOR 0
PLOT AREA:X-M,Y;X,Y-N;X+M,Y;X,Y+M
SET AREA COLOR 7
SELECT CASE P
CASE 1
   PLOT AREA:X-M,Y;X-M/2,Y-N/2;X,Y;X-M/2,Y+N/2
   PLOT AREA:X,Y;X+M/2,Y-N/2;X+M,Y;X+M/2,Y+N/2
CASE 2
   PLOT AREA:X,Y;X-M/2,Y-N/2;X,Y-N;X+M/2,Y-N/2
   PLOT AREA:X,Y;X+M/2,Y+N/2;X,Y+N;X-M/2,Y+N/2
END SELECT
END SUB
 

波打ってる?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時50分46秒
  OPTION BASE 0
CALL GINIT(600,600)
DIM C(7)
FOR I=0 TO 7
   READ C(I)
NEXT I
DATA 3,2,2,3,2,3,3,2
CALL TILE(0,0,599,599,6,7,600/17)
FOR Y=35 TO 565 STEP 600/17
   FOR X=35 TO 565 STEP 600/17
      CALL DIA(X,Y,5,C(MOD(A+B,8)))
      LET B=B+1
   NEXT X
   LET A=A+1
NEXT Y
END

EXTERNAL  SUB TILE(XS,YS,XE,YE,C1,C2,SIZE)
FOR Y=YS TO YE
   FOR X=XS TO XE
      LET I=INT(X/SIZE)
      LET J=INT(Y/SIZE)
      IF MOD(I+J,2)=0 THEN LET C=C1 ELSE LET C=C2
      CALL PSET(X,Y,C)
   NEXT X
NEXT Y
END SUB

EXTERNAL SUB PSET(X,Y,C)
SET POINT COLOR C
PLOT POINTS:X,Y
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) 204/255,0,152/255
SET COLOR MIX(3) 1,1,1
SET COLOR MIX(4) 0,1,0
SET COLOR MIX(5) 0,1,1
SET COLOR MIX(6) 160/255,215/255,51/255
SET COLOR MIX(7) 79/255,187/255,129/255
CLEAR
END SUB

EXTERNAL SUB DIA(X,Y,RR,C)
DIM XX(4),YY(4)
SET AREA COLOR  C
FOR I=1 TO 4
   LET XX(I)=X+RR*COS(I*PI/2)
   LET YY(I)=Y+RR*SIN(I*PI/2)
NEXT I
MAT PLOT AREA:XX,YY
END SUB
 

動いてる?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時52分39秒
  CALL GINIT(600,600)
CALL TILE(0,0,599,599,1,2,3,2,20)
LET C=0
LET XX=40
FOR Y=20 TO 590 STEP 20
   FOR X=XX TO 590 STEP 40
      CALL DIA(X,Y,5,C)
      LET C=7-C
   NEXT X
   LET XX=60-XX
NEXT Y
CALL TILE2(120,120,479,479,1,2,3,2,20)
LET C=7
LET XX=140
FOR Y=140 TO 480 STEP 20
   FOR X=XX TO 480 STEP 40
      CALL DIA(X,Y,5,C)
      LET C=7-C
   NEXT X
   LET XX=260-XX
NEXT Y
END

EXTERNAL  SUB TILE(XS,YS,XE,YE,C1,C2,C3,C4,SIZE)
FOR Y=YS TO YE
   FOR X=XS TO XE
      LET I=INT(X/SIZE)
      LET J=INT(Y/SIZE)
      IF MOD(I+J,4)=0 THEN LET C=C1
      IF MOD(I+J,4)=1 THEN LET C=C2
      IF MOD(I+J,4)=2 THEN LET C=C3
      IF MOD(I+J,4)=3 THEN LET C=C4
      CALL PSET(X,Y,C)
   NEXT X
NEXT Y
END SUB

EXTERNAL  SUB TILE2(XS,YS,XE,YE,C1,C2,C3,C4,SIZE)
FOR Y=YS TO YE
   FOR X=XS TO XE
      LET I=INT(X/SIZE)
      LET J=INT(Y/SIZE)
      IF MOD(4+I-J,4)=0 THEN LET C=C1
      IF MOD(4+I-J,4)=1 THEN LET C=C2
      IF MOD(4+I-J,4)=2 THEN LET C=C3
      IF MOD(4+I-J,4)=3 THEN LET C=C4
      CALL PSET(X,Y,C)
   NEXT X
NEXT Y
END SUB

EXTERNAL SUB PSET(X,Y,C)
SET POINT COLOR C
PLOT POINTS:X,Y
END SUB

EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,0,YSIZE-1
SET POINT STYLE 1
SET COLOR MODE "REGULAR"
SET COLOR MIX(0) 0,0,0
SET COLOR MIX(1) 1,0,0
SET COLOR MIX(2) 1,.5,0
SET COLOR MIX(3) 1,204/255,0
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 DIA(X,Y,RR,C)
DIM XX(4),YY(4)
SET AREA COLOR  C
FOR I=1 TO 4
   LET XX(I)=X+RR*COS(I*PI/2)
   LET YY(I)=Y+RR*SIN(I*PI/2)
NEXT I
MAT PLOT AREA:XX,YY
END SUB
 

動いてる?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時53分12秒
  LET XSIZE=600
LET YSIZE=600
CALL GINIT(XSIZE,YSIZE)
CALL TILE(0,0,XSIZE-1,YSIZE-1,0,7,10)
CALL CIRCLEFULL(XSIZE/2,YSIZE/2,150,0,7,10)
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(X0,Y0,R,C1,C2,SIZE)
FOR Y=-R+Y0 TO R+Y0
   FOR X=-R+X0 TO R+X0
      IF(X-X0)*(X-X0)+(Y0-Y)*(Y0-Y)<=R*R THEN
         LET I=INT(X/SIZE)
         LET J=INT(Y/SIZE/4)
         IF MOD(I+J,2)=0 THEN LET C=C1 ELSE LET C=C2
         CALL PSET(X,Y,C)
      END IF
   NEXT X
NEXT Y
END SUB

EXTERNAL SUB TILE(XS,YS,XE,YE,C1,C2,SIZE)
FOR Y=YS TO YE
   FOR X=XS TO XE
      LET I=INT(X/SIZE/4)
      LET J=INT(Y/SIZE)
      IF MOD(I+J,2)=0 THEN LET C=C1 ELSE LET C=C2
      CALL PSET(X,Y,C)
   NEXT X
NEXT Y
END SUB

EXTERNAL SUB PSET(X,Y,C)
SET POINT COLOR C
PLOT POINTS:X,Y
END SUB
 

螺旋?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時53分55秒
  CALL GINIT(600,600)
CALL BOXFULL(0,0,599,599,4)
LET K=-50
FOR L=1 TO 4
   READ R,K
   DATA 62,-50
   DATA 115,20
   DATA 161,-30
   DATA 231,10
   LET TH=-90
   LET C=0
   DO
      LET XX=300+R*COS(TH*PI/180)
      LET YY=300+R*SIN(TH*PI/180)
      DO
         LET TH=TH+.5
         LET X0=300+R*COS(TH*PI/180)
         LET Y0=300+R*SIN(TH*PI/180)
      LOOP UNTIL SQR((XX-X0)^2+(YY-Y0)^2)>24
      PLOT LINES
      SET COLOR C
      FOR I=0 TO 4
         LET X=XX+12*COS((I*90+TH+K)*PI/180)
         LET Y=YY+12*SIN((I*90+TH+K)*PI/180)
         PLOT LINES:X,Y;
      NEXT I
      LET C=7-C
   LOOP WHILE TH<270
NEXT L
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) .5,.5,.5
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 BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA:X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB
 

点が消える?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時54分50秒
  !'回る円の中心を見つめていると黄色の点が消える
CALL GINIT(600,600)
DO
   FOR TH=0 TO 360 STEP 30
      SET DRAW MODE HIDDEN
      CLEAR
      CALL CIRCLE(300,300,200,1)
      FOR I=0 TO 7
         LET X=300+200*COS((I*45+TH)*PI/180)
         LET Y=300+200*SIN((I*45+TH)*PI/180)
         CALL LINE(300,300,X,Y,1)
      NEXT I
      FOR I=0 TO 2
         LET XX=300+100*COS((-30+I*120)*PI/180)
         LET YY=300+100*SIN((-30+I*120)*PI/180)
         CALL CIRCLEFULL(XX,YY,2,6)
      NEXT I
      SET DRAW MODE EXPLICIT
      WAIT DELAY 1/8
   NEXT TH
LOOP
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

EXTERNAL SUB CIRCLEFULL(X,Y,RR,C)
SET COLOR C
DRAW DISK WITH SCALE(RR)*SHIFT(X,Y)
END SUB

EXTERNAL  SUB CIRCLE(X,Y,R,C)
SET COLOR C
PLOT LINES
FOR I=0 TO 360 STEP 10
   LET XX=X+R*COS(I*PI/180)
   LET YY=Y+R*SIN(I*PI/180)
   PLOT LINES:XX,YY;
NEXT I
PLOT LINES
END SUB
 

チカチカする?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時55分21秒
  CALL GINIT(600,600)
LET S=5
FOR X=0 TO 600 STEP 6*S
   CALL BOXFULL(X,0,X+S,600,4)
NEXT X
FOR Y=0 TO 600 STEP 6*S
   CALL BOXFULL(0,Y,600,Y+S,4)
NEXT Y
FOR Y=0 TO 600 STEP 6*S
   FOR X=0 TO 600 STEP 6*S
      CALL CIRCLEFULL(X+S/2,Y+S/2,3,7)
   NEXT X
NEXT Y
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) .5,.5,.5
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 BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA:X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB

EXTERNAL SUB CIRCLEFULL(X,Y,RR,C)
SET COLOR C
DRAW DISK WITH SCALE(RR)*SHIFT(X,Y)
END SUB
 

呼吸してる?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時55分49秒
  CALL GINIT(600,600)
DIM X(4),Y(4)
DO
   FOR TH=0 TO 360 STEP 5
      FOR I=1 TO 4
         LET X(I)=300+170*COS((I*90+TH)*PI/180)
         LET Y(I)=300+170*SIN((I*90+TH)*PI/180)
      NEXT I
      SET DRAW MODE HIDDEN
      CLEAR
      SET COLOR 2
      MAT PLOT AREA:X,Y
      MOUSE POLL XX,YY,LEFT,RIGHT
      IF RIGHT=1 THEN STOP
      IF LEFT=0 THEN  !'左クリック中、描画なし
         CALL CIRCLEFULL(140,300,80,7)
         CALL CIRCLEFULL(460,300,80,7)
         CALL CIRCLEFULL(300,140,80,7)
         CALL CIRCLEFULL(300,460,80,7)
      END IF
      SET DRAW MODE EXPLICIT
      WAIT DELAY 1/16
   NEXT TH
LOOP
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
 

右回り? or 左回り?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時56分24秒
  CALL GINIT(600,600)
DIM XX(4),YY(4)
SET AREA COLOR 7
SET COLOR 7
LET S=3
DO
   FOR TH=S TO S+360 STEP 10
      LET X=300+200*COS(TH*PI/180)
      LET Y=300+200*SIN(TH*PI/180)
      PLOT LINES:300,300;X,Y
      FOR I=1 TO 4
         LET XX(I)=X+15*COS((I*90+TH+45)*PI/180)
         LET YY(I)=Y+15*SIN((I*90+TH+45)*PI/180)
      NEXT I
      MAT PLOT AREA:XX,YY
   NEXT TH
   SET DRAW MODE EXPLICIT
   WAIT DELAY .2
   SET DRAW MODE HIDDEN
   CLEAR
   LET S=-S
LOOP
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
 

白い球?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時56分58秒
  CALL GINIT(640,640)
SET LINE WIDTH 4
FOR Y=0 TO 640 STEP 40
   CALL LINE(0,Y,640,Y,7)
NEXT Y
FOR X=0 TO 640 STEP 40
   CALL LINE(X,0,X,640,7)
NEXT X
FOR Y=40 TO 600 STEP 80
   FOR X=40 TO 600 STEP 80
      CALL BOXFULL(X-10,Y-10,X+10,Y+10,0)
   NEXT X
NEXT Y
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) 1,1,1
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) 0,0,0
CLEAR
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 BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA:X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB
 

手前側? or 向こう側?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時57分27秒
  CALL GINIT(600,600)
LOCATE VALUE NOWAIT,RANGE -100 TO 100 ,AT 50: Y
LET XX=5
LET X=50
DO
   LET X=X+XX
   SET DRAW MODE HIDDEN
   CLEAR
   LOCATE VALUE NOWAIT:Y
   PLOT AREA:300,150;X,150-Y;X,450+Y;300,450
   SET DRAW MODE EXPLICIT
   WAIT DELAY 1/50
   IF X<50 THEN  LET XX=-XX
   IF X>550 THEN LET XX=-XX
LOOP
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) 1,1,1
SET COLOR MIX(1) 0,0,0
CLEAR
END SUB
 

線分ABとAC,どっちが長い?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時57分57秒
  CALL GINIT(600,600)
CALL DISPLAY(1)
PAUSE
CALL DISPLAY(0)
END

EXTERNAL  SUB DISPLAY(SW)
CLEAR
SET LINE WIDTH 5
CALL LINE(270,220,70,450,7)
CALL LINE(270,220,470,450,7)
CALL LINE(70,450,470,450,7)
IF SW=1 THEN
   CALL LINE(160,220,560,220,7)
   CALL LINE(160,220,70,450,7)
   CALL LINE(560,220,470,450,7)
   CALL LINE(270,220,180,450,7)
END IF
CALL SYMBOL(270,190,"A",7)
CALL SYMBOL(50,450,"B",7)
CALL SYMBOL(490,450,"C",7)
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
CLEAR
SET TEXT HEIGHT 30
SET TEXT JUSTIFY "CENTER","HALF"
END SUB

EXTERNAL SUB SYMBOL(X,Y,A$,C)
SET TEXT COLOR C
PLOT TEXT,AT X,Y:A$
END SUB

EXTERNAL SUB LINE(XS,YS,XE,YE,C)
SET COLOR C
PLOT LINES
PLOT LINES:XS,YS;XE,YE
END SUB
 

どの線と繋がっているかな?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時58分22秒
  CALL GINIT(600,600)
SET LINE WIDTH 5
RANDOMIZE
FOR X=25 TO 200 STEP 25
   CALL LINE(X,0,300,300-X,7)
NEXT X
LET X=25+INT(RND*9)*25
CALL LINE(500,500-X,600,600-X,7)
CALL BOX(300,50,500,500,7)
PAUSE
CALL LINE(X,0,600,600-X,2)
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

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 BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA:X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB
 

上段と下段は同じ色? or 違う色?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時58分56秒
  CALL GINIT(600,600)
LET C1=1
LET C2=6
CALL DISPLAY(C1,C2,5)
PAUSE
CALL DISPLAY(C1,C2,50)
END

EXTERNAL  SUB DISPLAY(C1,C2,SIZE)
CALL TILE(0,0,599,599,C1,C2,SIZE)
CALL TILE(50,50,250,250,2,C2,SIZE)
CALL TILE(350,50,550,250,4,C2,SIZE)
CALL TILE(50,350,250,550,C1,2,SIZE)
CALL TILE(350,350,550,550,C1,4,SIZE)
END SUB

EXTERNAL  SUB TILE(XS,YS,XE,YE,C1,C2,SIZE)
FOR Y=YS TO YE
   FOR X=XS TO XE
      LET I=INT(X/SIZE)
      LET J=INT(Y/SIZE)
      IF MOD(I+J,2)=0 THEN LET C=C1 ELSE LET C=C2
      CALL PSET(X,Y,C)
   NEXT X
NEXT Y
END SUB

EXTERNAL SUB PSET(X,Y,C)
SET POINT COLOR C
PLOT POINTS:X,Y
END SUB

EXTERNAL SUB GINIT(XSIZE,YSIZE)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE,YSIZE,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
 

2つの円は同じ色? or 違う色?

 投稿者:しばっち  投稿日:2013年12月15日(日)18時59分21秒
  CALL GINIT(600,600)
LET C1=4
LET C2=6
CALL DISPLAY(C1,C2,5)
PAUSE
CALL DISPLAY(C1,C2,60)
END

EXTERNAL  SUB DISPLAY(C1,C2,SIZE)
FOR X=0 TO 600 STEP SIZE
   CALL BOXFULL(X,0,X+SIZE/2,600,C1)
   CALL BOXFULL(X+SIZE/2,0,X+SIZE,600,C2)
NEXT X
CALL CIRCLEFULL(150,300,130,C1,7,SIZE/2)
CALL CIRCLEFULL(450,300,130,7,C2,SIZE/2)
END SUB

EXTERNAL SUB PSET(X,Y,C)
SET POINT COLOR C
PLOT POINTS:X,Y
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) .5,.5,.5
CLEAR
END SUB

EXTERNAL SUB BOXFULL(X1,Y1,X2,Y2,C)
SET COLOR C
PLOT AREA:X1,Y1;X2,Y1;X2,Y2;X1,Y2;X1,Y1
END SUB

EXTERNAL SUB CIRCLEFULL(X0,Y0,R,C1,C2,SIZE)
FOR Y=-R+Y0 TO R+Y0
   FOR X=-R+X0 TO R+X0
      IF(X-X0)*(X-X0)+(Y0-Y)*(Y0-Y)<=R*R THEN
         LET I=INT(X/SIZE)
         IF MOD(I,2)=0 THEN LET C=C1 ELSE LET C=C2
         CALL PSET(X,Y,C)
      END IF
   NEXT X
NEXT Y
END SUB
 

 戻る