Skip to content

Commit affb320

Browse files
committed
12/2024 (part 1)
1 parent eb852d3 commit affb320

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

2024/12/index.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { getPuzzle } from "../../utils";
2+
3+
const puzzleInput = getPuzzle(__dirname).trim();
4+
5+
const farm = puzzleInput.split("\n").map((row) => row.split(""));
6+
7+
const FARM_HEIGHT = farm.length;
8+
const FARM_WIDTH = farm[0].length;
9+
10+
type Coordinate = { x: number; y: number };
11+
12+
const directions = {
13+
UP: { x: 0, y: -1 },
14+
RIGHT: { x: 1, y: 0 },
15+
DOWN: { x: 0, y: 1 },
16+
LEFT: { x: -1, y: 0 },
17+
} satisfies Record<string, Coordinate>;
18+
19+
const getCellKey = (cell: Coordinate) => `${cell.x},${cell.y}`;
20+
21+
const getCellFromKey = (key: string) => {
22+
const [x, y] = key.split(",").map(Number);
23+
24+
return { x, y };
25+
};
26+
27+
const move = (cell: Coordinate, direction: Coordinate) => {
28+
return { x: cell.x + direction.x, y: cell.y + direction.y };
29+
};
30+
31+
const getRegions = () => {
32+
const visited = new Set<string>();
33+
const regions = new Map<string, { type: string; cells: Set<string> }>();
34+
35+
for (let y = 0; y < FARM_HEIGHT; y++) {
36+
for (let x = 0; x < FARM_WIDTH; x++) {
37+
const currentCellKey = getCellKey({ x, y });
38+
if (visited.has(currentCellKey)) {
39+
continue;
40+
}
41+
42+
const currentCell = farm[y][x];
43+
44+
regions.set(currentCellKey, {
45+
type: currentCell,
46+
cells: new Set([currentCellKey]),
47+
});
48+
const cells = regions.get(currentCellKey).cells;
49+
50+
const queue = [{ x, y }];
51+
const visitedInner = new Set<string>();
52+
53+
while (queue.length) {
54+
const cell = queue.shift();
55+
const cellKey = getCellKey(cell);
56+
57+
if (visitedInner.has(cellKey)) {
58+
continue;
59+
}
60+
visitedInner.add(cellKey);
61+
62+
for (const direction of Object.values(directions)) {
63+
const nextCell = move(cell, direction);
64+
const nextCellKey = getCellKey(nextCell);
65+
66+
if (visitedInner.has(nextCellKey)) {
67+
continue;
68+
}
69+
70+
if (
71+
nextCell.x < 0 ||
72+
nextCell.x >= FARM_WIDTH ||
73+
nextCell.y < 0 ||
74+
nextCell.y >= FARM_HEIGHT
75+
) {
76+
continue;
77+
}
78+
79+
const nextCellValue = farm[nextCell.y][nextCell.x];
80+
81+
if (nextCellValue === currentCell) {
82+
queue.push(nextCell);
83+
visited.add(nextCellKey);
84+
cells.add(nextCellKey);
85+
}
86+
}
87+
}
88+
}
89+
}
90+
91+
return regions;
92+
};
93+
94+
// Part 1
95+
(() => {
96+
console.time("part 1");
97+
const regions = getRegions();
98+
let totalPrice = 0;
99+
100+
for (const [, region] of regions) {
101+
const area = region.cells.size;
102+
let perimeter = 0;
103+
104+
for (const regionCellKey of region.cells) {
105+
const cell = getCellFromKey(regionCellKey);
106+
107+
for (const direction of Object.values(directions)) {
108+
const neighbourCell = {
109+
x: cell.x + direction.x,
110+
y: cell.y + direction.y,
111+
};
112+
113+
if (farm?.[neighbourCell.y]?.[neighbourCell.x] !== region.type) {
114+
perimeter++;
115+
}
116+
}
117+
}
118+
119+
totalPrice += area * perimeter;
120+
}
121+
122+
console.log("part 1 totalPrice ::", totalPrice);
123+
console.timeEnd("part 1");
124+
})();
125+
126+
// Part 2
127+
// (() => {
128+
// console.time("part 2");
129+
// console.timeEnd("part 2");
130+
// })();

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
| Day | Part 1 | Part 2 |
88
| :----------------------------------------: | :----: | :----: |
9+
| [12](https://adventofcode.com/2024/day/12) || - |
910
| [11](https://adventofcode.com/2024/day/11) |||
1011
| [10](https://adventofcode.com/2024/day/10) |||
1112
| [09](https://adventofcode.com/2024/day/9) |||

0 commit comments

Comments
 (0)