summaryrefslogtreecommitdiff
path: root/2019/3.hs
blob: 7f0180a81d13dc6ee1b8aa74f02575d73ca71321 (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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
module Main where

import Data.Char
import Data.List
import qualified Data.Set as Set

import Input


data Pt = Pt Int Int deriving (Show, Eq, Ord)
data Dir = U | L | D | R deriving (Show)
data Seg = Seg Pt Dir Int deriving (Show)

direction :: Dir -> Pt
direction U = Pt 0 1
direction R = Pt 1 0
direction D = Pt 0 (-1)
direction L = Pt (-1) 0

add :: Pt -> Pt -> Pt
add (Pt x y) (Pt a b) = Pt (x + a) (y + b)

scale :: Int -> Pt -> Pt
scale n (Pt x y) = Pt (n * x) (n * y)

parse :: String -> [(Dir, Int)]
parse "" = []
parse (c:s) =
    let dir = case c of
                  'U' -> U
                  'R' -> R
                  'D' -> D
                  'L' -> L
                  _ -> undefined
        (ns, r) = span isDigit s
    in (dir, read ns) : parse (dropWhile (== ',') r)

process :: Pt -> [(Dir, Int)] -> [Seg]
process _ [] = []
process pt ((dir, n) : rest) =
    Seg pt dir n : process (add pt (scale n (direction dir))) rest

points :: Seg -> [Pt]
points (Seg pt dir n) =
    let delta = direction dir
    in [add pt (scale k delta) | k <- [1..n]]

manhattan :: Pt -> Int
manhattan (Pt x y) = abs x + abs y

main :: IO ()
main = do
    ls <- map (process (Pt 0 0) . parse) <$> getInput 3
    let pts = Set.toList (foldl1 Set.intersection (map (Set.fromList . concatMap points) ls))
    print (manhattan (head (sortOn manhattan pts)))