66 lines
1.6 KiB
Crystal
66 lines
1.6 KiB
Crystal
|
require "advent"
|
||
|
|
||
|
def parse_range(str)
|
||
|
data = str.match(/([a-z ]+): (\d+)-(\d+) or (\d+)-(\d+)/).not_nil!
|
||
|
return {data[1], (data[2].to_i32..data[3].to_i32), (data[4].to_i32.. data[5].to_i32)}
|
||
|
end
|
||
|
|
||
|
fields, your, nearby = input(2020, 16).split("\n\n")
|
||
|
fields = fields.lines.map { |l| parse_range(l) }
|
||
|
your = your.lines[1].split(",").map(&.to_i32)
|
||
|
nearby = nearby.lines[1..].map(&.split(",").map(&.to_i32))
|
||
|
|
||
|
def part1(input)
|
||
|
fields, your, nearby = input
|
||
|
all_ranges = [] of Range(Int32, Int32)
|
||
|
fields.each do |a|
|
||
|
all_ranges << a[1] << a[2]
|
||
|
end
|
||
|
nearby.select! do |nb|
|
||
|
nb.all? do |n|
|
||
|
all_ranges.any? &.includes?(n)
|
||
|
end
|
||
|
end
|
||
|
nearby << your
|
||
|
field_map = {} of String => Set(Int32)
|
||
|
fields.each do |f|
|
||
|
field_map[f[0]] = Set(Int32).new
|
||
|
nearby[0].size.times do |i|
|
||
|
next if field_map.values.includes? i
|
||
|
all_match = nearby.all? do |nb|
|
||
|
f[1].includes?(nb[i]) || f[2].includes?(nb[i])
|
||
|
end
|
||
|
if all_match
|
||
|
field_map[f[0]] << i
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
sum = 1_u64
|
||
|
numbers = (0...nearby[0].size).to_a
|
||
|
solved = {} of String => Int32
|
||
|
while solved.size != fields.size
|
||
|
cleared = [] of {String, Int32}
|
||
|
field_map.each do |k, v|
|
||
|
next unless v.size == 1
|
||
|
cleared << {k, v.to_a[0]}
|
||
|
end
|
||
|
cleared.each do |f,n|
|
||
|
solved[f] = n
|
||
|
field_map.each do |k, v|
|
||
|
v.delete n
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
fields.each do |f|
|
||
|
next unless f[0].starts_with? "departure"
|
||
|
sum *= your[solved[f[0]]]
|
||
|
end
|
||
|
sum
|
||
|
end
|
||
|
|
||
|
def part2(input)
|
||
|
end
|
||
|
|
||
|
puts part1({fields, your, nearby})
|
||
|
puts part2({fields, your, nearby})
|