From 64b9e2cd74064a0bbd3fa5c919cc0ac5eaccf9a2 Mon Sep 17 00:00:00 2001 From: weaponsforge Date: Mon, 30 Dec 2024 01:08:39 +0800 Subject: [PATCH 1/2] feat: day 11 plutonian pebbles complete soln, #16 --- src/2024/2024-12-11/README.md | 20 +++++++++ src/2024/2024-12-11/lib/blink.ts | 68 ++++++++++++++++++++++++++++++ src/2024/2024-12-11/lib/utils.ts | 37 ++++++++++++++++ src/2024/2024-12-11/main.ts | 17 ++++++++ src/2024/2024-12-11/sample.test.ts | 9 ++++ 5 files changed, 151 insertions(+) create mode 100644 src/2024/2024-12-11/README.md create mode 100644 src/2024/2024-12-11/lib/blink.ts create mode 100644 src/2024/2024-12-11/lib/utils.ts create mode 100644 src/2024/2024-12-11/main.ts create mode 100644 src/2024/2024-12-11/sample.test.ts diff --git a/src/2024/2024-12-11/README.md b/src/2024/2024-12-11/README.md new file mode 100644 index 0000000..1b3ca56 --- /dev/null +++ b/src/2024/2024-12-11/README.md @@ -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
+**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." diff --git a/src/2024/2024-12-11/lib/blink.ts b/src/2024/2024-12-11/lib/blink.ts new file mode 100644 index 0000000..81a2161 --- /dev/null +++ b/src/2024/2024-12-11/lib/blink.ts @@ -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 = {} + + /** 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 + } +} diff --git a/src/2024/2024-12-11/lib/utils.ts b/src/2024/2024-12-11/lib/utils.ts new file mode 100644 index 0000000..85b2ef1 --- /dev/null +++ b/src/2024/2024-12-11/lib/utils.ts @@ -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} Object + */ +export const arrayToObject = (numbers: number[]): Record => { + return numbers.reduce((list: Record, num) => + (list[num] === undefined + ? list[num] = 1 + : list[num] += 1, list), + {} + ) +} diff --git a/src/2024/2024-12-11/main.ts b/src/2024/2024-12-11/main.ts new file mode 100644 index 0000000..96bbc6d --- /dev/null +++ b/src/2024/2024-12-11/main.ts @@ -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() diff --git a/src/2024/2024-12-11/sample.test.ts b/src/2024/2024-12-11/sample.test.ts new file mode 100644 index 0000000..c2bfb33 --- /dev/null +++ b/src/2024/2024-12-11/sample.test.ts @@ -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) +}) From 975a52eb180de7b8461f21e1a713926fb5ac7c09 Mon Sep 17 00:00:00 2001 From: weaponsforge Date: Mon, 30 Dec 2024 01:09:39 +0800 Subject: [PATCH 2/2] chore: update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5b1454a..dfc92f4 100644 --- a/README.md +++ b/README.md @@ -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)