Port common input fetcher helpers, cleanup, and add tests
This commit is contained in:
parent
7f23dd444a
commit
790f3ceaec
3
2021/nim/.gitignore
vendored
Normal file
3
2021/nim/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!*.nim
|
55
2022/deno/common.ts
Normal file
55
2022/deno/common.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import { copy } from "https://deno.land/std@0.167.0/streams/copy.ts";
|
||||||
|
import * as path from "https://deno.land/std@0.167.0/path/mod.ts";
|
||||||
|
import { readLines } from "https://deno.land/std@0.167.0/io/buffer.ts";
|
||||||
|
import { readerFromStreamReader } from "https://deno.land/std@0.167.0/streams/reader_from_stream_reader.ts";
|
||||||
|
|
||||||
|
const YEAR: number = parseInt(Deno.env.get("AOC_YEAR") || "2022");
|
||||||
|
const HOME = Deno.env.get("HOME");
|
||||||
|
if (!HOME) throw new Error("HOME not set");
|
||||||
|
const COOKIE_PATH = path.resolve(`${HOME}/.advent-of-code-session-cookie`);
|
||||||
|
const CACHE_DIR = path.resolve(`${HOME}/.cache/aoc${YEAR}`);
|
||||||
|
|
||||||
|
async function loadSessionCookie() {
|
||||||
|
const td = new TextDecoder();
|
||||||
|
const bytes = await Deno.readFile(COOKIE_PATH);
|
||||||
|
return td.decode(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
function inputFilePath(day: number): string {
|
||||||
|
return path.resolve(path.join(CACHE_DIR, `${day}.input`));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchAndCacheInput(day: number): Promise<void> {
|
||||||
|
const req = new Request(`https://adventofcode.com/${YEAR}/day/${day}/input`);
|
||||||
|
req.headers.set("Cookie", await loadSessionCookie());
|
||||||
|
const resp = await fetch(req);
|
||||||
|
const f = await Deno.open(inputFilePath(day), { write: true });
|
||||||
|
if (!resp.body) {
|
||||||
|
throw new Error("Response had empty body");
|
||||||
|
}
|
||||||
|
await copy(readerFromStreamReader(resp.body.getReader()), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function inputLines(
|
||||||
|
day: number,
|
||||||
|
fetched = false,
|
||||||
|
): Promise<AsyncIterableIterator<string>> {
|
||||||
|
try {
|
||||||
|
return readLines(await Deno.open(inputFilePath(day), { read: true }));
|
||||||
|
} catch (e) {
|
||||||
|
if (!fetched) {
|
||||||
|
await fetchAndCacheInput(day);
|
||||||
|
return await inputLines(day, true);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function inputLinesArray(day: number) {
|
||||||
|
const lines = [];
|
||||||
|
for await (const l of await inputLines(day)) {
|
||||||
|
lines.push(l);
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
|
@ -1,19 +1,47 @@
|
||||||
const tDec = new TextDecoder();
|
import { inputLinesArray } from "./common.ts";
|
||||||
const input = tDec.decode(Deno.readFileSync("../inputs/day1.input"));
|
|
||||||
|
|
||||||
console.log(
|
function orderedCalories(lines: string[]) {
|
||||||
"final",
|
const calories: number[] = [0];
|
||||||
input.split("\n\n").map((p) => {
|
|
||||||
const ns = p.split("\n").map((s) => {
|
|
||||||
const n = parseInt(s, 10);
|
|
||||||
console.log("inner", s, n);
|
|
||||||
return n;
|
|
||||||
}).filter((n) => !isNaN(n));
|
|
||||||
if (ns.length < 1) return NaN;
|
|
||||||
const n = ns.reduce((prev, cur) => prev + cur, 0);
|
|
||||||
console.log("oter", p, n, ns);
|
|
||||||
return n;
|
|
||||||
}).filter((n) => !isNaN(n)).sort().reverse(),
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log(71924 + 69893 + 68589);
|
lines.forEach((line) => {
|
||||||
|
if (line.trim() == "") {
|
||||||
|
calories.splice(0, 0, 0);
|
||||||
|
} else {
|
||||||
|
calories[0] += parseInt(line);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
calories.sort((a, b) => b - a);
|
||||||
|
return calories;
|
||||||
|
}
|
||||||
|
|
||||||
|
const calories = orderedCalories(await inputLinesArray(1));
|
||||||
|
console.log("Part 1:", calories[0]);
|
||||||
|
console.log("Part 2:", calories.slice(0, 3).reduce((a, b) => a + b));
|
||||||
|
|
||||||
|
const TEST_INPUT = `1000
|
||||||
|
2000
|
||||||
|
3000
|
||||||
|
|
||||||
|
4000
|
||||||
|
|
||||||
|
5000
|
||||||
|
6000
|
||||||
|
|
||||||
|
7000
|
||||||
|
8000
|
||||||
|
9000
|
||||||
|
|
||||||
|
10000`.split("\n");
|
||||||
|
|
||||||
|
Deno.test("orderedCalories", async (t) => {
|
||||||
|
const { assertEquals } = await import(
|
||||||
|
"https://deno.land/std@0.167.0/testing/asserts.ts"
|
||||||
|
);
|
||||||
|
|
||||||
|
const calories = orderedCalories(TEST_INPUT);
|
||||||
|
await t.step("part 1", () => assertEquals(calories[0], 24000));
|
||||||
|
await t.step(
|
||||||
|
"part 2",
|
||||||
|
() => assertEquals(calories.slice(0, 3).reduce((a, b) => a + b), 45000),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue