import Data.List (nub) import Parsing (splitByString) main :: IO () main = do input <- getContents let crabs = parseCrabs input (putStrLn . show . solution1) crabs (putStrLn . show . solution2) crabs solution1 :: [Int] -> Int solution1 = minFuel crabFuel1 solution2 :: [Int] -> Int solution2 = minFuel crabFuel2 parseCrabs :: String -> [Int] parseCrabs = (map read) . (splitByString ",") minFuel :: (Int -> Int -> Int) -> [Int] -> Int minFuel crabf crabs = minimum (map total positions) where uniqueCrabs = nub crabs positions = [minimum uniqueCrabs..maximum uniqueCrabs] total position = totalFuel crabf position crabs totalFuel :: (Int -> Int -> Int) -> Int -> [Int] -> Int totalFuel crabf position = sum . (map (crabf position)) crabFuel1 :: Int -> Int -> Int crabFuel1 crab position = abs (crab - position) crabFuel2 :: Int -> Int -> Int crabFuel2 crab position = -- Just the sum of 1.. -- (using that Gauß-attributed sum) end * (end + 1) `quot` 2 where end :: Int end = crabFuel1 crab position -- Tests testInput = "16,1,2,0,4,2,7,1,2,14" parsedInput = parseCrabs testInput test1 = solution1 parsedInput test2 = solution2 parsedInput testTotalFuel1 = totalFuel crabFuel1 2 parsedInput testTotalFuel2 = totalFuel crabFuel1 1 parsedInput testTotalFuel3 = totalFuel crabFuel1 3 parsedInput testTotalFuel4 = totalFuel crabFuel1 10 parsedInput