1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cards = ARGF.read.scan(/Card\s+(\d+):+((?~\|))\|(.*)/)
  .to_h {|id, *v|
    [id.to_i, v.map { _1.scan(/\d+/).map(&:to_i) }]
  }

# part one
p cards.values
  .map {|winning,card|
    winners = (card & winning)
    winners.empty? ? 0 : 2 ** (winners.length - 1)
  }
  .sum

# part two
wins = Hash.new {|h,k|
  winning, card = cards.fetch(k)
  winners = winning & card
  new_cards = (1..winners.length).map { k + _1 }

  h[k] = 1 + (winners.empty? ? 0 : new_cards.sum { h[_1] })
}
p cards.keys.sum { wins[_1] }