* PYTHAGORAS
* This Greek mathematician and philosopher is famous for many reasons.
* Amongst other things, he discovered harmonic sequences, sequences of
* reciprocals of integers, as a result of investigating relationships
* connecting musical notes obtained from plucking strings. In fact, and
* paradoxically, he discovered irrational numbers - but he only believed
* in integers. To this day, square and other inexact roots of numbers
* are called surds (from absurd).
* Of course, Pythagoras is best known for his famous theorem on the
* right-angled triangle. Most of us have met, in high school, triangles,
* the sides of which are in the ratio of 3:4:5 or 5:12:13 or perhaps
* 7:24:25. It is possible to generate number triples such as these from
* a simple formula which only needs 2 numbers. The remarkable thing about
* these number triples is this:
* if x:y:z is a Pythagorean triple, then x^2+y^2=z^2, satisfying the
* theorem, but that is only the start of a multiplicity of interconnecting
* relationships amongst the x,y and z's. For example, you will note that
* for the three ratios given above, and a complete sequence of which these
* are the first three members, x^2=y+z; furthermore,z-y=1. Other relation-
* ships are found in related sequences. How can we produce these sequences?
* Well, let a and b be two distinct mutually prime integers having an odd
* sum (this last more for convenience than any other reason). Then, from
* a and b, let x=a^2-b^2, y=2*a*b and z=a^2+b^2. So, from the two integers
* a and b, we produce three integers. You can confirm, with only minimal
* algebra, that x^2+y^2=z^2 under these conditions for all values of a and b
* (it is useful to have a>b so that x>0).
* The LEX file below has been written to accept an input of to numbers, a & b,
* which it will round to integers, a & b are swapped if b>a, and it then
* calculates the integer lengths of the three sides of a Pythagorean triangle.
* Now it is well known that a function can only output a single value,
* (mathematically, a function is a one-to-one or a many-to-one relation), so
* when we wish to output three(3!) results, fun can be expected. The solution
* is simple. Calculate each of x,y and z, then place the results one at a
* time on the mathstack and convert to a string. By clearing ST1 for the
* first and third numbers and setting ST1 for the middle one, we create
* spaces as separators. Thus the output is, in fact, a string.
* The reason that the keyword is PYTH2$ is that it is possible to repeat
* this exercise with Pythagorean quadruples. Examples of the latter are
* (1,2,2,3),(2,3,6,7) and (3,4,12,13). These can also be generated from two
* integers, although the integers don't need to be distinct now.
* The formula is: x=a*b, y=a*(a+b), z=b*(a+b) and t=a^2+a*b+b^2.
* (t=[a^3-b^3]/[a-b] when a#b). Suppose a=b=1, then (x,y,z,t)=(1,2,2,3),
* and for a=1 & b=2, we have (2,3,6,7). For the quadruples, we have:
* x^2+y^2+z^2=t^2. These quadruples also have their interesting patterns.
* When a=1, z=x*y and t=z+1, in other words when x & y are consecutive
* integers, z is their product and t is one bigger than that. When I
* get around to coding up for quadruples, the keyword will be PYTH3$.
* In both cases, some readers may be able to recognize the last member of
* the n-tuple as the Euclidean distance to a point in the (n-1) dimensonal
* space [ the point (3,4) is 5 units from the origin in 2-space, while the
* the point (2,3,6) is 7 units from the origin in 3-space; it now will not
* surprise anyone that 236 (EC in hex) is the ID in many of my LEX files.
* The reason that PYTHLEX has an ID of 238 is even more mathemystical.
* All will be revealed when the file CODER appears.
LEX 'PYTHLEX' * A file to create Pythagorean triples,
ID #EE * using a number pair as input. Jack Elhay,17/7/88.
MSG 0 * no mesage table &
POLL 0 * no poll handler
ENTRY PYTH2
CHAR #F * a function
KEY 'PYTH2$' * Syntax: PYTH2$(a,b), where a & b are
TOKEN 5 * distinct integers
ENDTXT
A-MULT EQU #1B349 * multiply 2 20 bit hex integers
ADHEAD EQU #181B7 * add header to string on stack
ARGERR EQU #0BF19 * invalid argument error exit
D=AVMS EQU #1A460 * set D(A) to available memory start
DSPFMT EQU #2F6DC * the 1st 2 bits of this nib define display format
F-R0-0 EQU #2F89B * function scratch RAM
FUNCD0 EQU #2F8BB * temporary D0 storage area
HDFLT EQU #1B31B * hex to float conversion
RNDAHX EQU #136CB * pop,round,test & conv to hex
STR$00 EQU #1815C * STR$ generic function
XXHEAD EQU #1A44E * strip header off, undo ADHEAD
ERR GOVLNG ARGERR
NIBHEX 8822 * 2 obligatory numeric parameters
PYTH2 GOSBVL RNDAHX * pop as a hex integer, with rounding
GONC ERR * exclude negatives
R1=A * save argument in R1
D1=D1+ 16 * point to 1st argument
GOSBVL RNDAHX * and pop it
GONC ERR * it must also not be negative
R0=A * save 1st arg in R0
D1=D1+ 16 * point past 1st arg, where start of string will be
CD1EX * swap into C(A)
D1=(5) (FUNCD0)+5 * set D1 to FUNCD1
DAT1=C A * save D1 there, ADHEAD will need R1 set to this
D1=C * and restore D1
C=R1 * recover 2nd argument
?C>A A * is it larger than the 1st?
GOYES NOSWAP * leave them in place
AR1EX * otherwise swap 1st and 2nd
CR0EX * to keep a^2-b^2>0
NOSWAP C=R0 * A(A) and C(A) will be multiplied
GOSUB a-mult * in hex mode
R3=A * this b^2
A=R1 * now we will get a^2
C=R1 * in the same way
GOSUB a-mult * by multiplying
R2=A * then saving a^2
A=R0 * next we calculate 2*a*b
C=R1 * by
GOSUB a-mult * multiplying a & b
A=A+A A * and doubling
R0=A * finally saving it in R0
A=R2 * pick up a^2
C=R3 * pick up b^2
A=A+C A * a^2+b^2
R3=A * saved in R3
A=R2 * reset A(A) to a^2, C(A) unchanged
A=A-C A * a^2-b^2
R2=A * saved in R2
AD0EX * start stashing in scratch
D0=(5) FUNCD0 * beginning with D0, which will be used
DAT0=A A * save D0
D0=(5) DSPFMT * set D0 to display format nib
A=DAT0 S * read the nib
LCHEX 8 * this will force STD, LC OFF, BASE OPTION 1
DAT0=C 1 * when poked in here
D0=(5) F-R0-0 * set D0 to function scratch
C=R2 * a^2-b^2
GOSUB SAVE * saved in F-R0-0
C=R0 * 2*a*b
GOSUB SAVE * saved in F-R0-1
C=R3 * a^2+b^2
GOSUB SAVE * saved in F-R0-2
DAT0=A S * display nib saved in F-R0-3
D0=D0- 15 * point again to F-R0-0
ST=1 0 * no spaces before and after
ST=0 1 * return required
GOSUB STACK * read the number,float,write to stack,conv to str
ST=1 1 * we want a space before and after this time
GOSUB STACK * transform hex # in scratch to str on stack
ST=0 1 * no spaces needed this time
GOSUB STACK * 3rd number fixed up
A=DAT0 1 * read original display nib
D0=(5) DSPFMT * this where original format will be restored
DAT0=A 1 * put format back as found on entry
D0=(5) (FUNCD0)+5 * now we want address for start of string
C=DAT0 A * read it
R1=C * ADHEAD needs it in R1
D0=D0- 5 * next we will restore D0
C=DAT0 A * read what D0 should be
D0=C * and reset D0
ST=0 0 * no return now
GOSBVL D=AVMS * needed by ADHEAD
GOVLNG ADHEAD * exit after adding string header
SAVE DAT0=C A * write to scratch
D0=D0+ 5 * move pointer to next area
RTN
a-mult GOSBVL A-MULT * mult a pair of 20 bit hex integer
RTNC * return on carry, carry set=ok
GOTO ERR * carry clear= overflow
STACK A=DAT0 A * read the number from scratch
D0=D0+ 5 * move pointer past the number read
D1=D1- 16 * make room on mathstack for the number
GOSBVL HDFLT * float the number
DAT1=A W * write the number to the stack
GOSBVL STR$00 * convert to string
GOSBVL XXHEAD * strip off header, sets D1 where we want it
RTN * go back
* Well, there we are. Clearly, there are some limitations on the values
* we can choose for a & b, since a^2+b^2 cannot exceed FFFFF, but this
* is hardly a problem. We hardly ever want values that high. The pedants
* can use BASIC for those rare ocasions.
* Happy Programming,
* Jack Elhay.