-
Notifications
You must be signed in to change notification settings - Fork 0
/
day05.hs
36 lines (28 loc) · 970 Bytes
/
day05.hs
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
import qualified Data.Map.Strict as M
import Util (wordsBy, listToTuple)
main :: IO ()
main = do
allLines <- fmap (fmap parseLine . lines) getContents
print $ solve . filter isStraight $ allLines
print $ solve allLines
return ()
type Point = (Int, Int)
type Line = ((Int, Int), (Int, Int))
type Grid = M.Map Point Int
solve :: [Line] -> Int
solve = M.size . M.filter (> 1) . foldl markGrid M.empty . fmap genPoints
markGrid :: Grid -> [Point] -> Grid
markGrid = foldl (\m p -> M.insertWith (+) p 1 m)
genPoints :: Line -> [Point]
genPoints ((x1, y1), (x2, y2)) = zip (genLine x1 x2) (genLine y1 y2)
isStraight :: Line -> Bool
isStraight ((x1, y1), (x2, y2)) = x1 == x2 || y1 == y2
genLine :: Int -> Int -> [Int]
genLine a b
| a < b = [a..b]
| a == b = repeat a
| otherwise = reverse [b..a]
parseLine :: String -> Line
parseLine s = let
[posA, _, posB] = words s
in listToTuple . fmap (listToTuple . fmap read . wordsBy (== ',')) $ [posA, posB]