Skip to content

Commit ac0b459

Browse files
authored
Merge pull request #43 from weaponsforge/feat/weaponsforge-16
feat: day 11 plutonian pebbles 20241211
2 parents d919fdb + 975a52e commit ac0b459

File tree

6 files changed

+152
-0
lines changed

6 files changed

+152
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ The codes are structured in a way that discusses and walks through the solution
1919
- Day 8: Resonant Collinearity [[link]](/src/2024/2024-12-08/README.md)
2020
- Day 9: Disk Fragmenter [[link]](/src/2024/2024-12-09/README.md)
2121
- Day 10: Hoof It [[link]](/src/2024/2024-12-10/README.md)
22+
- Day 11: Plutonian Pebbles [[link]](/src/2024/2024-12-11/README.md)
2223

2324
</details>
2425

src/2024/2024-12-11/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Day 11: Plutonian Pebbles
2+
3+
Visit the Advent of Code website for more information on this puzzle at:
4+
5+
**Source:** https://adventofcode.com/2024/day/11<br>
6+
**Status:** Complete ⭐⭐
7+
8+
## Code
9+
10+
### `utils.ts` - contains helper and utility scripts for the quiz.
11+
12+
- `isEvenDigits()` - Checks if a number has an even number of digits
13+
- `halfDigit()` - Divides the number into two (2) separate groups (digits) if they have an even number of digits, each group having half the original number's digits.
14+
- `arrayToObject()` - Converts an array of numbers to an Object, using the array number elements as keys with a default numeric value of `1`
15+
16+
### `blink.ts`
17+
18+
- **`Blinker`** class
19+
- A class that counts the number of transformed and new stones after blinking.
20+
- Has methods for storing the stone's data, counting, and "blinking."

src/2024/2024-12-11/lib/blink.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { arrayToObject, isEvenDigits, halfDigit } from './utils.js'
2+
3+
/**
4+
* @class Blinker
5+
* @description A class that counts the number of transformed and new stones after blinking.
6+
*/
7+
export class Blinker {
8+
/** Stone numbers tracking storage at each blink */
9+
numberStorage: Record<number, number> = {}
10+
11+
/** Total number of stones after the last blink */
12+
stoneCount: number = 0
13+
14+
/**
15+
* Stores a number in the `this.numberStorage` object as a key with value.
16+
* @param {number} stoneNum - Number to store in an Object data
17+
* @param {number} value - Number value associated with the `stoneNum` number key
18+
* @returns {void}
19+
*/
20+
store (stoneNum: number, value: number = 1): void {
21+
if (this.numberStorage[stoneNum] === undefined) {
22+
this.numberStorage[stoneNum] = value
23+
} else {
24+
this.numberStorage[stoneNum] += value
25+
}
26+
}
27+
28+
/**
29+
* Simulates the quiz's "blink" and stones morphing.
30+
* Calculates the number of transformed stones after blinking `blinkTimes`
31+
* @param {number[]} stones - Array of numbers (stones)
32+
* @param {number} blinkTimes - Number of times to simulate "blinking"
33+
* @returns {number} Total number of transformed stones after blinking
34+
*/
35+
blink (stones: number[], blinkTimes: number): number {
36+
let unique = arrayToObject([...stones])
37+
38+
for (let i = 0; i < blinkTimes; i += 1) {
39+
for (const num in unique) {
40+
const numberKey = Number(num)
41+
const count = unique[numberKey] as number
42+
43+
if (numberKey === 0) {
44+
this.store(1, count)
45+
} else if (isEvenDigits(numberKey)) {
46+
const group = halfDigit(numberKey)
47+
48+
group.forEach(part => {
49+
this.store(part, count)
50+
})
51+
} else {
52+
this.store(numberKey * 2024, count)
53+
}
54+
}
55+
56+
unique = { ...this.numberStorage }
57+
this.numberStorage = {}
58+
59+
this.stoneCount = Object
60+
.values(unique)
61+
.reduce(
62+
(sum, ct) => sum += ct, 0
63+
)
64+
}
65+
66+
return this.stoneCount
67+
}
68+
}

src/2024/2024-12-11/lib/utils.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Checks if a number has an even number of digits
3+
* @param {number} number - Number input
4+
*/
5+
export const isEvenDigits = (number: number): boolean => {
6+
return number.toString().length % 2 === 0
7+
}
8+
9+
/**
10+
* Divides the number into two (2) separate groups (digits) if they have an even number of digits,
11+
* aach group having half the original number's digits.
12+
* @param {number} number - Number input
13+
*/
14+
export const halfDigit = (number: number): number[] => {
15+
const numberStr = number.toString()
16+
17+
return [
18+
Number(numberStr.substring(0, numberStr.length / 2)),
19+
Number(numberStr.substring(
20+
numberStr.length / 2, numberStr.length)
21+
)
22+
]
23+
}
24+
25+
/**
26+
* Converts an array of numbers to an Object, using the array number elements as keys with a default numeric value of `1`
27+
* @param {number[]} numbers - Array of numbers
28+
* @returns {Record<number, number>} Object
29+
*/
30+
export const arrayToObject = (numbers: number[]): Record<number, number> => {
31+
return numbers.reduce((list: Record<number, number>, num) =>
32+
(list[num] === undefined
33+
? list[num] = 1
34+
: list[num] += 1, list),
35+
{}
36+
)
37+
}

src/2024/2024-12-11/main.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Blinker } from './lib/blink.js'
2+
3+
/**
4+
* Part 1/2 and 2/2 of the 2024-12-10 quiz
5+
* Counts the number of visible stones after blinking
6+
*/
7+
const quiz20241211 = () => {
8+
const numBlinks = 25
9+
const blinker = new Blinker()
10+
11+
const stones = '125 17'.split(' ').map(Number)
12+
const count = blinker.blink(stones, numBlinks)
13+
14+
console.log(`${count} stones available after ${numBlinks} blinks`)
15+
}
16+
17+
quiz20241211()

src/2024/2024-12-11/sample.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test, expect } from 'vitest'
2+
import { Blinker } from './lib/blink.js'
3+
4+
test('Number of stones after blinking:', () => {
5+
const stones = '125 17'.split(' ').map(Number)
6+
const blinker = new Blinker()
7+
8+
expect(blinker.blink(stones, 25)).toBe(55312)
9+
})

0 commit comments

Comments
 (0)