-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday11.cr
66 lines (59 loc) · 1.48 KB
/
day11.cr
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
input = 5153
SIZE = 300
def calc(x, y, input)
rack_id = x + 10
power_level = rack_id * y
power_level += input
power_level *= rack_id
power_level = power_level.to_s.chars[-3].to_i || 0
power_level -= 5
end
def calcsize(i, j, s, levels, sums)
case {s, i, j}
when {1, _, _}
levels[i][j]
when {_, 0, 0}
sums[i][j]
when {_, 0, _}
sums[i + s - 1][j + s - 1] - sums[i + s - 1][j - 1]
when {_, _, 0}
sums[i + s - 1][j + s - 1] - sums[i - 1][j + s - 1]
else
sums[i + s - 1][j + s - 1] - sums[i - 1][j + s - 1] - sums[i + s - 1][j - 1] + sums[i - 1][j - 1]
end
end
levels = Array(Array(Int32)).new(SIZE) { |i| Array(Int32).new(SIZE) { |j| calc(i, j, input) } }
# https://en.wikipedia.org/wiki/Summed-area_table
sums = Array(Array(Int32)).new
SIZE.times do |i|
sums << Array(Int32).new
SIZE.times do |j|
sums[i] << levels[i][j] +
case {i, j}
when {0, 0}
0
when {0, _}
sums[0][j - 1]
when {_, 0}
sums[i - 1][0]
else
sums[i - 1][j] + sums[i][j - 1] - sums[i - 1][j - 1]
end
end
end
max3 = {-1, -1, 0, -Int32::MAX}
max = {-1, -1, 0, -Int32::MAX}
(1..SIZE).each do |s|
size = SIZE - s + 1
size.times do |i|
size.times do |j|
sum = calcsize(i, j, s, levels, sums)
max3 = {i, j, s, sum} if sum > max3.last && s == 3
max = {i, j, s, sum} if sum > max.last
end
end
end
puts "part1"
puts max3.values_at(0, 1).join(",")
puts "part2"
puts max.values_at(0, 1, 2).join(",")