Code for the Advent of Code event
aoc advent-of-code
at main 71 lines 1.7 kB view raw
1#!/usr/bin/env ruby 2# frozen_string_literal: true 3 4PLAYER_1 = ARGF.readline.split(':')[1].to_i - 1 5PLAYER_2 = ARGF.readline.split(':')[1].to_i - 1 6 7player_1_score = 0 8player_2_score = 0 9 10die = 0 11die_rolls = 0 12 13player1 = PLAYER_1 14player2 = PLAYER_2 15 16(0..).each do |n| 17 die_value = die + 1 18 die = (die + 1) % 100 19 die_value += die + 1 20 die = (die + 1) % 100 21 die_value += die + 1 22 die = (die + 1) % 100 23 die_rolls += 3 24 if n.even? 25 player1 = (player1 + die_value) % 10 26 player_1_score += player1 + 1 27 else 28 player2 = (player2 + die_value) % 10 29 player_2_score += player2 + 1 30 end 31 break if player_1_score >= 1000 || player_2_score >= 1000 32end 33 34puts [player_1_score, player_2_score].min * die_rolls 35 36OUTCOMES = [1, 2, 3].repeated_permutation(3).map(&:sum).tally 37CACHE = {} # rubocop:disable Style/MutableConstant 38 39def dirac(flag = true, p1 = 0, p2 = 0, p1_score = 0, p2_score = 0) # rubocop:disable Style/OptionalBooleanParameter 40 cache_key = [flag, p1, p2, p1_score, p2_score] 41 return CACHE[cache_key] if CACHE.key? cache_key 42 43 return [1, 0] if p1_score >= 21 44 return [0, 1] if p2_score >= 21 45 46 result = [0, 0] 47 48 if flag 49 OUTCOMES.each do |outcome, count| 50 p1_o = (p1 + outcome) % 10 51 p1_o_s = p1_score + p1_o + 1 52 o_r = dirac(false, p1_o, p2, p1_o_s, p2_score) 53 result[0] += o_r[0] * count 54 result[1] += o_r[1] * count 55 end 56 else 57 OUTCOMES.each do |outcome, count| 58 p2_o = (p2 + outcome) % 10 59 p2_o_s = p2_score + p2_o + 1 60 o_r = dirac(true, p1, p2_o, p1_score, p2_o_s) 61 result[0] += o_r[0] * count 62 result[1] += o_r[1] * count 63 end 64 end 65 66 CACHE[cache_key] = result 67 68 result 69end 70 71puts dirac(true, PLAYER_1, PLAYER_2).max