available, desired = DATA.read.split("\n\n") available = available.split(", ") desired = desired.lines(chomp: true) available_r = Regexp.new("^(#{available.join(?|)})+$") pp desired.select { _1 =~ available_r }.size ways = Hash.new {|h,k| h[k] = available .select { k.start_with?(_1) } .map { k.sub(_1, "") } .sum { h[_1] } } ways[""] = 1 pp desired.sum { ways[_1] } __END__ r, wr, b, g, bwu, rb, gb, br brwrr bggr gbbr rrbgbr ubwu bwurrg brgr bbrgwb