Day 21
Another nice puzzle today - we finally got the annual iterative game from Eric!
Part 1 is pretty easy. You may notice a few tricks I used; instead of simulating both players per loop, I just switch the index of the player using modular arithmetic (used a lot in this solution - it's very useful!).
Part 2 was a notably harder - there had to be some sort of efficient route to solve this problem. I just programmed a recursive function which calls itself for every possible universe with the same rules, and a similar player switching technique - by only manipulating p1's metrics, I can call the function recursively switching the positions of the players' metrics to enable the other play to play their turn. The key to this problem was dynamic problem/memoisation. Of course, if you went the non-lazy route you could implement a dictionary with previous known results given a state of the game. However, I just imported cache from functools and use that to cache my previous results. This achieves the same effect but with a lot less effort! To keep track of the score, I returned a list with the first number being the wins for player 1, and the second being the wins for player 2. I selected the larger of the two to print as my answer.
Okay, when are we going to have to use Day 16's BITS...? Or was Eric just fooling us....