Are you participating in the Advent of code this year?
If you don't know what the advent of code is, it's a website where you'll find a daily challenge (every day it gets harder). It's a really fun event, you should participate!
I try to solve the exercises using either JavaScript or TypeScript and will share my solutions daily (with one day delay so no one can cheat!). I only share the solution for the second part.
Interesting day! Nothing too complex, no hidden tricks, completely doable step by step. Fun fact, in order to complete the challenge I created a test file with the description of the game (the sample), and made my code return logs instead of the result. Once I had the exact same logs as the sample, I ran the code, and voilà, the solution appeared!
Here is my solution for day #22:
export class RecursiveGame { player1: number[] player2: number[] logs: string[] = [] played = new Set<string>() constructor(deck1: number[], deck2: number[]) { this.player1 = deck1 this.player2 = deck2 } isFinished(): boolean { return this.player1.length === 0 || this.player2.length === 0 } playAll() { while (!this.isFinished()) { this.playTurn() } } playTurn() { // if already happened, game end for player 1 const key = `${this.player1}|${this.player2}` if (this.played.has(key)) { this.player2.length = 0 return } this.played.add(key) const cardPlayer1 = this.player1.shift() const cardPlayer2 = this.player2.shift() if (!cardPlayer1 || !cardPlayer2) throw new Error('game already finished') let winner: 1 | 2 | null if (this.player1.length >= cardPlayer1 && this.player2.length >= cardPlayer2) { const subGame = new RecursiveGame(this.player1.slice(0, cardPlayer1), this.player2.slice(0, cardPlayer2)) subGame.playAll() winner = subGame.getWinner() } else { if (cardPlayer1 > cardPlayer2) { winner = 1 } else { winner = 2 } } if (winner === null) throw new Error('winner cant be found') if (winner === 1) { this.player1.push(cardPlayer1, cardPlayer2) } else { this.player2.push(cardPlayer2, cardPlayer1) } } getWinner(): 1 | 2 { if (this.player1.length === 0) return 2 if (this.player2.length === 0) return 1 throw new Error('not over yet') } getWinnerDeck(): number[] { const winner = [this.player1, this.player2].find((deck) => deck.length !== 0) if (!winner) throw new Error('Game not finished yet') return winner } } function resolve(input: string) { const [deck1, deck2] = input.split('\n\n').map((deck) => { return deck .split('\n') .slice(1) .map((card) => parseInt(card, 10)) }) const game = new RecursiveGame(deck1, deck2) game.playAll() console.log( game.getWinnerDeck().reduce((acc, card, index, deck) => { return acc + (deck.length - index) * card }, 0), ) } resolve(input) Feel free to share your solution in the comments!
Photo by Markus Spiske on Unsplash
Top comments (0)