Decomposing a Factorial into Large Factors
terrytao.wordpress.com
terrytao.wordpress.com
The "naive" way
100!= 2*3*4*...*99*100
Obviously t(100) > 1. If we can get rid of the single 2, we know that t(100) > 2. If you multiply the whole thing by 2/2 (=1), 100! = (2/2)*2*3*4*...*50*...99*100
= (2*2/2)*3*4*...*50*...99*100
= (4/2)*3*4*...*50*...99*100
= 4*3*4*...*50*...99*(100/2)
= 3*4*4*...*50*50*...99
We can continue with t(100) > 3 by multiplying by 3/3 and pairing it with 99, i.e. 99*3*(3/3) = (99/3)*3*3 = 33*9 yielding 100! = 4*4*5*...*9*9*10*..*33*33*...*50*50...*97*98
However, once we get to t(100) > 4, trying to get rid of 4, we have to skip 98 since its not divisible by 4. The other problem is we have two 4s... If we had instead using 98 for getting rid of 2, we can then use 100, and 96 for the other 4. This is our first "gotcha" for the naive algorithm of always picking the largest number, which seems intuitive at first glance.Now if we test all possibilities starting with 2, we get 48 choices for the dividing 2 (even numbers > 2, not including 2 which will not increase t(100) beyond 2. Then ~33 choices for dividing 3 (depending if our div of 2 resulted in a factor of 3), ~25 for 4, But notice since we now have two 4s, we have to do it twice, so its 25*24 choices for getting rid of 4.*
You can’t replace 2*100 with 50, it has to be 4*50. But there’s no reason you have to divide by 2 at all - why not replace 2*99 with 6*33?
The basic idea is to "pair" the lowest numbers with the highest ones - sort of pushing everything towards the middle values
Like I said, its naive greedy and non-optimal - otherwise time would be linear.
A straightforward greedy approach will see those final buckets differing by factors of around 2. Which is a lot worse than Terry's current approach.
This really is a knapsack problem.
The first one I tried did poorly: I start with a goal t*, and append all remaining factors of N!, starting with t* and increasing greedily. That terminates in a very suboptimal place, where you're left with a bunch of large prime factors p_i < t*, such that all pairs p_i * p_j >> t* ("much greater than") — there's a large amount of wasted "slack". The optimal solution should probably pair the largest primes with small multipliers.
I'm curious what other people have tried!
It’s a bit unfortunate, because you’d think it meant iterating the factorial, so 3!! = 720, etc. But there are basically no situations where you want to do that.
There is. It is N! divided by the product of all even numbers up to N.
>No; in fact, in Guy’s article on this problem, he notes that there is a jump of 2 from t(124)=35 to t(125)=37
Huh. Can we actually prove t(N) is monotonic? Jumps like that seem like they could be one-offs in some cases.
As the post states, writing N! as a product of factors is equivalent to writing log(N!) as a sum of those factors' logarithms. So log(t(N)) is the smallest bin size such that the factors all "fit" into N bins of that size.
This computation is simple to describe and implement, it's just inefficient because there's a combinatorial explosion of possible ways to pack factors into bins. It's an instance of the knapsack problem which is NP-complete.
import math
factorize = lambda N, number_of_factors: [(factor,) + rest for factor in range(1, N+1) if N % factor == 0 for rest in factorize(N//factor, number_of_factors-1)] if number_of_factors > 1 else [(N,)]
t = lambda N: max(min(factors) for factors in factorize(math.factorial(N), N)) 1! = 1
2! = 1 * 2
3! = 1 * 2 * 3
4! = 2 * 2 * 2 * 3
5! = 2 * 2 * 2 * 3 * 5
6! = 2 * 2 * 3 * 3 * 4 * 5
7! = 2 * 2 * 3 * 3 * 4 * 5 * 7
8! = 2 * 3 * 3 * 4 * 4 * 4 * 5 * 7
9! = 3 * 3 * 3 * 4 * 4 * 4 * 5 * 6 * 7
10! = 3 * 3 * 4 * 4 * 4 * 5 * 5 * 6 * 6 * 7
11! = 3 * 3 * 4 * 4 * 4 * 5 * 5 * 6 * 6 * 7 * 11
12! = 3 * 4 * 4 * 4 * 5 * 5 * 6 * 6 * 6 * 6 * 7 * 11
13! = 3 * 4 * 4 * 4 * 5 * 5 * 6 * 6 * 6 * 6 * 7 * 11 * 13
14! = 4 * 4 * 4 * 5 * 5 * 6 * 6 * 6 * 6 * 6 * 7 * 7 * 11 * 13
15! = 4 * 5 * 5 * 5 * 6 * 6 * 6 * 6 * 6 * 6 * 7 * 7 * 8 * 11 * 13
16! = 5 * 5 * 5 * 6 * 6 * 6 * 6 * 6 * 6 * 7 * 7 * 8 * 8 * 8 * 11 * 13EDIT: Never mind, that's part of the definition of the problem!