private (int winner, long score) PlayRecursiveCombat_WithHashing(IEnumerable <int> deck1cards, IEnumerable <int> deck2cards) { var deck1 = new HashQueue(deck1cards); var deck2 = new HashQueue(deck2cards); var cache = new HashSet <(long, long)>(); int GetRoundWinner(int card1, int card2) { if (card1 <= deck1.Count && card2 <= deck2.Count) { return(PlayRecursiveCombat_WithHashing(deck1.Take(card1), deck2.Take(card2)).winner); } return(card1 > card2 ? 1 : 2); } while (deck1.Any() && deck2.Any()) { var state = (deck1.Hash, deck2.Hash); if (!cache.Add(state)) { return(1, GetWinnerScore(deck1, deck2)); } var card1 = deck1.Dequeue(); var card2 = deck2.Dequeue(); var winner = GetRoundWinner(card1, card2); var winnerDeck = winner == 1 ? deck1 : deck2; winnerDeck.Enqueue(winner == 1 ? card1 : card2); winnerDeck.Enqueue(winner == 1 ? card2 : card1); } return(winner: deck1.Any() ? 1 : 2, GetWinnerScore(deck1, deck2)); }