[2021][ruby][21.x]
change tnwowlnsmnowxqxlypkvnwqymrxwqwnk
commit 68a5a86a5f62e613ec0400c3f93bc0aa99e0e524
author Alpha Chen <alpha@kejadlen.dev>
date
parent zvvnrxwy
diff --git a/2021/ruby/day_21.rb b/2021/ruby/day_21.rb
new file mode 100644
index 0000000..497b33e
--- /dev/null
+++ b/2021/ruby/day_21.rb
@@ -0,0 +1,76 @@
+# Player = Struct.new(:space, :score)
+# one = Player.new(7, 0)
+# two = Player.new(3, 0)
+
+# class Die
+#   def initialize
+#     @value = 0
+#     @rolls = 0
+#   end
+
+#   attr_reader :rolls
+
+#   def roll
+#     value = @value
+
+#     @value += 1
+#     @value %= 100
+
+#     @rolls += 1
+
+#     value
+#   end
+# end
+# die = Die.new
+
+# loop do
+#   one.space += 3.times.sum { die.roll + 1 }
+#   one.space %= 10
+#   one.score += one.space + 1
+#   break if one.score >= 1000
+
+#   two.space += 3.times.sum { die.roll + 1 }
+#   two.space %= 10
+#   two.score += two.space + 1
+#   break if two.score >= 1000
+# end
+
+# p [one, two].map(&:score).min * die.rolls
+
+ROLLS = (1..3).flat_map {|a| (1..3).flat_map {|b| (1..3).map {|c|
+  [a, b, c].sum
+}}}.tally
+Player = Struct.new(:score, :space, keyword_init: true)
+wins = Hash.new {|h,k|
+  one, two = k
+
+  multiverse = ROLLS.map {|delta,n|
+    space = (one.space + delta) % 10
+    [Player.new(score: one.score + space + 1, space: space), n]
+  }
+  one_wins, one_ongoing = multiverse.partition {|player,_| player.score >= 21 }
+  one_wins = one_wins.sum(&:last)
+
+  multiverse = ROLLS.map {|delta,n|
+    space = (two.space + delta) % 10
+    [Player.new(score: two.score + space + 1, space: space), n]
+  }
+
+  wins = one_ongoing.flat_map {|one, n_one| multiverse.map {|two, n_two|
+    n = n_one * n_two
+    if two.score >= 21
+      { one: 0, two: n }
+    else
+      h[[one, two]].map { [_1, _2 * n] }.to_h
+    end
+  }}
+  wins = wins.inject({one: 0, two: 0}) {|acc,wins| acc.merge(wins) { _2 + _3 }}
+
+  h[k] = {
+    one: one_wins + wins.fetch(:one),
+    two: wins.fetch(:two),
+  }
+}
+
+# p wins[[Player.new(score: 0, space: 3), Player.new(score: 0, space: 7)]]
+p wins[[Player.new(score: 0, space: 7), Player.new(score: 0, space: 3)]].values.max