From 3e70ac4498be94082fac55b815de3ef47e4fc80d Mon Sep 17 00:00:00 2001 From: Jack Bond-Preston Date: Sun, 9 Dec 2018 15:38:52 +0000 Subject: [PATCH] Day 9 --- aoc-9/inputs.txt | 1 + aoc-9/main.ts | 188 +++++++++++++++++++++++++++++++++++++++++++++ aoc-9/package.json | 16 ++++ 3 files changed, 205 insertions(+) create mode 100644 aoc-9/inputs.txt create mode 100644 aoc-9/main.ts create mode 100644 aoc-9/package.json diff --git a/aoc-9/inputs.txt b/aoc-9/inputs.txt new file mode 100644 index 0000000..4ad1485 --- /dev/null +++ b/aoc-9/inputs.txt @@ -0,0 +1 @@ +462 players; last marble is worth 71938 points \ No newline at end of file diff --git a/aoc-9/main.ts b/aoc-9/main.ts new file mode 100644 index 0000000..ac1d5f9 --- /dev/null +++ b/aoc-9/main.ts @@ -0,0 +1,188 @@ +const fs = require("fs"); + +function mod(n: number, m: number): number { + return ((n % m) + m) % m; +} + +interface BoardNode { + prev: BoardNode | null, + data?: T, + next: BoardNode | null +} + +// doubly linked "board" +class Board { + private head: BoardNode; + private tail: BoardNode; + + private current: BoardNode | null; + + constructor() { + this.head = { + prev: null, + next: this.tail + }; + this.tail = { + prev: this.head, + next: null + } + + this.current = null; + } + + isEmpty(): boolean { + return this.head.next == this.tail; + } + + insertAfter(data: T): Board { + let next: BoardNode; + let prev: BoardNode; + + if (this.current == null) { + next = this.tail; + prev = this.head; + } + else { + next = this.current.next; + prev = this.current; + } + + this.current = { + prev: prev, + data: data, + next: next + }; + this.current.prev.next = this.current; + this.current.next.prev = this.current; + + return this; + } + + removeCurrent(): T { + let data: T = this.current.data; + + this.current.prev.next = this.current.next; + this.current.next.prev = this.current.prev; + + if (this.isEmpty()) this.current = null; + else this.next(); + + return data; + } + + next(): Board { + if (this.current == null) return this; + + this.current = this.current.next; + if (this.current == this.tail) this.current = this.head.next; + + return this; + } + + prev(): Board { + if (this.current == null) return this; + + this.current = this.current.prev; + if (this.current == this.head) this.current = this.tail.prev; + + return this; + } + + moveBy(amount: number): Board { + if (amount > 0) { + for (let i = 0; i < amount; i++) { + this.next(); + } + } + if (amount < 0) { + amount = Math.abs(amount); + for (let i = 0; i < amount; i++) { + this.prev(); + } + } + + return this; + } + + toString(): string { + let output: string = "[ "; + + if (this.current != null) { + let node: BoardNode = this.head; + + while (node.next != this.tail) { + node = node.next; + + if (node == this.current) { + output += "(" + node.data + "), "; + } + else { + output += node.data + ", "; + } + } + output = output.slice(0, -2); + } + + output += " ]"; + + return output; + } +} + +interface Players { + scores: Array; + currentPlayer: number; +} + +class Game { + private board: Board; + private roundNo: number; + private players: Players; + + constructor(numPlayers: number) { + this.players = { + scores: Array(numPlayers).fill(0), + currentPlayer: 0 + } + + this.board = new Board(); + this.roundNo = 0; + } + + private nextTurn(): void { + let points: number = 0; + + if (this.roundNo % 23 === 0 && this.roundNo > 0) { + points = this.roundNo + this.board.moveBy(-7).removeCurrent(); + } + else { + this.board.next().insertAfter(this.roundNo); + } + + this.roundNo++; + + this.players.scores[this.players.currentPlayer] += points; + this.players.currentPlayer = (this.players.currentPlayer + 1) % this.players.scores.length; + } + + runUntil(round: number): Game { + while (this.roundNo <= round) { + this.nextTurn(); + } + + return this; + } + + getHighScore(): number { + return Math.max(... this.players.scores); + } +} + +let input: string = fs.readFileSync("inputs.txt", "utf8"); +let numPlayers: number = Number(input.split(' ')[0]); +let lastRound: number = Number(input.split(' ')[6]); + +let game: Game = new Game(numPlayers); + +console.log(game.runUntil(lastRound).getHighScore()); +console.log(game.runUntil(lastRound * 100).getHighScore()); \ No newline at end of file diff --git a/aoc-9/package.json b/aoc-9/package.json new file mode 100644 index 0000000..f5bb31e --- /dev/null +++ b/aoc-9/package.json @@ -0,0 +1,16 @@ +{ + "name": "aoc-9", + "version": "1.0.0", + "description": "", + "main": "main.js", + "dependencies": {}, + "devDependencies": { + "@types/node": "^10.12.12", + "ts-node": "^7.0.1", + "typescript": "^3.2.2" + }, + "scripts": { + "start": "ts-node -O '{\"lib\": [ \"es2017\" ]}' main.ts" + }, + "author": "Jack Bond-Preston" +}