import Data.List.Split import Data.List import qualified Data.Set as Set import Data.Maybe main = do content <- readFile "input" let input = map (splitOn ",") (lines content) let parsedinput = map (map parseone) input let trace1 = tracewire (head parsedinput) (0,0) [(0,0)] let trace2 = tracewire (last parsedinput) (0,0) [(0,0)] print (day3a trace1 trace2) print (day3b trace1 trace2) parseone :: String -> (Char, Int) parseone xs = (head xs, read $ tail xs) tracewire :: [(Char,Int)] -> (Int,Int) -> [(Int,Int)] -> [(Int,Int)] tracewire [] _ x = x tracewire ((x,n):xs) (accx,accy) trc | x=='U'=tracewire xs (accx,accy+n) (trc++[(accx,accy+i) | i<-[1..n]]) | x=='R'=tracewire xs (accx+n,accy) (trc++[(accx+i,accy) | i<-[1..n]]) | x=='D'=tracewire xs (accx,accy-n) (trc++[(accx,accy-i) | i<-[1..n]]) | x=='L'=tracewire xs (accx-n,accy) (trc++[(accx-i,accy) | i<-[1..n]]) day3a :: [(Int,Int)] -> [(Int,Int)] -> Int day3a xs ys = Set.findMin $ Set.map manhattan (intersections xs ys) where manhattan x = (abs $ fst x) + (abs $ snd x) intersections :: [(Int,Int)] -> [(Int,Int)] -> Set.Set (Int, Int) intersections xs ys = Set.delete (0,0) crossset where crossset = (Set.fromList xs) `Set.intersection` (Set.fromList ys) day3b xs ys = minimum [let f = fromJust . findIndex (==x) in f xs + f ys | x<-Set.toList $ intersections xs ys]