Skip to content

Instantly share code, notes, and snippets.

@Robert-Wett
Last active January 17, 2019 03:00
Show Gist options
  • Save Robert-Wett/a8a5e14252a6da8f080e475484240cc3 to your computer and use it in GitHub Desktop.
Save Robert-Wett/a8a5e14252a6da8f080e475484240cc3 to your computer and use it in GitHub Desktop.
class Player {
constructor(id) {
this.id = id;
this.score = 0;
}
}
/*
[2] 0 (2) 1 // PREV: 1, LEN: 2, NEW: 1
[3] 0 2 1 (3) // PREV: 1, LEN: 3, NEW: 3
[4] 0 (4) 2 1 3 // PREV: 3, LEN: 4, NEW: 1
[5] 0 4 2 (5) 1 3 // PREV: 2, LEN: 5, NEW: 3
[6] 0 4 2 5 1 (6) 3 // PREV: 3, LEN: 6, NEW: 5
[7] 0 4 2 5 1 6 3 (7) // PREV: 5, LEN: 7, NEW: 7
[8] 0 (8) 4 2 5 1 6 3 7 // PREV: 7, LEN: 8, NEW: 1
[9] 0 8 4 (9) 2 5 1 6 3 7 // PREV: 1, LEN: 9, NEW: 3
[1] 0 16 8 17 4 18 9(19) 2 10 5 11 1 12 6 13 3 14 7 15 // PREV: 5, LEN: 19, NEW: 7
[2] 0 16 8 17 4 18 9 19 2(20)10 5 11 1 12 6 13 3 14 7 15 // PREV: 7, LEN: 20, NEW: 9
[3] 0 16 8 17 4 18 9 19 2 20 10(21) 5 11 1 12 6 13 3 14 7 15 // PREV: 9, LEN: 21, NEW: 11
[4] 0 16 8 17 4 18 9 19 2 20 10 21 5(22)11 1 12 6 13 3 14 7 15 // PREV: 11, LEN: 22, NEW: 13
[5] 0 16 8 17 4 18(19) 2 20 10 21 5 22 11 1 12 6 13 3 14 7 15 // PREV: 13, LEN: 23, NEW: 6
[6] 0 16 8 17 4 18 19 2(24)20 10 21 5 22 11 1 12 6 13 3 14 7 15 // PREV: 6, LEN: 24, NEW: 8
[7] 0 16 8 17 4 18 19 2 24 20(25)10 21 5 22 11 1 12 6 13 3 14 7 15
*/
// PREV: 5, LEN: 23, NEW:
class Node {
constructor(val, prev, next) {
this.value = val;
this.prev = prev;
this.next = next;
}
}
class LinkedList {
constructor(head, tail) {
let [h, t] = [new Node(head), new Node(tail)];
h.next = t;
t.next = h;
this.curNode = t;
}
next() {
this.curNode = this.curNode.next;
console.log(this.curNode.value);
}
remove() {
this.curNode.prev =
this.prev.next = this.next;
this.next.prev = this.prev;
let value = this.value;
this.prev = this.next = this.value = null;
return value;
}
}
const simulateGame = (numPlayers, lastMarble) => {
const players = [];
for (let i = 0; i < numPlayers; i++) {
players.push(new Player(i));
}
let turn = 2;
let board = [0, 1];
let prev;
for (turn; turn < lastMarble; turn++) {
let player = players[turn % (numPlayers - 1)];
[board, prev] = takeTurn(board, player, turn, prev);
}
return players;
};
const simulateGame2 = (numPlayers, lastMarble) => {
const players = [];
for (let i = 0; i < numPlayers; i++) {
players.push(new Player(i));
}
let game = {
board: [0, 1],
turn: 2,
prev: 1
}
for (game.turn; game.turn <= lastMarble; game.turn++) {
let player = players[game.turn % (numPlayers - 1)];
takeTurn2(game, player);
}
return players;
};
const printBoard = (board, i) => {
return;
let hi = board.map((marble, idx) => {
if (idx === i) {
return `(${marble})`;
}
return marble;
})
console.log(hi.join(' '));
}
const takeTurn2 = (game, player) => {
const prevMarbleIdx = game.prev;
if (game.turn % 23 === 0) {
/*
let offset =
prevMarbleIdx - 7 > 0 ? prevMarbleIdx - 7 : game.board.length - Math.abs(prevMarbleIdx - 7);
*/
const offset = (prevMarbleIdx - 7 + game.board.length) % game.board.length;
const score = game.board.splice(offset, 1)[0]
//player.score += game.board.splice(offset, 1)[0];
player.score += (score+game.turn);
game.prev = offset;
printBoard(game.board, offset);
return;
}
// Regular marble
let newMarbleIdx = (prevMarbleIdx + 2) % game.board.length;
if (newMarbleIdx === 0) {
game.board.push(game.turn);
game.prev = game.board.indexOf(game.turn);
printBoard(game.board, game.prev);
return;
}
game.prev = newMarbleIdx;
game.board = game.board
.slice(0, newMarbleIdx)
.concat([game.turn])
.concat(game.board.slice(newMarbleIdx, game.board.length));
printBoard(game.board, newMarbleIdx);
};
const takeTurn = (board, player, marble, prevMarble) => {
const prevMarbleIdx = prevMarble || board.indexOf(marble - 1);
if (marble % 23 === 0) {
player.score += marble;
let offset =
prevMarbleIdx - 7 > 0 ? prevMarbleIdx - 7 : board.length - Math.abs(prevMarbleIdx - 7);
if (offset === board.length) {
}
player.score += board.splice(offset, offset + 1)[0];
return [board, offset];
}
// Regular marble
let newMarbleIdx = (prevMarbleIdx + 2) % board.length;
if (newMarbleIdx === 0) {
board.push(marble);
return [board, ];
}
return [
board
.slice(0, newMarbleIdx)
.concat([marble])
.concat(board.slice(newMarbleIdx, board.length)),
];
};
let output = '';
const tests = () => {
let passed = true;
[
{
input: {
numPlayers: 7,
highMarble: 25
},
expected: 32
},
{
input: {
numPlayers: 9,
highMarble: 25
},
expected: 32
},
{
input: {
numPlayers: 10,
highMarble: 1618
},
expected: 8317
},
{
input: {
numPlayers: 13,
highMarble: 7999
},
expected: 146373
},
{
input: {
numPlayers: 17,
highMarble: 1104
},
expected: 2764
},
{
input: {
numPlayers: 21,
highMarble: 6111
},
expected: 54718
},
{
input: {
numPlayers: 30,
highMarble: 5807
},
expected: 37305
}
].forEach(({ input, expected }, index) => {
try {
const players = simulateGame2(input.numPlayers, input.highMarble);
const actual = players.reduce((acc, p) => {
if (acc > p.score) return acc;
return p.score;
}, 0);
if (actual !== expected) {
output += `\n Failed test #${index + 1}: Expected ${expected}, got ${actual}.`;
passed = false;
}
} catch (e) {
console.log(e);
passed = false;
}
});
console.log(output);
if (!passed) {
process.exit(1);
}
};
//tests();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment