Fractran: Difference between revisions
Content added Content deleted
m (→The Code) |
(→Revised Code: Output of zero powers is replaced by spaces.) |
||
Line 895: | Line 895: | ||
END TYPE FACTORED !Rather than as a simple number multiplied out. |
END TYPE FACTORED !Rather than as a simple number multiplied out. |
||
TYPE(FACTORED) FP(ENUFF),FQ(ENUFF) !Thus represent a factored fraction, P(i)/Q(i). |
TYPE(FACTORED) FP(ENUFF),FQ(ENUFF) !Thus represent a factored fraction, P(i)/Q(i). |
||
INTEGER PLIVE(ENUFF),NL !Helps subroutine SHOWN display NPPOW. |
|||
CONTAINS !Now for the details. |
CONTAINS !Now for the details. |
||
SUBROUTINE SHOWFACTORS(N) !First, to show an internal data structure. |
SUBROUTINE SHOWFACTORS(N) !First, to show an internal data structure. |
||
Line 974: | Line 975: | ||
END DO !This relies on ALL(zero tests) yielding true, as when Q = 1. |
END DO !This relies on ALL(zero tests) yielding true, as when Q = 1. |
||
FRACTRAN = 0 !No hit. |
FRACTRAN = 0 !No hit. |
||
END FUNCTION FRACTRAN !No massive |
END FUNCTION FRACTRAN !No massive multi-precision arithmetic! |
||
SUBROUTINE SHOWN(S,F) !Service routine to show the state after a step is calculated. |
|||
Could imaging a function I6FMT(23) that returns " 23" and " " for non-positive numbers. |
|||
Can't do it, as if this were invoked via a WRITE statement, re-entrant use of WRITE usually fails. |
|||
INTEGER S,F !Step number, Fraction number. |
|||
INTEGER I !A stepper. |
|||
CHARACTER*(9+4+1 + NL*6) ALINE !A scratchpad matching FORMAT 103. |
|||
⚫ | |||
⚫ | |||
IF (F.LE.0) ALINE(10:13) = "" !Scrub when no fraction is fingered. |
|||
DO I = 1,NL !Step along the live primes. |
|||
IF (NPPOW(PLIVE(I)).GT.0) CYCLE !Ignoring the empowered ones. |
|||
ALINE(15 + (I - 1)*6:14 + I*6) = "" !Blank out zero powers. |
|||
⚫ | |||
WRITE (MSG,"(A)") ALINE !Reveal at last. |
|||
END SUBROUTINE SHOWN !A struggle. |
|||
END MODULE CONWAYSIDEA !Simple... |
END MODULE CONWAYSIDEA !Simple... |
||
PROGRAM POKE |
PROGRAM POKE |
||
USE CONWAYSIDEA |
USE CONWAYSIDEA !But, where does he get his ideas from? |
||
INTEGER P(ENUFF),Q(ENUFF) !Holds the fractions as P(i)/Q(i). |
INTEGER P(ENUFF),Q(ENUFF) !Holds the fractions as P(i)/Q(i). |
||
INTEGER N |
INTEGER N !The working number. |
||
INTEGER |
INTEGER LF !Last fraction given. |
||
INTEGER LP !Last prime needed. |
INTEGER LP !Last prime needed. |
||
INTEGER MS !Maximum number of steps. |
|||
INTEGER I,IT !Assistants. |
|||
LOGICAL*1 PUSED(ENUFF) !Track the usage of prime numbers, |
|||
MSG = 6 !Standard output. |
MSG = 6 !Standard output. |
||
Line 990: | Line 1,010: | ||
Chew into an example programme. |
Chew into an example programme. |
||
10 OPEN (10,FILE = "Fractran.txt",STATUS="OLD",ACTION="READ") !Rather than compiled-in stuff. |
10 OPEN (10,FILE = "Fractran.txt",STATUS="OLD",ACTION="READ") !Rather than compiled-in stuff. |
||
READ (10,*) |
READ (10,*) LF !I need to know this without having to scan the input. |
||
WRITE (MSG,11) |
WRITE (MSG,11) LF !Reveal in case of trouble. |
||
11 FORMAT (I0," fractions, as follow:") !Should the input evoke problems. |
11 FORMAT (I0," fractions, as follow:") !Should the input evoke problems. |
||
READ (10,*) (P(I),Q(I),I = 1, |
READ (10,*) (P(I),Q(I),I = 1,LF) !Ask for the specified number of P,Q pairs. |
||
WRITE (MSG,12) (P(I),Q(I),I = 1, |
WRITE (MSG,12) (P(I),Q(I),I = 1,LF) !Show what turned up. |
||
12 FORMAT (24(I0,"/",I0:", ")) !As P(i)/Q(i) pairs. The colon means that there will be no trailing comma. |
12 FORMAT (24(I0,"/",I0:", ")) !As P(i)/Q(i) pairs. The colon means that there will be no trailing comma. |
||
READ (10,*) N, |
READ (10,*) N,MS !The start value, and the step limit. |
||
CLOSE (10) !Finished with input. |
CLOSE (10) !Finished with input. |
||
WRITE (MSG,13) N, |
WRITE (MSG,13) N,MS !Hopefully, all went well. |
||
13 FORMAT ("Start with N = ",I0,", step limit ",I0) |
13 FORMAT ("Start with N = ",I0,", step limit ",I0) |
||
IF (.NOT.GRASPPRIMEBAG(66)) STOP "Gan't grab my file of primes!" !Attempt in hope. |
IF (.NOT.GRASPPRIMEBAG(66)) STOP "Gan't grab my file of primes!" !Attempt in hope. |
||
Line 1,008: | Line 1,028: | ||
NPPOW(FP(1).PNUM(I)) = FP(1).PPOW(I) !Convert from a variable-length list |
NPPOW(FP(1).PNUM(I)) = FP(1).PPOW(I) !Convert from a variable-length list |
||
END DO !To a fixed-length random-access array. |
END DO !To a fixed-length random-access array. |
||
PUSED = NPPOW.GT.0 !Note which primes have been used. |
|||
LP = FP(1).PNUM(FP(1).PNUM(0)) !Recall the last prime required. More later. |
|||
Convert the supplied P(i)/Q(i) fractions to lists of prime number factors and powers in FP(i) and FQ(i). |
Convert the supplied P(i)/Q(i) fractions to lists of prime number factors and powers in FP(i) and FQ(i). |
||
DO I = 1, |
DO I = 1,LF !Step through the fractions. |
||
IT = GCD(P(I),Q(I)) !Suspicion. |
IT = GCD(P(I),Q(I)) !Suspicion. |
||
IF (IT.GT.1) THEN !Justified? |
IF (IT.GT.1) THEN !Justified? |
||
Line 1,019: | Line 1,040: | ||
Q(I) = Q(I)/IT !And, as N is factorised in NPPOW |
Q(I) = Q(I)/IT !And, as N is factorised in NPPOW |
||
END IF !And Q in FQ, subtractions of powers only is needed. |
END IF !And Q in FQ, subtractions of powers only is needed. |
||
FP(I) = FACTOR(P(I)) !Righto, form the factor list for P. |
FP(I) = FACTOR(P(I)) !Righto, form the factor list for P. |
||
PUSED(FP(I).PNUM(1:FP(I).PNUM(0))) = .TRUE. !Mark which primes it fingers. |
|||
LP = MAX(LP,FP(I).PNUM(FP(I).PNUM(0))) !One has no prime factors: PNUM(0) = 0. |
|||
FQ(I) = FACTOR(Q(I)) !And likewise for Q. |
|||
⚫ | |||
PUSED(FQ(I).PNUM(1:FQ(I).PNUM(0))) = .TRUE. !Some primes may be omitted. |
|||
⚫ | |||
END DO !All this messing about saves on multiplication and division. |
END DO !All this messing about saves on multiplication and division. |
||
Check which primes are in use, preparing an index of live primes.. |
|||
⚫ | |||
NL = 0 !No live primes. |
|||
⚫ | |||
⚫ | |||
IF (PUSED(I)) THEN !This one used? |
|||
NL = NL + 1 !Yes. Another. |
|||
PLIVE(NL) = I !Fingered. |
|||
END IF !So much for that prime. |
|||
END DO !On to the next. |
|||
⚫ | |||
⚫ | |||
IF (LP.GT.LASTP) STOP "But, that's too many for array NPPOW!" |
IF (LP.GT.LASTP) STOP "But, that's too many for array NPPOW!" |
||
Cast forth a heading. |
|||
100 WRITE (MSG,101) (PRIME(I), I = 1, |
100 WRITE (MSG,101) (PRIME(PLIVE(I)), I = 1,NL) !Splat a heading. |
||
101 FORMAT (/,14X,"N as powers of prime factors",/, !The prime heading, |
101 FORMAT (/,14X,"N as powers of prime factors",/, !The prime heading, |
||
1 5X,"Step F# |
1 5X,"Step F#:",<LP>I6) !With primes beneath. |
||
CALL SHOWN(0,0) |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
Commence! |
|||
⚫ | |||
DO I = 1,MS !Here we go! |
|||
⚫ | |||
CALL SHOWN(I,IT) !Show it! |
|||
END DO !The next step. |
|||
Complete! |
|||
⚫ | |||
</lang> |
|||
===Revised Results=== |
===Revised Results=== |