-
Notifications
You must be signed in to change notification settings - Fork 0
/
day22.jl
87 lines (79 loc) · 2.28 KB
/
day22.jl
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
84
85
86
87
module Day22
using AdventOfCode2017
using DataStructures
@enum State clean weakend infected flagged
function day22(input::String = readInput(joinpath(@__DIR__, "..", "data", "day22.txt")))
infections, start = parse_input(input)
p1 = part1(infections, start)
p2 = part2(infections, start)
return [p1, p2]
end
function parse_input(input::String)
infectedM = map(x -> x[1] == '#' ? true : false, reduce(vcat, permutedims.(split.(split(input), ""))))
starti, startj = size(infectedM) .÷ 2 .+ 1
infected = DefaultDict{CartesianIndex{2},Bool}(false)
for i = 1:size(infectedM, 1)
for j = 1:size(infectedM, 2)
if infectedM[i,j]
infected[CartesianIndex(i,j)] = true
end
end
end
return infected, CartesianIndex(starti, startj)
end
function part1(infections, start)
infections = copy(infections)
p1 = 0
current = start
dir = CartesianIndex(-1, 0)
for _ ∈ 1:10_000
if infections[current]
dir = turnl(dir, -1)
else
dir = turnl(dir, 1)
end
if !infections[current]
infections[current] = true
p1 += 1
else
infections[current] = false
end
current += dir
end
return p1
end
function turnl(dir, n)
directions = (CartesianIndex(-1, 0), CartesianIndex(0, -1), CartesianIndex(1, 0), CartesianIndex(0, 1))
return directions[mod1(findfirst(==(dir), directions) + n, 4)]
end
function part2(infections, start)
p2 = 0
d = DefaultDict{CartesianIndex{2},State}(clean)
for key ∈ keys(infections)
d[key] = infected
end
current = start
dir = CartesianIndex(-1, 0)
for _ ∈ 1:10_000_000
if d[current] == clean
dir = turnl(dir, 1)
elseif d[current] == infected
dir = turnl(dir, -1)
elseif d[current] == flagged
dir = turnl(dir, 2)
end
if d[current] == clean
d[current] = weakend
elseif d[current] == weakend
p2 += 1
d[current] = infected
elseif d[current] == infected
d[current] = flagged
elseif d[current] == flagged
d[current] = clean
end
current += dir
end
return p2
end
end # module