{-# Language QuasiQuotes #-}
module Main where
import Advent.Format (format)
import Data.List (transpose)
main :: IO ()
IO ()
main =
do input <- [format|2015 15 (%s: (%s %ld)&(, )%n)*|]
let stats = (([Char], [([Char], Integer)]) -> [Integer])
-> [([Char], [([Char], Integer)])] -> [[Integer]]
forall a b. (a -> b) -> [a] -> [b]
map ((([Char], Integer) -> Integer) -> [([Char], Integer)] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map ([Char], Integer) -> Integer
forall a b. (a, b) -> b
snd ([([Char], Integer)] -> [Integer])
-> (([Char], [([Char], Integer)]) -> [([Char], Integer)])
-> ([Char], [([Char], Integer)])
-> [Integer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], [([Char], Integer)]) -> [([Char], Integer)]
forall a b. (a, b) -> b
snd) [([Char], [([Char], Integer)])]
input
n = Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([([Char], [([Char], Integer)])] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [([Char], [([Char], Integer)])]
input)
possibilities = [[Integer]] -> [Integer] -> [Integer]
computeStats [[Integer]]
stats ([Integer] -> [Integer]) -> [[Integer]] -> [[Integer]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Integer -> Integer -> [[Integer]]
divisions Integer
n Integer
100
print (maximum (map score possibilities))
print (maximum [score meal | meal <- possibilities, last meal == 500])
score ::
[Integer] ->
Integer
score :: [Integer] -> Integer
score = [Integer] -> Integer
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product ([Integer] -> Integer)
-> ([Integer] -> [Integer]) -> [Integer] -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Integer] -> [Integer]
forall a. HasCallStack => [a] -> [a]
init
computeStats ::
[[Integer]] ->
[Integer] ->
[Integer]
computeStats :: [[Integer]] -> [Integer] -> [Integer]
computeStats [[Integer]]
props [Integer]
divs
= ([Integer] -> Integer) -> [[Integer]] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map (Integer -> Integer -> Integer
forall a. Ord a => a -> a -> a
max Integer
0 (Integer -> Integer)
-> ([Integer] -> Integer) -> [Integer] -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Integer] -> Integer
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum)
([[Integer]] -> [Integer]) -> [[Integer]] -> [Integer]
forall a b. (a -> b) -> a -> b
$ [[Integer]] -> [[Integer]]
forall a. [[a]] -> [[a]]
transpose
([[Integer]] -> [[Integer]]) -> [[Integer]] -> [[Integer]]
forall a b. (a -> b) -> a -> b
$ (Integer -> [Integer] -> [Integer])
-> [Integer] -> [[Integer]] -> [[Integer]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((Integer -> Integer) -> [Integer] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map ((Integer -> Integer) -> [Integer] -> [Integer])
-> (Integer -> Integer -> Integer)
-> Integer
-> [Integer]
-> [Integer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*)) [Integer]
divs [[Integer]]
props
divisions ::
Integer ->
Integer ->
[[Integer]]
divisions :: Integer -> Integer -> [[Integer]]
divisions Integer
1 Integer
n = [[Integer
n]]
divisions Integer
cnt Integer
n =
do x <- [Integer
1..Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
cntInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1]
xs <- divisions (cnt - 1) (n-x)
return (x:xs)