Advent of Code 2020: Day 7 (Ruby solution)
This time the puzzle is a little bit harder.
You get text instructions in not-trivial to parse form, like:
- striped white bags contain 4 drab silver bags.
- drab silver bags contain no other bags.
- pale plum bags contain 1 dark black bag.
- muted gold bags contain 1 wavy red bag, 3 mirrored violet bags, 5 bright gold bags, 5 plaid white bags.
Obviously, the file is much longer.
So the first intuitive step is to parse them to ruby structure like Hash:
file = File.read('inputs/day7.txt')
@bags_hash = {}
file.each_line do |line|
bags_params = line.scan(/(?:\d+ )?[[:alpha:]]+ [[:alpha:]]+(?= bags?)/)
@bags_hash[bags_params[0]] = {}
bags_params[1..].each do |bag|
next if bag == 'no other'
expression_params = bag.split(/(?<=\d) /)
quantity = expression_params.size == 1 ? 1 : expression_params.first.to_i
color_name = expression_params.last
@bags_hash[bags_params[0]][color_name] = quantity
end
end
The first task is to count how many bag colors can eventually contain at least one "shiny gold bag". I do it this way:
def bag_include_requested_color_bag? color_bag, requested_color_bag
return true if @bags_hash[color_bag].keys.include? requested_color_bag
return @bags_hash[color_bag].any? do |key, value|
bag_include_requested_color_bag?(key, requested_color_bag)
end
end
res = @bags_hash.keys.sum do |color|
bag_include_requested_color_bag?(color, 'shiny gold') ? 1 : 0
end
puts "First task answer: #{res}"
Another task is to find how many individual bags are required inside a single "shiny gold bag". Here is my code:
def bags_count color_bag, quantity
quantity + @bags_hash[color_bag].sum do |key, value|
quantity * bags_count(key, value)
end
end
res = @bags_hash['shiny gold'].sum do |key, value|
value * bags_count(key, 1)
end
puts "Second task answer: #{res}"