mirror of
https://github.com/seigler/aoc2021
synced 2025-07-27 01:16:09 +00:00
day 21
This commit is contained in:
parent
36173c1a15
commit
9a7167c3b0
4 changed files with 109 additions and 15 deletions
|
@ -299,16 +299,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"part1": {
|
"part1": {
|
||||||
"solved": false,
|
"solved": true,
|
||||||
"result": null,
|
"result": "1002474",
|
||||||
"attempts": [],
|
"attempts": [],
|
||||||
"time": null
|
"time": 0.08
|
||||||
},
|
},
|
||||||
"part2": {
|
"part2": {
|
||||||
"solved": false,
|
"solved": true,
|
||||||
"result": null,
|
"result": "919758187195363",
|
||||||
"attempts": [],
|
"attempts": [],
|
||||||
"time": null
|
"time": 147.4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
18
README.md
18
README.md
|
@ -31,7 +31,7 @@
|
||||||
[](src/day18)
|
[](src/day18)
|
||||||

|

|
||||||

|

|
||||||

|
[](src/day21)
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
@ -188,9 +188,9 @@ Both parts: 430.38ms
|
||||||
|
|
||||||
```
|
```
|
||||||
Day 18
|
Day 18
|
||||||
Time part 1: 38.77ms
|
Time part 1: 35.41ms
|
||||||
Time part 2: 147.3ms
|
Time part 2: 268.36ms
|
||||||
Both parts: 186.07000000000002ms
|
Both parts: 303.77ms
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -209,9 +209,9 @@ Both parts: -
|
||||||
|
|
||||||
```
|
```
|
||||||
Day 21
|
Day 21
|
||||||
Time part 1: -
|
Time part 1: 0.08ms
|
||||||
Time part 2: -
|
Time part 2: 147.4ms
|
||||||
Both parts: -
|
Both parts: 147.48000000000002ms
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -243,8 +243,8 @@ Both parts: -
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
Total stars: 36/50
|
Total stars: 38/50
|
||||||
Total time: 2519.45ms
|
Total time: 2784.6299999999997ms
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--/RESULTS-->
|
<!--/RESULTS-->
|
||||||
|
|
9
src/day21/README.md
Normal file
9
src/day21/README.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# 🎄 Advent of Code 2021 - day 21 🎄
|
||||||
|
|
||||||
|
## Info
|
||||||
|
|
||||||
|
Task description: [link](https://adventofcode.com/2021/day/21)
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
...
|
85
src/day21/index.js
Normal file
85
src/day21/index.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import run from "aocrunner"
|
||||||
|
|
||||||
|
const parseInput = (rawInput) => rawInput.match(/(?<=: )\d+/g).map(x=>+x)
|
||||||
|
|
||||||
|
const part1 = (rawInput) => {
|
||||||
|
const [aStart, bStart] = parseInput(rawInput)
|
||||||
|
let a = aStart, b = bStart, aScore = 0, bScore = 0, isATurn = true
|
||||||
|
let die = 0, numRolls = 0
|
||||||
|
function roll() {
|
||||||
|
numRolls++
|
||||||
|
return (die = die % 100 + 1)
|
||||||
|
}
|
||||||
|
while (aScore < 1000 && bScore < 1000) {
|
||||||
|
const rolls = [roll(),roll(),roll()]
|
||||||
|
if (isATurn) {
|
||||||
|
a += rolls[0] + rolls[1] + rolls[2]
|
||||||
|
a = (a - 1) % 10 + 1
|
||||||
|
aScore += a
|
||||||
|
} else {
|
||||||
|
b += rolls[0] + rolls[1] + rolls[2]
|
||||||
|
b = (b - 1) % 10 + 1
|
||||||
|
bScore += b
|
||||||
|
}
|
||||||
|
isATurn = !isATurn
|
||||||
|
}
|
||||||
|
return Math.min(aScore, bScore) * numRolls
|
||||||
|
}
|
||||||
|
|
||||||
|
const frequencies = []
|
||||||
|
for (let i = 1; i <= 3; i++)
|
||||||
|
for (let j = 1; j <= 3; j++)
|
||||||
|
for (let k = 1; k <= 3; k++) {
|
||||||
|
frequencies[i + j + k] = (frequencies[i + j + k] ?? 0) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const part2 = (rawInput) => {
|
||||||
|
const [aStart, bStart] = parseInput(rawInput)
|
||||||
|
const memo = []
|
||||||
|
const winThreshold = 21
|
||||||
|
function countWins(aScore, bScore, aPos, bPos, isATurn) {
|
||||||
|
let existing = memo[[aScore, bScore, aPos, bPos, isATurn]]
|
||||||
|
if (existing !== undefined) return existing
|
||||||
|
if (aScore >= winThreshold) {
|
||||||
|
memo[[aScore, bScore, aPos, bPos, isATurn]] = [1, 0]
|
||||||
|
return [1, 0]
|
||||||
|
}
|
||||||
|
if (bScore >= winThreshold) {
|
||||||
|
memo[[aScore, bScore, aPos, bPos, isATurn]] = [0, 1]
|
||||||
|
return [0, 1]
|
||||||
|
}
|
||||||
|
let totalWins = [0, 0]
|
||||||
|
for (let diceSum = 3; diceSum <= 9; diceSum++) {
|
||||||
|
let thisWin
|
||||||
|
if (isATurn) {
|
||||||
|
const nextAPos = (aPos - 1 + diceSum) % 10 + 1
|
||||||
|
thisWin = countWins(aScore + nextAPos, bScore, nextAPos, bPos, !isATurn)
|
||||||
|
} else {
|
||||||
|
const nextBPos = (bPos - 1 + diceSum) % 10 + 1
|
||||||
|
thisWin = countWins(aScore, bScore + nextBPos, aPos, nextBPos, !isATurn)
|
||||||
|
}
|
||||||
|
totalWins = [totalWins[0] + frequencies[diceSum] * thisWin[0], totalWins[1] + frequencies[diceSum] * thisWin[1]]
|
||||||
|
}
|
||||||
|
memo[[aScore, bScore, aPos, bPos, isATurn]] = totalWins
|
||||||
|
return totalWins
|
||||||
|
}
|
||||||
|
return Math.max(...countWins(0, 0, aStart, bStart, true))
|
||||||
|
}
|
||||||
|
|
||||||
|
run({
|
||||||
|
part1: {
|
||||||
|
tests: [
|
||||||
|
{ input: `Player 1 starting position: 4
|
||||||
|
Player 2 starting position: 8`, expected: 739785 },
|
||||||
|
],
|
||||||
|
solution: part1,
|
||||||
|
},
|
||||||
|
part2: {
|
||||||
|
tests: [
|
||||||
|
{ input: `Player 1 starting position: 4
|
||||||
|
Player 2 starting position: 8`, expected: 444356092776315 },
|
||||||
|
],
|
||||||
|
solution: part2,
|
||||||
|
},
|
||||||
|
trimTestInputs: true,
|
||||||
|
})
|
Loading…
Add table
Add a link
Reference in a new issue