import argparse import importlib import logging import logging.handlers import sys from datetime import datetime from pathlib import Path from .base import BaseSolver from .utils.api import FileHandlerAPI, LoggerAPIHandler, ProgressAPI, dump_answer from .utils.files import SimpleFileHandler from .utils.progress import ProgressNone, ProgressTQDM 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") parser.add_argument( "-o", "--output", type=Path, default=Path("files"), help="output folder for created files", ) parser.add_argument( "-u", "--user", type=str, default="holt59", help="user input to use" ) parser.add_argument( "--stdin", action="store_true", default=False, help="use stdin as input", ) parser.add_argument( "-i", "--input", type=Path, default=None, help="input to use (override user and test)", ) parser.add_argument("-y", "--year", type=int, help="year to run", default=2024) parser.add_argument("day", type=int, help="day to run") args = parser.parse_args() verbose: bool = args.verbose api: bool = args.api test: bool = args.test stdin: bool = args.stdin user: str = args.user files_output: Path = args.output input_path: Path | None = args.input year: int = args.year day: int = args.day logging.basicConfig( level=logging.INFO if verbose or api else logging.WARNING, handlers=[LoggerAPIHandler()] if api else None, ) 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 files=FileHandlerAPI(files_output) if api else SimpleFileHandler(logging.getLogger("AOC"), files_output) if verbose else None, ) data: str if stdin: data = sys.stdin.read() 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: 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)" ) last = current