advent-of-code/2021/1.ts

49 lines
1.7 KiB
TypeScript
Raw Normal View History

import { inputNumbers } from "./common.ts";
2021-12-01 08:43:02 -06:00
/** This solution is relatively simple. Keep track of the last depth we
* measured in `lastDepth` (skipping the first line of input by defaulting it
* to `Number.MAX_VALUE`) and compare it to each line of input as we read it.
* Once we've compared, set the `lastDepth` to the current depth for the next
2021-12-01 09:45:18 -06:00
* iteration.
*
* This solution should be O(n) for compute and O(n) for memory since we
* iterate the input once and only read a line at a time, we actually have O(1)
* memory, but since the input is on disk, that's kind of unfair to say.
*/
export async function part1(
input: AsyncIterableIterator<number>,
): Promise<number> {
let increases = 0;
let lastDepth = Number.MAX_VALUE;
for await (const depth of input) {
if (depth > lastDepth) increases++;
lastDepth = depth;
}
return increases;
2021-12-01 08:43:02 -06:00
}
console.log("Part 1", await part1(await inputNumbers("1")));
2021-12-01 09:45:18 -06:00
/** Since the windows we need to compare overlap, we really only need to
* compare the values unique to each window, which will be the first of the
* first window and the last of the last window. Since the windows have size 3,
* we really only need to compare a value with the "three-lines-ago" value.
* This solution otherwise is identical to the previous one.
2021-12-01 09:45:18 -06:00
*/
export async function part2(
input: AsyncIterableIterator<number>,
windowSize = 3,
): Promise<number> {
let increases = 0;
2021-12-01 11:39:38 -06:00
const window: number[] = await Promise.all(Array.from(
Array(windowSize),
async (_x, _i) => parseInt((await input.next()).value),
));
2021-12-01 09:45:18 -06:00
for await (const depth of input) {
2021-12-01 11:39:38 -06:00
if (depth > (window.shift() as number)) increases++;
window.push(depth);
}
return increases;
2021-12-01 09:45:18 -06:00
}
console.log("Part 2", await part2(await inputNumbers("1")));