1 import Data.Text (Text)
2 import qualified Data.Text as T
3 import qualified Data.Text.IO as TIO
5 import Text.Megaparsec hiding (State)
6 import qualified Text.Megaparsec.Lexer as L
7 import Text.Megaparsec.Text (Parser)
8 import qualified Control.Applicative as CA
10 import Data.List (nub)
12 type Position = (Integer, Integer)
14 (+:) (a, b) (c, d) = (a + c, b + d)
20 text <- TIO.readFile "data/infi.txt"
21 let (starts, unchunkedSteps) = successfulParse text
22 let steps = chunks (length starts) unchunkedSteps
23 let points = visited starts steps
25 putStrLn $ part2 points
28 visited :: [Position] -> [[Position]] -> [[Position]]
29 visited = scanl (zipWith (+:))
31 intersections :: [[Position]] -> [[Position]]
32 intersections = filter ((== 1) . length . nub)
34 part1 :: [[Position]] -> Int
35 part1 = length . intersections
37 part2 :: [[Position]] -> String
38 part2 points = showPoints bds $ nub $ concat $ intersections points
39 where bds = bounds $ nub $ concat points
41 chunks :: Int -> [b] -> [[b]]
42 chunks n xs = (take n xs) : if null xs' then [] else chunks n xs'
45 bounds :: [Position] -> (Integer, Integer, Integer, Integer)
46 bounds ps = ( minimum $ map fst ps
47 , maximum $ map fst ps
48 , minimum $ map snd ps
49 , maximum $ map snd ps
53 showPoints :: (Integer, Integer, Integer, Integer) -> [Position] -> String
54 showPoints (minr, maxr, minc, maxc) ps = unlines [ [ if (r, c) `elem` ps then '*' else ' ' | r <- [minr..maxr] ] | c <- [minc..maxc] ]
58 sc = L.space (skipSome spaceChar) CA.empty CA.empty
61 integer = lexeme L.integer
62 signedInteger = L.signed sc integer
66 pointP :: Parser Position
67 pointP = (,) <$> signedInteger <* comma <*> signedInteger
69 startPosP = between (symbol "[") (symbol "]") pointP
70 stepP = between (symbol "(") (symbol ")") pointP
72 descriptionP = (,) <$> (some startPosP) <*> (some stepP)
74 successfulParse :: Text -> ([Position], [Position])
75 successfulParse input =
76 case parse descriptionP "input" input of
77 Left _error -> ([], [])
78 Right description -> description