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
|
import Data.List
type Vec = (Int, Int)
type Ant = (Int, Int, Char)
type Map = (Vec, [Ant])
consume2 :: [Ant] -> Int -> Int -> [Char] -> [Ant]
consume2 acc _ _ [] = acc
consume2 acc r c ('.':t) = consume2 acc r (c+1) t
consume2 acc r c (h:t) = consume2 ((r, c, h):acc) r (c+1) t
consume1 :: [Ant] -> Int -> [[Char]] -> [Ant]
consume1 acc _ [] = acc
consume1 acc r (h:t) = consume1 (acc ++ (consume2 [] r 0 h)) (r+1) t
consume :: [Char] -> Map
consume file =
((length grid, length $ head grid), consume1 [] 0 grid)
where grid = lines file
neg :: Vec -> Vec
neg (r, c) = (-r, -c)
add :: Vec -> Vec -> Vec
add (fr, fc) (dr, dc) = (fr + dr, fc + dc)
scale :: Int -> Vec -> Vec
scale m (r, c) = (r * m, c * m)
path :: (Vec, Vec) -> Vec
path (f, t) = add t $ neg f
inside :: Vec -> Vec -> Bool
inside (mr, mc) (r, c) =
r >= 0 && r < mr && c >= 0 && c < mc
simplify :: Vec -> Vec
simplify (r, c) =
(r `div` d, c `div` d)
where d = gcd r c
antiNodes :: Map -> Char -> [Vec]
antiNodes (size, ants) freq =
filter (inside size) $ map (\p@(f, _) -> add f $ scale 2 $ path p) pairs
where
fants = filter (\(_, _, f) -> f == freq) ants
coos = map (\(r, c, _) -> (r, c)) fants
pairs = [(a1, a2) | a1 <- coos, a2 <- coos, a1 /= a2]
antiNodes22 :: [Vec] -> Vec -> Vec -> Vec -> [Vec]
antiNodes22 acc size from del
| inside size nxt = antiNodes22 (nxt:acc) size nxt del
| otherwise = acc
where nxt = add from del
antiNodes21 :: Vec -> (Vec, Vec) -> [Vec]
antiNodes21 s p@(f, t) =
antiNodes22 [] s f d ++
[f] ++
antiNodes22 [] s f (neg d)
where
d = simplify $ path p
antiNodes2 :: Map -> Char -> [Vec]
antiNodes2 (size, ants) freq =
nub $ concat $ map (antiNodes21 size) pairs
where
fants = filter (\(_, _, f) -> f == freq) ants
coos = map (\(r, c, _) -> (r, c)) fants
pairs = [(a1, a2) | a1 <- coos, a2 <- coos, a1 /= a2]
part1 mp@(_, ants) =
length $ nub $ concat $ map (antiNodes mp) freqs
where
freqs = nub $ map (\(_, _, f) -> f) ants
part2 mp@(_, ants) =
length $ nub $ concat $ map (antiNodes2 mp) freqs
where
freqs = nub $ map (\(_, _, f) -> f) ants
main = do
file <- readFile "day08.input"
let mp = consume file
putStrLn ("Part 1: " ++ (show $ part1 mp))
putStrLn ("Part 2: " ++ (show $ part2 mp))
|