-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay08.hs
83 lines (65 loc) · 2.84 KB
/
Day08.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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
module Day08 where
import qualified Data.Map as M
import qualified Data.Set as S
type Pos = (Int,Int)
type Map = (Pos,M.Map Char [Pos])
parse :: String -> Map
parse s = ((maxX,maxY),M.fromListWith (++) [(c,[(x,y)]) | (y,row) <- rows
, (x,c) <- zip [0..] row
, c /= '.'])
where rows = zip [0..] (lines s)
maxY = fst (last rows)
maxX = length (snd $ head rows) - 1
slurp = parse <$> readFile "input-08"
antinodes (x1,y1) (x2,y2) = [(x1-dx,y1-dy),(x2+dx,y2+dy)]
where dx = x2-x1
dy = y2-y1
between a b c = a <= b && b <= c
inBounds (maxX,maxY) (x,y) = between 0 x maxX && between 0 y maxY
allAntinodes :: Map -> S.Set Pos
allAntinodes (bounds,antennas) = S.fromList [p | ps <- M.elems antennas
, p1 <- ps
, p2 <- ps
, p1 /= p2
, p <- antinodes p1 p2
, inBounds bounds p]
part1 = S.size . allAntinodes
example = parse "............\n\
\........0...\n\
\.....0......\n\
\.......0....\n\
\....0.......\n\
\......A.....\n\
\............\n\
\............\n\
\........A...\n\
\.........A..\n\
\............\n\
\............\n"
visualize :: Map -> S.Set Pos -> String
visualize ((maxX,maxY),antennas) antinodes = unlines [ concat [[visAnt (x,y), visNode (x,y)] | x <- [0..maxX]]
| y<-[0..maxY]]
where visNode p = if S.member p antinodes then '#' else ' '
visAnt p = case [sym | (sym,ps) <- M.assocs antennas
, p `elem` ps]
of (sym:_) -> sym
[] -> '.'
visualize1 m = putStrLn $ visualize m (allAntinodes m)
antinodes2 bounds (x1,y1) (x2,y2) = takeWhile (inBounds bounds) left ++ takeWhile (inBounds bounds) right
where dx = x2-x1
dy = y2-y1
left = [(x1-k*dx,y1-k*dy) | k<-[0..]]
right = [(x2+k*dx,y2+k*dy) | k<-[0..]]
allAntinodes2 (bounds,antennas) = S.fromList [p | ps <- M.elems antennas
, p1 <- ps
, p2 <- ps
, p1 /= p2
, p <- antinodes2 bounds p1 p2
, inBounds bounds p]
part2 = S.size . allAntinodes2
visualize2 m = putStrLn $ visualize m (allAntinodes2 m)
main = do
--print . part1 =<< slurp
--visualize1 example
--visualize2 example
print . part2 =<< slurp