Skip to content

Commit 9a80fb5

Browse files
committed
feat(day05): unoptimized Part 2
1 parent 0722e7a commit 9a80fb5

File tree

1 file changed

+67
-9
lines changed

1 file changed

+67
-9
lines changed

day05_test.ts

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,38 @@ Deno.test("Day 5: If You Give A Seed A Fertilizer", async (t) => {
5252
});
5353
});
5454

55-
await t.step("Solution", async (t) => {
55+
await t.step("Solution", async () => {
5656
const solution = almanac(
5757
(await Deno.readTextFile("./input/day05.txt")).split("\n")
5858
);
5959
assertEquals(lowest(solution), 403695602);
6060
});
6161
});
62+
63+
await t.step("Part 2", async (t) => {
64+
await t.step("Example", async () => {
65+
const example = lowestSeedRange(
66+
(await Deno.readTextFile("./input/day05.example.txt")).split("\n")
67+
);
68+
assertEquals(example, 46);
69+
});
70+
/**
71+
* FIXME: Completes after ~5 minutes
72+
* This should be optimizable by
73+
* - combining all the maps into one final map
74+
* - reverting the algorithm to start at the lowest positions until a matching seed is found.
75+
await t.step("Solution", async () => {
76+
const solution = lowestSeedRange(
77+
(await Deno.readTextFile("./input/day05.txt")).split("\n")
78+
);
79+
assertEquals(solution, 219529182);
80+
});
81+
*/
82+
});
6283
});
6384

85+
const lowest = (numbers: Set<number>) => Math.min(...numbers.values());
86+
6487
const rangeRx =
6588
/^(?<destRangeStart>\d+) (?<sourceRangeStart>\d+) (?<rangeLength>\d+)$/;
6689

@@ -96,6 +119,48 @@ const almanac = (almanac: string[]) => {
96119
const seeds = almanac[0].split(":")[1].trim().split(" ").map(toNumber);
97120

98121
// Read in all the map ranges
122+
const maps = almanacToMaps(almanac);
123+
124+
return mapSeeds(seeds, maps);
125+
};
126+
127+
const lowestSeedRange = (almanac: string[]): number => {
128+
// Get the seed pairs from the first line
129+
const seedPairs = almanac[0]
130+
.split(":")[1]
131+
.trim()
132+
.matchAll(/(\d+ \d+)+/g);
133+
134+
// Read in all the map ranges
135+
const maps = almanacToMaps(almanac);
136+
137+
let lowest = Number.MAX_SAFE_INTEGER;
138+
for (const pair of seedPairs) {
139+
const [start, length] = pair[0].split(" ").map(toNumber);
140+
for (let i = start; i < start + length; i++) {
141+
lowest = Math.min(
142+
maps.reduce((mapped, seedMap) => seedMap(mapped), i),
143+
lowest
144+
);
145+
}
146+
}
147+
148+
return lowest;
149+
};
150+
151+
// Pass each seed through each map
152+
const mapSeeds = (
153+
seeds: number[],
154+
maps: Array<(seed: number) => number>
155+
): Set<number> =>
156+
new Set<number>(
157+
seeds.map((seed) => maps.reduce((mapped, seedMap) => seedMap(mapped), seed))
158+
);
159+
160+
/**
161+
* Parses the almanac to maps
162+
*/
163+
const almanacToMaps = (almanac: string[]): Array<(seed: number) => number> => {
99164
const mapRanges: Array<Array<string>> = [[]];
100165
let i = 0;
101166
// Skip first three lines
@@ -110,12 +175,5 @@ const almanac = (almanac: string[]) => {
110175
}
111176

112177
// Convert to maps
113-
const maps = mapRanges.map(seedMap);
114-
115-
// Pass each seed through each map
116-
return new Set<number>(
117-
seeds.map((seed) => maps.reduce((mapped, seedMap) => seedMap(mapped), seed))
118-
);
178+
return mapRanges.map(seedMap);
119179
};
120-
121-
const lowest = (numbers: Set<number>) => Math.min(...numbers.values());

0 commit comments

Comments
 (0)