In [1]:
inputLines = lines <$> readFile "input/day03.txt"
inputLine1 = head <$> inputLines
inputLine2 = head . tail <$> inputLines
In [2]:
import qualified Data.Set as Set
import Data.List.Split
import Control.Lens
import Data.Function
In [3]:
calculatePath :: String -> [(Int, Int)]
calculatePath path =
let
parseDirection 'U' = over _2 succ
parseDirection 'D' = over _2 pred
parseDirection 'L' = over _1 pred
parseDirection 'R' = over _1 succ
parseSegment (direction:distance) = replicate (read distance) (parseDirection direction)
moves = concatMap parseSegment $ splitOn "," path
in
tail $ scanl (flip ($)) (0, 0) moves
In [4]:
pathIntersections :: String -> String -> [(Int, Int)]
pathIntersections path1 path2 = Set.toList $ on Set.intersection pointsForPath path1 path2
where
pointsForPath = Set.fromList . calculatePath
In [5]:
pathIntersections "R8,U5,L5,D3" "U7,R6,D4,L4"
In [6]:
manhattanDistance = uncurry ((+) `on` abs)
closestIntersectionDistance :: String -> String -> Int
closestIntersectionDistance path1 path2 = minimum . map manhattanDistance $ pathIntersections path1 path2
In [7]:
closestIntersectionDistance "R8,U5,L5,D3" "U7,R6,D4,L4"
In [8]:
closestIntersectionDistance "R75,D30,R83,U83,L12,D49,R71,U7,L72" "U62,R66,U55,R34,D71,R55,D58,R83"
In [9]:
closestIntersectionDistance "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51" "U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"
In [10]:
closestIntersectionDistance <$> inputLine1 <*> inputLine2
In [11]:
import qualified Data.Map as Map
In [12]:
pathIntersectionsWithCombinedDistance :: String -> String -> [((Int, Int), Int)]
pathIntersectionsWithCombinedDistance path1 path2 = Map.toList $ on (Map.intersectionWith (+)) pointsForPathWithDistance path1 path2
where
pointsForPathWithDistance path = Map.fromList (zip (calculatePath path) [1..])
In [13]:
minimumCombinedDistanceForIntersections :: String -> String -> Int
minimumCombinedDistanceForIntersections path1 path2 = minimum . map snd $ pathIntersectionsWithCombinedDistance path1 path2
In [14]:
minimumCombinedDistanceForIntersections "R8,U5,L5,D3" "U7,R6,D4,L4"
In [15]:
minimumCombinedDistanceForIntersections "R75,D30,R83,U83,L12,D49,R71,U7,L72" "U62,R66,U55,R34,D71,R55,D58,R83"
In [16]:
minimumCombinedDistanceForIntersections "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51" "U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"
In [17]:
minimum . map snd <$> (pathIntersectionsWithCombinedDistance <$> inputLine1 <*> inputLine2)