-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday3.rb
48 lines (39 loc) · 1.1 KB
/
day3.rb
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
module Enumerable
def around(index_or_range, &block)
left, right = case index_or_range
in Range => r then [[r.min - 1, 0].max, (r.max + 1)]
in Numeric => i then [[i - 1, 0].max, (i + 1)]
end
drop(left).take(right - left + 1).each(&block)
end
end
lines = File.readlines(ARGV[0], chomp: true)
sum = 0
gear_parts = Hash.new { |hash, key| hash[key] = [] }
lines.each_with_index do |line, y|
offset = 0
while match = line.match(/\d+/, offset)
left, right = match.begin(0), match.end(0)
offset = right
num = match.to_s.to_i
# Part 1
has_adjacent_symbol = lines.around(y).any? do |adjacent_line|
adjacent_line.chars.around(left...right).to_a.join.match?(/[^\d\.]/)
end
sum += num if has_adjacent_symbol
# Part 2
lines.each_with_index.around(y) do |adjacent_line, y|
_, x = adjacent_line
.chars
.each_with_index
.around(left...right)
.find { |c, _| c == '*' }
break gear_parts[[x, y]] << num if x
end
end
end
p sum
p gear_parts.values
.filter { |ps| ps.length == 2 }
.map { |ps| ps.reduce(&:*) }
.sum