Skip to content

feat: day 11 plutonian pebbles 20241211 #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ The codes are structured in a way that discusses and walks through the solution
- Day 8: Resonant Collinearity [[link]](/src/2024/2024-12-08/README.md)
- Day 9: Disk Fragmenter [[link]](/src/2024/2024-12-09/README.md)
- Day 10: Hoof It [[link]](/src/2024/2024-12-10/README.md)
- Day 11: Plutonian Pebbles [[link]](/src/2024/2024-12-11/README.md)

</details>

Expand Down
20 changes: 20 additions & 0 deletions src/2024/2024-12-11/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Day 11: Plutonian Pebbles

Visit the Advent of Code website for more information on this puzzle at:

**Source:** https://adventofcode.com/2024/day/11<br>
**Status:** Complete ⭐⭐

## Code

### `utils.ts` - contains helper and utility scripts for the quiz.

- `isEvenDigits()` - Checks if a number has an even number of digits
- `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.
- `arrayToObject()` - Converts an array of numbers to an Object, using the array number elements as keys with a default numeric value of `1`

### `blink.ts`

- **`Blinker`** class
- A class that counts the number of transformed and new stones after blinking.
- Has methods for storing the stone's data, counting, and "blinking."
68 changes: 68 additions & 0 deletions src/2024/2024-12-11/lib/blink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { arrayToObject, isEvenDigits, halfDigit } from './utils.js'

/**
* @class Blinker
* @description A class that counts the number of transformed and new stones after blinking.
*/
export class Blinker {
/** Stone numbers tracking storage at each blink */
numberStorage: Record<number, number> = {}

/** Total number of stones after the last blink */
stoneCount: number = 0

/**
* Stores a number in the `this.numberStorage` object as a key with value.
* @param {number} stoneNum - Number to store in an Object data
* @param {number} value - Number value associated with the `stoneNum` number key
* @returns {void}
*/
store (stoneNum: number, value: number = 1): void {
if (this.numberStorage[stoneNum] === undefined) {
this.numberStorage[stoneNum] = value
} else {
this.numberStorage[stoneNum] += value
}
}

/**
* Simulates the quiz's "blink" and stones morphing.
* Calculates the number of transformed stones after blinking `blinkTimes`
* @param {number[]} stones - Array of numbers (stones)
* @param {number} blinkTimes - Number of times to simulate "blinking"
* @returns {number} Total number of transformed stones after blinking
*/
blink (stones: number[], blinkTimes: number): number {
let unique = arrayToObject([...stones])

for (let i = 0; i < blinkTimes; i += 1) {
for (const num in unique) {
const numberKey = Number(num)
const count = unique[numberKey] as number

if (numberKey === 0) {
this.store(1, count)
} else if (isEvenDigits(numberKey)) {
const group = halfDigit(numberKey)

group.forEach(part => {
this.store(part, count)
})
} else {
this.store(numberKey * 2024, count)
}
}

unique = { ...this.numberStorage }
this.numberStorage = {}

this.stoneCount = Object
.values(unique)
.reduce(
(sum, ct) => sum += ct, 0
)
}

return this.stoneCount
}
}
37 changes: 37 additions & 0 deletions src/2024/2024-12-11/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Checks if a number has an even number of digits
* @param {number} number - Number input
*/
export const isEvenDigits = (number: number): boolean => {
return number.toString().length % 2 === 0
}

/**
* Divides the number into two (2) separate groups (digits) if they have an even number of digits,
* aach group having half the original number's digits.
* @param {number} number - Number input
*/
export const halfDigit = (number: number): number[] => {
const numberStr = number.toString()

return [
Number(numberStr.substring(0, numberStr.length / 2)),
Number(numberStr.substring(
numberStr.length / 2, numberStr.length)
)
]
}

/**
* Converts an array of numbers to an Object, using the array number elements as keys with a default numeric value of `1`
* @param {number[]} numbers - Array of numbers
* @returns {Record<number, number>} Object
*/
export const arrayToObject = (numbers: number[]): Record<number, number> => {
return numbers.reduce((list: Record<number, number>, num) =>
(list[num] === undefined
? list[num] = 1
: list[num] += 1, list),
{}
)
}
17 changes: 17 additions & 0 deletions src/2024/2024-12-11/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Blinker } from './lib/blink.js'

/**
* Part 1/2 and 2/2 of the 2024-12-10 quiz
* Counts the number of visible stones after blinking
*/
const quiz20241211 = () => {
const numBlinks = 25
const blinker = new Blinker()

const stones = '125 17'.split(' ').map(Number)
const count = blinker.blink(stones, numBlinks)

console.log(`${count} stones available after ${numBlinks} blinks`)
}

quiz20241211()
9 changes: 9 additions & 0 deletions src/2024/2024-12-11/sample.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { test, expect } from 'vitest'
import { Blinker } from './lib/blink.js'

test('Number of stones after blinking:', () => {
const stones = '125 17'.split(' ').map(Number)
const blinker = new Blinker()

expect(blinker.blink(stones, 25)).toBe(55312)
})
Loading