Advent of Code π solving framework by @Aquaj
This repository template provides:
- some common useful libraries (run
bundle installto fetch them) - a clean README in the eventuality you'd make your solutions public afterwards (see Usable README)
- a simple structure to interact with the Advent of Code problems (see The day-xx.rb files)
- automatic copying of the solution to your clipboard (see Clipboard access)
- a basic test runner to check your solution with (see Checking your solution against expected values)
- some general-purposes standard lib enhancements (see Utility methods)
To run properly the framework needs two specific variables in your environment:
YEARneeds to contain the year we're fetching the exercises and inputs fromSESSIONneeds to contain a valid session cookie value for adventofcode.com - which you can find by logging in and using developer tools (in the "Storage" tab or your browser's equivalent)
A .env.template you can complete and rename into .env is provided, the gem dotenv is setup on the project to
facilitate their manipulation.
Each file for the 25 days of the AoC are prefilled with an empty AdventDay template consisting of three parts:
- The
#first_partmethod is meant to hold the code to your solution to the first challenge of the day - The
#second_partmethod is meant to hold the code to your solution to the second challenge of the day - The
#convert_datamethod will be used to turn the input from the challenge (dynamically fetched from the website) into whatever structure you want it to be. Result of this method call is then accessible through the#inputmethod. Default (super) will simply split line by line.
The first call to #input will download the input from AoC's website (provided the SESSION env var is set) and store
it in inputs/<day-number> to cache it. Those files are not tracked by git.
Running the file (ruby day-01.rb) will display the result of your #first_part methods, then the result to your
#second_part method in order, accompanied each by the time it took to run it.
Example:
require_relative 'common'
## file contents of input/1
# 123
# 456
# 789
class Day1 < AdventDay
def first_part
input.last(2).sum
end
def second_part
input.last(2).map(&:to_s).map(&:reverse).map(&:to_i).sum
end
private
def convert_data(data)
super.map(&:to_i)
end
end
Day1.solve$ ruby day-01.rb
#1. 1245 - 0.342ms
#2. 1641 - 0.108msThe output of the solver might be formatted (bold/italics/...) and/or colored. If this is an issue, you can disable it
by running your files with the flag --no-color, or by putting COLOR=false in your ENV.
By running the solution with the --debug flag, the solver will attempt to find debug data in the inputs/{day}-debug
file.
Example:
$ echo '12\n34\n56' > inputs/debug-1
$ ruby day-01.rb # Still works as previously
#1. 1245 - 0.342ms
#2. 1641 - 0.108ms
$ ruby day-01.rb --debug # Runs on debug input
#1. 90 - 0.301ms
#2. 108 - 0.237msAnother way to provide your own debug data is to override the #debug_input method in your DayX class:
require_relative 'common'
class Day1 < AdventDay
def first_part
input.last(2).sum
end
def second_part
input.last(2).map(&:to_s).map(&:reverse).map(&:to_i).sum
end
private
def convert_data(data)
super.map(&:to_i)
end
def debug_data
"13\n34\n56" # Formatted like the input !- PRE #convert_data -!
end
end
Day1.solve#debug_input will still be fed to convert_data, to test the whole solution β
be careful to have it return a string formatted similarly to the input you're going to solve later.
It is possible to provide expected result values, which will be compared to the results of running your solution against debug data before running your actual solver.
The first way is to provide an EXPECTED_RESULTS constant Hash inside the class, containing the expected results:
require_relative 'common'
class Day1 < AdventDay
EXPECTED_RESULTS = { 1 => 90, 2 => 108 }.freeze
def first_part
input.last(2).sum
end
def second_part
input.last(2).map(&:to_s).map(&:reverse).map(&:to_i).sum
end
private
def convert_data(data)
super.map(&:to_i)
end
end
Day1.solve$ cat '12\n34\n56' > inputs/debug-01.rb
$ ruby day-01.rb
EXAMPLES: 1 - (90: 90) β | 2 - (108: 108) β
#1. 1245 - 0.317ms
#2. 1641 - 0.263msBut it is also possible to provide the expected results through the CLI with use of the --test argument: (in which
case the suplied values take precedence over the ones in the eventual constant)
$ ruby day-01.rb --test 90,108
EXAMPLES: 1 - (90: 90) β | 2 - (108: 108) β
#1. 1245 - 0.317ms
#2. 1641 - 0.263msTrying to run in test mode without providing either hte constant or a --test parameter will raise an error.
NOTE: the output of test runs is colorized green or red according to the success or failure of the comparison, if this is an issue check Colors and formatting to disable it.
When you run the file with the --copy <1 or 2> flag, the lib will copy the result of the specified part into your
clipboard, to make it easier for you to fill it on AoC.
In the support/ folder you'll find the AdventDay framework class (support/advent_day.rb), and a Patches module
(support/patches.rb) containing some utility patches to the standard ruby library that I've found useful to keep at
hand during exercises.
Feel free to add your own to it.
At the end of this explanation you'll find a complete README you can use almost-as-is for your own repository if you decide to make your solutions public once the AoC is over.
To set it up you should:
- replace
@yournamehereby your own name or pseudonym - replace all
20xxoccurrences (including in urls) by the year the repository is for - set up the pitch of the year's AoC storyline in the appropriate section
The README also holds a table recapping the repository's solutions content.
Each time an exercise is published you can set its actual name instead of the TBD in the Day column, then put a golden
star emoji π in the appropriate Part column when completing it. When working on the solution you can put an hourglassemoji β³ in the first column, and replace it with a checkmark emoji βοΈ once you're done with both solutions.
For convenience all 3 emojis are stored in an HTML comment above the table, you only need to copy-paste the appropriate one in its place.
Advent of Code 20xx π solutions by @yournamehere
README is based on JΓ©rΓ©mie Bonal's AoC Ruby template.
Advent of Code is an online event created by Eric Wastl. Each year, starting on Dec 1st, an advent calendar of small programming puzzles are unlocked once a day at midnight (EST/UTC-5). Developers of all skill sets are encouraged to solve them in any programming language they choose!
TODO: Fill in with story pitch from the text of Day 1's challenge
These were not written as example of clean or efficient code but are simply my attempts at finding the answers to each day's puzzle as quickly as possible. Performance logging was added simply as a fun way to compare implementations with other competitors.
Run bundle install to install any dependencies.
Each day computes and displays the answers to both of the day questions and their computing time in ms. To run it type ruby day<number>.rb.
If the session cookie value is provided through the SESSION env variable (dotenv is available to provide it) β it will
fetch the input from the website and store it as a file under the inputs/ folder on its first run.
Lack of a SESSION value will cause the code to raise an exception unless the input file (inputs/{number}) already
present. The code will also raise if the input isn't available from AoC's website (404 error).