EDIT: Yes, it is trial division with a sieve. I also have a SQUFOF program, which takes around O(∜N) time rather than O(√N) for trial division, but it's only faster with large numbers, which I haven't figured out how to use yet.

]]>(Also close that comment on line 1 x]) ]]>

EDIT: Here's my modified version of PrimeC1.

` ``/* L1 holds the factors, and L2 is the list of numbers relatively prime to 210. A is a possible divisor, B is the index for batch dividing, and C saves B so the Goto trick can be used. */ ClrHome Prompt X startTmr→T DelVar CClrList L₁ cumSum({11,2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2→L₂ For(A,2,13 //Can probably be 7? In any case, 13 is not much slower for large semiprimes but faster for 11^11 and such. Lbl 1 While not(remainder(X,A //"While" to check for small factors that occur more than once X/A→X A→L₁(1+dim(L₁ Output(8,1,A End End //exits first For loop, but also the second one when jumping back //Main loop for batch dividing For(B,C,sqrt(X),210) If min(remainder(X,B+L₂ End L₂+B min(Ans+E9remainder(X,Ans→A //the smallest divisor if there is one, and something very large if not B→C X→B //Now B>>sqrt(X), so we will get out of the For() we're still in at the above End. If A²≤X Goto 1 If X>1 X→L₁(1+dim(L₁ Disp "TIME:", checkTmr(T Disp dim(L₁ Pause L₁`

It takes 9 seconds to factor 500259937 into 10007 and 49991.

]]>` ``If not(min(remainder(X,B:Return //should be If not(remainder(X,B:Return`

It takes about four seconds to return prime for X=8675309.

]]>` ``Prompt X 0 If not(fPart(.5X:Return //First we check if there are divisors less than 211, including 2, 3, 5, and 7. //The reason we don't use the list the first time is so that a number like 191 won't be divided by 191—it'll stop at 13. For(B,3,min(211,√(X)),2) If not(remainder(X,B:Return End //Now we don't need to check any possible divisors that are divisible by 2, 3, 5, or 7. //We can just use the list, and keep shifting it up by 210 to catch all the possible divisors. For(B,210,√(X),210) //keep the parenthesis on for If speed. Remember that √(X) is only computed once, at the start of the For loop. If min(remainder(X,B+L₁ //if ALL of the remainders are greater than zero; in other words, if there's no divisor End //Executed if the If is true, of course. As long as B<sqrt(X) it will jump back to the For( for the next batch of numbers. //This way the parser doesn't need to skip a :Return every time it doesn't find a divisor. B>√(X //This returns 1 if the loop went all the way, and 0 if it ended prematurely because it didn't see an End. //Since there's no End here, the program will forget it was in a loop (if it was) and quit with the answer.`

Without comments, it looks like this:

` ``Prompt X 0 If not(fPart(.5X:Return For(B,3,min(211,√(X)),2) If not(remainder(X,B:Return End For(B,210,√(X),210) If min(remainder(X,B+L₁ End B>√(X`

Yes, the parser works like this with the If… :End. It was strange to me too.

There's a slightly better way to try the numbers below 210, but I can't remember it right now. Also, I may have missed an edge case.

Try this with X=8675309. I don't have my calculator with me, but it should return 1 in less than five seconds.

EDIT: You probably knew this, but remainder(X,M can be replaced with fPart(X/M.

Also, if you want to turn this into a prime factorization program, you can use

` ``min(Ans+E9remainder(X,Ans`

where Ans is L₁+B, to find which number was the divisor. This works because all of the other numbers in the list will have something really large added to them, so the least one will be the divisor.

EDIT AGAIN: Credit to someone named "Anders Tiberg" and their program "PRIMEC1", which can be found on ticalc, which has some of these ideas in it.

]]>Another also, this subroutine relies on the answer being stored in the Ans variable. If I store anything inside the program then Ans is overwritten when that is stored, thus erasing the answer or requiring me to do a equivalency check.

Also, code please. I wanna see it do a primality check on a 10**8 number in 8 seconds. That'd be cool. ]]>

EDIT: Some smaller tricks for that last 20% or so of speed (less if you're using a list) include using If [not divisible]:End:B>√(X) rather than If[divisible]:Return:End:— this saves a not( — and, if your calculator is an 84+, using remainder( rather than a division and an fpart(.

]]>If you want a program which will check the primality of a number quickly and easily regardless of the size of the number, use For( loops.

` ``Input "Number:",X 0 If not(fPart(X/2:Return For(B,3,sqrt(X),2) If not(fPart(X/B:Return End 1`

(Kudos again to Timtech who provided the idea of checking only odd numbers after the initial even verification.) ]]>

A user-defined list name can't start with a number.

]]>is the same as

BfPart(A/B)

or

B((A/B)-int(A/B))

I feel like you should know this, its been mentioned to you at least twice, and I think you've even used it before in your own code…

]]>Checks if ans is prime

Returns 1 if prime, 0 if composite

` ``0≠min(remainder(Ans,seq(A,A,2,1+√(Ans`

it works very well

]]>augment (L1,{b-> L1w ]]>

