A composite number is - more or less - a non-prime number.
A lot of them can be written as the sum of a prime, and twice a square, eg
\(9 = 7 + 2 1^2\)
What is the smallets, odd, number that can not be written as such.
Loading numbers
to handle primes. And
purrr
:
library(numbers)
library(purrr)
Make a guess, the answer is smaller than 100000
Generate primes, and candidate, odd, numbers, smaller than that
prim <- Primes(100000)
test <- seq(3,100000,by=2)
Remove primes from test:
test <- setdiff(test, prim)
Generate candidate squares:
upper_limit <- ceiling(sqrt(100000/2))
squares <- 2*(1:upper_limit)^2
Next up is getting candidate squares.
Next I’m writing a function to test if any x can be expressed as the sum of twice a square and a prime.
x - squares will give me a vector with the result of substracting each of the elements in squares from x. I do not need to consider values in squares that are larger than x. Subtracting those from x would give a negative number - and that is not a prime.
To do that:
x - squares[squares<x]
Next, are the elements in that vector prime? The easy way is to test if they are in the list of primes. I use the %in% operator for that:
(x - squares[squares<x]) %in% prim
That will return a logical vector, with a value TRUE or FALSE for each element in the vector resulting from the subtraction, depending on whether it is in the list of primes. If any element is TRUE, we have a result.
The any() function does that. If any element in the vector is true, any() will return true.
Putting all of that into a function:
testing <- function(x){
any((x - squares[squares<x]) %in% prim)
}
I now have a function that returns true, if a number x can be written as the sum of a prime and twice a square.
Finally I filter that through the discard() function - basically getting rid of all the numbers in my test-vector, that can be written as this sum. And finally passing those values to the min() function. And I have my answer:
answer <- test %>%
discard(function(x) testing(x)) %>%
min()