import Data.List import Data.List.Split main :: IO () main = do input <- readFile "7/input.txt" let x = sort $ parse input -- Problem 1 print $ f x -- Problem 2 print $ g x where f = solve distance g = solve triangle -- | Split on comma and interpret each element as an integer parse :: String -> [Int] parse = map read . wordsBy (== ',') -- | Solve the problem by finding the minimum of a list of integers, where -- | each element is the total amount of fuel needed for each crab to reach -- | that position. solve :: (Int -> Int -> Int) -- ^ Fuel calculation to get between two points -> [Int] -- ^ List of initial positions -> Int solve f x = minimum $ map g (narrow x) where g t = sum $ map (f t) x -- | Get a slice of numbers around the mean in order to narrow the -- | range of possible best positions to search. narrow :: [Int] -> [Int] narrow x = [ m - n .. m + n ] where m = sum x `div` length x n = 5 -- | Calculate the fuel usage based on the triangle number of the distance -- | between the two numbers. triangle :: Int -> Int -> Int triangle a b = tri $ distance a b where tri n = n * (n + 1) `div` 2 -- Calculate nth triangle number -- | Calculate the absolute distance between two numbers distance :: Int -> Int -> Int distance a b = abs (a - b)