-
Notifications
You must be signed in to change notification settings - Fork 0
/
day03.jl
67 lines (60 loc) · 2.35 KB
/
day03.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
module Day03
# Parses the input into a char matrix
load_input(s) = permutedims(hcat((collect(strip(l)) for l in split(s, '\n') if length(l) > 1)...))
# Check if a symbol neighbors this position
issymbol(c) = c != '.' && !isdigit(c)
inbound(img, i, j) = (1 <= i <= size(img)[1]) && (1 <= j <= size(img)[2])
neighbors(img, i, j) = ((i+x, j+y) for x in [-1 0 1] for y in [-1 0 1] if inbound(img, i+x, j+y) && (x != 0 || y != 0))
is_symbol_adjacent(img, i, j) = any(issymbol(img[n...]) for n in neighbors(img, i, j))
# Sums up any numbers in the char matrix that are adjacent to a symbol
function sum_symbol_adjecent_nums(img)
total = 0
for i in 1:size(img)[1]
num = 0
keep = false
for j in 1:size(img)[2]
if isdigit(img[i, j])
num = 10*num + parse(Int64, img[i, j])
keep = keep || is_symbol_adjacent(img, i, j)
end
if !isdigit(img[i, j]) || j == size(img)[2]
keep && (total += num)
num = 0
keep = false
end
end
end
total
end
# Sums the "gear ratios" in the char array. These are gears adjacent to exactly two "part numbers"
get_gear_ratio_sum(img) = sum(prod(v) for v in values(get_gear_nums(img)) if length(v) ==2)
# Find all the gears in the image and their adjacent part numbers. Returns a dict mapping gear location in the matrix to
# a vector of part numbers
function get_gear_nums(img)
all_gears = Dict{Tuple{Int64, Int64}, Vector{Int64}}()
for i in 1:size(img)[1]
num = 0
our_gears = Set{Tuple{Int64, Int64}}()
for j in 1:size(img)[2]
if isdigit(img[i, j])
num = 10*num + parse(Int64, img[i, j])
for n in neighbors(img, i, j)
img[n...] == '*' && push!(our_gears, n)
end
end
if !isdigit(img[i, j]) || j == size(img)[2]
for g in our_gears
all_gears[g] = [get(all_gears, g, Vector{Int64}()); num]
end
num = 0
our_gears = Set{Tuple{Int64, Int64}}()
end
end
end
all_gears
end
function day03(input::String = readInput(joinpath(@__DIR__, "data", "day03.txt")))
img = load_input(input)
[sum_symbol_adjecent_nums(img), get_gear_ratio_sum(img)]
end
end