◆東京都 明 さんからの解答
【問題1】のプログラムです。(10進BASICです。)
----------------------
DECLARE EXTERNAL SUB combp
DECLARE EXTERNAL SUB zyun
LET LS$="ABCDEFGHIJKLMNOPQRm"
DIM AL(19) ! 記号列
DATA 1,3,5,7,9,11
DATA 13,14,15,16,17,18
DATA 12,4,8,2,6,10,19
MAT READ AL
REM 方程式の解
DIM AR(12,19) ! 方程式表示配列
! A,C,E,G,I,K,M,N,O,P,Q,R,L,D,H,B,F,J,m
DATA 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-1
DATA 0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,-1
DATA 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,-1
DATA 0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,-1
DATA 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,-1
DATA 1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,-1
DATA 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,-1
DATA 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,-1
DATA 0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,-1
DATA 0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,-1
DATA 0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,-1
DATA 0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,-1
MAT READ AR
DIM OP(12,19) ! 演算過程表示配列
DIM DM(12)
DIM IDP(2)
MAT DM=ZER
MAT OP=ZER
FOR J=1 TO 12
LET OP(J,J)=1
NEXT J
LET Q=1
FOR J=1 TO 19
FOR K=1 TO 12
IF AR(K,J)<>0 AND DM(K)=0 THEN
LET DM(K)=1
LET DV=AR(K,J)
FOR L=1 TO 19
LET AR(K,L)=AR(K,L)/DV
LET OP(K,L)=OP(K,L)/DV
NEXT L
FOR M=1 TO 12
IF M<>K THEN
LET MP=AR(M,J)
FOR N=1 TO 19
LET AR(M,N)=AR(M,N)-MP*AR(K,N)
LET OP(M,N)=OP(M,N)-MP*OP(K,N)
NEXT N
END IF
NEXT M
EXIT FOR
END IF
IF K=12 AND Q<=2 THEN
LET IDP(Q)=J
LET Q=Q+1
END IF
NEXT K
NEXT J
PRINT " 方程式の解 "
FOR J=1 TO 19
PRINT " ";LS$(AL(J):AL(J));
IF J=19 THEN PRINT ELSE PRINT ",";
NEXT J
FOR J=1 TO 12
FOR K=1 TO 19
PRINT USING"-%":AR(J,K);
IF K=19 THEN PRINT ELSE PRINT ",";
NEXT K
NEXT J
PRINT
PRINT " 演算過程表示 "
LET LS2$=" 1 2 3 4 5 6 7 8 9101112"
FOR J=1 TO 12
PRINT LS2$(2*J-1:2*J);")";
IF J=12 THEN PRINT
NEXT J
FOR J=1 TO 12
FOR K=1 TO 19
PRINT USING"-%":OP(J,K);
IF K=19 THEN PRINT ELSE PRINT ",";
NEXT K
NEXT J
REM 数入れ探索
LET N=18
LET K=5
DIM NA(N+1)
DIM NAC(N+1)
DIM NAC2(N+1)
DIM CK(N)
DIM CKC(N)
DIM CKC2(N)
DIM CKC3(N)
DIM VL(N)
DIM VO(N,2)
MAT VO=CON
FOR J=1 TO N
LET VL(J)=J
LET VO(J,1)=J
NEXT J
FOR J=1 TO K
LET VO(J,2)=0
NEXT J
LET L=5
LET M=3
DIM VO2(L,2)
DIM VL2(L)
LET P=3
DIM VL3(P)
LET IDP1=AL(IDP(1))
LET IDP2=AL(IDP(2))
PRINT
PRINT " 数入れの解 "
FOR J=1 TO 19
PRINT " ";LS$(J:J);
IF J=19 THEN PRINT ELSE PRINT ",";
NEXT J
DO
CALL serch
CALL combp(K,N,EX,VL,VO)
LOOP UNTIL EX=0
PRINT "終了"
STOP
SUB serch
MAT NA=ZER
MAT CK=ZER
MAT VO2=CON
FOR J=1 TO L
LET VO2(J,1)=VL(J)
LET VL2(J)=VL(J)
NEXT J
FOR J=1 TO M
LET VO2(J,2)=0
NEXT J
DO
CALL serch2
CALL combp(M,L,EX,VL2,VO2)
LOOP UNTIL EX=0
END SUB
SUB serch2
LET NA(12)=VL2(1) ! L代入
LET NA(4)=VL2(2) ! D代入
LET NA(8)=VL2(3) ! H代入
LET CK(NA(12))=1
LET CK(NA(4))=1
LET CK(NA(8))=1
LET RN=VL2(1)
FOR J=2 TO 3
LET RN=RN+VL2(J)-VL2(J+2)
NEXT J
IF RN<=VL(5) THEN EXIT SUB
FOR J=1 TO 2
LET VL3(J)=VL2(J+3)
NEXT J
IF RN>18 THEN EXIT SUB
LET VL3(3)=RN
LET SUM=0
FOR J=1 TO 3
LET SUM=SUM+VL2(J)+VL3(J)
NEXT J
IF MOD(SUM+6,12)<>0 THEN EXIT SUB
LET TM=(SUM+6)/12+28
IF TM>43 THEN EXIT SUB
LET NA(19)=TM ! m代入
MAT CKC=CK
MAT NAC=NA
DO
CALL serch3
CALL zyun(P,EX,VL3)
LOOP UNTIL EX=0
END SUB
SUB serch3
MAT CK=CKC
MAT NA=NAC
LET NA(2)=VL3(1) ! B代入
LET NA(6)=VL3(2) ! F代入
LET NA(10)=VL3(3) ! J代入
LET CK(NA(2))=1
LET CK(NA(6))=1
LET CK(NA(10))=1
MAT CKC2=CK
MAT NAC2=NA
REM 従属変数を求める
LET X=1
DO
MAT CK=CKC2
IF CK(X)=0 THEN
LET CK(X)=1
MAT CKC3=CK
LET Y=1
DO
MAT CK=CKC3
CALL lokdep
LET Y=Y+1
LOOP WHILE Y<=18
END IF
LET X=X+1
LOOP WHILE X<=18
END SUB
SUB lokdep
IF CK(Y)=1 THEN EXIT SUB
MAT NA=NAC2
LET NA(IDP1)=X
LET NA(IDP2)=Y
LET CK(Y)=1
FOR RAW=1 TO 12
FOR J=1 TO 12
IF AR(RAW,J)=1 THEN
LET IDX=AL(J)
FOR U=J+1 TO 19
LET NA(IDX)=NA(IDX)-NA(AL(U))*AR(RAW,U)
NEXT U
IF NA(IDX)>0 AND NA(IDX)<=18 AND CK(NA(IDX))=0 THEN
LET CK(NA(IDX))=1
ELSE
EXIT SUB
END IF
EXIT FOR
END IF
NEXT J
NEXT RAW
FOR J=1 TO 19
PRINT USING"##":NA(J);
IF J=19 THEN PRINT ELSE PRINT ",";
NEXT J
END SUB
END
REM N個の数列VO(,)からK個の数列VL()を取る組合せ
EXTERNAL SUB combp(K,N,EX,VL(),VO(,))
LET EX=0
LET P=K
DO WHILE P>=1
LET IDX=1
DO WHILE IDX<=N-(K-P)
IF VO(IDX,2)=1 AND VO(IDX,1)>VL(P) THEN
LET EX=1
FOR J=IDX-1 TO 1 STEP -1
IF VO(J,2)=0 AND VO(J,1)=VL(P) THEN
LET VO(J,2)=1
LET VO(IDX,2)=0
LET VL(P)=VO(IDX,1)
LET IDY=P+1
DO WHILE IDY=<K
FOR L=IDX TO N
IF VO(L,2)=1 THEN
LET VL(IDY)=VO(L,1)
LET IDY=IDY+1
LET VO(L,2)=0
EXIT FOR
END IF
NEXT L
LOOP
LET ID=K+1
FOR L=1 TO N
IF VO(L,2)=1 THEN
LET VL(ID)=VO(L,1)
LET ID=ID+1
END IF
NEXT L
EXIT SUB
END IF
NEXT J
END IF
LET IDX=IDX+1
LOOP
FOR J=N TO 1 STEP -1
IF VO(J,2)=0 AND VO(J,1)=VL(P) THEN
LET VO(J,2)=1
EXIT FOR
END IF
NEXT J
LET P=P-1
LOOP
END SUB
REM K個の数列N()の順列
EXTERNAL SUB zyun(K,EX,N())
DECLARE EXTERNAL SUB seiretu
LET EX=0
LET J=1
DO
IF J>=K THEN EXIT DO
IF N(K-J)<N(K-J+1) THEN
CALL seiretu(J,K,N)
LET L=1
DO
IF N(K-J)>=N(K-J+L) THEN
LET L=L+1
ELSE
LET B=N(K-J)
LET N(K-J)=N(K-J+L)
LET N(K-J+L)=B
LET EX=1
EXIT DO
END IF
LOOP
EXIT DO
ELSE
LET J=J+1
END IF
LOOP
END SUB
!配列の整列
EXTERNAL SUB seiretu(G,K,N())
LET D=G
DO
LET J=K-D+1
IF J>=K THEN EXIT DO
LET B=J
DO WHILE J<K
LET J=J+1
IF N(B)>N(J) THEN
LET T=N(B)
LET N(B)=N(J)
LET N(J)=T
END IF
LOOP
LET D=D-1
LOOP
END SUB
----------------------
◆ 問題へもどる
◆ 今週の問題へ