Fastest way to find out a number with most divisors - algorithm

Given a number n how fast can one find the smallest number with most factors and is less than n?
PS:other than the naive approach of finding number of divisors for all numbers upto n.
UPDATE : My observation:
int solve(int primes[],int s,int n)
{
int i=0;
while(s<n)
{
s*=primes[i];
i++;
}
if(s>n)
s/=primes[i-1];
return s;
}
int main()
{
int primes[] = {2,3,5,7,11,13,17,19,23,29,31,37};
int n;
scanf("%d",&n);
int s=1;
while(s*2<n)//checking the possibility of existence of any prime such that s*p<n
{
s=solve(primes,s,n);
}
printf("%d\n",s);
}
The output for this for 100000 is 60060. Is this observation true? Because I don't have any concrete proof of this approach.
What I observed is that suppose take a prime array {2,3,5,7,11} and suppose that the given n is 100. Then observe that keep multiplying distinct primes until that point that you get it >100. That is 2*3*5.Repeat multiplying primes from the array from the first element again.That is 2*3*5*2. This is the number required 60 with 12 factors.Now there is no prime that can be multiplied without exceeding 100. Is this observation true? If its true then with primes upto 37 we can deal with n<=10000000 easily.All the numbers below 100 with most factors are 60, 72, 84, 90 and 96. We get the smallest of these numbers with this approach. All have 12 factors. No number below 100 has more than 12 factors.

I think this problem can be solved by algorithm similar to Hamming Number, indeed your original concept is very similar to Hamming Number as well.
Hamming Number is a problem to generate number x, where x = 2^i * 3*j * 5*k, from small to large in O(N) where N is the number of hamming number to be generated.
Here, I think similar concept can be used but we have to use the set of prime which is below your upper bound instead of {2,3,5}, we just need to also count the maximum # of prime factors when generating the number, and output it after the number generated is larger than N.
For example, here is the list of hamming number(using {2,3,5} for demo purpose) < 100:
1 2 3 4 5 6 8 9 10 12 15 16 18 20 24 25 27 30 32 36 40 45 48 50 54 60 64 72 75 80 81 90 96 100
60 = 2^2 * 3^1 * 5^1, total factors = 3*2*2 = 12 or
96 = 2^5 * 3^1, total factors = 6*2 = 12
So there may be multiple answer but you should be able to capture them while generating hamming number.
One can show that it is logically correct because
The numbers are generated by prime numbers (prime factors)
The numbers are generated in order
Note that in your case, basically you are generating all positive numbers from 1 to your upper bound.
Here is a site with tons of example in different language implementing this algorithm to generate hamming numbers: https://rosettacode.org/wiki/Hamming_numbers

Adapting Sieve of Eratosthenes it is doable in O(n^2) time.
Start with an array of size n i.e divisors.
For each number k less than n increment divisors[k] and all other indexes that are k*i < n
Find index of the larger value in divisors

Related

Checking if a number can be written as a product of some fibonacci numbers

