* Permutations/Derangements 01/04/2017 DERANGE CSECT USING DERANGE,R13 base register B 72(R15) skip savearea DC 17F'0' savearea STM R14,R12,12(R13) save previous context ST R13,4(R15) link backward ST R15,8(R13) link forward LR R13,R15 set addressability XPRNT PG1,L'PG1 print title LA R1,4 4 LA R2,1 1 : combinations print BAL R14,DERGEN call dergen STH R0,COUNT count=dergen(4,1) XPRNT PG2,L'PG2 print table headings XPRNT PG3,L'PG3 print hyphens SR R4,R4 STH R4,II ii=0 DO WHILE=(CH,R4,LE,=H'9') do ii=0 to 9 MVC PG,=CL80' ' clear buffer XDECO R4,PG edit ii LR R1,R4 ii LA R2,0 0 : no combination print BAL R14,DERGEN dergen(ii,0) XDECO R0,PG+12 edit LH R1,II ii BAL R14,SUBFACT subfact(ii) XDECO R0,PG+24 edit XPRNT PG,L'PG print LH R4,II ii LA R4,1(R4) i+1 STH R4,II i=i+1 ENDDO , enddo i LA R0,12 12 STH R0,II ii=12 MVC PG,=CL16'!xx=' init buffer XDECO R0,XDEC edit ii MVC PG+1(2),XDEC+10 output LH R1,II ii BAL R14,SUBFACT subfact(ii) XDECO R0,PG+4 edit subfact(ii) XPRNT PG,16 print L R13,4(0,R13) restore previous savearea pointer LM R14,R12,12(R13) restore previous context XR R15,R15 rc=0 BR R14 exit *------- ---- ------------------------------------------- DERGEN EQU * dergen(n,fprt) ST R14,SAVEDG ST R1,N n ST R2,FPRT fprt IF LTR,R1,Z,R1 THEN if n=0 then LA R0,1 1 B RETDG return(1) ENDIF , endif MVC C,=F'0' c=0 LA R6,1 i=1 DO WHILE=(C,R6,LE,N) do i=1 to 2 LR R1,R6 i SLA R1,1 STH R6,A-2(R1) a(i)=i STH R6,AO-2(R1) ao(i)=i LA R6,1(R6) i++ ENDDO , enddo i L R1,N n BAL R14,FACT ST R0,FACTNM1 fact(n)-1 SR R6,R6 i=0 DO WHILE=(C,R6,LE,FACTNM1) do i=0 to fact(n)-1 L R1,N n BAL R14,NEXTPER call nextper(n) MVI D,X'01' d=true LA R7,1 DO WHILE=(C,R7,LE,N) do j=1 to n LR R1,R7 j SLA R1,1 LH R2,A-2(R1) a(j) LH R3,AO-2(R1) ao(j) IF CR,R2,EQ,R3 THEN if a(j)=ao(j) then MVI D,X'00' d=false ENDIF , endif LA R7,1(R7) j++ ENDDO , enddo j IF CLI,D,EQ,X'01' THEN if d then L R2,C c LA R2,1(R2) c+1 ST R2,C c=c+1 IF CLI,FPRT+3,EQ,X'01' THEN if fprt=1 then MVC PG,=CL80' ' clear buffer LA R10,PG pgi=0 LA R7,1 j=1 DO WHILE=(C,R7,LE,N) do j=1 to n LR R1,R7 j SLA R1,1 LH R2,A-2(R1) a(j) XDECO R2,XDEC edit MVC 0(1,R10),XDEC+11 output LA R10,2(R10) pgi=pgi+2 LA R7,1(R7) j++ ENDDO , enddo j XPRNT PG,L'PG print ENDIF , endif ENDIF , endif LA R6,1(R6) i++ ENDDO , enddo i L R0,C c B RETDG return(c) RETDG L R14,SAVEDG BR R14 SAVEDG DS A *------- ---- ------------------------------------------- NEXTPER EQU * nextper(nk) ST R14,SAVENP ST R1,NK nk BCTR R1,0 nk-1 ST R1,NELEM nelem=nk-1 IF C,R1,LT,=F'1' THEN if nelem<1 then LA R0,0 return(0) B RETNP ENDIF , endif L R8,NELEM nelem BCTR R8,0 pos=nelem-1 LOOPW1 EQU * while a(pos+1)>=a(pos+2) LR R1,R8 pos SLA R1,1 LH R2,A(R1) a(pos+1) CH R2,A+2(R1) if a(pos+1)a(pos+1) BH ELOOPW2 then exit while BCTR R9,0 last=last-1 B LOOPW2 endwhile ELOOPW2 LR R1,R8 pos SLA R1,1 *2 LA R2,A(R1) @a(pos+1) LR R1,R9 last SLA R1,1 LA R3,A(R1) @a(last+1) LH R0,0(R2) w=a(pos+1) MVC 0(2,R2),0(R3) a(pos+1)=a(last+1) STH R0,0(R3) a(last+1)=w LA R1,1(R8) pos+1 L R2,NELEM nelem BAL R14,PERMREV call permrev(pos+1,nelem) RETNP L R14,SAVENP BR R14 SAVENP DS A *------- ---- ------------------------------------------- PERMREV EQU * permrev(firstix,lastix) LR R4,R1 xfirst LR R5,R2 xlast DO WHILE=(CR,R4,LT,R5) do while(xfirst