This commit is contained in:
Jack Bond-Preston 2018-12-09 15:38:52 +00:00
parent 560fe542e6
commit 3e70ac4498
3 changed files with 205 additions and 0 deletions

1
aoc-9/inputs.txt Normal file
View File

@ -0,0 +1 @@
462 players; last marble is worth 71938 points

188
aoc-9/main.ts Normal file
View File

@ -0,0 +1,188 @@
const fs = require("fs");
function mod(n: number, m: number): number {
return ((n % m) + m) % m;
}
interface BoardNode<T> {
prev: BoardNode<T> | null,
data?: T,
next: BoardNode<T> | null
}
// doubly linked "board"
class Board<T> {
private head: BoardNode<T>;
private tail: BoardNode<T>;
private current: BoardNode<T> | 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<T> {
let next: BoardNode<T>;
let prev: BoardNode<T>;
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<T> {
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<T> {
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<T> {
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<T> = 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<number>;
currentPlayer: number;
}
class Game {
private board: Board<number>;
private roundNo: number;
private players: Players;
constructor(numPlayers: number) {
this.players = {
scores: Array(numPlayers).fill(0),
currentPlayer: 0
}
this.board = new Board<number>();
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());

16
aoc-9/package.json Normal file
View File

@ -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"
}