I have tried to solve the problem above but I got stuck. I guess that it all comes to factorization by non-prime numbers. The number could be really big - about 10^15.
What I attempted to do is to factor the x and all the Fibonacci numbers up to about 155th(this is the one that is over 10^30, and that means that I can not include its factors in my x's factors), then just like in normal factorization, I loop from the highest Fibonacci number to the lowest and check if my x has all the factors of the i-th Fibonacci number. If it does then I divide x by it. When I get to the i=1(I looped through all the Fibonacci factors table), I just check if my x is equal to 1. If it is, then my answer is YES, otherwise it is NO.
This solution does not work, because sometimes it divides x in way which rules out further division, so I tried to split it into two loops - the first one can divide the x by only Fibonacci numbers which have at least one number which does not belong to the Fibonacci sequence, and the second one can divide by every number.
I took factored Fibonacci numbers from this website: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html
Here is an example which destroys the 1st idea:
x=2^10 × 3^5 × 5^2 × 7 × 11 × 17 × 23 × 47 × 89 × 1103
I divide it by: 48th number, 12th, 11th, 10th and after that I can't get rid of the 17 so my answer is no, but it should be yes dividing by: 48th, 11th, 10th, 9th, 10th, 6th, 5th, 3*4th.
My 2nd idea is a little bit weird so that is why I wrote it. Is my solution correct? Or maybe there is another which can determine if the number can be written as a product of Fibonacci numbers? (Note that x can be really big)
Without relying on any special properties of Fibonnacci numbers, you could categorise this as a coin change problem, where the available coins are the Fibonacci numbers, and the target must be achieved via multiplication instead of addition.
A solution is then to use a recursive algorithm combined with memoization to avoid the same subproblem to be solved repeatedly (principle of dynamic programming).
Here is a demo implementation in JavaScript, which runs the algorithm for the problem you mentioned in the question:
// Preprocessing: collect all Fibonacci numbers with 15 digits or less:
let fib = [];
let a = 1, b = 2;
while (b < 1e16) {
fib.push(b);
[a, b] = [b, a+b];
}
fib.reverse(); // Put greatest Fib numbers first
let memo = new Map(); // For memoization
function solve(n, start=0) {
if (n === 1) return true;
let result = memo.get(n);
if (result === undefined) { // Not in map:
let i;
for (i = start; i < fib.length; i++) {
if (n % fib[i] == 0) {
// Try solving problem after division by this factor:
if (solve(n / fib[i], i)) break;
}
}
result = i < fib.length;
memo.set(n, result);
}
return result;
}
// Example input from question:
n = 2**10 * 3**5 * 5**2 * 7 * 11 * 17 * 23 * 47 * 89 * 1103
console.log(n, solve(n)); // 864126051784934400 true
Your first idea is almost correct: a tiny modification makes it work. By Carmichael's theorem, every Fibonacci number except 1, 8, and 144 has a prime divisor that does not divide any smaller Fibonacci number. Since 8 and 144 can both be written as the product of Fibonacci numbers themselves, we can ignore them when trying to find divisors.
// Given: integer N
F <- [2, 3, 5, 8, 13...] // All Fibonacci numbers x, 1 < x <= N
F.reverse() // put in decreasing order
for x in F:
if x == 8 or x == 144: continue
while N % x == 0:
N = N / x
return (N == 1)
Ignoring 8 and 144, this works because if f is the largest Fibonacci number dividing N, then f has a prime factor p that no earlier Fibonacci number has, so we have to divide p out of N as many times as possible if it is to be written as a product of Fibonacci numbers.
In fact, up to the isomorphism of replacing (8 with 2^3) and (144 with 2^4 * 3^2 or 8 * 2 * 3^2), this factorization has to be unique by that argument.

How many numbers have a maximum number of unique prime factors in a given range

Note that the divisors have to be unique
So 32 has 1 unique prime factor [2], 40 has [2, 5] and so on.
Given a range [a, b], a, b <= 2^31, we should find how many numbers in this range have a maximum number of unique divisors.
The best algorithm I can imagine is an improved Sieve of Eratosthenes, with an array counting how many prime factors a number has. But it is not only O(n), which is unacceptable with such a range, but also very inefficient in terms of memory.
What is the best algorithm to solve this question? Is there such an algorithm?
I'll write a first idea in Python-like pseudocode. First find out how many prime factors you may need at most:
p = 1
i = 0
while primes[i] * p <= b:
p = p * primes[i]
i = i + 1
This only used b, not a, so you may have to decrease the number of actual prime factors. But since the result of the above is at most 9 (as the product of the first 10 primes already exceeds 231), you can conceivably go down from this maximum one step at a time:
cnt = 0
while cnt == 0:
cnt = count(i, 1, 0)
i = i - 1
return cnt
So now we need to implement this function count, which I define recursively.
def count(numFactorsToGo, productSoFar, nextPrimeIndex):
if numFactorsToGo > 0:
cnt = 0
while productSoFar * primes[nextPrimeIndex] <= b:
cnt = cnt + count(numFactorsToGo - 1,
productSoFar * primes[nextPrimeIndex],
nextPrimeIndex + 1)
nextPrimeIndex = nextPrimeIndex + 1
return cnt
else:
return floor(b / productSoFar) - ceil(a / productSoFar) + 1
This function has two cases to distinguish. In the first case, you don't have the desired number of prime factors yet. So you multiply in another prime, which has to be larger than the largest prime already included in the product so far. You achieve this by starting at the given index for the next prime. You add the counts for all these recursive calls.
The second case is where you have reached the desired number of prime factors. In this case, you want to count all possible integers k such that a ≤ k∙p ≤ b. Which translates easily into ⌈a/p⌉ ≤ k ≤ ⌊b/p⌋ so the count would be ⌊b/p⌋ − ⌈a/p⌉ + 1. In an actual implementation I'd not use floating-point division and floor or ceil, but instead I'd make use of truncating integer division for the sake of performance. So I'd probably write this line as
return (b // productSoFar) - ((a - 1) // productSoFar + 1) + 1
As it is written now, you'd need the primes array precomouted up to 231, which would be a list of 105,097,565 numbers according to Wolfram Alpha. That will cause considerable memory requirements, and will also make the outer loops (where productSoFar is still small) iterate over a large number of primes which won't be needed later on.
One thing you can do is change the end of loop condition. Instead of just checking that adding one more prime doesn't make the product exceed b, you can check whether including the next primesToGo primes in the product is possible without exceeding b. This will allow you to end the loop a lot earlier if the total number of prime factors is large.
For a small number of prime factors, things are still tricky. In particular if you have a very narrow range [a, b] then the number with maximal prime factor count might well be a large prime factor times a product of very small primes. Consider for example [2147482781, 2147482793]. This interval contains 4 elements with 4 distinct factors, some of which contain quite large prime factors, namely
3 ∙ 5 ∙ 7 ∙ 20,452,217
22 ∙ 3 ∙ 11 ∙ 16,268,809
2 ∙ 5 ∙ 19 ∙ 11,302,541
23 ∙ 7 ∙ 13 ∙ 2,949,839
Since there are only 4,792 primes up to sqrt(231), with 46,337 as their largest (which fits into a 16 bit unsigned integer). It would be possible to precompute only those, and use that to factor each number in the range. But that would again mean iterating over the range. Which makes sense for small ranges, but not for large ones.
So perhaps you need to distinguish these cases up front, and then choose the algorithm accordingly. I don't have a good idea of how to combine these ideas – yet. If someone else does, feel free to extend this post or write your own answer building on this.

ACM: The 3n + 1 [duplicate]

This question already has answers here:
Uva's 3n+1 problem
(8 answers)
Project Euler Question 14 (Collatz Problem)
(8 answers)
Closed 9 years ago.
The 3n + 1 problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18416 Accepted Submission(s): 6803
Problem Description
Problems in Computer Science are often classified as belonging to a certain class of problems (e.g., NP, Unsolvable, Recursive). In this problem you will be analyzing a property of an algorithm whose classification is not known for all possible inputs.
Consider the following algorithm:
1. input n
2. print n
3. if n = 1 then STOP
4. if n is odd then n <- 3n + 1
5. else n <- n / 2
6. GOTO 2
Given the input 22, the following sequence of numbers will be printed 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
It is conjectured that the algorithm above will terminate (when a 1 is printed) for any integral input value. Despite the simplicity of the algorithm, it is unknown whether this conjecture is true. It has been verified, however, for all integers n such that 0 < n < 1,000,000 (and, in fact, for many more numbers than this.)
Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.
For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j.
Input
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 1,000,000 and greater than 0.
You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.
You can assume that no opperation overflows a 32-bit integer.
Output
For each pair of input integers i and j you should output i, j, and the maximum cycle length for integers between and including i and j. These three numbers should be separated by at least one space with all three numbers on one line and with one line of output for each line of input. The integers i and j must appear in the output in the same order in which they appeared in the input and should be followed by the maximum cycle length (on the same line).
Sample Input
1 10
100 200
201 210
900 1000
Sample Output
1 10 20
100 200 125
201 210 89
900 1000 174
if you use the plain way.for each case,cal all integer's solution.
so ,you can cal the solution for all between 1 and 1,000,000,than store in an array.
use the ST way to cal a new dp[N][M].
than when there is a query ,you can get the ans with O(1) times;
or you can use the Segment Tree to get the ans.
but i am not sure it won't get TLE...
for(int j=0;j<=log(N);j++)
for(int i=1;i<=N;i++)
dp[i][j]=max(dp[i][j-1]+dp[i+pow(2,j-1)][j-1];

Fast algorithm to calculate large n! mod 2³²

I want to calculate the exact value of N! mod 232. N can be up to 231
Any language is fine but I would appreciate detailed explanation of algorithm.
Time limit is < 1 sec
In python:
if n > 33:
return 0
else
return reduce(lambda x, y: x*y, range(1, n+1)) % 2**32
Justification:
We know that 34! is divisible by 232 because in the sequence:
1 * 2 * 3 * 4 * ... * 34
there are:
17 multiples of 2
8 multiples of 4
4 multiples of 8
2 multiples of 16
1 multiple of 32
--
32 multiplications by 2
It's a factor of every larger factorial, so all the larger ones are 0 mod 232
For small values of N, if you don't have bignum arithmetic available, you can do the individual multiplications mod 232, and/or you can prefactor the power of 2 in the factorial, which is easy to compute (see above).
Calculate the factorial normally (multiply the numbers 1,2,3,...), performing the modulo after each multiplication. This will give you the result for small values of N.
For larger values of N, do the same. Pretty soon, your intermediate result will be 0, and then you can stop the loop immediately and return 0. The point at which you stop will be relatively fast: For N == 64 the result will already be 0 because the product of 1..64 contains 32 even numbers and is therefore divisible by 2^32. The actual minimal value of N where you get 0 will be less than 64.
In general, you can implement algorithms modulo small powers of two without bignums or modular reduction using the integer types (int, long) available in most programming languages. For modulo 232 you would use a 32-bit int. "Integer overflow" takes care of the modular arithmetic.
In this case, since there are only 34 distinct results, a lookup table may be faster than computing the factorial, assuming the factorials are used often enough that the table gets loaded into the CPU cache. The execution time will be measured in microseconds.
When multiplying 2 numbers of arbitrary length, the lower bits are always exact because it doesn't depend on high order bits. Basically a×b mod m = [(a mod m)×(b mod m)] mod m so to do N! mod m just do
1×2×...×N mod m = (...(((1×2 mod m)×3 mod m)×4 mod m)...)×N mod m
Modulo 2n is a special case because getting the modulus is rather easy with an AND operation. Modulo 232 is even more special because all unsigned operations in C and most C-like languages are reduced modulo 232 for a 32-bit unsigned type
As a result you can just multiply the numbers in a twice-as-wide type then after that AND with 232 - 1 to get the modulus
uint64_t p = 1;
for (uint32_t i = 1; i <= n; i++)
p = p*i & 0xFFFFFFFFU;
return p;
Calculating a modulo is a very fast operation, especially the modulo of a power of 2. A multiplication is very costly in comparison.
The fastest algorithm would factorize the factors of the factorial in prime numbers (which is very fast since the numbers are smaller than 33). And get the result by multiplying all of them together, by taking the modulo in between each multiplication, and starting with the big numbers.
E.g.: to calculate 10! mod 232: use de Polignac's formula, to get the prime factors of 10!
which gives you :
10! = 7 * 5 * 5 * 3 * 3 * 3 * 3 * 2 ...
this would be faster than the basic algorithm, because calculating
(29! mod 232) X 30
is much harder than multiplying by 5, 3 and 2, and taking the modulo in between each time.

Finding the first number larger than N that is a relative prime to M

Basically, the title says everything. The numbers are not too big (the maximum for N is ~2/3 * max(long) and max M is max(long)), so I think even a simple solution that I currently have is sufficient. M is always bigger than N.
What I currently have:
Most simple, just start from N + 1, perform plain Euclidean GCD, and if it returns 1 we are done, if not increment and try again.
I would like to know what is the worst case scenario with this solution. Performance is not a big issue, but still I feel like there must be a better way.
Thanks.
About the worst case, I made a small test:
Random r = new Random();
while (true)
{
long num = (long) r.Next();
num *= r.Next();
f((long)(num * 0.61), num);
}
...
public static int max;
public static int f(long N, long M)
{
int iter = 0;
while (GCD(N++, M) != 1)
{
iter++;
}
if (iter > max)
{
max = iter;
Console.WriteLine(max);
}
return 0;
}
It is running for ~30 minutes and the worst case so far is 29 iterations. So I believe that there is a more precise answer then O(N).
I don't know the worst scenario, but using the fact that M < 264, I can bound it above by 292 iterations and below by 53 (removing the restriction that the ratio N/M be approximately fixed).
Let p1, …, pk be the primes greater than or equal to 5 by which M is divisible. Let N' ≥ N be the least integer such that N' = 1 mod 6 or N' = 5 mod 6. For each i = 1, …, k, the prime pi divides at most ceil(49/pi) of the integers N', N' + 6, N' + 12, …, N' + 288. An upper bound on ∑i=1,…,k ceil(49/pi) is ∑i=3,…,16 ceil(49/qi) = 48, where q is the primes in order starting with q1 = 2. (This follows because ∏i=3,…,17 ≥ 264 implies that M is the product of at most 14 distinct primes other than 2 and 3.) We conclude that at least one of the integers mentioned is relatively prime to M.
For the lower bound, let M = 614889782588491410 (product of the first fifteen primes) and let N = 1. After 1, the first integer relatively prime to the first fifteen primes is the sixteenth prime, 53.
I expect both bounds could be improved without too much work, though it's not clear to me for what purpose. For the upper bound, handle separately the case where 2 and 3 are both divisors of M, as then M can be the product of at most thirteen other primes. For the lower bound, one could try to find a good M by running the sieve of Eratosthenes to compute, for a range of integers, the list of primes dividing those integers. Then sweep a window across the range; if the product of the distinct primes in the window is too large, advance the trailing end of the window; otherwise, advance the leading end.
Sure it's not O(n), By knowing that prime number gaps is logen we can simply say your algorithm has at most logen iterations,(because after passing at most logen number you will see new prime number which is prime respect to your given number n) for more detail about this gap, you can see prime numbers gap.
So for your bounded case it is smaller than logen = loge264 <= 44 and it will be smaller than 44 iterations.

Resources