-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathpart-two.js
47 lines (40 loc) · 1.47 KB
/
part-two.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const { input } = require('./input');
function parseLine(line) {
// @example `Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53`
const [, cardNum, winningCards, yourHand] = /^Card\s+(\d+): ([^\|]+) \| ([^\|]+)$/.exec(line);
return {
cardNum: parseInt(cardNum, 10),
winningCards: winningCards
.trim()
.split(' ') // Split on single space and remove empties via Boolean filter
.filter(Boolean)
.map((v) => parseInt(v, 10)),
yourHand: yourHand
.trim()
.split(' ')
.filter(Boolean)
.map((v) => parseInt(v, 10)),
};
}
// Use `cardNum - 1` as indices. Each card's count starts at 1 for its own self
const copies = Array(input.length).fill(1);
for (let line of input) {
const { cardNum, winningCards, yourHand } = parseLine(line);
const winningCardsSet = new Set(winningCards);
const haveWins = yourHand.filter((card) => winningCardsSet.has(card));
const cardIndex = cardNum - 1;
// Get current count of number of copies of the current card
const cardCopies = copies[cardIndex];
// If our scratch card was a winner
if (haveWins.length) {
// Figure out which cards we need to get copies of
const nextCardIndices = Array(haveWins.length)
.fill()
.map((_, i) => cardIndex + 1 + i); // e.g. `cardNum + i`
for (let nextCardIndex of nextCardIndices) {
// Each scratch off wins `(1 copy * number of scratchoffs) = cardCopies`, so add that to counts so far
copies[nextCardIndex] += cardCopies;
}
}
}
console.log(copies.reduce((a, b) => a + b, 0));