never executed always true always false
1 {-|
2 Module: Y2015.D20
3 Description: Advent of Code Day 20 Solutions.
4 License: MIT
5 Maintainer: @tylerjl
6
7 Solutions to the day 20 set of problems for <adventofcode.com>.
8
9 Original credit for most of this due to aepsilon:
10 <https://www.reddit.com/r/adventofcode/comments/3xjpp2/day_20_solutions/cy5brqe>
11 -}
12
13 module Y2015.D20 (withMinPresents, withMinPresents2) where
14
15 import Data.List (group)
16 import Data.Set (Set)
17 import qualified Data.Set as Set
18
19 -- |Finds lowest house number that receives as many as the given presents
20 withMinPresents :: Int -- ^ Minimum number of presents house should receive
21 -> Int -- ^ Position of house
22 withMinPresents n = head $ filter ((>=n `divCeil` 10) . divisorSum) [1..]
23
24 divCeil :: Int -> Int -> Int
25 n `divCeil` d = (n-1) `div` d + 1
26
27 divisorSum :: Int -> Int
28 divisorSum = sum . divisorList
29
30 divisorList :: Int -> [Int]
31 divisorList = map product . mapM (scanl (*) 1) . group . factorize
32
33 factorize :: Int -> [Int]
34 factorize 1 = []
35 factorize n | null factors = [n]
36 | otherwise = p : factorize q
37 where factors = [ (p',q') | p' <- takeWhile (<= intsqrt n) primes
38 , let (q',r) = quotRem n p'
39 , r == 0 ]
40 p = fst $ head factors
41 q = snd $ head factors
42
43 intsqrt :: Int -> Int
44 intsqrt i = floor ((sqrt $ fromIntegral i) :: Double)
45
46 primes :: [Int]
47 primes = 2 : 3 : [ p | p <- [5,7..]
48 , and [p `rem` d /= 0 | d <- takeWhile (<= intsqrt p) primes]
49 ]
50
51 -- |Finds lowest house number that receives as many as the given presents
52 -- |given the special delivery case.
53 withMinPresents2 :: Int -- ^ Minimum number of presents house should receive
54 -> Int -- ^ Position of house
55 withMinPresents2 n = head $ filter ((>=n `divCeil` 11)
56 . divisorSumLimit 50) [1..]
57
58 divisorSumLimit :: Int -> Int -> Int
59 divisorSumLimit limit n = sum . snd . Set.split ((n-1)`div`limit) . divisors $ n
60
61 divisors :: Int -> Set Int
62 divisors = Set.fromList . divisorList