Skip to content

v1.2.1 #42

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 38 commits into from
Dec 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b5b9ef3
ref: move fxn out of loop
weaponsforge Dec 17, 2024
9b6c82a
chore: update notes
weaponsforge Dec 17, 2024
d97e4c1
chore: common aoc file input reader
weaponsforge Dec 18, 2024
854190b
feat: day 6 guard gallivant 1/2 soln, #11
weaponsforge Dec 18, 2024
db1eb28
chore: add class notes
weaponsforge Dec 20, 2024
71999a5
feat: day 6 guard gallivant quiz 2/2 soln, #11
weaponsforge Dec 20, 2024
7e5dc64
Merge pull request #31 from weaponsforge/feat/weaponsforge-11
weaponsforge Dec 20, 2024
2a85433
chore: update README
weaponsforge Dec 20, 2024
ec8e6bb
feat: day 7 bridge repair 1/2 soln, #12
weaponsforge Dec 21, 2024
99c10a0
chore: use random input
weaponsforge Dec 21, 2024
376b3ba
chore: update note
weaponsforge Dec 21, 2024
943486f
feat: day 7 bridge repair 2/2 soln, #12
weaponsforge Dec 21, 2024
45d3a5f
chore: ignore text files in root dir
weaponsforge Dec 21, 2024
6582fb3
chore: update README
weaponsforge Dec 21, 2024
d800db1
Merge pull request #34 from weaponsforge/feat/weaponsforge-12
weaponsforge Dec 21, 2024
c81121d
feat: day 8 resonant collinearity 1/2 soln, #13
weaponsforge Dec 24, 2024
0d8138b
chore: independent board for printing antinodes
weaponsforge Dec 25, 2024
28ebded
feat: day 8 resonant collinearity 2/2 soln, #13
weaponsforge Dec 25, 2024
26e3194
chore: update README
weaponsforge Dec 25, 2024
526661f
Merge pull request #39 from weaponsforge/feat/weaponsforge-13
weaponsforge Dec 25, 2024
58b4777
chore: require node v20.15.0 or higher
weaponsforge Dec 25, 2024
97c5429
chore: use method
weaponsforge Dec 25, 2024
1397c51
feat: day 9 disk fragmenter 1/2 soln, #14
weaponsforge Dec 25, 2024
18ae4b8
chore: use random non-aoc provided input
weaponsforge Dec 25, 2024
2ac3e83
chore: print logs
weaponsforge Dec 25, 2024
1f81685
feat: day 9 disk fragmenter 2/2 soln, #14
weaponsforge Dec 26, 2024
93abfc0
chore: update docs
weaponsforge Dec 26, 2024
ecfe773
fix: print logs
weaponsforge Dec 26, 2024
25a1a9d
chore: use a random non-aoc input
weaponsforge Dec 26, 2024
ea61a69
Merge pull request #40 from weaponsforge/feat/weaponsforge-14
weaponsforge Dec 26, 2024
08e9965
chore: update docs
weaponsforge Dec 26, 2024
59fbd7f
chore: refactor currentDirectory name to directory
weaponsforge Dec 27, 2024
8e559d0
fix: unrenamed currentDirectory
weaponsforge Dec 27, 2024
4d1c496
feat: day 10 hoof it 1/2 soln, #15
weaponsforge Dec 29, 2024
44e154c
chore: commit scratch visuals
weaponsforge Dec 29, 2024
adb9f66
feat: day 10 hoof it 2/2 soln, #15
weaponsforge Dec 29, 2024
92b8248
chore: update comment
weaponsforge Dec 29, 2024
d919fdb
Merge pull request #41 from weaponsforge/feat/weaponsforge-15
weaponsforge Dec 29, 2024
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ dist/
*.zip
*.rar
*.tgz
src/**/*.js

**/*.txt
!src/**/*.txt
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.15.0
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## ✨ adventofcode

