106 lines
2.0 KiB
Ruby
106 lines
2.0 KiB
Ruby
|
#prepare the input which is a string containing new lines
|
||
|
def parse(input)
|
||
|
data = []
|
||
|
row = 0
|
||
|
symbols = []
|
||
|
numbers = []
|
||
|
input.each_line do |line|
|
||
|
start_num = false
|
||
|
num = ""
|
||
|
num_cols = []
|
||
|
|
||
|
line.chomp.chars.each_with_index do |c,col|
|
||
|
if c == "."
|
||
|
if start_num
|
||
|
# finish a number
|
||
|
numbers << [num.to_i, row, num_cols]
|
||
|
start_num = false
|
||
|
num = ""
|
||
|
num_cols = []
|
||
|
end
|
||
|
elsif /\d/.match?(c)
|
||
|
# a digit
|
||
|
start_num = true
|
||
|
num += c
|
||
|
num_cols << col
|
||
|
elsif c == "*"
|
||
|
# symbol
|
||
|
if start_num
|
||
|
# finish a number
|
||
|
numbers << [num.to_i, row, num_cols]
|
||
|
start_num = false
|
||
|
num = ""
|
||
|
num_cols = []
|
||
|
end
|
||
|
# fill adjacents
|
||
|
|
||
|
symbols << [row,col]
|
||
|
else
|
||
|
# other symbol
|
||
|
if start_num
|
||
|
# finish a number
|
||
|
numbers << [num.to_i, row, num_cols]
|
||
|
start_num = false
|
||
|
num = ""
|
||
|
num_cols = []
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if start_num
|
||
|
# finish a number
|
||
|
numbers << [num.to_i, row, num_cols]
|
||
|
start_num = false
|
||
|
num = ""
|
||
|
num_cols = []
|
||
|
end
|
||
|
row += 1
|
||
|
end
|
||
|
data = [symbols,numbers]
|
||
|
data
|
||
|
end
|
||
|
|
||
|
def find_adjacent_numbers(row,col,numbers)
|
||
|
adjacents = []
|
||
|
matches = [
|
||
|
[row-1,col-1],
|
||
|
[row-1,col,],
|
||
|
[row-1,col+1],
|
||
|
[row,col-1],
|
||
|
[row,col+1],
|
||
|
[row+1,col-1],
|
||
|
[row+1,col],
|
||
|
[row+1,col+1]
|
||
|
]
|
||
|
numbers.each do |number|
|
||
|
num, row, cols = number
|
||
|
cols.each do |col|
|
||
|
if matches.include? [row,col]
|
||
|
adjacents << num
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
adjacents
|
||
|
end
|
||
|
|
||
|
# result should a single string or integer
|
||
|
def calculate(data)
|
||
|
result = ""
|
||
|
symbols, numbers = data
|
||
|
selected_numbers = []
|
||
|
symbols.each do |symbol|
|
||
|
row,col = symbol
|
||
|
adj = find_adjacent_numbers(row,col,numbers)
|
||
|
if adj.length == 2
|
||
|
selected_numbers << adj.first * adj.last
|
||
|
end
|
||
|
end
|
||
|
|
||
|
result = selected_numbers.reduce(&:+)
|
||
|
|
||
|
result
|
||
|
end
|