advent-of-code/src/holt59/aoc/__main__.py

123 lines
3.3 KiB
Python
Raw Normal View History

2023-12-19 14:39:10 +00:00
import argparse
import importlib
import logging
import logging.handlers
2023-12-19 14:39:10 +00:00
import sys
2024-12-10 14:38:00 +00:00
from datetime import datetime
2023-12-19 14:39:10 +00:00
from pathlib import Path
from .base import BaseSolver
2024-12-10 14:38:00 +00:00
from .utils.api import FileHandlerAPI, LoggerAPIHandler, ProgressAPI, dump_answer
from .utils.files import SimpleFileHandler
from .utils.progress import ProgressNone, ProgressTQDM
2023-12-19 14:39:10 +00:00
def main():
parser = argparse.ArgumentParser("Holt59 Advent-Of-Code Runner")
parser.add_argument("-v", "--verbose", action="store_true", help="verbose mode")
parser.add_argument("-t", "--test", action="store_true", help="test mode")
parser.add_argument("-a", "--api", action="store_true", help="API mode")
2024-12-10 14:38:00 +00:00
parser.add_argument(
"-o",
"--output",
type=Path,
default=Path("files"),
help="output folder for created files",
)
2023-12-19 14:39:10 +00:00
parser.add_argument(
"-u", "--user", type=str, default="holt59", help="user input to use"
)
2024-01-04 17:36:30 +00:00
parser.add_argument(
"--stdin",
action="store_true",
default=False,
help="use stdin as input",
)
2023-12-19 14:39:10 +00:00
parser.add_argument(
"-i",
"--input",
type=Path,
default=None,
help="input to use (override user and test)",
)
2024-12-01 09:26:02 +00:00
parser.add_argument("-y", "--year", type=int, help="year to run", default=2024)
2023-12-19 14:39:10 +00:00
parser.add_argument("day", type=int, help="day to run")
args = parser.parse_args()
verbose: bool = args.verbose
api: bool = args.api
2023-12-19 14:39:10 +00:00
test: bool = args.test
2024-01-04 17:36:30 +00:00
stdin: bool = args.stdin
2023-12-19 14:39:10 +00:00
user: str = args.user
2024-12-10 14:38:00 +00:00
files_output: Path = args.output
2023-12-19 14:39:10 +00:00
input_path: Path | None = args.input
year: int = args.year
day: int = args.day
logging.basicConfig(
2024-12-15 09:44:47 +00:00
level=logging.INFO if verbose else logging.WARNING,
handlers=[LoggerAPIHandler()] if api else None,
)
2023-12-19 14:39:10 +00:00
if input_path is None:
input_path = Path(__file__).parent.joinpath(
"inputs", "tests" if test else user, str(year), f"day{day}.txt"
)
assert input_path.exists(), f"{input_path} missing"
solver_class: type[BaseSolver] = importlib.import_module(
f".{year}.day{day}", __package__
).Solver
solver = solver_class(
logging.getLogger("AOC"),
verbose=verbose,
year=year,
day=day,
progress=ProgressAPI()
if api
else ProgressTQDM()
if verbose
else ProgressNone(), # type: ignore
2024-12-10 14:38:00 +00:00
files=FileHandlerAPI(files_output)
2024-12-15 09:44:47 +00:00
if api and verbose
2024-12-10 14:38:00 +00:00
else SimpleFileHandler(logging.getLogger("AOC"), files_output)
if verbose
else None,
)
data: str
2024-01-04 17:36:30 +00:00
if stdin:
data = sys.stdin.read()
2024-01-04 17:36:30 +00:00
else:
with open(input_path) as fp:
data = fp.read()
start = datetime.now()
last = start
it = solver.solve(data.rstrip())
if it is None:
solver.logger.error(f"no implementation for {year} day {day}")
exit()
for i_answer, answer in enumerate(it):
current = datetime.now()
if api:
2024-12-10 14:38:00 +00:00
dump_answer(
part=i_answer + 1,
answer=answer,
answer_time=current - last,
total_time=current - start,
)
else:
print(
f"answer {i_answer + 1} is {answer} (found in {(current - last).total_seconds():.2f}s)"
)
2023-12-19 14:39:10 +00:00
last = current