Skip to content

feat: day 13 claw contraption 20241213 #47

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 5 commits into from
Jan 8, 2025
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
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This repository contains solutions and a local development environment for the [
- Day 10: Hoof It [[link]](/src/2024/2024-12-10/README.md)
- Day 11: Plutonian Pebbles [[link]](/src/2024/2024-12-11/README.md)
- Day 12: Garden Groups [[link]](/src/2024/2024-12-12/README.md)
- Day 13: Claw Contraption [[link]](/src/2024/2024-12-13/README.md)

</details>

Expand Down Expand Up @@ -67,20 +68,20 @@ It follows the directory structure:

#### Quiz Folders

Each Advent of Code (AOC) event quiz has its folder under **`"/src/<YEAR>/<YYYY-MM-DD>"`** containing:
Each Advent of Code (AoC) event quiz has its folder under **`"/src/<YEAR>/<YYYY-MM-DD>"`** containing:
- **/lib**: Folder containing main quiz solution logic
- **input.txt**: Random quiz input
> _**INFO:** The sample quiz inputs were slightly altered from the original AoC input text and quiz samples as advised on their website_
- **main.ts**: Main program entry point containing quiz answer(s) using random input
- **sample.test.ts**: Minimal sample input with expected correct answers
- **README.md**: Reference and other notes about the AOC quiz question
- **README.md**: Reference and other notes about the AoC quiz question

#### Other Items

- **/src/aoc**: 🗃️ Folder containing generic utility and common AoC helper functions
- **/src/dist**: Folder containing the JavaScript files compiled from TypeScript (not committed to the repository)
- **/src/sample**: Miscellaneous random examples
- **/src/index.ts**: Exports all solutions to AOC quiz answer functions
- **/src/index.ts**: Exports all solutions to AoC quiz answer functions

### 📋 Requirements

Expand All @@ -106,7 +107,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.
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 from the project's _**"root directory"**_. For example:
```
npx vite-node src/sample/sample.ts
Expand Down Expand Up @@ -171,6 +172,10 @@ Runs the sample TS script.

Builds the JavaScript files from the TypeScript files.

### `npm run transpile:noemit`

Runs type-checking without generating the JavaScript or declatation files from the TypeScript files.

### `npm run lint`

Lints TypeScript source codes.
Expand Down
13 changes: 6 additions & 7 deletions src/2024/2024-12-06/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import path from 'path'
import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
import { directory } from '@/aoc/file/utils.js'
import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { file } from '@/aoc/file/utils.js'

import { guardController } from './lib/guardController.js'
import { findObstructionPositions } from './lib/guardControllerLoop.js'

const file = readAOCInputFile({
filePath: path.join(directory(import.meta.url), 'input.txt'),
const input = readAOCInputFile({
filePath: file(import.meta.url, 'input.txt'),
type: AOC_OUTPUT_TYPE.STRING_ARRAY_2D
}) as string [][]

Expand All @@ -15,7 +14,7 @@ const file = readAOCInputFile({
* Counts the number of distinct guard positions in a grid
*/
export const quiz20241206_01 = () => {
const grid = guardController(file, true)
const grid = guardController(input, true)

console.log('Distinct guard positions:', grid.positionCount)
return grid.positionCount
Expand All @@ -27,7 +26,7 @@ export const quiz20241206_01 = () => {
* obstacle will cause the Guard to walk in an infinite loop
*/
export const quiz20241206_02 = () => {
const infinitePositions = findObstructionPositions(file)
const infinitePositions = findObstructionPositions(input)

console.log('Obstruction positions for infinite walk:', infinitePositions)
return infinitePositions
Expand Down
13 changes: 6 additions & 7 deletions src/2024/2024-12-06/sample.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import path from 'path'
import { test, expect } from 'vitest'

import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
import { directory } from '@/aoc/file/utils.js'
import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { file } from '@/aoc/file/utils.js'

import { guardController } from './lib/guardController.js'
import { findObstructionPositions } from './lib/guardControllerLoop.js'

const file = readAOCInputFile({
filePath: path.join(directory(import.meta.url), 'input.txt'),
const input = readAOCInputFile({
filePath: file(import.meta.url, 'input.txt'),
type: AOC_OUTPUT_TYPE.STRING_ARRAY_2D
}) as string [][]

test('Count distinct guard positions', () => {
expect(guardController(file).positionCount).toBe(26)
expect(guardController(input).positionCount).toBe(26)
})

test('Count obstacle positions', () => {
expect(findObstructionPositions(file)).toBe(2)
expect(findObstructionPositions(input)).toBe(2)
})
5 changes: 2 additions & 3 deletions src/2024/2024-12-07/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import path from 'path'
import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { directory } from '@/aoc/file/utils.js'
import { file } from '@/aoc/file/utils.js'

import { totalCalibrationResult } from './lib/totalCalibration.js'
import { totalCalibrationConcat } from './lib/totalCalibrationConcat.js'

// Read and process the input file
const input = (readAOCInputFile({
filePath: path.join(directory(import.meta.url), 'input.txt'),
filePath: file(import.meta.url, 'input.txt'),
type: AOC_OUTPUT_TYPE.STRING
}) as string)
.split('\n')
Expand Down
7 changes: 3 additions & 4 deletions src/2024/2024-12-07/sample.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import path from 'path'
import { test, expect } from 'vitest'

import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
import { directory } from '@/aoc/file/utils.js'
import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { file } from '@/aoc/file/utils.js'

import { totalCalibrationResult } from './lib/totalCalibration.js'
import { totalCalibrationConcat } from './lib/totalCalibrationConcat.js'

// Read and process the input file
const input = (readAOCInputFile({
filePath: path.join(directory(import.meta.url), 'input.txt'),
filePath: file(import.meta.url, 'input.txt'),
type: AOC_OUTPUT_TYPE.STRING
}) as string)
.split('\n')
Expand Down
5 changes: 2 additions & 3 deletions src/2024/2024-12-08/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import path from 'path'
import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { directory } from '@/aoc/file/utils.js'
import { file } from '@/aoc/file/utils.js'

import { countAntinodes } from './lib/uniqueAntinodes.js'
import { countAllAntinodes } from './lib/allAntinodes.js'

const input = readAOCInputFile({
filePath: path.join(directory(import.meta.url), 'input.txt'),
filePath: file(import.meta.url, 'input.txt'),
type: AOC_OUTPUT_TYPE.STRING_ARRAY_2D
}) as string[][]

Expand Down
5 changes: 2 additions & 3 deletions src/2024/2024-12-08/sample.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import path from 'path'
import { test, expect } from 'vitest'

import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { directory } from '@/aoc/file/utils.js'
import { file } from '@/aoc/file/utils.js'

import { countAntinodes } from './lib/uniqueAntinodes.js'
import { countAllAntinodes } from './lib/allAntinodes.js'

const input = readAOCInputFile({
filePath: path.join(directory(import.meta.url), 'input.txt'),
filePath: file(import.meta.url, 'input.txt'),
type: AOC_OUTPUT_TYPE.STRING_ARRAY_2D
}) as string[][]

Expand Down
6 changes: 2 additions & 4 deletions src/2024/2024-12-09/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import path from 'path'

import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { directory } from '@/aoc/file/utils.js'
import { file } from '@/aoc/file/utils.js'

import { CompactDisk } from './lib/compact.js'
import { WholeDisk } from './lib/whole.js'

const input = readAOCInputFile({
filePath: path.join(directory(import.meta.url), 'input.txt'),
filePath: file(import.meta.url, 'input.txt'),
type: AOC_OUTPUT_TYPE.STRING
}) as string

Expand Down
5 changes: 2 additions & 3 deletions src/2024/2024-12-09/sample.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import path from 'path'
import { test, expect } from 'vitest'

import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { directory } from '@/aoc/file/utils.js'
import { file } from '@/aoc/file/utils.js'

import { CompactDisk } from './lib/compact.js'
import { WholeDisk } from './lib/whole.js'

const input = readAOCInputFile({
filePath: path.join(directory(import.meta.url), 'input.txt'),
filePath: file(import.meta.url, 'input.txt'),
type: AOC_OUTPUT_TYPE.STRING
}) as string

Expand Down
2 changes: 1 addition & 1 deletion src/2024/2024-12-10/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import { readAOCInputFile, AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
import { AOC_OUTPUT_TYPE, readAOCInputFile } from '@/aoc/file/aocfile.js'
import { file } from '@/aoc/file/utils.js'

import { countTrailScores } from './lib/scoresRatings.js'
Expand Down
4 changes: 2 additions & 2 deletions src/2024/2024-12-12/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Visit the Advent of Code website for more information on this puzzle at:

**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).
- **`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.
- **`calculateFencePrice()`** - Calculates the total fencing price of all regions in a garden per connected plot using the formula: area * perimeter (per plot).

### `wholesale.ts`

Expand Down
1 change: 0 additions & 1 deletion src/2024/2024-12-12/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { Point } from '@/aoc/point/types.js'
import { getDiagonalNeighbors } from '@/aoc/grid/utils.js'
import { getGridDimensions, isOutOfBounds } from '@/aoc/grid/utils.js'


/**
* 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
Expand Down
8 changes: 4 additions & 4 deletions src/2024/2024-12-12/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const input = readAOCInputFile({
* Part 1/2 of the 2024-12-12 quiz
* Counts the total fencing price: area * perimeter per plot
*/
const quiz20241231_01 = () => {
const quiz20241212_01 = () => {
const garden = new Garden()
const totalPrice = garden.calculateFencePrice(input, true)

Expand All @@ -24,12 +24,12 @@ const quiz20241231_01 = () => {
* Part 2/2 of the 2024-12-12 quiz
* Counts the wholesale fencing price: area * perimeter of whole region (edges)
*/
const quiz20241231_02 = () => {
const quiz20241212_02 = () => {
const garden = new WholesaleGarden()
const totalPrice = garden.calculateFencePrice(input, true)

console.log('---Wholesale fencing price', totalPrice)
}

quiz20241231_01()
quiz20241231_02()
quiz20241212_01()
quiz20241212_02()
4 changes: 1 addition & 3 deletions src/2024/2024-12-12/sample.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { test, expect } from 'vitest'
import { AOC_OUTPUT_TYPE } from '@/aoc/file/aocfile.js'
import { AOC_OUTPUT_TYPE, readAOCInputFileAsync } from '@/aoc/file/aocfile.js'
import { file } from '@/aoc/file/utils.js'

import { readAOCInputFileAsync } from '@/aoc/file/aocfile.js'

import { Garden } from './lib/garden.js'
import { WholesaleGarden } from './lib/wholesale.js'

Expand Down
31 changes: 31 additions & 0 deletions src/2024/2024-12-13/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Day 13: Claw Contraption

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

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

## Code

### `count.ts`

- **`countTokensPrizes()`** - Counts the number of tokens needed to win all possible prizes.

### `countAdjusted.ts`

- **`countTokensOnAdjustedPrizes()`** - Counts the number of tokens needed to win all possible prizes with adjusted +10000000000000 coordinates.

### `utils.ts`

- **`getDeterminant()`** - Counts the determinant of a 2x2 coefficient matrix. Currently only works with a 2x2 number matrix.
- **`coefficientMatrix()`** - Builds a coefficient matrix by replacing column values with the constants. Currently only works with a 2x2 number matrix.
- **`solveEquation()`** - Calculates the number of needed (x,y) button A "and" B presses to reach the prize by solving the 2 equations using Cramer's Rule.

### `fileReader.ts`

- Reads and formats the quiz input TXT file

## References

<sup>[[1]](https://www.youtube.com/watch?v=jBsC34PxzoM)</sup>&nbsp; Cramer's Rule<br>
<sup>[[2]](https://www.youtube.com/playlist?list=PLybg94GvOJ9En46TNCXL2n6SiqRc_iMB8)</sup>&nbsp; Linear Algebra Videos
15 changes: 15 additions & 0 deletions src/2024/2024-12-13/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400

Button A: X+3, Y+8
Button B: X+4, Y+15
Prize: X=123, Y=456

Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450

Button A: X+30, Y+9
Button B: X+78, Y+14
Prize: X=777, Y=14344
Loading
Loading