%%HP: T(3)A(R)F(.); @ by Mark Adler @ FACNUM (BYTES = 277.5, #74FFh) @ Given an integer, return its prime factorization as a list. @ For example, 16353 FACNUM returns { 3 3 23 79 }. \<< @ initialize factor list { } SWAP @ For this part of the program the stack is: n factorlist, where the two are @ kept so that the product of the list times n is the original integer. @ factor out 2's WHILE DUP 2 MOD NOT REPEAT 2 / SWAP 2 + SWAP END @ factor out 3's WHILE DUP 3 MOD NOT REPEAT 3 / SWAP 3 + SWAP END @ start factor search at 5 5 @ The stack is now: k n factorlist, where the second two are maintained as @ before, and k is the largest 5 mod 6 integer less than or equal to the @ last factor found (execpt initially when it is set to 5). @ search from k to sqrt(n) for factors---k must be 5 mod 6 WHILE OVER 1 \=/ REPEAT @ do while n is not one OVER \v/ FLOOR @ go up to the floor of the square root IFERR @ (divide by zero used as a loop breaker) FOR i @ look at factors that are 1 and 5 mod 6 IF DUP i MOD NOT THEN i 0 / END @ if 5 mod 6 divides n, then cause error IF DUP i 2 + MOD NOT THEN i 2 + 0 / END @ if 1 mod 6 divides n, then cause error 6 STEP THEN DROP @ got an error---trash the zero ELSE DUP @ end of loop---n divides n END @ after this, stack is: factor n factorlist ROT OVER + ROT ROT @ add factor to list (factor n factorlist') SWAP OVER / SWAP @ divide out divisor (factor n' factorlist') DUP 6 MOD 5 - 2 / + @ set k' to largest 5 mod 6 <= divisor END @ find next factor (k' n' factorlist') @ return list, dropping n and k DROP2 \>>