Improved performance and readability for day 7

This commit is contained in:
Riley Apeldoorn 2021-12-07 15:23:29 +01:00
parent e2fdb863ee
commit cca98d409a

View file

@ -1,22 +1,18 @@
import Data.List
import Data.List.Split import Data.List.Split
import Debug.Trace
main :: IO () main :: IO ()
main = do main = do
input <- readFile "7/input.txt" input <- readFile "7/input.txt"
let x = parse input let x = sort $ parse input
-- Problem 1 -- Problem 1
print $ f x print $ f x
-- Problem 2 -- Problem 2
print $ g x print $ g x
where where
f x = solve distance [ minimum x .. maximum x ] x f = solve distance
g x | length x >= 100 = solve triangle [ sum x `div` length x ] x g = solve triangle
| otherwise = solve triangle [ minimum x .. maximum x ] x
-- NOTE for part 2 (`g`):
-- Just testing against the mean value of `x` only gives accurate results if the
-- sample is large enough. Here, lists of size 100 or larger are deemed "large enough",
-- but that's pretty arbitrary.
-- | Split on comma and interpret each element as an integer -- | Split on comma and interpret each element as an integer
parse :: String -> [Int] parse :: String -> [Int]
@ -26,13 +22,19 @@ parse = map read . wordsBy (== ',')
-- | each element is the total amount of fuel needed for each crab to reach -- | each element is the total amount of fuel needed for each crab to reach
-- | that position. -- | that position.
solve :: (Int -> Int -> Int) -- ^ Fuel calculation to get between two points solve :: (Int -> Int -> Int) -- ^ Fuel calculation to get between two points
-> [Int] -- ^ List of possible target positions
-> [Int] -- ^ List of initial positions -> [Int] -- ^ List of initial positions
-> Int -> Int
solve f a x = minimum $ map g a solve f x = minimum $ map g (narrow x)
where where
g t = sum $ map (f t) x 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 -- | Calculate the fuel usage based on the triangle number of the distance
-- | between the two numbers. -- | between the two numbers.
triangle :: Int -> Int -> Int triangle :: Int -> Int -> Int