Fractran: Difference between revisions

→‎Revised Code: Output of zero powers is replaced by spaces.
(→‎Revised Code: Output of zero powers is replaced by spaces.)
Line 895:
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).
INTEGER PLIVE(ENUFF),NL !Helps subroutine SHOWN display NPPOW.
CONTAINS !Now for the details.
SUBROUTINE SHOWFACTORS(N) !First, to show an internal data structure.
Line 974 ⟶ 975:
END DO !This relies on ALL(zero tests) yielding true, as when Q = 1.
FRACTRAN = 0 !No hit.
END FUNCTION FRACTRAN !No massive miltimulti-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.
WRITE (6ALINE,103) IS,ITF,NPPOW(PLIVE(1:LPNL)) !Show it!
103 FORMAT (I9,I4,":",<LPNL>I6) !As a sequence of powers of primes.
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.
END DO !TheOn nextto stepthe next.
WRITE (MSG,"(A)") ALINE !Reveal at last.
END SUBROUTINE SHOWN !A struggle.
END MODULE CONWAYSIDEA !Simple...
 
PROGRAM POKE
USE CONWAYSIDEA !But, where does he get his ideas from?
INTEGER P(ENUFF),Q(ENUFF) !Holds the fractions as P(i)/Q(i).
INTEGER N !The working number.
INTEGER I,IT,L,M LF !AssistantsLast fraction given.
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.
Line 990 ⟶ 1,010:
Chew into an example programme.
10 OPEN (10,FILE = "Fractran.txt",STATUS="OLD",ACTION="READ") !Rather than compiled-in stuff.
READ (10,*) LLF !I need to know this without having to scan the input.
WRITE (MSG,11) LLF !Reveal in case of trouble.
11 FORMAT (I0," fractions, as follow:") !Should the input evoke problems.
READ (10,*) (P(I),Q(I),I = 1,LLF) !Ask for the specified number of P,Q pairs.
WRITE (MSG,12) (P(I),Q(I),I = 1,LLF) !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.
READ (10,*) N,MMS !The start value, and the step limit.
CLOSE (10) !Finished with input.
WRITE (MSG,13) N,M MS !Hopefully, all went well.
13 FORMAT ("Start with N = ",I0,", step limit ",I0)
IF (.NOT.GRASPPRIMEBAG(66)) STOP "Gan't grab my file of primes!" !Attempt in hope.
Line 1,008 ⟶ 1,028:
NPPOW(FP(1).PNUM(I)) = FP(1).PPOW(I) !Convert from a variable-length list
END DO !To a fixed-length random-access array.
LPPUSED = FP(1)NPPOW.PNUM(FP(1)GT.PNUM(0)) !RecallNote thewhich lastprimes primehave requiredbeen 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).
DO I = 1,LLF !Step through the fractions.
IT = GCD(P(I),Q(I)) !Suspicion.
IF (IT.GT.1) THEN !Justified?
Line 1,019 ⟶ 1,040:
Q(I) = Q(I)/IT !And, as N is factorised in NPPOW
END IF !And Q in FQ, subtractions of powers only is needed.
FP(I) = FACTOR(P(I)) !Righto, form the factor list for P.
LP = MAXPUSED(LP,FP(I).PNUM(1:FP(I).PNUM(0))) = .TRUE. !OneMark haswhich noprimes primeit factors: PNUM(0) = 0fingers.
FQ(I)LP = FACTORMAX(QLP,FP(I).PNUM(FP(I).PNUM(0))) !AndOne likewisehas forno prime factors: PNUM(0) = Q0.
FQ(I) = FACTOR(Q(I)) !And likewise for Q.
LP = MAX(LP,FQ(I).PNUM(FQ(I).PNUM(0))) !If zero prime factors, PNUM(0) fingers element zero, which is zero.
PUSED(FQ(I).PNUM(1:FQ(I).PNUM(0))) = .TRUE. !Some primes may be omitted.
LP = MAX(LP,FQ(I).PNUM(FQ(I).PNUM(0))) !If zerono prime factors, PNUM(0) fingers element zero, which is zero.
END DO !All this messing about saves on multiplication and division.
Check which primes are in use, preparing an index of live primes..
WRITE (MSG,22) LP,PRIME(LP)
NL = 0 !No live primes.
22 FORMAT ("Require primes only up to Prime(",I0,") = ",I0)
DO I = 1,M LP !HereCheck weup go!to the last prime.
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.
WRITE (MSG,22) NL,LP,PRIME(LP) !Remark on usage.
22 FORMAT ("Require ",I0," primes only, up to Prime(",I0,") = ",I0) !Presume always more than one prime.
IF (LP.GT.LASTP) STOP "But, that's too many for array NPPOW!"
 
CommenceCast withforth a heading.
100 WRITE (MSG,101) (PRIME(PLIVE(I)), I = 1,LP),0,NPPOW(1:LPNL) !Splat a heading.
101 FORMAT (/,14X,"N as powers of prime factors",/, !The prime heading,
1 5X,"Step F#:",<LP>I6,/,I9,4X,":",<LP>I6) !With primes beneath.
CALL SHOWN(0,0)
 
DO I = 1,M !Here we go!
IT = FRACTRAN(L) !Do it!
WRITE (6,103) I,IT,NPPOW(1:LP) !Show it!
103 FORMAT (I9,I4,":",<LP>I6) !As a sequence of powers of primes.
END DO !The next step.
 
Commence!
END !Whee!</lang>
DO I = 1,MS !Here we go!
IT = FRACTRAN(LLF) !Do it!
CALL SHOWN(I,IT) !Show it!
END DO !The next step.
Complete!
END !Whee!</lang>
</lang>
 
===Revised Results===
1,220

edits