50g Mini-Challenge: Number of positive divisors of x! +- HP Forums (http://www.hpmuseum.org/forum) +-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html) +--- Forum: General Forum (/forum-4.html) +--- Thread: 50g Mini-Challenge: Number of positive divisors of x! (/thread-9195.html) |
50g Mini-Challenge: Number of positive divisors of x! - Joe Horn - 09-29-2017 06:49 PM The HP 50g program << ! DIVIS SIZE >> returns the number of positive divisors of the input factorial. However, this brute-force program becomes impossibly slow for medium-sized inputs, and runs out of memory for any input that's interestingly large. Just look how this slows down: << 12 ! DIVIS SIZE >> returns 792 in 6.1 seconds << 13 ! DIVIS SIZE >> returns 1584 in 17.5 seconds << 14 ! DIVIS SIZE >> returns 2592 in 39.3 seconds << 15 ! DIVIS SIZE >> returns 4032 in 86.2 seconds! (Unrelated note: Prime's CAS returns 4032 for size(idivis(15!)) in 0.7 seconds) The winner of this challenge will be the 49G/49g+/50g RPL program that returns the exact number of positive divisors of X! the fastest. Testing will focus on large inputs. Although half the fun of this challenge will consist in thinking up different ways of doing it (obviously avoiding the factorial and DIVIS functions), some algorithmic hints can be found here if you totally get stuck: https://oeis.org/A027423 Many thanks to Gerald H for his many OEIS-related postings and programs which inspired this mini-challenge. RE: 50g Mini-Challenge: Number of positive divisors of x! - Thomas Okken - 09-29-2017 08:48 PM I realize that this doesn’t qualify since it’s a 42S program, but I couldn’t resist: Code: 00 { 67-Byte Prgm } Constant memory use; run time something like O(n*sqrt(n)), I think, but that analysis is harder than writing the program. :-) RE: 50g Mini-Challenge: Number of positive divisors of x! - Thomas Okken - 09-30-2017 09:01 AM HP-67: 52 → 8087040000 in 69 s. (I really should get that card reader restored. It’s been 40 years since the last time I used a calculator that would forget everything when you turned it off!) UPDATE: HP-25: 52 → 8087040000 in 54 s. :-) Code: 01 23 00 STO 0 RE: 50g Mini-Challenge: Number of positive divisors of x! - Thomas Okken - 09-30-2017 10:33 AM My algorithm is based on the prime factorization of n!. When a number has prime factorization Π(i=1,j,p[i]^k[i]), i.e. it is the product of j distinct primes and each prime p[i] occurs k[i] times in the factorization, then the number of divisors is Π(i=1,j,k[i]+1). To find this prime factorization of n!, realize that it can only contain primes that are less than or equal to n, so the search space is pleasantly small. And how often does a prime p occur in n!? Answer: floor(n/p) of the factors 1, 2, 3, ... , n are divisible by p; floor(n/p^2) are divisible by p^2, etc. Keep dividing n by p and rounding toward zero, until you reach zero; the sum of all the intermediate results equals the exponent k[i] of the prime p[i], and the number of possible contributions of p[i] to divisors of n! is thus k[i]+1. Multiply all those k[i]+1 factors together, and you end up with the total number of divisors. The first part of the program finds primes using a simple but reasonably efficient algorithm, only checking divisors <= sqrt(p). Hence the O(n*sqrt(n)) part of my time estimate. Once a prime has been found, the repeated divisions take O(log(n)). Working this out more accurately would require dusting off my rusty calculus skills... Maybe later. :-) RE: 50g Mini-Challenge: Number of positive divisors of x! - Gerald H - 09-30-2017 11:29 AM Thank you, Thomas. Here a SysRPL programme following Thomas' suggestion which correctly processes 100 in 0.5604s a definite improvement on my first attempt, and bestfit gives the input time relationship as linear. Size: 124. CkSum: # 6E3Ch Code: :: RE: 50g Mini-Challenge: Number of positive divisors of x! - Joe Horn - 09-30-2017 03:17 PM Wow, very impressive! Two quick questions: (1) FPTR 6 119 (^RADDext) and FPTR 6 118 (^QAdd) both resolve to address 6:5253B, so they are really identical functions. Is there a reason that you prefer using ^RADDext instead of ^QAdd in this program? Same question for the identical functions ^RMULText and ^QMul. (It might help if I knew what the "Q" and the "R" stand for in those function names.) (2) Your second System RPL program evaluates an input of 100 in half a second, so when I keyed up the same program in User RPL (exactly the same, step-by-step, just in URPL), I expected it to run slower, but it ran MUCH slower than I anticipated. URPL is always slower than SysRPL, but this difference seems crazy: 320 SysRPL --> 1.5 seconds 320 URPL --> 18.6 seconds! Why is this SysRPL program so much faster? Is it simply because SysRPL is always faster, especially when looping is involved? Always eager to learn! Thanks in advance for your insights! RE: 50g Mini-Challenge: Number of positive divisors of x! - Gerald H - 09-30-2017 04:31 PM The User programme below took 14.9141s to process 320. To question 1, ^RMULText etc is just habit, to q 2 I have surely less idea than you. How great a speed improvement occurs is variable, loops do seem to go much faster in Sys. Code: « 1 SWAP 0 |