From 0f0e3b1da81450d27eb8f788c930e78df1b92a29 Mon Sep 17 00:00:00 2001 From: Alex Gustafsson Date: Wed, 24 Nov 2021 11:11:28 +0100 Subject: [PATCH] Add utilities for reading puzzle input --- .gitignore | 2 ++ .vscode/settings.json | 9 +++++++ go.mod | 3 +++ package.json | 4 +++ pyrightconfig.json | 7 +++++ utils/deno/input.ts | 24 +++++++++++++++++ utils/go/parsing/input.go | 52 ++++++++++++++++++++++++++++++++++++ utils/python/aoc/__init__.py | 5 ++++ utils/python/aoc/input.py | 29 ++++++++++++++++++++ 9 files changed, 135 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 go.mod create mode 100644 package.json create mode 100644 pyrightconfig.json create mode 100644 utils/deno/input.ts create mode 100644 utils/go/parsing/input.go create mode 100644 utils/python/aoc/__init__.py create mode 100644 utils/python/aoc/input.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6320fb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +node_modules diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c8dbac1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "deno.enable": true, + "deno.lint": true, + "deno.unstable": false, + "deno.suggest.imports.hosts": { + "https://deno.land": true + }, + "python.pythonPath": "/usr/local/opt/python@3.10/bin/python3" +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..39af3e6 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/alexg-axis/advent-of-code + +go 1.17 diff --git a/package.json b/package.json new file mode 100644 index 0000000..e5b487d --- /dev/null +++ b/package.json @@ -0,0 +1,4 @@ +{ + "name": "advent-of-code", + "repository": "git@github.com:alexg-axis/advent-of-code.git" +} diff --git a/pyrightconfig.json b/pyrightconfig.json new file mode 100644 index 0000000..252b8ad --- /dev/null +++ b/pyrightconfig.json @@ -0,0 +1,7 @@ +{ + "extraPaths": ["utils/python"], + "exclude": [ + "**/__pycache__", + "node_modules" + ], +} diff --git a/utils/deno/input.ts b/utils/deno/input.ts new file mode 100644 index 0000000..ded7801 --- /dev/null +++ b/utils/deno/input.ts @@ -0,0 +1,24 @@ +import * as path from "https://deno.land/std/path/mod.ts"; + +const directory = path.dirname(path.fromFileUrl(Deno.mainModule)); + +const raw = await Deno.readTextFile(path.resolve(directory, "input.txt")) + +/** Input represents a puzzle's input. */ +class Input { + constructor(public readonly raw: string) {} + + /** The lines of the input. Trims trailing whitespace. */ + get lines() { + return this.raw.trimEnd().split("\n") + } + + /** The numbers of the input, one number per line. */ + get numbers() { + return this.lines.map(x => Number(x)) + } +} + +/** The puzzle's input */ +const input = new Input(raw) +export default input diff --git a/utils/go/parsing/input.go b/utils/go/parsing/input.go new file mode 100644 index 0000000..cf2e892 --- /dev/null +++ b/utils/go/parsing/input.go @@ -0,0 +1,52 @@ +package parsing + +import ( + "fmt" + "io/ioutil" + "path/filepath" + "runtime" + "strconv" + "strings" +) + +// Input represents a puzzle's input. +type Input string + +// ReadInput reads the input for a puzzle. Must be called from a file in the same +// directory as the `input.txt` file. +func ReadInput() (Input, error) { + // Assume that the caller is from a file in the same directory as the input + _, filename, _, ok := runtime.Caller(1) + if !ok { + return "", fmt.Errorf("unknown caller") + } + + path := filepath.Dir(filename) + data, err := ioutil.ReadFile(filepath.Join(path, "input.txt")) + if err != nil { + return "", err + } + + return Input(data), nil +} + +// Lines returns the lines of the input. Trims trailing newlines. +func (input Input) Lines() []string { + return strings.Split(strings.TrimSuffix(string(input), "\n"), "\n") +} + +// Ints returns the integers found in the input - one integer per line. +func (input Input) Ints() ([]int, error) { + lines := input.Lines() + values := make([]int, len(lines)) + + for i, line := range lines { + value, err := strconv.ParseInt(line, 10, 32) + if err != nil { + return nil, fmt.Errorf("unable to parse input as ints - %w", err) + } + values[i] = int(value) + } + + return values, nil +} diff --git a/utils/python/aoc/__init__.py b/utils/python/aoc/__init__.py new file mode 100644 index 0000000..bda80e1 --- /dev/null +++ b/utils/python/aoc/__init__.py @@ -0,0 +1,5 @@ +"""Python utilities for Advent of Code.""" + +__package__ = "aoc" + +from aoc.input import input as input diff --git a/utils/python/aoc/input.py b/utils/python/aoc/input.py new file mode 100644 index 0000000..e937d4f --- /dev/null +++ b/utils/python/aoc/input.py @@ -0,0 +1,29 @@ +import sys +from os import path + +class Input: + """Puzzle input.""" + + def __init__(self, raw: str) -> None: + self.__raw = raw + + @property + def raw(self) -> str: + """Raw input.""" + return self.__raw + + @property + def lines(self) -> list[str]: + """Lines of the input. Strips whitespace.""" + return self.__raw.strip().splitlines() + + @property + def ints(self) -> list[int]: + """Ints found in the input, one int per line.""" + return [int(x) for x in self.lines] + +input = Input("") + +directory = path.dirname(path.abspath(sys.modules["__main__"].__file__ or "")) +with open(path.join(directory, "input.txt"), "r") as file: + input = Input(file.read())