It does 6-digit numbers in 5 seconds; 7-digit numbers in ~10 seconds. (When they are prime. Otherwise, it's much faster depending on how quickly it finds a factor.)

` ``Prompt X While fPart(X)≠0 or X≤0 Disp "USE INTEGER > 0" Prompt X End If X=1 Then Disp "1 IS NOT PRIME." Stop End If (X)≥4 Then 2→Y If fPart(X/Y)=0 Then Disp {Y,X/Y} Stop End 3→Y If fPart(X/Y)=0 Then Disp {Y,X/Y} Stop End While √(X)≥Y Y+2→Y If fPart(X/Y)=0 Then Disp {Y,X/Y} Stop End End End Disp "PRIME"`

Also, did you not see that it DISPLAYS 1 or 0?

]]>` ``Input N:0:If N>1 and not(fPart(N:2=sum(seq(not(fPart(N/I)),I,1,N:Ans`

At 42 bytes, this might be one of, if not THE smallest. However, it is not as fast as it could be. ]]>

` ``:Prompt A :If fPart(A :Return :DelVarB{1→L₁ :Repeat A=1 :B+2-(B=2→B :While not(fPart(A/B :augment(L₁,{B→L₁ :A/B→A :End :End`

I suppose if I did a for loop and and If to check when A=1, I could've used Ans for A. Though the optimization of looping every two would be more difficult. With this method, since I'm dividing it by a prime until it doesn't contain that factor anymore, there's no way a composite is accidentally added; the number is no longer a factor of any of the potential composite… i.e. with 88, the number becomes 11 with the loop of the 2, and 4 and 8 are not accidentally added. Only primes are added with this code, without the use of a prime checking loop.

Primality Checker

` ``:Prompt A :If fPart(A :Return :A=2 or A=3 :If fPart((A-1)/6) and fPart((A+1)/6 // deals with factors 2 and 3 :Return :For(B,5,√A),2 :If not(fPart(A/B :Return :End :1`

Prime factorizer

Input "NUM?",A

0->dim(L1

While A≠1

B+2-(B=2

If B+1>√A:A // the key to exiting the loop on time. It now enters the last loop and saves the last factor to the list. The +1 at B+1

Ans->B keeps it from doing an iteration too many.

While not(fpart(A/B

A/B->A

B->L1(1+dim(L1

End

End

Primality checker

Input "NUM?",A

√A->B

2-not(fpart(B //start at two UNLESS the square root is an integer

While Ans≤B and fpart(A/Ans

Ans+2-(Ans=2

End

Ans>B // display a 1 or 0 for Prime or Composite

` ``ClrHome SetUpEditor L1 {1→L1 Input "INPUT NUMBER:",N Disp "FACTORING... While not(fPart(.5N .5N→N 2→L1(1+dim(L1 Disp 2 End 3→A √(N→D While N>1 and A≤D If fPart(N/A Then A+2→A Else N/A→N A→L1(1+dim(L1 √(N→D End End N→L1(1+dim(L1 L1`

For a code break down:

` ``SetUpEditor L1 {1→L1`

This part just sets up L1. The SetUpEditor will unarchive L1 if it is archived and create it if it doesn't exist.

` ``Input "INPUT NUMBER:",N Disp "FACTORING...`

Self explanatory.

` ``While not(fPart(.5N .5N→N 2→L1(1+dim(L1 End`

This basically divides out all of the 2s as a special case. This way, we know that all the rest of the factors must be odd, so we can skip through the trial divisions 2 at a time.

` ``3→A √(N→D`

Set up A as the number against which to divide, and D as the upper limit for A. So for example, if N=97, We only need to test prime numbers up to about 9.848857…

` ``While N>1 and A≤D`

If N is ever 1, we have found all of the factors. As well, if A>D, then that means we have past our upper bound for potential factors.

` ``If fPart(N/A Then A+2→A`

If A doesn't evenly divide N, then it will leave stuff after the decimal. So then fPart(N/A will return a non-zero result and we know that we have to check the next possible factor.

` ``Else N/A→N A→L1(1+dim(L1 √(N→D End`

Otherwise, we divide out the factor of A, append A to our list, then set our new bound for D.

` ``End N→L1(1+dim(L1 L1`

Finally, we just append our last value for N and then leave L1 in Ans (so it will get displayed on exit). ]]>

(I'm new here, do I post the code verbatim? If not, I can put it into pastebin)

` ``ClrHome Disp "Enter the desired number." Disp "UPPER LIMIT=238" (comment: this was added after someone complained they couldn't factor something high, I think it was 6969 because they were immature) Prompt F Disp "Please wait." Disp "Finding factors..." ClrList L1 1 sto> A 0 sto> L Lbl L F-A sto>G If G=0 Then: :Goto X Else: : F/G sto> B round (B,0) sto> T If TG=F Then: :L+1 sto> L :B sto> L1(L) :A+1 sto> A :Goto L Else: :A+1 sto> A :Goto L Lbl X If L1(1)=F Then: :Disp "Number is prime." Else: :Disp "All factors found." :Disp "Check STAT>Edit to view." :Disp "Factors in list L1."`