summaryrefslogtreecommitdiff
path: root/2017/11.hs
blob: 19fe8626ac198acad91fdaabe671067ac6d9f558 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import Control.Monad
import Data.Char
import qualified Data.Map.Strict as Map
import Data.Map.Strict ((!))

splitOn :: Eq a => a -> [a] -> [[a]]
splitOn c xs = case break (== c) xs of
    (pre, []) -> [pre]
    (pre, _ : post) -> pre : splitOn c post

strip :: String -> String
strip = dropWhile isSpace . reverse . dropWhile isSpace . reverse

dirmap :: Map.Map String (Int, Int)
dirmap = Map.fromList [("n", (0,2)), ("ne", (1,1)), ("se", (1,-1)), ("s", (0,-2)), ("sw", (-1,-1)), ("nw", (-1,1))]

add :: (Int, Int) -> (Int, Int) -> (Int, Int)
add (a,b) (c,d) = (a + c, b + d)

distance :: (Int, Int) -> Int
distance (0,0) = 0
distance (0,y) = abs y `div` 2
distance (x,0) = abs x
distance (x,y) = let m = min (abs x) (abs y) in m + distance (x - m * signum x, y - m * signum y)

main :: IO ()
main = do
    input <- liftM (map (dirmap !) . splitOn ',' . strip) (readFile "11.in")
    print $ distance $ foldl1 add input
    print $ maximum $ map distance $ scanl add (0,0) input