Skip to content

Commit

Permalink
day 5 (#17)
Browse files Browse the repository at this point in the history
* day 5 init

* day 5
  • Loading branch information
spalberg authored Dec 6, 2024
1 parent 4cc21c7 commit d70615a
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 2 deletions.
70 changes: 70 additions & 0 deletions days/5/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { loadInput } from "utils";

export function part1(input: Array<string>) {
const { rules, updates } = parseInput(input);
const graph = buildDependencyGraph(rules);
return updates.filter((update) => isUpdateOrderValid(update, graph)).reduce(
(acc, update) => acc + update[Math.floor(update.length / 2)],
0,
);
}

export function part2(input: Array<string>) {
const { rules, updates } = parseInput(input);
const graph = buildDependencyGraph(rules);
return updates.filter((update) => !isUpdateOrderValid(update, graph))
.map((update) => orderUpdateCorrectly(update, graph)).reduce(
(acc, update) => acc + update[Math.floor(update.length / 2)],
0,
);
}

function isUpdateOrderValid(update: Array<number>, graph: DependencyGraph) {
const visited = new Set<number>();
for (const page of update) {
const dependencies = graph.get(page) ?? [];
for (const dependency of dependencies) {
if (update.includes(dependency) && !visited.has(dependency)) {
return false;
}
}
visited.add(page);
}
return true;
}

function orderUpdateCorrectly(update: Array<number>, graph: DependencyGraph) {
function compare(a: number, b: number) {
return update.includes(b) && graph.get(a)?.has(b) ? 1 : -1;
}
return update.toSorted(compare);
}

type DependencyGraph = Map<number, Set<number>>;
function buildDependencyGraph(rules: Array<[number, number]>): DependencyGraph {
const graph = new Map<number, Set<number>>();
for (const [predecessor, dependent] of rules) {
const set = graph.get(dependent) ?? new Set<number>();
set.add(predecessor);
graph.set(dependent, set);
}
return graph;
}

function parseInput(input: Array<string>) {
const rules: Array<[number, number]> = [];
const updates: Array<Array<number>> = [];
const split = input.indexOf("");
for (let i = 0; i < split; i++) {
rules.push(input[i].split("|").map(Number) as [number, number]);
}
for (let i = split + 1; i < input.length; i++) {
updates.push(input[i].split(",").map(Number));
}
return { rules, updates };
}

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

const input = [
"47|53",
"97|13",
"97|61",
"97|47",
"75|29",
"61|13",
"75|53",
"29|13",
"97|29",
"53|29",
"61|53",
"97|53",
"61|29",
"47|13",
"75|47",
"97|75",
"47|61",
"75|61",
"47|29",
"75|13",
"53|13",
"",
"75,47,61,53,29",
"97,61,53,29,13",
"75,29,13",
"75,97,47,61,53",
"61,13,29",
"97,13,75,29,47",
];

describe("day 5 example", () => {
it("part 1", () => {
expect(part1(input)).toBe(143);
});

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

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

it("part 2", async () => {
expect(part2(await loadInput(5))).toBe(6004);
});
});
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]) {
for (const day of [1, 2, 3, 4, 5]) {
days.set(day, await import(`./${day}/main.ts`));
}

Expand Down
2 changes: 1 addition & 1 deletion inputs

0 comments on commit d70615a

Please sign in to comment.