This is my solution the the March 2024 IBM Ponder this problem.
March 2024 IBM Ponder this problem
Let
-
$a_i=a_{i-1} + i$ for$0 < i < n$ - None of the sequence terms is prime.
- There is no other sequence with the above properties and a smaller initial term
$a_0$ .
The first such sequences are:
Your Goal: Please find the initial term
A Bonus "*" will be given for finding the initial term
There is an obvious naive algorithm which consists in trying all integers as the starting point of the sequence:
- Set
$a_i=a_0$ to next integer. - Check if
$a_i$ is prime.- if so, go back to step 1, trying the next integer
$a_0+1$ , - otherwise increment
$i$ and compute$a_i = a_{i-1} + i$ and go back to step 2 until$i=n$ , in which case$a_0$ is a valid initial term for the sequence.
- if so, go back to step 1, trying the next integer
But my first opinion was that it would be impracticable for large
So I reversed the point of view and instead of starting from integers, I decided to use the prime numbers to ruled out integers:
- Start with a prime number
$p=b_0$ . Rule out integer$b_0$ from starting the sequence. - Going backwards, compute
$b_i = b_{i-1} - i$ and rule out integer$b_i$ from starting the sequence as after$i$ steps in the sequence, we would stumble on$p$ which is prime. Repeat step 2 until$i=n-1$ . - Repeat step 1 with the next prime
$p'$ .
When should we stop? We know that if
-
$2$ rules out$2$ and$2-1=1$ ;$3$ is the smallest non ruled-out. -
$3$ rules out$3$ and$2$ ;$4$ is the smallest. -
$5$ rules out$5$ ,$4$ and$4-2=2$ ;$6$ is the smallest. -
$7$ rules out$7$ ,$6$ and$4$ ;$8$ is the smallest. -
$11$ rules out$11$ ,$10$ and$8$ ;$9$ is the smallest. -
$13$ is greater than$9+\frac{3\times2}{2}$ , so$9$ cannot be ruled out anymore and is the smallest initial term.
The code can be found in the IBM_ponder_2024-03_1
folder.
One issue was to be able to generate prime numbers. I went on using the prime-numbers website where a list of all prime numbers up to one hundred billions can be downloaded, but:
- That proved not to be enough to solve the bonus question (
$X_{2024}$ ), - There are 10,000 prime numbers missing from the first file!
So I ended up installing the primesieve library and generate prime on the fly while running the code.
Another issue is how to store the array of integers while they are being ruled out as memory is not infinite and we do not know the size of the initial term. The solution is to work one block of integers
That code enabled me to compute
So problem solved. I just wanted to bragg and show how clever my algorithm was by comparing it to the obviously inferior naive algorithm...
So I coded it (see the IBM_ponder_2024-03_2
folder) and much to my disappointment, the naive algorithm happened to be twice to three times quicker...
The idea is pretty simple: use an array of char
to mark primes in block
But wait! Each integer sequence can be checked independently so this is a perfect algorithm waiting to be parallelized.
So we launch IBM_ponder_2024-03_2_MT
folder).
There are some read-only global variables used by each thread: array of primes (and size and offset value),
There is one shared variable, bestValue
used to communicate between threads when a possible initial value is found. At each iteration, a thread will check whether another thread has found an initial value and will stop if this value is smaller than our current tested value. When a thread finds an possible initial value, it will check whether it is smaller than the current best value found so far and update it accordingly (using a mutual exclusion lock for protection). Beware that this variable has to be declared volatile
to ensure all threads get any real-time updated value and not a former register or cache value. An argument to the command sets the desired number of threads.
That code enabled me to compute