### The Problem

The first two consecutive numbers to have two distinct prime factors are:

- 14 = 2 × 7
- 15 = 3 × 5
The first three consecutive numbers to have three distinct prime factors are:

- 644 = 2² × 7 × 23
- 645 = 3 × 5 × 43
- 646 = 2 × 17 × 19.
Find the first four consecutive integers to have four distinct prime factors. What is the first of these numbers?

### The Solution

Once again, we need primes. Lots of them. So we'll start by stealing the `getSomePrimes`

function from
yesterday.

```
let intsqrt i = int(sqrt(float i))
let isPrime i =
if i <= 1 then false
elif i = 2 then true
elif (i &&& 1) = 0 then false
else
let sr = intsqrt i
seq { 3..2..sr } |> Seq.forall (fun f -> i%f<>0)
let rec nextPrime i =
match i with
| i when isPrime i -> i
| i -> nextPrime (i + 1)
let getSomePrimes num =
let primeGenerator (candidate,count) =
if count > num then
None
elif candidate = 2 then
Some(2,(3,count+1))
else
let next = nextPrime candidate
Some(next,(next+2,count+1))
Seq.unfold primeGenerator (2,1)
let factors = getSomePrimes 1000 |> List.ofSeq
```

So how many primes do we need? As with yesterday's problem, I don't know. I'm going to pick 100 because "it sounds good" and adjust later if I need to.

Why 100? We're looking for 4 prime factors. If we generate 1000 primes and take the last 4, we get:

- 7883
- 7901
- 7907
- 7919

If you multiply those 4 numbers together you get 3,899,919,746,694,739. That's way out of 32-bit integer territory. Are we willing to bet that the answer is less than that? Yes, we are.

Now we'll write a function to get the prime factors of a number.

```
let f n =
let rec getFactors (acc : Set<int>) (factors : int list) =
match factors with
| [] -> acc
| x::xs ->
if n % (x*x) = 0 then
getFactors (Set.add (x*x) acc) xs
elif n % x = 0 then
getFactors (Set.add x acc) xs
else
getFactors acc xs
getFactors Set.empty<int> factors
```

The function `f`

takes a number `n`

and returns its prime factors.

The recursive internal `getFactors`

function simply starts with a list of factors
and tests them all to see if they are factors of `n`

. The problem definition
clearly shows that squares of primes are allowed to be counted as a "distinct factor"
so we account for that case.

Now we need a function to look at a number and see if it has the specified number of distinct prime factors. In fact, we need to know if several consecutive numbers have that property, so we'll take a list of numbers as input instead of just a single number. We need to verify that:

- Each number has 4 distinct factors
- The set of 4 numbers has 16 distinct factors

The problem definition doesn't come right out and **say** that "distinct prime factors"
means "distinct across the 4 consecutive numbers", but you don't get the right
answer without accounting for that.

```
[<Literal>]
let factorCount = 4
[<Literal>]
let requiredDistinct = 16
let haveDistinctPrimeFactors numbers =
let numbersFactors =
numbers
|> Seq.map f
|> List.ofSeq
let distinctCount =
numbersFactors
|> List.reduce (fun acc elem -> acc + elem)
|> Set.count
(numbersFactors |> List.forall (fun x -> (Set.count x) = factorCount)) &&
(distinctCount = requiredDistinct)
```

The `haveDistinctPrimeFactors`

function starts by computing a couple of values.

`numbersFactors`

becomes a list of factors for each of the input `numbers`

.

`distinctCount`

is the count of the distinct factors across all 4 input `numbers`

.
The factors are of type `Set`

so when we add them together, we wind up with the
union of all 4 sets. Thus, the `count`

of that union is the number of distinct factors.

If the count of distinct factors for each input is 4 **and** the count of distinct
factors is `requiredDistinct`

then the function returns `true`

; otherwise, it returns
`false`

.

Now we can solve the problem:

```
#time
Seq.unfold (fun state -> Some(state, state+1)) 647
|> Seq.filter (fun x -> haveDistinctPrimeFactors [x..x+3])
|> Seq.head
#time
```

We start by using `Seq.unfold`

to generate an infinite sequence of numbers starting
at 647. The problem definition says that 644..646 is the first set of consecutive
numbers of have 3 prime factors, so we'll start looking right after that.

Next, we filter out any values that don't have the required distinct prime factors and return the head of the resulting sequence. That is the answer.

Other Posts in This Series