2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?


In [13]:
// This is a fucking horrible solution
//
// optimisations needed:
// 1. in "divisibleByAll" bail out early if we find a non-divisor, instead of 
//    finding them all and folding the results
// 2. when calculating numberBeforeSmallestDivisor don't use takeWhile - we're 
//    just building a huge sequence only to discard all of them (and munching\
//    through a load of memory in the process). A loop or recursive func would 
//    be better here.

let limit = 20

let isDivisible num den = num % den = 0

let hasFactors x ys = 
    Seq.fold (fun acc y -> (isDivisible y x) || acc) false ys

// first cut down the list of numbers to test (2 divides 4 so no need to check 2 if we check 4, etc)
let targetNumbers = 
    [ 2 .. limit ]
    |> List.where (fun x -> not (hasFactors x [ (1+x) .. limit ]))
    
// next create a nice infinite sequence of +ve ints
let positiveIntegers = 
    Seq.initInfinite (fun idx -> 1+idx)

// the function we'll apply to each integer
let divisibleByAll x = 
    targetNumbers
    |> List.map (fun a -> isDivisible x a)
    |> List.fold (fun allTrue (a) -> allTrue && a) true 
    
// next spin through integers, checking if they're factors of our list of integers
let numberBeforeSmallestDivisor = 
    Seq.takeWhile (fun x -> not (divisibleByAll x)) positiveIntegers
    |> Seq.last
    
numberBeforeSmallestDivisor + 1


Out[13]:
232792560

In [ ]: