diff --git a/README.md b/README.md
index 05f923e..76431b0 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,7 @@ It follows the directory structure:
> [!NOTE]
> 📂 dist
> 📂 src
-> └─ 📂 utils
+> └─ 📂 aoc
> └─ 📂 sample
> └─ 📂 2024
> └─── 📂 2024-12-01
@@ -77,7 +77,7 @@ Each Advent of Code (AOC) event quiz has its folder under **`"/src// {
+export const checkVertical = (coord: Coordinate, fullData: string[][], WORD: string): boolean => {
let yIndex = coord.y
let subWord = ''
@@ -79,11 +68,11 @@ export const checkHorizontal = (coord: Coordinate, rowData: string[], WORD: stri
* @typedef param {CoordinateData} Direction and data object
* @param param.xDirection {number} `-1` for "left" going to (0,0) or `1` for "right" going to (N,N) from the `coord`
* @param param.yDirection {number} `-1` for "up" going to (0,0) or `1` for "down" going to (N,N) from the `coord`
- * @param param.data {CharacterArray} 2D string array containing the input text
+ * @param param.data {string[][]} 2D string array containing the input text
* @returns {boolean} Flag indicating the existence of the `WORD`
* @param WORD {string} Word to find
*/
-export const checkDiagonal = (coord: CoordinateBase, param: CoordinateData, WORD: string): boolean => {
+export const checkDiagonal = (coord: Point, param: CoordinateData, WORD: string): boolean => {
let xIndex = coord.x
let yIndex = coord.y
let subWord = ''
diff --git a/src/2024/2024-12-04/lib/wordCount.ts b/src/2024/2024-12-04/lib/wordCount.ts
index 463aeb3..0db10c3 100644
--- a/src/2024/2024-12-04/lib/wordCount.ts
+++ b/src/2024/2024-12-04/lib/wordCount.ts
@@ -2,7 +2,7 @@ import { checkVertical, checkHorizontal, checkDiagonal } from './wordCheckerUtil
/**
* Counts the number of occurence of the `WORD` from a set of input
- * @param data {CharacterArray} 2D string array containing the input text
+ * @param data {string[][]} 2D string array containing the input text
* @param WORD_TO_FIND {string} Word to find
* @returns {number} Number of `WORD`s
*/
diff --git a/src/2024/2024-12-04/main.ts b/src/2024/2024-12-04/main.ts
index d12deaf..75051e4 100644
--- a/src/2024/2024-12-04/main.ts
+++ b/src/2024/2024-12-04/main.ts
@@ -1,5 +1,5 @@
import path from 'path'
-import { directory, readFile } from '@/utils/file.js'
+import { directory, readFile } from '@/aoc/file/utils.js'
import { wordCount } from './lib/wordCount.js'
import { countMASword } from './lib/xmasCount.js'
diff --git a/src/2024/2024-12-05/lib/fileReader.ts b/src/2024/2024-12-05/lib/fileReader.ts
index 48b12c9..e9a4cbe 100644
--- a/src/2024/2024-12-05/lib/fileReader.ts
+++ b/src/2024/2024-12-05/lib/fileReader.ts
@@ -1,6 +1,6 @@
import path from 'path'
-import { directory, readFile } from '@/utils/file.js'
-import { uniformArrayElements } from '@/utils/arrays.js'
+import { directory, readFile } from '@/aoc/file/utils.js'
+import { uniformArrayElements } from '@/aoc/array/utils.js'
export type Rules = Record
diff --git a/src/2024/2024-12-05/lib/fixOrderingUpdates.ts b/src/2024/2024-12-05/lib/fixOrderingUpdates.ts
index b7001eb..5221143 100644
--- a/src/2024/2024-12-05/lib/fixOrderingUpdates.ts
+++ b/src/2024/2024-12-05/lib/fixOrderingUpdates.ts
@@ -1,5 +1,5 @@
import { isOrderedReport } from './orderedUpdates.js'
-import { arrayMiddleIndex, uniformArrayElements } from '@/utils/arrays.js'
+import { arrayMiddleIndex, uniformArrayElements } from '@/aoc/array/utils.js'
import type { Rules } from './fileReader.js'
import type { QuizData } from './fileReader.js'
diff --git a/src/2024/2024-12-05/lib/orderedUpdates.ts b/src/2024/2024-12-05/lib/orderedUpdates.ts
index 9511495..9fb8824 100644
--- a/src/2024/2024-12-05/lib/orderedUpdates.ts
+++ b/src/2024/2024-12-05/lib/orderedUpdates.ts
@@ -1,5 +1,5 @@
import type { QuizData, Rules } from './fileReader.js'
-import { uniformArrayElements, arrayMiddleIndex } from '@/utils/arrays.js'
+import { arrayMiddleIndex, uniformArrayElements } from '@/aoc/array/utils.js'
/**
* Checks if an "update" list is correct according to defined "rules"
diff --git a/src/2024/2024-12-06/README.md b/src/2024/2024-12-06/README.md
index eb3a023..7dabb26 100644
--- a/src/2024/2024-12-06/README.md
+++ b/src/2024/2024-12-06/README.md
@@ -7,19 +7,25 @@ Visit the Advent of Code website for more information on this puzzle at:
## Code
-1. **grid.ts**
- - `Grid` - class that has a 2D array object containing paths and obstacles in which a `Guard` runs.
+### `grid.ts`
+
+**`Grid`** class
+ - class that has a 2D array object containing paths and obstacles in which a `Guard` runs.
- Has functions and methods for managing a `Grid` object
-2. **guard.ts**
- - `Guard` - class representing an object that can walk in the `Grid` map.
+### `guard.ts`
+
+**`Guard`** class
+ - class representing an object that can walk in the `Grid` map.
- Have methods for moving around in the `Grid`.
-3. **guardController.ts**
- - `guardController()` - Runs the `Guard` on the `Grid`, counting distinct positions/steps.
+### `guardController.ts`
+
+- **`guardController()`** - Runs the `Guard` on the `Grid`, counting distinct positions/steps.
+
+### `guardControllerLoop.ts`
+- **`gridHasInfiniteLoop()`**
+ - Runs the `Guard` on a `Grid` with obstacles, checking the placement of paths and obstacles that will make the `Guard` walk in an infinite loop
+- **`findObstructionPositions()`** - Counts the number of positions in the `Grid` in which inserting one (1) obstruction symbol # will cause the `Guard` to walk in an infinite loop.
+ - > _**WARNING:** This is a very slow, unoptimized program execution that takes about ~3 mins to complete using the actual AoC input text._
-5. **guardControllerLoop.ts**
- - `gridHasInfiniteLoop()`
- - Runs the `Guard` on a `Grid` with obstacles, checking the placement of paths and obstacles that will make the `Guard` walk in an infinite loop
- - `findObstructionPositions()` - Counts the number of positions in the `Grid` in which inserting one (1) obstruction symbol # will cause the `Guard` to walk in an infinite loop.
- - > _**WARNING:** This is a very slow, unoptimized program execution that takes about ~3 mins to complete using the actual AoC input text._
diff --git a/src/2024/2024-12-06/lib/grid.ts b/src/2024/2024-12-06/lib/grid.ts
index 38f6019..c5a71ff 100644
--- a/src/2024/2024-12-06/lib/grid.ts
+++ b/src/2024/2024-12-06/lib/grid.ts
@@ -1,7 +1,6 @@
import { GuardStatus, GuardDirection } from './guard.types.js'
import type { GuardState } from './guard.types.js'
-
/**
* @class Grid
* @description Object containing a 2D array of strings and other data in which a `Guard` object runs. Each item represents an open path or obstacle.
diff --git a/src/2024/2024-12-06/lib/grid.types.ts b/src/2024/2024-12-06/lib/grid.types.ts
deleted file mode 100644
index 4c18219..0000000
--- a/src/2024/2024-12-06/lib/grid.types.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * `Grid` dimensions properties
- *
- * @property {number} length - Length of the grid
- * @property {number} wwidth - Width of the grid
- */
-export type GridDimensions = {
- length: number;
- width: number;
-}
diff --git a/src/2024/2024-12-06/main.ts b/src/2024/2024-12-06/main.ts
index 285dded..1e11310 100644
--- a/src/2024/2024-12-06/main.ts
+++ b/src/2024/2024-12-06/main.ts
@@ -1,6 +1,6 @@
import path from 'path'
-import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/utils/aocInputFile.js'
-import { directory } from '@/utils/file.js'
+import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
+import { directory } from '@/aoc/file/utils.js'
import { guardController } from './lib/guardController.js'
import { findObstructionPositions } from './lib/guardControllerLoop.js'
diff --git a/src/2024/2024-12-06/sample.test.ts b/src/2024/2024-12-06/sample.test.ts
index d5629f5..b6d3327 100644
--- a/src/2024/2024-12-06/sample.test.ts
+++ b/src/2024/2024-12-06/sample.test.ts
@@ -1,8 +1,8 @@
import path from 'path'
import { test, expect } from 'vitest'
-import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/utils/aocInputFile.js'
-import { directory } from '@/utils/file.js'
+import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
+import { directory } from '@/aoc/file/utils.js'
import { guardController } from './lib/guardController.js'
import { findObstructionPositions } from './lib/guardControllerLoop.js'
diff --git a/src/2024/2024-12-07/main.ts b/src/2024/2024-12-07/main.ts
index 2db9ac2..c43eead 100644
--- a/src/2024/2024-12-07/main.ts
+++ b/src/2024/2024-12-07/main.ts
@@ -1,6 +1,6 @@
import path from 'path'
-import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/utils/aocInputFile.js'
-import { directory } from '@/utils/file.js'
+import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
+import { directory } from '@/aoc/file/utils.js'
import { totalCalibrationResult } from './lib/totalCalibration.js'
import { totalCalibrationConcat } from './lib/totalCalibrationConcat.js'
diff --git a/src/2024/2024-12-07/sample.test.ts b/src/2024/2024-12-07/sample.test.ts
index 710bdba..a555f8a 100644
--- a/src/2024/2024-12-07/sample.test.ts
+++ b/src/2024/2024-12-07/sample.test.ts
@@ -1,8 +1,8 @@
import path from 'path'
import { test, expect } from 'vitest'
-import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/utils/aocInputFile.js'
-import { directory } from '@/utils/file.js'
+import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
+import { directory } from '@/aoc/file/utils.js'
import { totalCalibrationResult } from './lib/totalCalibration.js'
import { totalCalibrationConcat } from './lib/totalCalibrationConcat.js'
diff --git a/src/2024/2024-12-08/README.md b/src/2024/2024-12-08/README.md
index b917a5e..9aa653c 100644
--- a/src/2024/2024-12-08/README.md
+++ b/src/2024/2024-12-08/README.md
@@ -9,14 +9,14 @@ Visit the Advent of Code website for more information on this puzzle at:
### `GridAntinodes.ts`
-- `GridAntiNodes` class - Object that tracks and manages `Antennas` and `Antinodes` in a 2D grid array
+- **`GridAntiNodes`** class - Object that tracks and manages `Antennas` and `Antinodes` in a 2D grid array
### `uniqueAntinodes.ts`
-- `uniqueAntinodes()` - Counts the unique locations in the grid that contains an antinode
+- **`countAntinodes()`** - Counts the unique locations in the grid that contains an antinode
### `allAntinodes.ts`
-- `getAntinodesInPath()` - Finds all `Antinode` coordinates along a path within a 2D array (grid) given a `Point`, increment steps and a +/- direction
+- **`getAntinodesInPath()`** - Finds all `Antinode` coordinates along a path within a 2D array (grid) given a `Point`, increment steps and a +/- direction
-- `countAllAntinodes()` - Counts the unique locations in the grid that contains all locations of antinodes along a path
+- **`countAllAntinodes()`** - Counts the unique locations in the grid that contains all locations of antinodes along a path
diff --git a/src/2024/2024-12-08/lib/allAntinodes.ts b/src/2024/2024-12-08/lib/allAntinodes.ts
index e63b7cb..db6d8d8 100644
--- a/src/2024/2024-12-08/lib/allAntinodes.ts
+++ b/src/2024/2024-12-08/lib/allAntinodes.ts
@@ -1,4 +1,5 @@
-import type { Antenna, Point } from './types.js'
+import type { Antenna } from './types.js'
+import type { Point } from '@/aoc/point/types.js'
import { GridAntiNodes } from './GridAntinodes.js'
/**
diff --git a/src/2024/2024-12-08/lib/types.ts b/src/2024/2024-12-08/lib/types.ts
index 868a9c2..3c9bb04 100644
--- a/src/2024/2024-12-08/lib/types.ts
+++ b/src/2024/2024-12-08/lib/types.ts
@@ -1,7 +1,4 @@
-export interface Point {
- x: number;
- y: number;
-}
+import type { Point } from '@/aoc/point/types.js'
export interface Antenna extends Point {
frequency: string;
diff --git a/src/2024/2024-12-08/lib/uniqueAntinodes.ts b/src/2024/2024-12-08/lib/uniqueAntinodes.ts
index 12c2882..8e494ef 100644
--- a/src/2024/2024-12-08/lib/uniqueAntinodes.ts
+++ b/src/2024/2024-12-08/lib/uniqueAntinodes.ts
@@ -1,4 +1,5 @@
-import type { Antenna, Point } from './types.js'
+import type { Antenna } from './types.js'
+import type { Point } from '@/aoc/point/types.js'
import { GridAntiNodes } from './GridAntinodes.js'
/**
diff --git a/src/2024/2024-12-08/main.ts b/src/2024/2024-12-08/main.ts
index 68ace42..190eb66 100644
--- a/src/2024/2024-12-08/main.ts
+++ b/src/2024/2024-12-08/main.ts
@@ -1,6 +1,6 @@
import path from 'path'
-import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/utils/aocInputFile.js'
-import { directory } from '@/utils/file.js'
+import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
+import { directory } from '@/aoc/file/utils.js'
import { countAntinodes } from './lib/uniqueAntinodes.js'
import { countAllAntinodes } from './lib/allAntinodes.js'
diff --git a/src/2024/2024-12-08/sample.test.ts b/src/2024/2024-12-08/sample.test.ts
index 43dd301..e01904c 100644
--- a/src/2024/2024-12-08/sample.test.ts
+++ b/src/2024/2024-12-08/sample.test.ts
@@ -1,8 +1,8 @@
import path from 'path'
import { test, expect } from 'vitest'
-import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/utils/aocInputFile.js'
-import { directory } from '@/utils/file.js'
+import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
+import { directory } from '@/aoc/file/utils.js'
import { countAntinodes } from './lib/uniqueAntinodes.js'
import { countAllAntinodes } from './lib/allAntinodes.js'
diff --git a/src/2024/2024-12-09/main.ts b/src/2024/2024-12-09/main.ts
index 7d13b4e..facbcb9 100644
--- a/src/2024/2024-12-09/main.ts
+++ b/src/2024/2024-12-09/main.ts
@@ -1,7 +1,7 @@
import path from 'path'
-import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/utils/aocInputFile.js'
-import { directory } from '@/utils/file.js'
+import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
+import { directory } from '@/aoc/file/utils.js'
import { CompactDisk } from './lib/compact.js'
import { WholeDisk } from './lib/whole.js'
diff --git a/src/2024/2024-12-09/sample.test.ts b/src/2024/2024-12-09/sample.test.ts
index 35ffb07..1ec89dd 100644
--- a/src/2024/2024-12-09/sample.test.ts
+++ b/src/2024/2024-12-09/sample.test.ts
@@ -1,8 +1,8 @@
import path from 'path'
import { test, expect } from 'vitest'
-import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/utils/aocInputFile.js'
-import { directory } from '@/utils/file.js'
+import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
+import { directory } from '@/aoc/file/utils.js'
import { CompactDisk } from './lib/compact.js'
import { WholeDisk } from './lib/whole.js'
diff --git a/src/2024/2024-12-10/README.md b/src/2024/2024-12-10/README.md
index 5faaddb..685faeb 100644
--- a/src/2024/2024-12-10/README.md
+++ b/src/2024/2024-12-10/README.md
@@ -13,6 +13,6 @@ Visit the Advent of Code website for more information on this puzzle at:
### `scoresRatings.ts`
-- `countTrailScores()`
+- **`countTrailScores()`**
- Finds valid hiking trails (trailheads) from a point coordinate in a 2D array starting with `0` and ending in `9` symbol and calculates the **scores** for each trailhead.
- Calculates the trailhead **ratings** instead of the trailhead scores if provided with the optional `{ isRating: true }` parameter. Defaults to `false`
diff --git a/src/2024/2024-12-10/lib/scoresRatings.ts b/src/2024/2024-12-10/lib/scoresRatings.ts
index 8d3176a..63d2e6d 100644
--- a/src/2024/2024-12-10/lib/scoresRatings.ts
+++ b/src/2024/2024-12-10/lib/scoresRatings.ts
@@ -1,11 +1,8 @@
-import type { Point } from '../../2024-12-08/lib/types.js'
-import type { InputOptions, PointSteps, PointDirection, TrailScores } from './types.js'
-
-import {
- findValidSteps,
- findZeroCoordinatePositions,
- getCoordinateSymbol
-} from './utils.js'
+import type { Point, PointDirection, PointSteps } from '@/aoc/point/types.js'
+import type { InputOptions, TrailScores } from './types.js'
+
+import { getCoordinateSymbol } from '@/aoc/grid/utils.js'
+import { findValidSteps, findZeroCoordinatePositions } from './utils.js'
// List of trailhead scores
const scores: Record = {}
diff --git a/src/2024/2024-12-10/lib/types.ts b/src/2024/2024-12-10/lib/types.ts
index 5318951..165bf76 100644
--- a/src/2024/2024-12-10/lib/types.ts
+++ b/src/2024/2024-12-10/lib/types.ts
@@ -1,44 +1,3 @@
-/**
- * Point (y,x) coordinate in a 2D array with direction
- * @type {Object} PointSteps
- * @property {number} x - x-coordinate of the point
- * @property {number} y - y-coordinate of the point
- * @property {Object} direction - Direction vector
- * @property {number} direction.x - Left/right x-direction denoted by `+1` or `-1`
- * @property {number} direction.y - Up/down y-direction denoted by `-1` or `+1`
- */
-export type PointSteps = {
- x: number;
- y: number;
- direction: {
- x: number;
- y: number;
- }
-}
-
-/**
- * Point (y,x) coordinate in a 2D array with a list of valid coordinates from its location.
- * @type {Object} PointDirection
- * @property {number} x - x-coordinate of the point
- * @property {number} y - y-coordinate of the point
- * @property {PointSteps[]} validSteps - List of valid up/down/left/right coordinates from the (y,x) position.
- */
-export type PointDirection = {
- x: number;
- y: number;
- validSteps: PointSteps[]
-}
-
-/**
- * Represents a "(y,x)" coordinate in string and its value from a 2D array.
- * @param {string} coordinate - String version of an "(y,x)" coordinate
- * @param {string | number} symbol - Number or character in a 2D arary denoted by the (y,x) coordinate
- */
-export type GridCoordinateSymbol = {
- coordinate: string;
- symbol: string | number;
-}
-
/**
* Data returned by the trailhead scores counting function.
* @param {Record} scores - Object list of trailhead scores per (y,x) coordinate that starts with a unique `0` and ends with a `9`
diff --git a/src/2024/2024-12-10/lib/utils.ts b/src/2024/2024-12-10/lib/utils.ts
index ac34313..d1c1c30 100644
--- a/src/2024/2024-12-10/lib/utils.ts
+++ b/src/2024/2024-12-10/lib/utils.ts
@@ -1,19 +1,6 @@
-import type { Point } from '@/2024/2024-12-08/lib/types.js'
-import type { GridDimensions } from '@/2024/2024-12-06/lib/grid.types.js'
-import type { GridCoordinateSymbol, PointSteps } from './types.js'
-
-/**
- * Converts a 2D `Point` point object to string and returns its value from the 2D array
- * @param {Point} point - (y,x) coordinatate in the 2D array
- * @param {number[][]} data - 2D number array containing hiking trail data
- * @returns {GridCoordinateSymbol} Returns the `poiint` (x,y) coordinate expressed in string and its value
- */
-export const getCoordinateSymbol = (point: Point, data: number[][] | string[][]): GridCoordinateSymbol => {
- return {
- coordinate: `${point!.x},${point!.y}`,
- symbol: data[point!.y]![point!.x] as number
- }
-}
+import type { Point, PointSteps } from '@/aoc/point/types.js'
+import type { GridDimensions } from '@/aoc/grid/types.js'
+import { isOutOfBounds } from '@/aoc/grid/utils.js'
/**
* Finds the (y,x) coordinates of starting positions in a trailhead grid
@@ -32,19 +19,6 @@ export const findZeroCoordinatePositions = (data: number[][], symbol?: number):
}, [])
}
-/**
- * Checks if a (y,x) coordinate is out of the grid area
- * @param {Point} point - (y,x) coordinate
- * @param {GridDimensions} gridMeta - Length and width definitions of a 2D array (grid)
- * @returns {boolean} Flag if a coordinate is out of the grid area
- */
-export const isOutOfBounds = (point: Point, gridMeta: GridDimensions): boolean => {
- return (
- point.x < 0 || point.x >= gridMeta.width ||
- point.y < 0 || point.y >= gridMeta.length
- )
-}
-
/**
* Finds valid positions and coordinates of next steps from a coordinate.
* @param {Point} point - (y,x) coordinate object in a 2D array grid
diff --git a/src/2024/2024-12-10/main.ts b/src/2024/2024-12-10/main.ts
index 13621d6..c7ecd48 100644
--- a/src/2024/2024-12-10/main.ts
+++ b/src/2024/2024-12-10/main.ts
@@ -1,6 +1,6 @@
-import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/utils/aocInputFile.js'
-import { file } from '@/utils/file.js'
+import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
+import { file } from '@/aoc/file/utils.js'
import { countTrailScores } from './lib/scoresRatings.js'
diff --git a/src/2024/2024-12-10/sample.test.ts b/src/2024/2024-12-10/sample.test.ts
index 8b456c8..bfbde18 100644
--- a/src/2024/2024-12-10/sample.test.ts
+++ b/src/2024/2024-12-10/sample.test.ts
@@ -1,7 +1,7 @@
import { test, expect } from 'vitest'
-import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/utils/aocInputFile.js'
-import { file } from '@/utils/file.js'
+import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
+import { file } from '@/aoc/file/utils.js'
import { countTrailScores } from './lib/scoresRatings.js'
diff --git a/src/2024/2024-12-11/README.md b/src/2024/2024-12-11/README.md
index 2be84da..39d4f10 100644
--- a/src/2024/2024-12-11/README.md
+++ b/src/2024/2024-12-11/README.md
@@ -10,9 +10,7 @@ Visit the Advent of Code website for more information on this puzzle at:
### `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`
+- **`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.
### `blink.ts`
diff --git a/src/2024/2024-12-11/lib/blink.ts b/src/2024/2024-12-11/lib/blink.ts
index 81a2161..f8d3af1 100644
--- a/src/2024/2024-12-11/lib/blink.ts
+++ b/src/2024/2024-12-11/lib/blink.ts
@@ -1,4 +1,6 @@
-import { arrayToObject, isEvenDigits, halfDigit } from './utils.js'
+import { arrayToObject } from '@/aoc/array/utils.js'
+import { isEvenDigits } from '@/aoc/number/utils.js'
+import { halfDigit } from './utils.js'
/**
* @class Blinker
diff --git a/src/2024/2024-12-11/lib/utils.ts b/src/2024/2024-12-11/lib/utils.ts
index 85b2ef1..30052a0 100644
--- a/src/2024/2024-12-11/lib/utils.ts
+++ b/src/2024/2024-12-11/lib/utils.ts
@@ -1,11 +1,3 @@
-/**
- * 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.
@@ -21,17 +13,3 @@ export const halfDigit = (number: number): number[] => {
)
]
}
-
-/**
- * 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-12/README.md b/src/2024/2024-12-12/README.md
index 38bafe6..bdf952c 100644
--- a/src/2024/2024-12-12/README.md
+++ b/src/2024/2024-12-12/README.md
@@ -9,27 +9,22 @@ Visit the Advent of Code website for more information on this puzzle at:
### `garden.ts`
-- **Garden** class
- - A set of methods and properties for calculating Garden, Region, and Plots data
- - `Garden.calculatePlot()` - Calculates the per-plot perimeter and total area of all garden regions in a 2D grid, each defined by an initial symbol at a starting (y,x) coordinate.
- - `Garden.calculateFencePrice()` - Calculates the total fencing price of all regions in a garden per connected plot using the formula: area * perimeter (per plot).
+**Garden** class
+- A set of methods and properties for calculating Garden, Region, and Plots data
+- `Garden.calculatePlot()` - Calculates the per-plot perimeter and total area of all garden regions in a 2D grid, each defined by an initial symbol at a starting (y,x) coordinate.
+- `Garden.calculateFencePrice()` - Calculates the total fencing price of all regions in a garden per connected plot using the formula: area * perimeter (per plot).
### `wholesale.ts`
-- **WholesaleGarden** class
- - A set of methods and properties for calculating the wholesale fencing price of garden regions
- - `WholesaleGarden.calculateRegionCorners()` - Calculates the number of corners (sides) of a whole region.
- - `WholesaleGarden.calculateFencePrice()` - Calculates the total fencing price of all regions in a garden using the formula: area * perimeter (of whole region).
+**WholesaleGarden** class
+- A set of methods and properties for calculating the wholesale fencing price of garden regions
+- **`calculateRegionCorners()`** - Calculates the number of corners (sides) of a whole region.
+- **`calculateFencePrice()`** - Calculates the total fencing price of all regions in a garden using the formula: area * perimeter (of whole region).
### `utils.ts`
- A script containing helper and utility scripts for the quiz
-- `findNeighbors()` - Finds all coordinates of the neighboring plots from a specified coordinate (up/down/left/right)
-- `isIllegalCoordinate()` - Checks if a point at coordinate (y,x) in a grid is illegal: if it's out of bounds of the grid area or if its symbol differs from the symbol parameter.
-- `getDiagonalNeighbors()` - Retrieves the four (4) diagonally-aligned (y,x) coordinates and the symbol character from a `Point` in the grid. Substitutes a `"*"` symbol character in the `NeighborPoint.symbol`if the `point` is out of the grid bounds.
-- `getCrossNeighbors()` - Retrieves the four (4) horizontal/vertical aligned (y,x) coordinates and the symbol character from a `Point` in the grid. Substitutes a `"*"` symbol character in the `NeighborPoint.symbol`if the `point` is out of the grid bounds.
-- `isDiagonal()` - Checks if two (2) `Points` are diagonally-aligned
-- `innerCorners()` - Counts the "inner" corners from groups of valid L-shaped `Points` that originate from a `Point` coordinate.
+- **`innerCorners()`** - Counts the "inner" corners from groups of valid L-shaped `Points` that has the `point` parameter coordinate as its center
## Notes
diff --git a/src/2024/2024-12-12/lib/garden.ts b/src/2024/2024-12-12/lib/garden.ts
index 7e29e38..b773c5f 100644
--- a/src/2024/2024-12-12/lib/garden.ts
+++ b/src/2024/2024-12-12/lib/garden.ts
@@ -1,8 +1,9 @@
import type { GardenRegionDetails } from './types.js'
-import type { GridDimensions } from '@/2024/2024-12-06/lib/grid.types.js'
-import type { Point } from '@/2024/2024-12-08/lib/types.js'
+import type { GridDimensions } from '@/aoc/grid/types.js'
+import type { Point } from '@/aoc/point/types.js'
-import { findNeighbors, isIllegalCoordinate } from './utils.js'
+import { findNeighbors } from '@/aoc/point/utils.js'
+import { isIllegalCoordinate } from '@/aoc/grid/utils.js'
/**
* @class Garden
diff --git a/src/2024/2024-12-12/lib/types.ts b/src/2024/2024-12-12/lib/types.ts
index 4b05820..9106e8f 100644
--- a/src/2024/2024-12-12/lib/types.ts
+++ b/src/2024/2024-12-12/lib/types.ts
@@ -1,6 +1,3 @@
-import type { GridDimensions } from '@/2024/2024-12-06/lib/grid.types.js'
-import type { Point } from '@/2024/2024-12-08/lib/types.js'
-
/**
* @type {Object} GardenRegionDetails
* @property {number} area - Area of a garden region - sum of connected plots with similar symbols.
@@ -20,21 +17,3 @@ export type GardenRegionSides = {
area: number;
sides: number;
}
-
-/**
- * @type {Object} IllegalCoordinateParams
- * @property {Point} point - (y,x) coordinate object in a 2D array grid
- * @property {string} symbol - Character to check in the `point` coordinate.
- * @property {GridDimensions} gridMeta - Grid length and width
- * @property {string[][]} grid - 2D string array input
- */
-export type IllegalCoordinateParams = {
- point: Point;
- symbol: string;
- gridMeta: GridDimensions;
- grid: string[][];
-}
-
-export interface NeighborPoint extends Point {
- symbol: string;
-}
diff --git a/src/2024/2024-12-12/lib/utils.ts b/src/2024/2024-12-12/lib/utils.ts
index e44785d..966d9bd 100644
--- a/src/2024/2024-12-12/lib/utils.ts
+++ b/src/2024/2024-12-12/lib/utils.ts
@@ -1,115 +1,11 @@
-import type { Point } from '@/2024/2024-12-08/lib/types.js'
-import type { IllegalCoordinateParams, NeighborPoint } from './types.js'
+import type { Point } from '@/aoc/point/types.js'
-import { getGridDimensions } from '@/utils/grid/utils.js'
-import { isOutOfBounds } from '@/2024/2024-12-10/lib/utils.js'
+import { getDiagonalNeighbors } from '@/aoc/grid/utils.js'
+import { getGridDimensions, isOutOfBounds } from '@/aoc/grid/utils.js'
-/**
- * Finds all coordinates of the neighboring plots from a specified coordinate (up/down/left/right)
- * @param {Point} point - (y,x) coordinate object in a 2D array grid
- * @param {GridDimensions} gridMeta - grid length and width
- * @param {string[][]} grid - 2D string array input
- * @returns {PointSteps[]} Array of neighboring similar plants from the given `point`
- */
-export const findNeighbors = (point: Point): Point[] | undefined => {
- // All 4 possible locations (directions) from a coordinate
- const steps = [
- { ...point, x: point.x - 1 }, // left
- { ...point, x: point.x + 1 }, // right
- { ...point, y: point.y - 1 }, // down
- { ...point, y: point.y + 1 } // up
- ]
-
- return steps
-}
-
-/**
- * Checks if a point at coordinate (y,x) in a grid is illegal: if it's out of bounds of the grid area
- * or if its symbol differs from the symbol parameter.
- * @param params {IllegalCoordinateParams} - Object input parameters.
- * See the `IllegalCoordinateParams` for more information.
- * @returns {boolean} Flag if a coordinate is illegae
- */
-export const isIllegalCoordinate = (params: IllegalCoordinateParams): boolean => {
- const { point, symbol, gridMeta } = params
-
- return (
- point.x < 0 ||
- point.x >= gridMeta.width ||
- point.y < 0 ||
- point.y >= gridMeta.length ||
- params.grid[point.y]![point.x] !== symbol
- )
-}
-
-/**
- * Retrieves the four (4) diagonally-aligned (y,x) coordinates and the symbol character from a `Point` in the grid.
- * Substitutes a `"*"` symbol character in the `NeighborPoint.symbol`if the `point` is out of the grid bounds.
- * @param {Point} point - (y,x) coordinate object in a 2D array grid
- * @param {string[][]} data - 2D string array input
- * @returns {NeighborPoint[]} Array of `NeighborPoint` with symbol characters.
- */
-export const getDiagonalNeighbors = (point: Point, data: string[][]): NeighborPoint[] => {
- const grid = getGridDimensions(data)
-
- // diagonal coordinates
- const diagonals = [
- { x: point.x + 1, y: point.y - 1 },
- { x: point.x - 1, y: point.y - 1 },
- { x: point.x + 1, y: point.y + 1 },
- { x: point.x - 1, y: point.y + 1 }
- ]
-
- return diagonals.reduce((list: NeighborPoint[], pt) => {
- const item = { x: pt.x, y: pt.y, symbol: '*' }
-
- if (!isOutOfBounds(pt, grid)) {
- item.symbol = data[pt.y]![pt.x] as string
- }
-
- return [...list, item]
- }, [])
-}
-
-/**
- * Retrieves the four (4) horizontal/vertical aligned (y,x) coordinates and the symbol character from a `Point` in the grid.
- * Substitutes a `"*"` symbol character in the `NeighborPoint.symbol`if the `point` is out of the grid bounds.
- * @param {Point} point - (y,x) coordinate object in a 2D array grid
- * @param {string[][]} data - 2D string array input
- * @returns {NeighborPoint[]} Array of `NeighborPoint` with symbol characters.
- */
-export const getCrossNeighbors = (point: Point, data: string[][]): NeighborPoint[] => {
- const neighbors = findNeighbors(point) as Point[]
- const grid = getGridDimensions(data)
-
- return neighbors.reduce((list: NeighborPoint[], pt) => {
- const item = { x: pt.x, y: pt.y, symbol: '*' }
-
- if (!isOutOfBounds(pt, grid)) {
- item.symbol = data[pt.y]![pt.x] as string
- }
-
- return [...list, item]
- }, [])
-}
-
-/**
- * Checks if two (2) `Points` are diagonally-aligned
- * @param {Point} p1 - (y,x) Start `Point`
- * @param {Point} p2 - (y,x) End `Point`
- * @returns {boolean} Flag indicating if 2 `Points` are diagonally aligned
- */
-export const isDiagonal = (p1: Point, p2: Point): boolean => {
- const diff = {
- x: Math.abs(p1.x - p2.x),
- y: Math.abs(p1.y - p2.y)
- }
-
- return diff.x == 1 && diff.y === 1
-}
/**
- * Counts the "inner" corners from groups of valid L-shaped `Points` that originate from a `Point` coordinate.
+ * Counts the "inner" corners from groups of valid L-shaped `Points` that has the `point` parameter coordinate as its center
* @param {Point} point - Origin (y,x) coordinate object in a 2D array grid
* @param {string} symbol - Character to check in the `point` coordinate.
* @param {string[][]} data - 2D string array input
diff --git a/src/2024/2024-12-12/lib/wholesale.ts b/src/2024/2024-12-12/lib/wholesale.ts
index 7fed7e2..01595fb 100644
--- a/src/2024/2024-12-12/lib/wholesale.ts
+++ b/src/2024/2024-12-12/lib/wholesale.ts
@@ -1,10 +1,10 @@
-import type { Point } from '@/2024/2024-12-08/lib/types.js'
-
-import { isOutOfBounds } from '@/2024/2024-12-10/lib/utils.js'
-import { getGridDimensions } from '@/utils/grid/utils.js'
-import { getCrossNeighbors, innerCorners, isDiagonal } from './utils.js'
+import type { Point } from '@/aoc/point/types.js'
import type { GardenRegionSides } from './types.js'
+import { getCrossNeighbors, getGridDimensions, isOutOfBounds } from '@/aoc/grid/utils.js'
+import { isDiagonal } from '@/aoc/point/utils.js'
+import { innerCorners } from './utils.js'
+
/**
* @class WholesaleGarden
* @description A set of methods and properties for calculating the wholesale fencing price of garden regions
@@ -46,7 +46,7 @@ export class WholesaleGarden {
corners += 2 * Math.floor(invalidPoints.length / 2)
}
- // Diagonally-aligned other symbols (if only 2) count as a corner
+ // diagonally aligned other symbols (if only 2) count as a corner
if (invalidPoints.length === 2) {
if (isDiagonal(invalidPoints[0] as Point, invalidPoints[1] as Point)) {
corners += 1
diff --git a/src/2024/2024-12-12/main.ts b/src/2024/2024-12-12/main.ts
index 41993a2..f8055b7 100644
--- a/src/2024/2024-12-12/main.ts
+++ b/src/2024/2024-12-12/main.ts
@@ -1,5 +1,5 @@
-import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/utils/aocInputFile.js'
-import { file } from '@/utils/file.js'
+import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
+import { file } from '@/aoc/file/utils.js'
import { Garden } from './lib/garden.js'
import { WholesaleGarden } from './lib/wholesale.js'
diff --git a/src/2024/2024-12-12/sample.test.ts b/src/2024/2024-12-12/sample.test.ts
index 1becc11..b9241a0 100644
--- a/src/2024/2024-12-12/sample.test.ts
+++ b/src/2024/2024-12-12/sample.test.ts
@@ -1,8 +1,8 @@
import { test, expect } from 'vitest'
-import { AOC_OUTPUT_TYPE } from '@/utils/aocInputFile.js'
-import { file } from '@/utils/file.js'
+import { AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
+import { file } from '@/aoc/file/utils.js'
-import { readAOCInputFileAsync } from '@/utils/aocInputFile.js'
+import { readAOCInputFileAsync } from '@/aoc/file/aocfile.js'
import { Garden } from './lib/garden.js'
import { WholesaleGarden } from './lib/wholesale.js'
diff --git a/src/aoc/README.md b/src/aoc/README.md
new file mode 100644
index 0000000..4a68ac1
--- /dev/null
+++ b/src/aoc/README.md
@@ -0,0 +1,48 @@
+## aoc
+
+This folder contains common AoC-related types, scripts, and other generic helper utility functions.
+
+### 📂 `array`
+
+#### `utils.ts`
+
+A collection handler functions for manipulating regular arrays.
+
+- **`arrangeArray()`** - Array sorting function that arranges array items in ascending or descending order.
+- **`arrayToObject()`** - Converts an array of numbers to an Object, using the array number elements as keys with a default numeric value of `1`
+- **`arrayMiddleIndex()`** - Retrieves the middle (center) index of an array
+- **`uniformArrayElements()`** - Checks if array elements have the same type using `typeof` and have no null or undefined values
+
+### 📂 `file`
+
+- **`utils.ts`** - ES modules file and directory handlers
+- **`aocfile.ts`** - Functions for reading common-format AoC file input (arrays of `strings` or `numbers`)
+
+### 📂 `grid`
+
+#### `utils.ts`
+
+A collection of convenience handler functions for AoC 2D input arrays.
+
+- **`getCoordinateSymbol()`** - Converts a 2D `Point` point object to a string and returns its value from the 2D array
+- **`getGridDimensions()`** - Retrieves the length and width of a 2D string or number array
+- **`isIllegalCoordinate()`** - Checks if a point at coordinate (y,x) in a grid is illegal: if it's out of bounds of the grid area or if its symbol differs from the symbol parameter.
+- **`isOutOfBounds()`** - Checks if a (y,x) coordinate is out of the grid area
+- **`getDiagonalNeighbors()`** - Retrieves the four (4) diagonally aligned (y,x) coordinates and the symbol character from a `Point` in the grid. Substitutes a `"*"` symbol character in the `PointSymbol.symbol`if the `point` is out of the grid bounds.
+- **`getCrossNeighbors()`** - Retrieves the four (4) horizontal/vertical aligned (y,x) coordinates and the symbol character from a `Point` in the grid. Substitutes a `"*"` symbol character in the `PointSymbol.symbol`if the `point` is out of the grid bounds.
+
+### 📂 `number`
+
+#### `utils.ts`
+
+- **`isNumber()`** - Checks if a number-like input is a number
+- **`isEvenDigits()`** - Checks if a number has an even number of digits
+
+### 📂 `point`
+
+#### `utils.ts`
+
+- **`findNeighbors()`** - Finds all coordinates of the neighboring plots from a specified coordinate (up/down/left/right)
+- **`isDiagonal()`** - Checks if two (2) `Points` are diagonally aligned
+
+
diff --git a/src/utils/arrays.ts b/src/aoc/array/utils.ts
similarity index 72%
rename from src/utils/arrays.ts
rename to src/aoc/array/utils.ts
index f8ce6b2..c252581 100644
--- a/src/utils/arrays.ts
+++ b/src/aoc/array/utils.ts
@@ -20,7 +20,30 @@ export const arrangeArray = (order: ARRAY_ORDERING) =>
}
/**
- * Checks if array elements have the same type using `typeof` and has no null or undefined values
+ * 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),
+ {}
+ )
+}
+
+/**
+ * Retrieves the middle (center) index of an array
+ * @param list {T[]} 1-dimensional array
+ * @returns {number} Middle index of an array
+ */
+export const arrayMiddleIndex = (list: T[]): number => {
+ return Math.floor(list.length / 2) + list.length % 2
+}
+
+/**
+ * Checks if array elements have the same type using `typeof` and have no null or undefined values
* @param items {S[]} array of elements
* @param type {T} primitive type name of the elements inside the array (e.g., number, string, boolean)
* @returns {boolean} Flag indicating if all array elements have the same type
@@ -34,12 +57,3 @@ export const uniformArrayElements = (
.length === items.length
)
}
-
-/**
- * Retrieves the middle (center) index of an array
- * @param list {T[]} 1-dimensional array
- * @returns {number} Middle index of an array
- */
-export const arrayMiddleIndex = (list: T[]): number => {
- return Math.floor(list.length / 2) + list.length % 2
-}
diff --git a/src/utils/aocInputFile.ts b/src/aoc/file/aocfile.ts
similarity index 98%
rename from src/utils/aocInputFile.ts
rename to src/aoc/file/aocfile.ts
index 690acae..2917931 100644
--- a/src/utils/aocInputFile.ts
+++ b/src/aoc/file/aocfile.ts
@@ -1,5 +1,5 @@
// This code contains file input readers for common AoC input types.
-import { readFile } from './file.js'
+import { readFile } from './utils.js'
/**
* Definitions of the privimite types (`AOCFileOutput`) in which to convert the AoC quiz input text file.
diff --git a/src/utils/file.ts b/src/aoc/file/utils.ts
similarity index 100%
rename from src/utils/file.ts
rename to src/aoc/file/utils.ts
diff --git a/src/aoc/grid/types.ts b/src/aoc/grid/types.ts
new file mode 100644
index 0000000..81d1d08
--- /dev/null
+++ b/src/aoc/grid/types.ts
@@ -0,0 +1,36 @@
+import type { Point } from '../point/types.js'
+
+/**
+ * Represents a "(y,x)" coordinate in string and its value from a 2D array.
+ * @param {string} coordinate - String version of an "(y,x)" coordinate
+ * @param {string | number} symbol - Number or character in a 2D arary denoted by the (y,x) coordinate
+ */
+export type GridCoordinateSymbol = {
+ coordinate: string;
+ symbol: string | number;
+}
+
+/**
+ * `Grid` dimensions properties
+ *
+ * @property {number} length - Length of the grid
+ * @property {number} wwidth - Width of the grid
+ */
+export type GridDimensions = {
+ length: number;
+ width: number;
+}
+
+/**
+ * @type {Object} IllegalCoordinateParams
+ * @property {Point} point - (y,x) coordinate object in a 2D array grid
+ * @property {string} symbol - Character to check in the `point` coordinate.
+ * @property {GridDimensions} gridMeta - Grid length and width
+ * @property {string[][]} grid - 2D string array input
+ */
+export type IllegalCoordinateParams = {
+ point: Point;
+ symbol: string;
+ gridMeta: GridDimensions;
+ grid: string[][];
+}
diff --git a/src/aoc/grid/utils.ts b/src/aoc/grid/utils.ts
new file mode 100644
index 0000000..73bab05
--- /dev/null
+++ b/src/aoc/grid/utils.ts
@@ -0,0 +1,117 @@
+import type {
+ IllegalCoordinateParams,
+ GridCoordinateSymbol,
+ GridDimensions
+} from './types.js'
+
+import type { Point, PointSymbol } from '../point/types.js'
+
+import { findNeighbors } from '../point/utils.js'
+
+/**
+ * Converts a 2D `Point` point object to a string and returns its value from the 2D array
+ * @param {Point} point - (y,x) coordinatate in the 2D array
+ * @param {number[][]} data - 2D number array containing hiking trail data
+ * @returns {GridCoordinateSymbol} Returns the `GridCoordinateSymbol` (x,y) coordinate expressed in string and its value
+ */
+export const getCoordinateSymbol = (point: Point, data: number[][] | string[][]): GridCoordinateSymbol => {
+ return {
+ coordinate: `${point!.x},${point!.y}`,
+ symbol: data[point!.y]![point!.x] as number
+ }
+}
+
+/**
+ * Retrieves the length and width of a 2D string or number array
+ * @param {string[][] | number[][]} data - 2D string or number array
+ * @returns {GridDimensions} Object containig the length and width of the 2D array
+ */
+export const getGridDimensions = (data: T[][]): GridDimensions => {
+ return {
+ length: data.length,
+ width: data[0]!.length
+ }
+}
+
+/**
+ * Checks if a point at coordinate (y,x) in a grid is illegal: if it's out of bounds of the grid area
+ * or if its symbol differs from the symbol parameter.
+ * @param params {IllegalCoordinateParams} - Object input parameters.
+ * See the `IllegalCoordinateParams` for more information.
+ * @returns {boolean} Flag if a coordinate is illegae
+ */
+export const isIllegalCoordinate = (params: IllegalCoordinateParams): boolean => {
+ const { point, symbol, gridMeta } = params
+
+ return (
+ point.x < 0 ||
+ point.x >= gridMeta.width ||
+ point.y < 0 ||
+ point.y >= gridMeta.length ||
+ params.grid[point.y]![point.x] !== symbol
+ )
+}
+
+/**
+ * Checks if a (y,x) coordinate is out of the grid area
+ * @param {Point} point - (y,x) coordinate
+ * @param {GridDimensions} gridMeta - Length and width definitions of a 2D array (grid)
+ * @returns {boolean} Flag if a coordinate is out of the grid area
+ */
+export const isOutOfBounds = (point: Point, gridMeta: GridDimensions): boolean => {
+ return (
+ point.x < 0 || point.x >= gridMeta.width ||
+ point.y < 0 || point.y >= gridMeta.length
+ )
+}
+
+/**
+ * Retrieves the four (4) diagonally aligned (y,x) coordinates and the symbol character from a `Point` in the grid.
+ * Substitutes a `"*"` symbol character in the `PointSymbol.symbol`if the `point` is out of the grid bounds.
+ * @param {Point} point - (y,x) coordinate object in a 2D array grid
+ * @param {string[][]} data - 2D string array input
+ * @returns {PointSymbol[]} Array of `PointSymbol` with symbol characters.
+ */
+export const getDiagonalNeighbors = (point: Point, data: string[][]): PointSymbol[] => {
+ const grid = getGridDimensions(data)
+
+ // diagonal coordinates
+ const diagonals = [
+ { x: point.x + 1, y: point.y - 1 },
+ { x: point.x - 1, y: point.y - 1 },
+ { x: point.x + 1, y: point.y + 1 },
+ { x: point.x - 1, y: point.y + 1 }
+ ]
+
+ return diagonals.reduce((list: PointSymbol[], pt) => {
+ const item = { x: pt.x, y: pt.y, symbol: '*' }
+
+ if (!isOutOfBounds(pt, grid)) {
+ item.symbol = data[pt.y]![pt.x] as string
+ }
+
+ return [...list, item]
+ }, [])
+}
+
+/**
+ * Retrieves the four (4) horizontal/vertical aligned (y,x) coordinates and the symbol character from a `Point` in the grid.
+ * Substitutes a `"*"` symbol character in the `PointSymbol.symbol`if the `point` is out of the grid bounds.
+ * @param {Point} point - (y,x) coordinate object in a 2D array grid
+ * @param {string[][]} data - 2D string array input
+ * @returns {PointSymbol[]} Array of `PointSymbol` with symbol characters.
+ */
+export const getCrossNeighbors = (point: Point, data: string[][]): PointSymbol[] => {
+ const neighbors = findNeighbors(point) as Point[]
+ const grid = getGridDimensions(data)
+
+ return neighbors.reduce((list: PointSymbol[], pt) => {
+ const item = { x: pt.x, y: pt.y, symbol: '*' }
+
+ if (!isOutOfBounds(pt, grid)) {
+ item.symbol = data[pt.y]![pt.x] as string
+ }
+
+ return [...list, item]
+ }, [])
+}
diff --git a/src/utils/numbers.ts b/src/aoc/number/utils.ts
similarity index 62%
rename from src/utils/numbers.ts
rename to src/aoc/number/utils.ts
index fc271eb..b7a4651 100644
--- a/src/utils/numbers.ts
+++ b/src/aoc/number/utils.ts
@@ -11,3 +11,11 @@ export const isNumber = (input: string | number): boolean => {
return !isNaN(Number(input))
}
+
+/**
+ * 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
+}
diff --git a/src/aoc/point/types.ts b/src/aoc/point/types.ts
new file mode 100644
index 0000000..f40c50b
--- /dev/null
+++ b/src/aoc/point/types.ts
@@ -0,0 +1,74 @@
+/**
+ * Point (y,x) coordinate in a 2D array
+ * @type {Object}
+ * @property {number} x - x-coordinate of the point
+ * @property {number} y - y-coordinate of the point
+ */
+export interface Point {
+ x: number;
+ y: number;
+}
+
+/**
+ * Point (y,x) coordinate in a 2D array with a direction that denotes either the vertical (y) or horizontal (x) direction of a `Point`
+ * @type {Object}
+ * @extends {Point}
+ * @property {number} direction - Vertical (y) or horizontal (x) direction of a `Point`
+ */
+export interface Coordinate extends Point {
+ direction: 1 | -1;
+}
+
+/**
+ * Point (y,x) coordinate in a 2D array with symbol character
+ * @type {Object}
+ * @extends {Point}
+ * @property {string | number} symbol - Character or number symbol in the (y,x) coordinate location
+ */
+export interface PointSymbol extends Point {
+ symbol: string;
+}
+
+/**
+ * Defines the x and y direction of a point and a 2D array data.
+ * @type {Object}
+ * @property {number} xDirection - `-1` or `1` x-coordinate direction
+ * @property {number} yDirection - `-1` or `1` y-coordinate direction
+ * @property {string[][] | number[][]} data - 2D string or number array
+ */
+export interface CoordinateData {
+ xDirection: 1 | -1;
+ yDirection: 1 | -1;
+ data: string[][] | number[][]
+}
+
+/**
+ * Point (y,x) coordinate in a 2D array with a (y,x) direction
+ * @type {Object} PointSteps
+ * @property {number} x - x-coordinate of the point
+ * @property {number} y - y-coordinate of the point
+ * @property {Object} direction - Direction vector
+ * @property {number} direction.x - Left/right x-direction denoted by `+1` or `-1`
+ * @property {number} direction.y - Up/down y-direction denoted by `-1` or `+1`
+ */
+export type PointSteps = {
+ x: number;
+ y: number;
+ direction: {
+ x: number;
+ y: number;
+ }
+}
+
+/**
+ * Point (y,x) coordinate in a 2D array with a list of valid coordinate `PointSteps[]` from its location.
+ * @type {Object} PointDirection
+ * @property {number} x - x-coordinate of the point
+ * @property {number} y - y-coordinate of the point
+ * @property {PointSteps[]} validSteps - List of valid up/down/left/right coordinates from the (y,x) position.
+ */
+export type PointDirection = {
+ x: number;
+ y: number;
+ validSteps: PointSteps[]
+}
diff --git a/src/aoc/point/utils.ts b/src/aoc/point/utils.ts
new file mode 100644
index 0000000..9155c91
--- /dev/null
+++ b/src/aoc/point/utils.ts
@@ -0,0 +1,35 @@
+import type { Point } from './types.js'
+
+/**
+ * Finds all coordinates of the neighboring plots from a specified coordinate (up/down/left/right)
+ * @param {Point} point - (y,x) coordinate object in a 2D array grid
+ * @param {GridDimensions} gridMeta - grid length and width
+ * @param {string[][]} grid - 2D string array input
+ * @returns {PointSteps[]} Array of neighboring similar plants from the given `point`
+ */
+export const findNeighbors = (point: Point): Point[] | undefined => {
+ // All 4 possible locations (directions) from a coordinate
+ const steps = [
+ { ...point, x: point.x - 1 }, // left
+ { ...point, x: point.x + 1 }, // right
+ { ...point, y: point.y - 1 }, // down
+ { ...point, y: point.y + 1 } // up
+ ]
+
+ return steps
+}
+
+/**
+ * Checks if two (2) `Points` are diagonally aligned
+ * @param {Point} p1 - (y,x) Start `Point`
+ * @param {Point} p2 - (y,x) End `Point`
+ * @returns {boolean} Flag indicating if 2 `Points` are diagonally aligned
+ */
+export const isDiagonal = (p1: Point, p2: Point): boolean => {
+ const diff = {
+ x: Math.abs(p1.x - p2.x),
+ y: Math.abs(p1.y - p2.y)
+ }
+
+ return diff.x == 1 && diff.y === 1
+}
diff --git a/src/utils/grid/utils.ts b/src/utils/grid/utils.ts
deleted file mode 100644
index 084dad2..0000000
--- a/src/utils/grid/utils.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import type { GridDimensions } from '@/2024/2024-12-06/lib/grid.types.js'
-
-/**
- * Retrieves the length and width of a 2D string or number array
- * @param {string[][] | number[][]} data - 2D string or number array
- * @returns {GridDimensions} Object containig the length and width of the 2D array
- */
-export const getGridDimensions = (data: T[][]): GridDimensions => {
- return {
- length: data.length,
- width: data[0]!.length
- }
-}