TIP: Click on subject to list as thread! ANSI
echo: science
to: ALL
from: DAVID WILLIAMS
date: 2004-08-15 14:18:30
subject: Pythagorean triples

Path: number1.nntp.dca.giganews.com!border2.nntp.ams.giganews.com!nntp.giganews.com!news.zanker.org!zen.net.uk!dedekind.zen.co.uk!newsfeed.esat.net!news2.telebyte.nl!news.icp.pl!newsfeed.atman.pl!news.intercom.pl!f124.n480!f127.n480!f112.n480!f200.n2432!f605.n774!f500.n123!f514.n250!not-for-mail
Newsgroups: fido.science
Distribution: fido
From: DAVID WILLIAMS 
Date: Sun, 15 Aug 04 14:18:30 +0200
Subject: Pythagorean triples
Message-ID: 
Organization: The Bayman BBS,Toronto, (416)698-6573 - 1:250/514
 111
 300
Lines: 158
Xref: number1.nntp.dca.giganews.com fido.science:316

->  DW> ->  DW> ->      SUB Delay (t%) 
 
->  DW> ->  DW> ->         StopTime& = TIMER + t% 
->  DW> ->  DW> ->         DO 
->  DW> ->  DW> ->            IF LEN(INKEY$) THEN EXIT DO 
->  DW> ->  DW> ->         LOOP UNTIL (StopTime& - TIMER) MOD 86400 <= 0 
 
->  DW> ->  DW> ->      END SUB 
 
->  DW> ->  DW> I usually use rather simpler code: 
 
->  DW> -> good! because that code fails at midnight. 
 
->  DW> Maybe. I'm not sure. I never use MOD with negative numbers. The way 
->  DW> BASIC does it doesn't make sense to me. 
 
-> at midnight timer goes back to 0 and stoptime will be more than 86400 
-> so the result of the subtraction will be more than 0 and so will the 
-> result of the mod... hmm except when it comes out at 86400 exatly... 
 
-> ok it'll work. 
  
By good luck, rather than good management! 
  
It might be better to write: 
  
Stoptime% = (TIMER + t%) MOD 86400 
DO WHILE TIMER  Stoptime% 
  IF LEN(INKEY$) THEN EXIT DO 
LOOP 
  
Then the thing isn't doing MODs all the time. But it will still handle 
only integer numbers of seconds. 
  
-> some basics don't have exit for. 
-> the end sub should fix that anyway. 
 
-> Jasen 
  
Maybe. Maybe not. What "should" happen is sometimes not the same as 
what "does" happen. 
  
In ye olde days, we used to write stuff like: 
  
FOR X = A TO B 
 ...... 
 IF  THEN X = B: NEXT: GOTO  
 ...... 
NEXT 
  
The "X = B: NEXT" would terminate the loop and clean the stack, so the 
GOTO could jump out of the loop without leaving stuff behind that might 
cause trouble later. But BASICs nowadays tend to freak out if there are 
two or more NEXT instructions for one FOR, even if only one of them is 
executed, so the above bit of code *has* to be replaced with an EXIT 
FOR. 
  
Incidentally, I found a way to streamline the triples program a bit 
further. Now, there are *no* SQRs in any of the loops. SQR is executed 
only three times altogether, in the initialization. SQR is a very slow 
operation compared with simple arithmetic, even floating-point 
arithmetic, so this does make the program significantly faster. 
  
                        dow 
  
--------------------------------------------------------- 
  
' Pythagorean Triples 
  
' David O. Williams. 2004 
  
' Calculates and prints integer triples, A, B, C, such that 
' A 1), and A^2 + B^2 = C^2. 
' List is printed in order of increasing A, then of B. 
' A counter of triples is also shown. 
  
DECLARE FUNCTION NoComFacs& (X&, Y&) 
DECLARE SUB PrintOut () 
DECLARE SUB Even () 
DECLARE SUB Odd () 
  
DEFLNG A-Z 
  
Mn = 3' minimum value of smallest number in triple 
Mx = 10000' maximum value of smallest number in triple 
  
DIM SHARED A, B, C  ' three numbers in triple (increasing order) 
DIM SHARED N, Z#, Q, R ' counter, utility factor, and loop limits 
  
N = 0 
Z# = SQR(2) - 1 
Q = INT(SQR(Z# * Mn)) - 1 OR 1 
R = INT(SQR(Z# * Mn / 2)) 
  
CLS 
  
FOR A = Mn TO Mx 
  SELECT CASE A MOD 4 
    CASE 0: Even 
    CASE 1, 3: Odd 
    ' case 2 produces no valid triples 
  END SELECT 
NEXT 
  
END 
  
SUB Even ' handles cases when A is even (and a multiple of 4) 
  S = A \ 2 
  T = R + 1 
  IF T * T < Z# * S THEN R = T 
  FOR F = R TO 1 STEP -1 
    G = S \ F 
    IF G * F = S THEN 
      IF (F XOR G) AND 1 THEN 
        IF NoComFacs(F, G) THEN 
          E = F + G 
          D = G - F 
          B = D * E 
          C = (E * E + D * D) \ 2 
          PrintOut 
        END IF 
      END IF 
    END IF 
  NEXT 
END SUB 
  
FUNCTION NoComFacs (X, Y) ' non-zero if X and Y have no common factors 
  U = Y 
  V = X 
  DO WHILE V > 1 
    W = U MOD V 
    U = V 
    V = W 
  LOOP 
  NoComFacs = V 
END FUNCTION 
  
SUB Odd ' handles cases when A is odd 
  T = Q + 2 
  IF T * T < Z# * A THEN Q = T 
  FOR D = Q TO 1 STEP -2 
    E = A \ D 
    IF E * D = A THEN 
      IF NoComFacs(D, E) THEN 
        B = ((E + D) * (E - D)) \ 2 
        C = (E * E + D * D) \ 2 
        PrintOut 
      END IF 
    END IF 
  NEXT 
END SUB 
  
SUB PrintOut 
  N = N + 1 
  PRINT N, , A, B, C 
END SUB 
  
---------------------------------------------- 

SOURCE: echoes via archive.org

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.