This repository contains solutions and a local development environment for the [Advent of Code](https://adventofcode.com/) event puzzles.
This repository contains solutions and a local development environment for the [Advent of Code](https://adventofcode.com/) event puzzles using TypeScript/JavaScript.

The codes are structured in a way that discusses and walks through the solution steps for the AoC quizzes rather than focusing on AoC's competitive programming.

### 🎄 Advent of Code Quiz Information

Expand All @@ -12,6 +14,11 @@ This repository contains solutions and a local development environment for the [
- Day 3: Mull It Over [[link]](/src/2024/2024-12-03/README.md)
- Day 4: Ceres Search [[link]](/src/2024/2024-12-04/README.md)
- Day 5: Print Queue [[link]](/src/2024/2024-12-05/README.md)
- Day 6: Guard Gallivant [[link]](/src/2024/2024-12-06/README.md)
- Day 7: Bridge Repair [[link]](/src/2024/2024-12-07/README.md)
- 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)

</details>

Expand Down Expand Up @@ -72,7 +79,7 @@ Each Advent of Code (AOC) event quiz has its folder under **`"/src/<YEAR>/<YYYY-

### 📋 Requirements

- Node v20.15.0
- Node v20.15.0 (at least)
- node: 20.15.0
- npm: 10.7.0

Expand All @@ -95,7 +102,7 @@ Each Advent of Code (AOC) event quiz has its folder under **`"/src/<YEAR>/<YYYY-
Using Node

1. (Optional) Replace the values of specific `input.txt` in the `"/src/<YEAR>/<YYYY-MM-DD>"` directories with actual AOC input.
2. Run a non-test TypeScript file inside the **/src** directory. For example:
2. Run a non-test TypeScript file inside the **/src** directory from the project's _**"root directory"**_. For example:
```
npx vite-node src/sample/sample.ts
```
Expand All @@ -108,7 +115,7 @@ Using Node
npm run transpile
node dist/sample/sample.js
```
4. See the [Available Scripts](#available-scripts) section for more information.
4. See the [Available Scripts](#-available-scripts) section for more information.

## ⚡ Alternate Usage

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"main": "dist/index.js",
"type": "module",
"engines": {
"node": "20.15.0",
"npm": "10.7.0"
"node": ">=20.15.0",
"npm": ">=10.7.0"
},
"scripts": {
"dev": "vitest",
Expand Down
6 changes: 3 additions & 3 deletions src/2024/2024-12-01/lib/fileReader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'path'
import { readFile, currentDirectory } from '@/utils/file.js'
import { readFile, directory } from '@/utils/file.js'

export type arrayLists = {
list1: string[];
Expand All @@ -12,8 +12,8 @@ export type arrayLists = {
*/
export const fileReader = (): arrayLists => {
// Read quiz input file
const directory = currentDirectory(import.meta.url)
const file = readFile(path.join(directory, '..', 'input.txt'))
const dir = directory(import.meta.url)
const file = readFile(path.join(dir, '..', 'input.txt'))
const pairs: string[] = file.split('\n')

const list1: string[] = []
Expand Down
6 changes: 3 additions & 3 deletions src/2024/2024-12-02/lib/fileReader.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import path from 'path'
import { readFile, currentDirectory } from '@/utils/file.js'
import { readFile, directory } from '@/utils/file.js'

/**
* Reads the quiz's input file into two (2) string arrays
* @returns {arrayLists} An object containing two (2) string arrays: `{ list1, list2 }`
*/
export const fileReader = (): number[][] => {
// Read quiz input file
const directory = currentDirectory(import.meta.url)
const file = readFile(path.join(directory, '..', 'input.txt'))
const dir = directory(import.meta.url)
const file = readFile(path.join(dir, '..', 'input.txt'))

return file
.split('\n')
Expand Down
6 changes: 3 additions & 3 deletions src/2024/2024-12-03/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import path from 'path'
import { currentDirectory, readFile } from '@/utils/file.js'
import { directory, readFile } from '@/utils/file.js'
import { extractMultiply, extractMultiplyCondition } from './lib/extractMultiply.js'

const directory = currentDirectory(import.meta.url)
const input = readFile(path.join(directory, 'input.txt'))
const dir = directory(import.meta.url)
const input = readFile(path.join(dir, 'input.txt'))

/**
* Part 1/2 of the 2024-12-03 quiz
Expand Down
6 changes: 3 additions & 3 deletions src/2024/2024-12-04/main.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import path from 'path'
import { currentDirectory, readFile } from '@/utils/file.js'
import { directory, readFile } from '@/utils/file.js'
import { wordCount } from './lib/wordCount.js'
import { countMASword } from './lib/xmasCount.js'

const directory = currentDirectory(import.meta.url)
const dir = directory(import.meta.url)

const data: string[][] = readFile(path.join(directory, 'input.txt'))
const data: string[][] = readFile(path.join(dir, 'input.txt'))
.split('\n')
.map(row => row.split(''))

Expand Down
6 changes: 3 additions & 3 deletions src/2024/2024-12-05/lib/fileReader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'path'
import { currentDirectory, readFile } from '@/utils/file.js'
import { directory, readFile } from '@/utils/file.js'
import { uniformArrayElements } from '@/utils/arrays.js'

export type Rules = Record<number, number[]>
Expand All @@ -15,8 +15,8 @@ export type QuizData = {
* @returns {QuizData} Formatted data
*/
export const fileReader = (fileName: string): QuizData => {
const directory = currentDirectory(import.meta.url)
const file = readFile(path.join(directory, '..', fileName))
const fir = directory(import.meta.url)
const file = readFile(path.join(fir, '..', fileName))

const segments = file.split('\n\n')

Expand Down
40 changes: 21 additions & 19 deletions src/2024/2024-12-05/lib/fixOrderingUpdates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type CurrentItem = {
}

/**
* Finds the next appropriate array index to swap places with the incorrectly placed current item accoring to the "rules"
* Finds the next appropriate array index to swap places with the incorrectly placed current item according to the "rules"
* @param rules {Rules} Object containing parsed and formatted rules and updates data
* @param restItems {number[]} "updates" array items content
* @param currentItem {CurrentItem} Object containing the "current" item data in focus: value and array index
Expand Down Expand Up @@ -44,30 +44,32 @@ export const fixOrdering = (rules: Rules, unorderedItems: number[]): number[] =>
throw new Error('Invalid item/s')
}

for (let i = 0; i < unorderedItems.length - 1; i += 1) {
let currentItem = unorderedItems[i] as number
const currentItemData = { value: currentItem, index: i }
let currentItem: number = -2

// Swaps incorrectly placed items with target items in the array
const swapItems = () => {
const indexToSwap = nextHotSwapIndex(
rules,
unorderedItems,
currentItemData
)
// Swaps incorrectly placed items with target items in the array
const swapItems = (activeItem: CurrentItem, activeIndex: number) => {
const indexToSwap = nextHotSwapIndex(
rules,
unorderedItems,
activeItem
)

const temp = unorderedItems[indexToSwap] as number
unorderedItems[indexToSwap] = currentItem
unorderedItems[i] = temp
currentItem = temp
const temp = unorderedItems[indexToSwap] as number
unorderedItems[indexToSwap] = activeItem.value
unorderedItems[activeIndex] = temp
currentItem = temp

fixOrdering(rules, unorderedItems)
}
fixOrdering(rules, unorderedItems)
}

for (let i = 0; i < unorderedItems.length - 1; i += 1) {
currentItem = unorderedItems[i] as number
const currentItemData = { value: currentItem, index: i }

// Correct "update" item should have en entry in the "rules" object
// Swap places with other items if its incorrect
if (rules[currentItem] === undefined) {
swapItems()
swapItems(currentItemData, i)
}

// Get the rest of items after the current item for comparison
Expand All @@ -76,7 +78,7 @@ export const fixOrdering = (rules: Rules, unorderedItems: number[]): number[] =>
// Correct item's "rule" should have the after-item entries
// Swap places with other items if its incorrect
if (!afterItems.every(item => rules[currentItem]?.includes(item))) {
swapItems()
swapItems(currentItemData, i)
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/2024/2024-12-06/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## Day 6: Guard Gallivant

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

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

## Code

1. **grid.ts**
- `Grid` - 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.
- Have methods for moving around in the `Grid`.

3. **guardController.ts**
- `guardController()` - Runs the `Guard` on the `Grid`, counting distinct positions/steps.

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._
10 changes: 10 additions & 0 deletions src/2024/2024-12-06/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
....#.....
.........#
..........
.#........
..........
.......#..
.#..^.....
.#......#.
....#.....
......#...
126 changes: 126 additions & 0 deletions src/2024/2024-12-06/lib/grid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
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.
*/
export class Grid {
/** 2D board string array */
board: string[][] = []

/** Board length */
length: number = 0

/** Board width */
width: number = 0

/** Number of distinct positions that a `Guard` can traverse on the board */
positionCount: number = 0

/** Initial (x,y) coordinate starting position of a `Guard` */
start: { x: number; y: number; }

/** Obstruction symbol. Guards turn clockwise if this symbol blocks their next step. */
obstruction = '#'

/** Path symbol. Guards proceed to the next (x,y) coordinate after on this symbol. */
pathSymbol = '.'

/**
* @constructor
* @param {string[][]} data 2D string array containing paths `"."`, obstacles `"#"` and the `Guard` object
* @param obstructionSymbol
*/
constructor (data: string[][], obstructionSymbol: string = '#') {
this.board = data
this.length = data.length
this.width = (data[0])?.length as number
this.obstruction = obstructionSymbol
this.start = { x: -1, y: -1 }

this.findGuardStartPosition()
}

/**
* Finds the initial position and state of the guard in a 2D board array
* @param data {string[][]} 2D string array of the guard board
* @returns {GuardState} Initial position and state of the guard
*/
findGuardStartPosition (): GuardState {
const GuardDirections: string[] = Object.values(GuardDirection)

const initialState: GuardState = {
direction: null,
xPos: -1,
yPos: -1,
status: GuardStatus.IDLE
}

for (let y = 0; y < this.board.length; y += 1) {
const row = this.board[y]

if (row === undefined) {
throw new Error('Undefined row')
}

for (let i = 0; i < GuardDirections.length; i += 1) {
const indexOfDirection = row.indexOf(GuardDirections[i] as string)

if (indexOfDirection >= 0) {
initialState.direction = GuardDirections[i] as GuardDirection
initialState.xPos = indexOfDirection
initialState.yPos = y
initialState.status = GuardStatus.ACTIVE
break
}
}

if (initialState.status === GuardStatus.ACTIVE) break
}

this.start.x = initialState.xPos
this.start.y = initialState.yPos

return initialState
}

/**
* Checks if an (x,y) coordinate is outside the grid area
* @param {number} x array x coordinate
* @param {number} y array y coordinate
* @returns {boolean} Flag indicating if the guard is outside the grid
*/
isOutOfBounds (x: number, y: number): boolean {
const row = this.board[0] as string[]

return x < 0 ||
x >= row.length ||
y < 0 ||
y >= this.board.length
}

/**
* Marks an (x,y) coordinate in the grid
* @param {number} x array x coordinate
* @param {number} y array y coordinate
* @returns {void}
*/
mark (x: number, y: number): void {
const row = this.board[y]

if (row !== undefined && row[x] !== 'X') {
row[x] = 'X'
this.positionCount += 1
}
}

/**
* Displays the guard's distinct positions in the grid
*/
print () {
console.clear()
console.log(this.board.map(row => row.join(' ')))
}
}
Loading
Loading