Skip to content

Cleanup AdventDay processing and README #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 104 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,147 @@ This is a community driven Java template and utility API for the annual [Advent

1. Clone this repository from GitHub as an IntelliJ repository (untested on other IDE's)
2. Add the `AOC_SESSION_COOKIE` environment variable to your gradle run config and set it equal to that of your session cookie after logging in to your AoC account.
* Alternatively you can set a system environment variable and restart the IDE/terminal.
3. Execute the gradle application -> run task.

# Creating and running a solution #
# Creating and Running Solutions #

## Solution Packages
Create a `package-info.java` in the package which contains your solutions for a given year.
Make sure to annotate it with the `@AdventYear` annotation.
Example:
Make sure to annotate it with the `@AdventYear` annotation, so we can pull the correct inputs.

**Example**:
```java
@AdventYear(year=2024)
package org.togetherjava.aoc.solutions;

import org.togetherjava.aoc.core.annotations.AdventYear;
```

Create an implementation of the `PuzzleSolution` interface and annotate it with the `@AdventDay` annotation
The package my contain any files or subpackages you wish, but as described next, the solutions need a specific structure.

```java
import org.togetherjava.aoc.core.annotations.AdventDay;
import org.togetherjava.aoc.core.puzzle.PuzzleInput;
import org.togetherjava.aoc.core.puzzle.PuzzleSolution;
---
## Solution Classes
Solution implementations must be under an `@AdventYear` package to be runnable.
Additionally, they must implement the `PuzzleSolution` interface, which provides methods
that give an input type directly.

A useful shortcut for this is `CTRL + I` in IntelliJ, which implements missing methods.

### Setting The Day

While `@AdventYear` explicitly defines the year, a solution can implicitly or explicitly
define which day of the year.

### Explicit Day Value
To explicitly set which day your solution corresponds to, use the `@AdventDay` annotation to override and ignore auto-detection.

**Example**:
```java
@AdventDay(day = 1)
public class DayOne implements PuzzleSolution
```

### Implicit Day Auto-Detection
If no `@AdventDay` annotation is provided, a default auto-detection is used instead.
This will look for the *first* number in the class name in the range `[1, 31]`, ignoring leading zeros.
Therefore, the following examples would be parsed as:

| Class Name | Implicit Day |
|----------------|--------------|
| `Day1` | 1 |
| `Day02` | 2 |
| `Day003` | 3 |
| `AocDay4` | 4 |
| `AocDay05` | 5 |
| `Aoc2024Day6` | 6 |
| `Aoc2024Day07` | 7 |
| `Day8Attempt2` | 8 |

---
If neither implicit nor explicit days can be resolved, an error is thrown at runtime.

### Puzzle Solution
The methods defined by `PuzzleSolution` return `Object`, which is because not all
AOC answers are `int` or `long`. You may still return an `int` or `long` type, and it will be autoboxed into an object.

Here is an example implementation

```java
public class Day01 implements PuzzleSolution {

@Override
public Object part1(PuzzleInput input) {
return 0L;
return 123;
}

@Override
public Object part2(PuzzleInput input) {
return 0L;
return 456L;
}
}
```

Then you can run your solutions with the static `AocRunner` class.
## Running Solutions
The `AocRunner` class provides static access to run your solution implementations.

There are 3 method names: `run`, `runPart1`, and `runPart2`, which each have the following overrides:

| Parameters | Description |
|------------------------------------------|------------------------------|
| `()` | Run today |
| `(int year, int day)` | Run the given day |
| `(PuzzleDate date)` | Run the given date |
| `(Class<? extends PuzzleSolution> impl)` | Run the given implementation |


Below are examples of different runner invocations:

```java
AocRunner.run(); //this will detect and invoke the current day's problems
AocRunner.run(2024, 1); //this will detect and invoke a day for a given year/day
AocRunner.run(Day01.class); //Invoke a specific class
AocRunner.run(); // Detect and run the current day's solution
AocRunner.run(2024, 1); // Detect and run the AOC 2024 Day 1 solution
AocRunner.run(Day01.class); // Run the solution implemented in Day01
AocRunner.run(Day01BruteForce.class); // Run the solution implemented in Day01BruteForce
```

# Getting your session cookie #
### Multiple Solutions
If more than one class implements a solution for a given date, all of those
implementations are registered internally. When trying to run them without
a specific class reference (`e.g. run(Day1BruteForce.class)`) then the specific
implementation chosen is not well-defined, and is whichever is reflectively found first.

# Input Caching
Input files are fetched from the AOC web API to get your input data. To support AOC,
we automatically cache the input responses on your local computer, preventing redundant API
calls every time you run an implementation.

## Local File Cache
Cached input files are stored locally in a path relative to your OS platform. This is done
with the `user.home` system property. Relative to that, `/.together-java/aoc/inputs/YYYY-DD-puzzle-input.txt`
is where the file is stored.

* Windows: `%userprofile%/.together-java/aoc/inputs/`

# Session Cookie (`AOC_SESSION_COOKIE`)
## Getting your session cookie

In Chrome, or other Chromium browsers such as Opera, OperaGX etc
1. Hit ctrl + shift + J to open up developer tools
1. Hit `ctrl + shift + J` to open up developer tools
2. Navigate to the application tab
3. Click cookies
4. Copy the session cookie

![](/setup/4.png)

# Modifiying Gradle run configuration #
1. Go to your Gradle tasks and go to application -> run and right click to modify the run configurations
![](/setup/1.png)
2. Click this box to add an environment variable
## Modifiying Gradle run configuration / env
1. Go to your Gradle tool window
* `Tasks`
* `application`
* Right-click `run` → `Modify Run Configuration...`

![](/setup/1.png)
2. Click this box to add an environment variable
![](/setup/2.png)
3. Name the environment variable `AOC_SESSION_COOKIE` and then paste the value of your session cookie from your browser in to the value box.
3. Name the environment variable `AOC_SESSION_COOKIE` and then paste the value of your session cookie from your browser in to the value box.
![](/setup/3.png)
4. Hit okay and then execute the Gradle run task
4. Hit okay and then execute the Gradle `run` task
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private static void init() {
if (solutionDay.isEmpty()) {
throw new RuntimeException("""
Unable to detect a valid day value from solution type '%s'. \
Follow standard naming, or use @DayOverride() instead.\
Follow standard naming, or use @AdventDay() instead.\
""".formatted(solution.getCanonicalName())
);
}
Expand All @@ -113,6 +113,7 @@ private static Optional<Integer> extractDay(String className) {
.results()
.map(MatchResult::group)
.map(StringUtils::trimLeadingZeros)
.filter(x -> 1 <= x && x <= 31)
.findFirst();
}

Expand Down