this repo has no description
at master 1.8 kB view raw
1<!-- vim:ft=markdown --> 2 3<!-- livebook:{"persist_outputs":true} --> 4 5# Day 21 6 7## Section 8 9```elixir 10input = File.read!("day21.txt") 11 12[[_, p1], [_, p2]] = Regex.scan(~r/: (\d)/, input) 13 14p1 = String.to_integer(p1) 15p2 = String.to_integer(p2) 16 17{p1, p2} 18``` 19 20<!-- livebook:{"output":true} --> 21 22``` 23{3, 5} 24``` 25 26```elixir 27round = 28 Stream.unfold(0, &{&1, &1 + 1}) 29 |> Stream.scan({{0, p1}, {0, p2}}, fn n, {{s, p}, other} -> 30 p = rem(p - 1 + 6 + n * 9, 10) + 1 31 32 {other, {s + p, p}} 33 end) 34 |> Enum.take_while(fn {{s, _}, {_, _}} -> s < 1000 end) 35 36{rounds, {{loser, _}, _}} = {length(round), List.last(round)} 37 38rounds * 3 * loser 39``` 40 41<!-- livebook:{"output":true} --> 42 43``` 44720750 45``` 46 47```elixir 48defmodule Day21.Task2 do 49 def play(p1, p2) do 50 tid = :ets.new(__MODULE__, []) 51 {a, b} = cached_round({p1 - 1, 0}, {p2 - 1, 0}, tid) 52 :ets.delete(tid) 53 max(a, b) 54 end 55 56 defp cached_round(a, b, tid) do 57 case :ets.lookup(tid, {a, b}) do 58 [{_, v}] -> 59 v 60 61 [] -> 62 value = round(a, b, tid) 63 64 :ets.insert(tid, {{a, b}, value}) 65 66 value 67 end 68 end 69 70 defp round({_, s}, _, _) when s >= 21, do: {1, 0} 71 defp round(_, {_, s}, _) when s >= 21, do: {0, 1} 72 73 defp round({pos, score}, p2, tid) do 74 for a <- 1..3, b <- 1..3, c <- 1..3, reduce: {0, 0} do 75 {wins1, wins2} -> 76 next = rem(pos + a + b + c, 10) 77 78 {nscore2, nscore1} = 79 cached_round( 80 p2, 81 {next, score + next + 1}, 82 tid 83 ) 84 85 {wins1 + nscore1, wins2 + nscore2} 86 end 87 end 88end 89``` 90 91<!-- livebook:{"output":true} --> 92 93``` 94{:module, Day21.Task2, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:round, 3}} 95``` 96 97```elixir 98Day21.Task2.play(p1, p2) 99``` 100 101<!-- livebook:{"output":true} --> 102 103``` 104275067741811212 105```