Skip to content

Commit

Permalink
day 12 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
spalberg committed Dec 20, 2024
1 parent a4161f0 commit 1ef581e
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 2 deletions.
106 changes: 106 additions & 0 deletions days/12/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Grid } from "@pal/datastructures";
import { loadInput } from "utils";

export function part1(input: Array<string>) {
let total = 0;
for (const region of extractRegions(input)) {
total += region.size * calculatePerimeter(region);
}
return total;
}

export function part2(input: Array<string>) {
let total = 0;
for (const region of extractRegions(input)) {
total += region.size * calculatePerimeter(region);
}
return total;
}

type Coord = { x: number; y: number };
type CoordId = string;
type Region = Set<CoordId>;

function* extractRegions(input: Array<string>): Generator<Region> {
const grid = Grid.fromStrings(input);
const regionsByType = new Map<string, Set<Region>>();
function addToRegion(
x: number,
y: number,
dx: number,
dy: number,
type: string,
regionsOfType: Set<Region>,
): Region | null {
const neighbourType = grid.at(x + dx, y + dy);
if (neighbourType === type) {
for (const region of regionsOfType) {
if (region.has(coordId({ x: x + dx, y: y + dy }))) {
region.add(coordId({ x, y }));
return region;
}
}
}
return null;
}
for (let y = 0; y < grid.height; y++) {
for (let x = 0; x < grid.width; x++) {
const type = grid.at(x, y)!;
let regionsOfType = regionsByType.get(type);
if (regionsOfType == null) {
regionsOfType = new Set<Region>();
regionsByType.set(type, regionsOfType);
}
const leftRegion = addToRegion(x, y, -1, 0, type, regionsOfType);
const rightRegion = addToRegion(x, y, 0, -1, type, regionsOfType);
if (
leftRegion != null && rightRegion != null && leftRegion !== rightRegion
) {
for (const coord of rightRegion) {
leftRegion.add(coord);
}
regionsOfType.delete(rightRegion);
}
if (leftRegion == null && rightRegion == null) {
regionsOfType.add(new Set([coordId({ x, y })]));
}
}
}
for (const regions of regionsByType.values()) {
yield* regions;
}
}

function calculatePerimeter(region: Region): number {
let perimeter = 0;
for (const c of region) {
const { x, y } = fromCoordId(c);
if (region.has(coordId({ x: x - 1, y })) === false) {
perimeter++;
}
if (region.has(coordId({ x: x + 1, y })) === false) {
perimeter++;
}
if (region.has(coordId({ x, y: y - 1 })) === false) {
perimeter++;
}
if (region.has(coordId({ x, y: y + 1 })) === false) {
perimeter++;
}
}
return perimeter;
}

function coordId(coord: Coord): CoordId {
return `${coord.x},${coord.y}`;
}

function fromCoordId(coordId: CoordId): Coord {
const [x, y] = coordId.split(",").map(Number);
return { x, y };
}

if (import.meta.main) {
console.log(part1(await loadInput(12)));
console.log(part2(await loadInput(12)));
}
37 changes: 37 additions & 0 deletions days/12/main_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { expect } from "@std/expect";
import { describe, it } from "@std/testing/bdd";
import { part1, part2 } from "./main.ts";
import { loadInput } from "utils";

describe("day 12 example", () => {
const input = [
"RRRRIICCFF",
"RRRRIICCCF",
"VVRRRCCFFF",
"VVRCCCJFFF",
"VVVVCJJCFE",
"VVIVCCJJEE",
"VVIIICJJEE",
"MIIIIIJJEE",
"MIIISIJEEE",
"MMMISSJEEE",
];

it("part 1", () => {
expect(part1(input)).toBe(1930);
});

it("part 2", () => {
expect(part2(input)).toBe(1206);
});
});

describe("day 12 solution", () => {
it("part 1", async () => {
expect(part1(await loadInput(12))).toBe(1467094);
});

it.ignore("part 2", async () => {
expect(part2(await loadInput(12))).toBe(-1);
});
});
2 changes: 1 addition & 1 deletion days/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ type Solution = { part1: PartFunction; part2: PartFunction };

const days = new Map<number, Solution>();

for (const day of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) {
for (const day of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) {
days.set(day, await import(`./${day}/main.ts`));
}

Expand Down
2 changes: 1 addition & 1 deletion inputs

0 comments on commit 1ef581e

Please sign in to comment.