-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
268 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { colors } from "@cliffy/ansi/colors"; | ||
import { Command } from "@cliffy/command"; | ||
import { Input, Select } from "@cliffy/prompt"; | ||
import { readLinesFromFile } from "utils"; | ||
import { days, getSolution } from "./days/mod.ts"; | ||
import denoJson from "./deno.json" with { type: "json" }; | ||
import { | ||
readLinesFromStdin, | ||
readLinesFromUrl, | ||
} from "./utils/readLinesFromStream.ts"; | ||
|
||
const list = new Command() | ||
.description("List all available solutions") | ||
.action(() => { | ||
console.log("Available solutions:"); | ||
for (const day of Object.keys(days)) { | ||
console.log(`- ${day}`); | ||
} | ||
}); | ||
|
||
const main = new Command() | ||
.name("Advent of Code - 2024") | ||
.version(denoJson.version) | ||
.description("...") | ||
.option("-d, --day <day:string>", "Day to run") | ||
.option("-i, --input <input:file>", "Input file, local path or remote URL") | ||
.action(async (options) => { | ||
let input: Array<string> | null = null; | ||
let stdinClosed = false; | ||
if (options.input != null) { | ||
input = await loadInput(options.input); | ||
} else { | ||
input = await readLinesFromStdin(); | ||
stdinClosed = input != null; | ||
input = input ?? await provideInput().then(loadInput); | ||
} | ||
if (input === null) { | ||
console.error("No input provided"); | ||
Deno.exit(1); | ||
} | ||
if (stdinClosed && options.day == null) { | ||
console.error("Day not provided"); | ||
Deno.exit(1); | ||
} | ||
const day = options.day ?? await selectDay(); | ||
const solution = getSolution(day); | ||
if (solution == null) { | ||
console.error(`Day ${day} not found`); | ||
Deno.exit(1); | ||
} | ||
console.log(colors.bold.yellow(`Day ${day}`)); | ||
console.log(`Part 1: ${solution.part1(input)}`); | ||
console.log(`Part 2: ${solution.part2(input)}`); | ||
}); | ||
|
||
async function provideInput(): Promise<string> { | ||
return await Input.prompt({ | ||
message: "Provide input (path or URL)", | ||
files: true, | ||
}); | ||
} | ||
|
||
async function selectDay(): Promise<string> { | ||
return await Select.prompt({ | ||
message: "Select day", | ||
options: Object.keys(days).map((day) => ({ | ||
name: day.toString().padStart(2, "0"), | ||
value: day, | ||
})), | ||
}); | ||
} | ||
|
||
async function loadInput(input: string) { | ||
return isWebUrl(input) | ||
? await readLinesFromUrl(input) | ||
: await readLinesFromFile(input); | ||
} | ||
|
||
function isWebUrl(path: string): boolean { | ||
return path.startsWith("http://") || path.startsWith("https://"); | ||
} | ||
|
||
if (import.meta.main) { | ||
await main | ||
.command("list", list) | ||
.parse(Deno.args); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
type PartFunction = (input: Array<string>) => number; | ||
type Solution = { part1: PartFunction; part2: PartFunction }; | ||
|
||
const days: Record<string, Solution> = {}; | ||
|
||
for (const day of [1]) { | ||
days[pad(day)] = await import(`./${pad(day)}/main.ts`); | ||
} | ||
|
||
export function getSolution(day: string | number): Solution | null { | ||
return days[pad(day)]; | ||
} | ||
|
||
export { days }; | ||
|
||
function pad(day: string | number) { | ||
return day.toString().padStart(2, "0"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,19 @@ | ||
{ | ||
"tasks": {}, | ||
"name": "@aoc/2024", | ||
"version": "0.0.1-rc.1", | ||
"license": "MIT", | ||
"exports": "./cli.ts", | ||
"tasks": { | ||
"cli": "deno run --allow-read ./cli.ts" | ||
}, | ||
"imports": { | ||
"@cliffy/ansi": "jsr:@cliffy/[email protected]", | ||
"@cliffy/command": "jsr:@cliffy/[email protected]", | ||
"@cliffy/prompt": "jsr:@cliffy/[email protected]", | ||
"@std/expect": "jsr:@std/expect@1", | ||
"@std/collections": "jsr:@std/collections@1", | ||
"@std/path": "jsr:@std/path@1", | ||
"@std/streams": "jsr:@std/streams@^1.0.8", | ||
"utils": "./utils/mod.ts" | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { TextLineStream } from "@std/streams"; | ||
|
||
export async function getLines( | ||
input: ReadableStream<Uint8Array>, | ||
): Promise<Array<string>> { | ||
const stream = input | ||
.pipeThrough(new TextDecoderStream()) | ||
.pipeThrough(new TextLineStream({ allowCR: true })); | ||
return await Array.fromAsync(stream); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
import { dirname, fromFileUrl, resolve } from "@std/path"; | ||
import { readLinesFromFile } from "./readLinesFromStream.ts"; | ||
|
||
export function loadInput(day: number): Array<string> { | ||
export function loadInput(day: number): Promise<Array<string>> { | ||
const path = resolve( | ||
dirname(fromFileUrl(import.meta.url)), | ||
"..", | ||
"inputs", | ||
`${day.toString().padStart(2, "0")}.txt`, | ||
); | ||
return Deno.readTextFileSync(path).split("\n"); | ||
return readLinesFromFile(path); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
export { loadInput } from "./loadInput.ts"; | ||
export { | ||
readLinesFromFile, | ||
readLinesFromStdin, | ||
readLinesFromUrl, | ||
} from "./readLinesFromStream.ts"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { getLines } from "./getLines.ts"; | ||
|
||
export async function readLinesFromFile(path: string): Promise<Array<string>> { | ||
using file = await Deno.open(path); | ||
return await getLines(file.readable); | ||
} | ||
|
||
export async function readLinesFromStdin(): Promise<Array<string> | null> { | ||
if (Deno.stdin.isTerminal()) return null; | ||
return await getLines(Deno.stdin.readable); | ||
} | ||
|
||
export async function readLinesFromUrl(url: string): Promise<Array<string>> { | ||
const response = await fetch(url); | ||
if (!response.ok || response.body === null) { | ||
throw new Error(`Failed to fetch ${url}`); | ||
} | ||
return await getLines(response.body); | ||
} |