8-Bit Software Online Conversion

Prime Numbers - Listing

10REM" * P R I M A T E * 20REM 8 prime number programs: V.2. 30REM J.Davis - '96. 40MODE7 50VDU23,1,0;0;0;0; 60DIMP%(2000) 70DIMT%(300):DIMU%(300) 80PM$=" * P R I M A T E * " 90LIN$=CHR$(145)+STRING$(39,",") 100SP$=" Press SPACE to run program." 110PG$=" Program " 120P2$=" 2 is prime 1" 130Q2$=" 2 is prime 1" 140P3$=" 3 is prime 2" 150Q3$=" 3 is prime 2" 160P5$=" 5 is prime 3" 170Q5$=" 5 is prime 3" 180PRINTPM$ 190PRINT'" This is a collection of e ight little programs about prime number s. (There had to be eight of them, so I could use the name.) In 8BS-51 Peter Davy set us" 200PRINT" a challenge by a program to generate prime numbers which improved on the speed of the one in 8BS-50. This posed the question: Can it be twea ked to go" 210PRINT" faster? Well, yes. Programs 1,3,5 and 6 are concerned with speed usi ng trial" 220PRINT" division methods. The maximu m prime possible here is 2,147,483,6 47. (Don't wait up.) Program 8 is usele ss, but interesting - it uses Fermat 's Little Theorem." 230PRINTLIN$; 240PRINT" Each program has its own i nfo page, which appears when the progr am is selected from the menu. The programs can be called in any order." 250PRINT" ESCAPE at any time returns to menu." 260PRINTLIN$; 270PRINTSPC(17);"Press SPACE for Menu. "; 280G=GET:CLS 290ONERRORVDU23,1,1;0;0;0;:END 300VDU15:PRINTPM$ 310PRINT'TAB(14)" Menu " 320PRINT'" Program:" 330PRINTCHR$(145)STRING$(8,",") 340PRINT" 1) Skip evens,to sq.root." 350PRINT'" 2) One Liner." 360PRINT'" 3) Skip 3's." 370PRINT'" 4) As 3) + time/gap." 380PRINT'" 5) Composite - fixed diviso rs." 390PRINT'" 6) Save & use primes." 400PRINT'" 7) Test any number." 410PRINT'" 8) Fermat's Little Theorem. " 420PRINT'" ESC To Escape." 430PRINTLIN$; 440G$=GET$ 450ONERROR IFERR=17 CLS:VDU23,1,0;0;0; 0;:GOTO290 ELSEPRINT"ERROR at line ";ERL :END 460IF G$="1" THEN570 470IF G$="2" THEN750 480IF G$="3" THEN870 490IF G$="4" THEN1050 500IF G$="5" THEN1370 510IF G$="6" THEN1890 520IF G$="7" THEN2120 530IF G$="8" THEN2890 540ONERRORVDU23,1,1;0;0;0;:END 550GOTO440 560REM"  570CLS:PRINTPM$ 580PRINT'PG$"1 ":PRINT 590PRINT" This program, in principle , is the same as Peter's - it generat es a list of primes by trial division, leaving out even numbers as both the number to test to see if it's a prime, and the" 600PRINT" divisors, and it tests only to the square root of the number." 610PRINT" Here the program structure is simpler which, with a bit of extra h elp from using short (but uninformati ve) names for variables, makes the pro gram run about five times quicker. It gets to" 620PRINT" the 1000th prime (7919 - now burned into my subconscious) in 2mi n 26sec vs. 12min 33sec." 630PRINTLIN$;:PRINTSP$ 640G=GET:CLS 650REM" Program 1 660PRINTP2$:PRINTP3$ 670C%=2 680FORA%=5TO2^31-1 STEP2 690S%=SQR(A%) 700FORN%=3TOS% STEP2 710IFA%MODN%<>0 NEXT ELSE N%=S%:NEXT:N EXT 720C%=C%+1:PRINT" ";A%" is prime ";C% 730NEXT 740REM"  750CLS:PRINTPM$ 760PRINT'PG$"2 ":PRINT 770PRINT" In passing, since Program 1 was so short, I wondered if it coul d be written as a one-liner. It f ought back, kicking and screaming, but e ventually" 780PRINT" succumbed to a convoluted wa y of avoiding an IF statement. Th e line - leaving out the first two pr imes, is:" 790PRINT 800PRINT"CLS:A%=3:C%=2:REPEAT:A%=A%+2: S%=SQR(A%):FORN%=3TOS%STEP2:N%=N%+(S%-N% +4ANDA%MODN%=0):NEXT:IFN%<S%+4C%=C%+1:PR INT"CHR$(34);CHR$(130);CHR$(34)";A%"CHR$ (34);CHR$(133)"is prime"CHR$(129);CHR$(3 4)";C%:UNTIL0 ELSEUNTIL0" 810PRINT'" This actually runs slower than the first program, taking 3min 20sec to the 1000th prime, vs. 2min 26sec for Program 1. You can earn bro wnie points by writing a quicker one-li ner." 820PRINTLIN$;:PRINTSP$ 830G=GET:CLS 840REM" Program 2 850CLS:A%=3:C%=2:REPEAT:A%=A%+2:S%=SQR (A%):FORN%=3TOS%STEP2:N%=N%+(S%-N%+4ANDA %MODN%=0):NEXT:IFN%<S%+4C%=C%+1:PRINT" " ;A%" is prime ";C%:UNTIL0 ELSEUNTIL0 860REM"  870CLS:PRINTPM$ 880PRINT'PG$"3 ":PRINT 890PRINT" Getting more speed from th is sort of prime generator means testin g fewer numbers and/or using fewer n umbers to do each test. It turns out t hat the" 900PRINT" only way of adding numbers t hat gives a speed boost above just add ing 2's to each is adding 4,2,4,2... to the test number to skip multiples of 3. Trying to skip 5's means adding 6,4 ,2,4,2,4,6,"; 910PRINT" 2, which is slower than tria l divisions with 5. Patterns including 7 , 11 etc. are hopeless. Even adding 4, 2,4,2... to the divisor slows things dow n. (See Programs 5 and 6 for other d ivisors.)" 920PRINT" This program just adds the routine which skips multiples of 3 i n the test number to Program 1. It gets to the 1000th prime in 2min 6sec vs . 2m 26s." 930PRINTLIN$;:PRINTSP$ 940G=GET:CLS 950REM" Program 3 960PRINTQ2$:PRINTQ3$:PRINTQ5$ 970C%=3:Q%=2 980FORA%=7TO2^31-1 STEP2 990Q%=ABS(Q%-2):A%=A%+Q%:S%=SQR(A%) 1000FORN%=5TOS% STEP2 1010IFA%MODN%<>0 NEXT ELSE N%=S%:NEXT:N EXT 1020C%=C%+1:PRINT" ";A%" is prime ";C% 1030NEXT 1040REM"  1050CLS:PRINTPM$ 1060PRINT'PG$"4 ":PRINT 1070PRINT" This program is exactly th e same as Program 3, but with a couple of bits of extra information availab le. This is a display of:" 1080PRINT'" 1) Elapsed time (minus disp lay pause)." 1090PRINT" 2) The largest gap so far be tween two consecutive primes, the t wo primes, and their position number s." 1100PRINT'" This display appears auto matically each time there is a new la rgest gap, and can be called at any ti me when the program is running by press ing Space." 1110PRINTLIN$;:PRINTSP$ 1120G=GET:CLS 1130REM" Program 4 1140PRINTP2$:PRINTP3$:PRINTP5$ 1150C%=3:Q%=2 1160AP%=5:G%=5:FB%=0:TIME=0 1170FORA%=7TO2^31-1 STEP2 1180Q%=ABS(Q%-2):A%=A%+Q%:S%=SQR(A%) 1190FORN%=5TOS% STEP2 1200IFA%MODN%<>0 NEXT ELSE N%=S%:NEXT:N EXT 1210C%=C%+1:PRINT" ";A%" is prime ";C% 1220IFA%-AP%>G% G%=A%-AP%:LP%=AP%:L%=A% :CC%=C%:FB%=1:PROCtimegap 1230AP%=A% 1240IFINKEY$(0)=" " PROCtimegap 1250NEXT 1260" ** 1270DEFPROCtimegap 1280T%=TIME/100:PRINT:PRINT" TIME= ";T% DIV60"m";T%MOD60"s":PRINT 1290IFC%>217 AND FB%=1 FB%=0:VDU7 1300PRINT" LARGEST GAP SO FAR: ";G% 1310PRINT" From PRIME ";LP%" to ";L% 1320PRINT" At Numbers ";CC%-1" and ";CC % 1330PRINT 1340FORD=1TO4000:NEXT:TIME=TIME-200 1350ENDPROC 1360REM"  1370CLS:PRINTPM$ 1380PRINT'PG$"5 ":PRINT 1390PRINT" As there is no routine or pattern for adding numbers to the diviso r for more speed, another approach is n eeded." 1400PRINT" As the number being tested only has to be divided by primes, wri ting some of these into the program in creases the speed. In this program, 25 p rimes," 1410PRINT" from 5, are used as initial divisors. Logically, these would be st ored in a look-up table, but it runs q uicker if, thanks to the Copy key, ther e are 25 consecutive IF statements in stead." 1420PRINT" This is a composite progra m. The first 500 (ideally about 400 ) primes are generated using Program 3. Then the prime divisors take over . Note the speed increase at the 500th prime." 1430PRINT" 1000th prime: 1m44s vs. 2m6s - Prog.3. 5000th prime: 15m4s vs.21m25 s - Prog.3."; 1440PRINTLIN$;:PRINTSP$; 1450G=GET:CLS 1460REM" Program 5 1470C%=3:Q%=2 1480PRINTQ2$:PRINTQ3$:PRINTQ5$ 1490FORA%=7TO3571 STEP2 1500Q%=ABS(Q%-2):A%=A%+Q%:S%=SQR(A%) 1510FORN%=5TOS% STEP2 1520IFA%MODN%<>0 NEXT ELSE N%=S%:NEXT:N EXT 1530C%=C%+1:PRINT" ";A%" is prime ";C% 1540NEXT 1550Q%=-1:A%=A%-2 1560Q%=Q%*-1:A%=A%+3+Q% 1570IFA%MOD5=0 THEN1560 1580IFA%MOD7=0 THEN1560 1590IFA%MOD11=0 THEN1560 1600IFA%MOD13=0 THEN1560 1610IFA%MOD17=0 THEN1560 1620IFA%MOD19=0 THEN1560 1630IFA%MOD23=0 THEN1560 1640IFA%MOD29=0 THEN1560 1650IFA%MOD31=0 THEN1560 1660IFA%MOD37=0 THEN1560 1670IFA%MOD41=0 THEN1560 1680IFA%MOD43=0 THEN1560 1690IFA%MOD47=0 THEN1560 1700IFA%MOD53=0 THEN1560 1710IFA%MOD59=0 THEN1560 1720IFA%MOD61=0 THEN1560 1730IFA%MOD67=0 THEN1560 1740IFA%MOD71=0 THEN1560 1750IFA%MOD73=0 THEN1560 1760IFA%MOD79=0 THEN1560 1770IFA%MOD83=0 THEN1560 1780IFA%MOD89=0 THEN1560 1790IFA%MOD97=0 THEN1560 1800IFA%MOD101=0 THEN1560 1810IFA%MOD103=0 THEN1560 1820S%=SQR(A%) 1830FORN%=105TOS% STEP2 1840IFA%MODN%=0 N%=S%:F%=1 1850NEXT 1860IF F%=0 C%=C%+1:PRINT" ";A%" is pri me ";C% ELSE F%=0 1870GOTO1560 1880REM"  1890CLS:PRINTPM$ 1900PRINT'PG$"6 ":PRINT 1910PRINT" This program, in principle , is the most efficient of the lot. I t takes the idea in Program 5 to its logical conclusion by always using o nly primes as divisors. It saves the pr imes it" 1920PRINT" finds in an array and uses t hem as divisors. It's always well a head of the game, with more saved at any time than it needs." 1930PRINT" This program is relatively slow at first with its extra number shuffling, taking 2min 36sec to the 100 0th prime, but the tortoise beats the h are on an overnight run, taking an hou r less to the 50,000th prime." 1940PRINTLIN$;:PRINTSP$ 1950G=GET:CLS 1960REM" Program 6 1970PRINTP2$:PRINTP3$:PRINTP5$ 1980A%=5:C%=3:F%=0 1990P%(3)=5:Q%=1 2000Q%=Q%*-1:A%=A%+3+Q% 2010S%=SQR(A%):N%=2 2020REPEAT 2030N%=N%+1 2040IFA%MODP%(N%)=0 S%=0:F%=1 2050UNTILP%(N%)>S% 2060IFF%=1 F%=0:GOTO2000 2070C%=C%+1 2080IFC%<2001 P%(C%)=A% 2090PRINT" ";A%" is prime ";C% 2100GOTO2000 2110REM"  2120CLS:PRINTPM$ 2130PRINT'PG$"7 (1) ":PRINT 2140PRINT" This program allows you to test any number, up to 2,147,483,647 (2^31-1), to see if it is a prime. If it isn't, it will give its factors. Th is usually takes a few seconds, but can take up to a minute." 2150PRINT" You can enter any number, odd or even, but if it is larger th an the one above, the program will cras h." 2160PRINT" There are three sorts of i nput you can use:" 2170PRINT" 1) Enter any number." 2180PRINT" 2) Enter just 'R'.This produ ces & tests random numbers up to 2 bi llion." 2190PRINT" 3) Enter 'R' plus a number, such as R654321. This produces an d tests random numbers up to the number." 2200PRINTLIN$; 2210PRINT" 2) & 3) run till stopped wit h Space." 2220PRINTLIN$; 2230PRINTSPC(15)"Press SPACE for page 2 ."; 2240G=GET:CLS:PRINTPM$ 2250PRINT'PG$"7 (2) " 2260PRINT'" And, if you're a real glu tton for punishment, you'll be in ho g heaven with the 'All' options. The se allow you test consecutive number s, from any" 2270PRINT" starting point, almost till doomsday." 2280PRINT" 4) Enter just 'A'. This prod uces and tests all consecutive number s from 10." 2290PRINT" 5) Enter 'A' plus a number, which gives consecutive numbers from tha t number." 2300PRINT" Like the random numbers, t hese run continuously till stopped wi th Space." 2310PRINTLIN$; 2320PRINT" For maximum speed, enter ' X' after any input, such as A12345678 X. This cancels the (rather pretty) running display of trial divisors. T his has to" 2330PRINT" be done after each new input . You now get a cursor with large numb ers, to show it hasn't gone to sleep ." 2340PRINTLIN$;:PRINTSP$; 2350G=GET:CLS 2360REM" Program 7 2370PRINTPM$ 2380PRINT" ENTER: Number; R; R+no.; A; A+no.; (+X)"; 2390PRINTLIN$ 2400FR%=0:FA%=0:AL%=10 2410VDU23,1,1;0;0;0; 2420INPUT" Number to test? "IN$ 2430CLS:VDU23,1,0;0;0;0;:PRINTPM$ 2440IFRIGHT$(IN$,1)="X" IN$=LEFT$(IN$,L EN(IN$)-1):D%=1 ELSE D%=0 2450IF LEFT$(IN$,1)<>"A" THEN2510 2460FA%=1 2470IFLEN(IN$)>1 AL%=VAL(RIGHT$(IN$,LEN (IN$)-1)) 2480IFAL%<10 AL%=10 2490ALL%=AL%:AL%=AL%-1 2500GOTO2530 2510IF LEFT$(IN$,1)<>"R" A%=VAL(IN$):GO TO2610 2520IF LEN(IN$)=1 R%=2000000000 ELSE R% =VAL(RIGHT$(IN$,LEN(IN$)-1)) 2530FR%=1 2540CLS:PRINTPM$ 2550PRINT" Press: SPACE for new run; P/ P Pause/Go."; 2560PRINTLIN$; 2570IFFA%=1 PRINT" All numbers from:":P RINT'" "STR$(ALL%):GOTO2600 2580PRINT" Random numbers up to:":PRINT 2590PRINT" "STR$(R%) 2600IFFA%=0 A%=RND(R%) ELSE AL%=AL%+1:A %=AL% 2610IFA%<2 A%=2 2620IFD%=1 ANDA%>10^6 VDU23,1,1;0;0;0; 2630PRINT'" Number being tested:" 2640PRINT'" "STR$(A%) 2650PRINT'" Factors: Testing:":PRINT 'SPC(9); 2660M%=3:Z%=0:AA%=A%:F%=0:TIME=0 2670IFA%<4 THEN2760 2680IFA%MOD2=0 A%=A%DIV2:VDU11:PRINT'2; " ";A%:GOTO2680 2690S%=SQR(A%) 2700VDU11:PRINT 2710FORN%=M%TOS% STEP2 2720IFD%=0 PRINTN%:VDU11 2730IFA%MODN%=0 A%=A%DIVN%:VDU11:PRINT' N%;" "A%:Z%=1:M%=N%+2:N%=N%+(S%ANDA%MO DN%<>0):GOTO2730 2740NEXT 2750IFZ%=1 Z%=0:GOTO2690 2760VDU23,1,0;0;0;0; 2770IFA%=AA% PRINT" ":PRINT'" No Fact ors: Time=";INT(TIME/100)+1;"sec. ":P RINT'" "STR$(A%)" is a prime number.":PR INTLIN$;:FORD=1TO5000:NEXT:GOTO2800 2780IFA%>1 AND A%<AA% VDU11:PRINT'A% 2790VDU11:PRINT'CHR$(145)",,,,,,,,,,," 2800IFFR%=0 GOTO2860 2810FORD=1TO5000:NEXT 2820G$=INKEY$(0) 2830IFG$="P" PRINT'" PAUSE ":G=GE T:G$="" 2840IFG$=" " G$="":CLS:GOTO2370 2850GOTO2540 2860PRINT'''" Press SPACE for new run." 2870G=GET:CLS:GOTO2370 2880REM"  2890CLS:PRINTPM$ 2900PRINT'PG$"8 (1) ":PRINT 2910PRINT" Fermat's Little Theorem sa ys that, with P = a prime number and A = any number not divisible by P, t hen:" 2920PRINT" A^(P-1)MODP=1" 2930PRINT" For example, taking A as 2 , and P as 1783 (which is a prime), the n:" 2940PRINT" 2^1782 MOD1783=1" 2950PRINT'" Well, there are two probl ems here. The first is that a random scattering of numbers, for a given A, will give 1" 2960PRINT" in the equation, even though they are non-primes, so it can't be u sed to generate a true list of prim e numbers." 2970PRINT" The second problem is that the number has to be used as a bloomin' EXPONENT - my Beeb went belly-up just at the thought of it. I tickled its tummy, and it revived a bit." 2980PRINTLIN$; 2990PRINTSPC(15)"Press SPACE for page 2 ."; 3000G=GET:CLS 3010PRINTPM$:PRINT'PG$"8 (2) ":PRINT 3020PRINT" Direct calculation of the example above, which would have to b e done to complete accuracy, would mea n working with numbers about 537 digit s long." 3030PRINT" Hmmm... Is there a way aroun d this? Mercifully, yes. We don't ac tually care what 2^1782 is. What we care about is remainders." 3040PRINT" It turns out that breaking it up into tiny bits, multiplying the r emainders, breaking that up etc. does t he trick." 3050PRINT" This is a dual program.It uses Fermat to generate primes and so-ca lled pseudo -primes, and checks each wit h trial division. The non-primes are shown." 3060PRINT" Speed is not a consideration . The largest number that can be t ested is 46,339. You can change base A at the start, which gives different results." 3070PRINTLIN$;:PRINTSP$; 3080G=GET 3090AA%=2 3100CLS:PRINTPM$ 3110PRINT'" As the program runs, the no n-primes are displayed automatically. Th ese are stored, and a list can be c alled at any time by pressing 'N'. The p rogram then continues." 3120PRINT" Pressing Space returns here. " 3130PRINTLIN$ 3140PRINT" Base A is currently ";AA% 3150PRINT'" To run with this, just pres s Return, or enter a new number." 3160PRINTTAB(0,17);LIN$ 3170VDU23,1,1;0;0;0; 3180PRINTTAB(0,15);:INPUT" Base A ? "Z% 3190IFZ%<>0 AA%=Z% 3200VDU23,1,0;0;0;0;:CLS 3210REM" Program 8 3220PRINTQ2$:PRINTQ3$ 3230REM" * Fermat Routine * 3240P%=3:C%=2:K%=0 3250P%=P%+2:Q%=P%-1 3260IFP%=46339 THEN3660 3270A%=AA%:X%=1 3280M%=(Q%)MOD2 3290Q%=(Q%)DIV2 3300IFM%=0 THEN3330 3310X%=X%*A% 3320X%=X%MODP% 3330A%=A%^2 3340IFA%>=P% A%=A%MODP% 3350IFQ%=1 THEN3370 3360GOTO3280 3370B%=A%*X% 3380R%=B%MODP% 3390IF R%=1 C%=C%+1:PRINT" ";P%;" is pr ime ";C%:GOTO3420 3400GOTO3250 3410REM" * * * * 3420G$=INKEY$(0) 3430IFG$="N" PROCprint 3440IFG$=" " THEN3100 3450S%=SQR(P%) 3460FORN%=3TOS% STEP2 3470IFP%MODN%<>0 THEN3530 3480K%=K%+1 3490T%(K%)=P%:U%(K%)=C% 3500PRINT'" ";P%;" is not a prime. (";K %;")":PRINT 3510FORD=1TO5000:NEXT 3520N%=S% 3530NEXT 3540GOTO3250 3550" ** 3560DEFPROCprint 3570PRINT 3580IFK%>22 VDU14:PRINT" Press SHIFT to scroll.":PRINT 3590FORL%=1TOK% 3600PRINT" ";L%;") ";T%(L%);" (";U%(L%) ;")" 3610NEXT 3620PRINT'" Press SPACE to continue." 3630G=GET:VDU15:PRINT 3640ENDPROC 3650" ** 3660PRINTLIN$:PRINT" LIMIT OF PROGRAM." 3670PRINT'" Press 'N' for list of non-p rimes. ESC for menu." 3680G$=GET$:IF G$="N" PROCprint:GOTO367 0 ELSEGOTO3680