# Advent of Code 2020: Day 7 (Ruby solution)

Subscribe to my newsletter and never miss my upcoming articles

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

``````

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