The solutions to advent of code 2020, solved using PHP 8.1. By James Thatcher
🎄 Day 1 🎅 Day 2 ☃️ Day 3 🦌 Day 4 🍪 Day 5 🥛 Day 6 🧦 Day 7 🎁 Day 8
⛄ Day 9 🛐 Day 10 ⛄ Day 11 🍪 Day 12 ☃️ Day 13 🎅 Day 14 🎄 Day 15 🧦 Day 16
My attempts at tacking the awesome challenges at Advent of Code 2020 using PHP 8.1.
For those who don't know what Advent of Code is, it is simply put, the best programming challenges you'll find on
the web.
Every year, starting December 1st, you receive a new challenge. The challenges get harder and are humorous, involving
helping Santa and his elves deliver on their quest to deliver pressies on time.
Each day comprises two parts, both based on the same input. You'll need to use all your smarts to solve these as they rely on good knowledge of algorithms, logic and data structures. The true beauty of Advent of Code is the solutions can be written in any programming language.
Best algorithm and optimisation: Day15
Day15, requires you to remember the numbers said in a list, appending the next based on when it was
previously said.
My first attempt at this (part 1) was pants. I used a single array to keep track of every number spoken and used the
array index to calculate turns. Fine for calculating the 2020th but when it came to the 30 millionth… No chance! 😂
After much playing around and refactoring, I was able to make some big improvements by using some lesser-known PHP
class types like SplFixedArray
. I've got this solution down to 1.3 seconds using 458mb of RAM. (using a standard array
takes 3.7 seconds however it only uses 240mb of RAM)
- Docker
- Makefile
- PHP8
- Pest
As mentioned I've chosen PHP8 and I had a blast using the new language features.
You'll find the solutions in the /src directory; typically one file per Day, although Day12 was an exception, and I ended up abstracting this puzzle into objects.
If you're feeling cheeky, the /tests folder
has your expected answers to each day. I use a DayFactory to generate each day with the input in $this->input
which frees me up to focus on the challenge.
The runner run.php detects which days have been completed and runs those, producing fancy output that times the execution time and memory consumption:
The raw inputs are stored in /input, fetched automatically via the make get-input
command.
Included in this repo is also a handy Makefile that launches a php docker container to execute the tests.
If you fancy having a go at the challenges yourself feel free to use this repo as a framework/skeleton.
Note: checkout the code then run make run
. The docker and composer libraries will auto install.
Solve all days puzzles
make run
Solve all days puzzles using the PEST testing framework
make tests
Solve an individual days puzzles
make run day={N}
e.g. make run day=13
Solve a single part of a days puzzles
make run day={N} part={N}
e.g. make run day=16 part=2
Create the next days PHP files
Auto detects what current Day you are on and will create the next (only if the files don't exist)
make new
# Created new file: src/Day17.php
# Created new file: tests/Day17Test.php
Fetch the next days input from the server.
make get-input
Note: The Makefile reads the /src directory to find the most recent DayN.php file. If you had just completed Day1.php
you would create a Day2.php
(by running make new
) and then run this command to fetch /input/day2.txt
Use XDebug
make xdebug
Xdebug can also be triggered on a single days and/or part
make xdebug day={N}
e.g. make xdebug day=13
or make xdebug day=13 part=2
IDE settings:
10000
- xdebug portaoc-2020
- PHP_IDE_CONFIG (what you put in PHPStorm -> settings -> debug -> server -> name)/app
- absolute path on the server- see xdebug.ini if you're stuck