8 votes

Day 22: Crab Combat

Today's problem description: https://adventofcode.com/2020/day/22


Join the Tildes private leaderboard! You can do that on this page, by entering join code 730956-de85ce0c.

Please post your solutions in your own top-level comment. Here's a template you can copy-paste into your comment to format it nicely, with the code collapsed by default inside an expandable section with syntax highlighting (you can replace python with any of the "short names" listed in this page of supported languages):

<details>
<summary>Part 1</summary>

```python
Your code here.
```

</details>

2 comments

  1. pnutzh4x0r
    Link
    Python Repo Link Part 1 Wow... compared to the past few days, the problem today was pretty straightforward (much more similar to the problems during the first week). I just implemented the game as...

    Python

    Repo Link

    Part 1

    Wow... compared to the past few days, the problem today was pretty straightforward (much more similar to the problems during the first week). I just implemented the game as described and that was it.

    import sys
    
    # Functions
    
    def read_hand(stream=sys.stdin):
        hand = []
        while card := stream.readline().strip():
            if card.isdigit():
                hand.append(int(card))
        return hand
    
    def play_game(hand1, hand2):
        while hand1 and hand2:
            card1 = hand1.pop(0)
            card2 = hand2.pop(0)
    
            if card1 > card2:
                hand1.append(card1)
                hand1.append(card2)
            else:
                hand2.append(card2)
                hand2.append(card1)
    
        return hand1 if hand1 else hand2
    
    def compute_score(winner):
        return sum(card * index for index, card in enumerate(winner[::-1], 1))
    
    # Main Execution
    
    def main():
        hand1  = read_hand()
        hand2  = read_hand()
        winner = play_game(hand1, hand2)
        score  = compute_score(winner)
    
        print(score)
    
    if __name__ == '__main__':
        main()
    
    Part 2

    I almost went to bed because the recursive game seemed too confusing to implement, but I decided to buckle down and just go bullet by bullet point. This is reflected in the commented sections below... I found placing those comments as really useful for figuring out what exactly I needed to do to implement the game.

    That said, once you see what is going on, then it really it just a matter of coding in the rules of the game as described. I did make a dumb mistake of forgetting to add the current configuration to the cache... which lead to the infinite loop the write-up warns about. After a few minutes of tracing, I realized my mistake and was able to fix it.

    import sys
    
    # Functions
    
    def read_hand(stream=sys.stdin):
        hand = []
        while card := stream.readline().strip():
            if card.isdigit():
                hand.append(int(card))
        return hand
    
    def play_game(hand1, hand2):
        configurations = set()
    
        while hand1 and hand2:
            # 1. Check configuration
            configuration = (tuple(hand1), tuple(hand2))
            if configuration in configurations:
                return 1
    
            configurations.add(configuration)
    
            # 2. Draw top card from decks
            card1 = hand1.pop(0)
            card2 = hand2.pop(0)
    
            # 3. Both players have at least as many cards remaining in deck as
            # value of the card they drew
            if len(hand1) >= card1 and len(hand2) >= card2:
                winner = play_game(hand1[:card1], hand2[:card2])
            else:
                winner = 1 if card1 > card2 else 2
    
            # 4. Winner of round takes both cards
            if winner == 1:
                hand1.append(card1)
                hand1.append(card2)
            else:
                hand2.append(card2)
                hand2.append(card1)
    
        return 1 if hand1 else 2
    
    def compute_score(winner):
        return sum(card * index for index, card in enumerate(winner[::-1], 1))
    
    # Main Execution
    
    def main():
        hand1  = read_hand()
        hand2  = read_hand()
        winner = hand1 if play_game(hand1, hand2) == 1 else hand2
        score  = compute_score(winner)
    
        print(score)
    
    if __name__ == '__main__':
        main()
    
    3 votes
  2. tomf
    Link
    well, I can do part one with sheets. I may have been able to do part 2, but recursion is always an issue. this is the crazy sheet with 2323 formulas :)

    well, I can do part one with sheets. I may have been able to do part 2, but recursion is always an issue.

    this is the crazy sheet with 2323 formulas :)

    1 vote