Advent of Code π solving framework by @Aquaj
This repository template provides:
- some common useful libraries (run
bundle install
to 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:
YEAR
needs to contain the year we're fetching the exercises and inputs fromSESSION
needs 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_part
method is meant to hold the code to your solution to the first challenge of the day - The
#second_part
method is meant to hold the code to your solution to the second challenge of the day - The
#convert_data
method 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#input
method. 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.108ms
The 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.237ms
Another 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.263ms
But 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.263ms
Trying 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
@yournamehere
by your own name or pseudonym - replace all
20xx
occurrences (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).