Skip to main content

Advent of Code in Python.

Project description

aoc-core

License Version Downloads Discord

Documentation Check Test Coverage

Advent of Code in Python.

Installing

Python 3.8 or above is required.

pip

Installing the library with pip is quite simple:

$ pip install aoc-core

Alternatively, the library can be installed from source:

$ git clone https://github.com/nekitdev/aoc-core.git
$ cd aoc-core
$ python -m pip install .

poetry

You can add aoc-core as a dependency with the following command:

$ poetry add aoc-core

Or by directly specifying it in the configuration like so:

[tool.poetry.dependencies]
aoc-core = "^0.2.0"

Alternatively, you can add it directly from the source:

[tool.poetry.dependencies.aoc-core]
git = "https://github.com/nekitdev/aoc-core.git"

Extras

aoc-core provides an extra ext, which installs modules like iters, funcs and wraps which can help solving problems in functional style.

Example

This example assumes aoc is installed and in PATH.

One also needs to install the ext extra to use the iters module.

We will be solving problem the first ever problem of Advent of Code, that is, 2015-01.

Firstly, we need to make sure we have the token configured:

$ aoc token print
token not found (path `/home/nekit/.aoc`)

Note that the token is placed in ~/.aoc by default.

Heading over to the Advent of Code website, we need to trace the requests and find the session cookie. This is the token we need to add:

$ aoc token set {TOKEN}

And now recheck:

$ aoc token print
{TOKEN}

Secondly, we need to download the data for the problem:

$ aoc download
Year: 2015
Day: 01
(... lots of brackets ...)

And we are met by our input data! In order to run the solutions, we need to save this.

$ aoc download --year 2015 --day 01 --save

Or, if you want to be quicker:

$ aoc download -y 2015 -d 01 -s

Now we have everything ready to solve the problem!

In order to define solutions, we need to figure out three types to use:

  • I, the input type that we parse the data into;
  • T, the answer type for the first part of the problem;
  • U, the answer type for the second part of the problem.

Since the problem is about navigating the given string and we return integers, our types will be: I = str, T = int and possibly U = int.

To define the solution, we need to derive from Solution:

# example.py

from aoc.solutions import Solution


class Year2015Day01(Solution[str, int, int]):
    ...

Note the class name, Year2015Day01. This is the convention for naming solutions, and all solutions must have their name in the YearYYYYDayDD format.

We also need to define three methods:

  • parse, which takes the data string and returns I;
  • solve_one, which takes I and returns T;
  • solve_two, which takes I and returns U.

Part one is rather simple, we need to count the occurrences of ( and ), and subtract the latter from the former:

from typing import Final

from aoc.solutions import Solution

UP: Final = "("
DOWN: Final = ")"


class Year2015Day01(Solution[str, int, int]):
    def parse(self, data: str) -> str:
        return data

    def solve_one(self, input: str) -> int:
        return input.count(UP) - input.count(DOWN)

    def solve_two(self, input: str) -> int:
        return 0

Since we don't yet know what part two is about, let's return 0 for now.

Time to run!

$ aoc run example.py
result for `2015-01`
    answer one: {ONE}
    answer two: 0
    parse time: 1.018us
    solve one time: 41.401us
    solve two time: 245.0ns

We have our answer for part one, let's submit it!

$ aoc submit --year 2015 --day 01 --part 1 {ONE}
the answer is correct

By the way, we can submit the answer directly after running the solution, using the --submit (-s) flag.

Now onto part two! We need to find the first position where the floor is -1.

Nothing too difficult, here is the solution for part two included:

from typing import Final

from iters.iters import iter

from aoc.solutions import Solution

UP: Final = "("
DOWN: Final = ")"

NEVER_REACHED_BASEMENT: Final = "the basement was never reached"


class Year2015Day01(Solution[str, int, int]):
    def parse(self, data: str) -> str:
        return data

    def solve_one(self, input: str) -> int:
        return input.count(UP) - input.count(DOWN)

    def solve_two(self, input: str) -> int:
        up = UP
        down = DOWN

        floor = 0

        for position, character in iter(input).enumerate_from(1).unwrap():  # one-based indexing
            if character == up:
                floor += 1

            if character == down:
                floor -= 1

            if floor < 0:
                return position

        raise ValueError(NEVER_REACHED_BASEMENT)

And let's run the solution again:

$ aoc run example.py
result for `2015-01`
    answer one: {ONE}
    answer two: {TWO}
    parse time: 989.0ns
    solve one time: 41.607us
    solve two time: 59.411us

We have our answer for part two, let's submit it!

$ aoc submit -y 2015 -d 01 -p 2 {TWO}
the answer is correct

And there we go, we have solved the first ever problem in the Advent of Code!

Documentation

You can find the documentation here.

Support

If you need support with the library, you can send an email or refer to the official Discord server.

Changelog

You can find the changelog here.

Security Policy

You can find the Security Policy of aoc-core here.

Contributing

If you are interested in contributing to aoc-core, make sure to take a look at the Contributing Guide, as well as the Code of Conduct.

License

aoc-core is licensed under the MIT License terms. See License for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aoc_core-0.2.0.tar.gz (19.7 kB view hashes)

Uploaded Source

Built Distribution

aoc_core-0.2.0-py3-none-any.whl (22.1 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page