# AdventOfCode2025 Solver for Advent of Code 2025 puzzles. This is a single command line application for the puzzles written in [Rust](https://rust-lang.org/). ## Puzzle Input This project does not contain the puzzle or example inputs as per the [copyright notice of Advent of Code](https://adventofcode.com/about). In order to run the compiled application, the puzzle inputs have to be downloaded from the [Advent of Code 2025](https://adventofcode.com/2025/) puzzle pages, and placed as text files into the `AdventOfCode2025\data` directory, e.g. `AdventOfCode2025\data\secret_entrance.txt`, or `AdventOfCode2025\data\example\secret_entrance.txt` for the unit tests. The application will output an error message with details if it cannot find an input file. ## Solutions ### Day 1: Secret Entrance :mag_right: Puzzle: , :white_check_mark: Solver: [`SecretEntrance`](src/solvers/secret_entrance.rs) For this one, we are moving around a dial with some not too complicated modulo calculations. ### Day 2: Gift Shop :mag_right: Puzzle: , :white_check_mark: Solver: [`GiftShop`](src/solvers/gift_shop.rs) Firstly, we calculate directly the sum of invalid IDs composed of two identical sequences of digits for part 1. This can easily be generalized for any number of repetitions of sequences. However, the problem is to avoid adding certain invalid IDs to the sum multiple times. Therefore we only check prime numbers of repetitions, and take care that invalid IDs that are composed of a repetition of a single digit are only counted once. On top of that we use a cache to avoid recalculating prime factors and certain helper variables for given ID lengths and repetition counts. ### Day 3: Lobby :mag_right: Puzzle: , :white_check_mark: Solver: [`Lobby`](src/solvers/lobby.rs) With a continuously updated tally of the current best joltage initialized at zero, we go once through each digit string from left to right and try to maximize the digit with the highest posiible significance in our joltage as we go, as long as the less significant digits in the joltage are not more than what remains in the string. If a better digit was encountered, all less significant digits are reset to zero. ### Day 4: Printing Department :mag_right: Puzzle: , :white_check_mark: Solver: [`PrintingDepartment`](src/solvers/printing_department.rs) For part 1, we create a two-dimensional grid to track location and neighbor counts for each paper roll. Parsing the input data row by row, for each location we only have to check the four neighbors that were not yet encountered, i.e. right in the same row, and the three neighbors in the next row, to handle all pairs of locations. This means that we know whether a location is accessible or not immediately before moving on to the next. For part 2, the accessible locations are tracked, and removed individually from the grid. After each removal, the neighbor counts of the neighbors are updated. Any of the neighbors that now fall under the threshold are counted as well and added to the removal list. ### Day 5: Cafeteria :mag_right: Puzzle: , :white_check_mark: Solver: [`Cafeteria`](src/solvers/cafeteria.rs) From the input data, we construct a [`MultiInterval`](src/common/interval.rs), which is a ordered set of integer intervals (based on a [B-tree](https://doc.rust-lang.org/std/collections/struct.BTreeSet.html)), such that all contained intervals are disjoint. With this data structure, testing for containment and determining the number of contained integers becomes trivial. ### Day 6: Trash Compactor :mag_right: Puzzle: , :white_check_mark: Solver: [`TrashCompactor`](src/solvers/trash_compactor.rs) We implement two different ways to collect numbers from the input. For part 1, numbers separated by space are read line by line, stored in a two-dimensional array and then aggregated in columns. While for part 2, each column of characters in the input data represents a number, and empty columns are interpreted as the separators between blocks for aggregation. ### Day 7: Laboratories :mag_right: Puzzle: , :white_check_mark: Solver: [`Laboratories`](src/solvers/laboratories.rs) Going row by row, for each column in the input data we count the number of different beam paths that reach that column in that row. When a beam is split, the count for that column is added to both columns the beam is split into. For part 1 we count the splits, and for parts 2 we sum the count for all columns of the final row. ### Day 8: Playground :mag_right: Puzzle: , :white_check_mark: Solver: [`Playground`](src/solvers/playground.rs) For part 1 we track a number of smallest distances between junction boxes up to the specified maximum in a priority queue, always dropping the highest when we find a better one. At the end, we use these to find connected circuits, and count their sizes. For part 2 we instead construct a spanning tree of all junction boxes, such that the maximum distance between any pair is minimal. Once all junction boxes have been added to this graph, the pair of junction boxes with the longest distance in the spanning tree. When adding any new junction box, we either take connect it via the shortest edge, if it is already longer than the current maximum in the tree. Otherwise, we connect it via the first edge shorter than the current maximum, and for additional edges shorter than the current maximum we find the longest edge on the unique path between the two vertices now already connected, remove it, and add the new shorter one. The current maximum is tracked again in a separate priority queue, and eventually gives the solution. ### Day 9: Movie Theater :mag_right: Puzzle: , :white_check_mark: Solver: [`MovieTheater`](src/solvers/movie_theater.rs) ## Tests The package contains integration tests for each solver, and unit tests for some, to help troubleshoot issues and prevent regressions. These tests cover the solutions for provided examples and full data inputs. The solutions used within the tests are user-specific. ## License Copyright (C) 2025-2026 Stefan Müller This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see .