Skip to content

Commit e545afc

Browse files
committed
feat(day04): Part 1
1 parent ee55eca commit e545afc

File tree

2 files changed

+313
-0
lines changed

2 files changed

+313
-0
lines changed

day04_test.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { assertEquals } from "https://deno.land/std@0.208.0/assert/assert_equals.ts";
2+
import { sum } from "./util/sum.ts";
3+
4+
const card1 = `Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53`;
5+
const card2 = `Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19`;
6+
const card3 = `Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1`;
7+
const card4 = `Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83`;
8+
const card5 = `Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36`;
9+
const card6 = `Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11`;
10+
11+
Deno.test("Day 4: Scratchcards", async (t) => {
12+
await t.step("Part 1", async (t) => {
13+
await t.step("Example", async (t) => {
14+
for (const [card, expectedWinningNumbers, expectedPoints] of [
15+
[card1, [48, 83, 17, 86], 8],
16+
[card2, [32, 61], 2],
17+
[card3, [1, 21], 2],
18+
[card4, [84], 1],
19+
[card5, [], 0],
20+
[card6, [], 0],
21+
] as [string, Array<number>, number][]) {
22+
await t.step(
23+
`card ${card} should have the winning numbers ${expectedWinningNumbers}`,
24+
() =>
25+
assertEquals(winningNumbers(card), new Set(expectedWinningNumbers))
26+
);
27+
28+
await t.step(`card ${card} should score ${expectedPoints} points`, () =>
29+
assertEquals(cardScore(card), expectedPoints)
30+
);
31+
}
32+
33+
await t.step("Sum of pile", () =>
34+
assertEquals(
35+
sum([card1, card2, card3, card4, card5, card6].map(cardScore)),
36+
13
37+
)
38+
);
39+
});
40+
41+
await t.step("Solution", async () =>
42+
assertEquals(
43+
sum(
44+
(await Deno.readTextFile("./input/day04.txt"))
45+
.split("\n")
46+
.map(cardScore)
47+
),
48+
28538
49+
)
50+
);
51+
});
52+
53+
await t.step("parseCard()", () =>
54+
assertEquals(parseCard(card3), [
55+
new Set([1, 21, 53, 59, 44]),
56+
new Set([69, 82, 63, 72, 16, 21, 14, 1]),
57+
])
58+
);
59+
});
60+
61+
const winningNumbers = (cardInfo: string): Set<number> => {
62+
const [winningNumbers, cardNumbers] = parseCard(cardInfo);
63+
const winners = new Set<number>();
64+
for (const number of cardNumbers.values()) {
65+
if (winningNumbers.has(number)) winners.add(number);
66+
}
67+
return winners;
68+
};
69+
const cardScore = (cardInfo: string): number =>
70+
winningNumbers(cardInfo).size === 0
71+
? 0
72+
: (1 * Math.pow(2, winningNumbers(cardInfo).size)) / 2;
73+
74+
const parseCard = (cardInfo: string): [Set<number>, Set<number>] => {
75+
const [, winningNumbers, cardNumbers] =
76+
/^Card +\d+: ([\d ]+)+ \| ([\d ]+)+/.exec(cardInfo) ?? [];
77+
return [
78+
new Set(
79+
winningNumbers
80+
.trim()
81+
.replace(/ +/g, " ")
82+
.split(" ")
83+
.map((s) => parseInt(s, 10))
84+
),
85+
new Set(
86+
cardNumbers
87+
.trim()
88+
.replace(/ +/g, " ")
89+
.split(" ")
90+
.map((s) => parseInt(s, 10))
91+
),
92+
];
93+
};

0 commit comments

Comments
 (0)