Getting Started

All of the code described in this blog can be found on GitHub here. When starting from any given day – I recommend downloading the release tagged with the previous days puzzle as a starting point. The release with the actual day#part# will contain the final solution. So for example if you join at Day2Part1 – I recommend downloading release Day1Part2 to follow along.

So the very first thing that I did before diving in to solving the first Advent of Code 2019 puzzle was to think about how I would set up my project. I’m going to assume a few prerequisites are installed if you’re following along:

My first thoughts were that I’d like to use a (not-strict) Test Driven Development (TDD) approach. So the first things I did were set up the folder structure, configure composer, install PHPUnit and create a simple Makefile for running my commands.

Folder Structure

The initial folder structure simply looked like this:

inputs/
src/
tests/
Makefile
composer.json

composer.json configures the autoload path and requires phpunit

composer.json

{
    "autoload": {
        "classmap": [
            "src/"
        ]
    },
    "require-dev": {
        "phpunit/phpunit": "^8"
    }
}

Next I ran composer install from the project root directory to install PHPUnit and generate the autoload files.

After that I normally like to create a simple Makefile for running repetitive tasks.

Makefile

.PHONY: tests
tests:
	./vendor/phpunit/phpunit/phpunit tests

Now you can run make tests from the project root directory. However we don’t have any tests yet…

First Tests

With the basic framework in place the next step was to create the first tests which would allow me to start working with the puzzles. Reading through the instructions for the first puzzle it seemed clear that the puzzles would essentially take the form of “take input”, “do stuff” and “generate output” which is perfect for TDD. For each puzzle there are examples of valid inputs and corresponding outputs. So I wanted to set up a test harness where I could define a set of inputs for each puzzle and test that they generate the correct output.

It also appeared that the inputs would be provided in the form of string in multi-line files. So first things first I wanted a way to load the inputs from file. I created a test input file in inputs/test.txt with the following content:

inputs/text.txt

123
456

Next I created a general purpose PuzzleSolver TestCase

/tests/PuzzleSolverTest.php

<?php

use PHPUnit\Framework\TestCase;
use PuzzleSolvers\PuzzleSolver;

final class PuzzleSolverTest extends TestCase
{
    public function testCanReadInputFile(): void
    {
        $puzzleSolver = new PuzzleSolver('test.txt');

        $inputs = $puzzleSolver->getInputs();

        $this->assertSame(['123', '456'], $inputs);
    }
}

Now running make tests is useful and gave the following error:
Error: Class 'PuzzleSolvers\PuzzleSolver' not found

This is not specifically a TDD tutorial so I won’t go through every excruciating detail. But the next step was to create my general PuzzleSolver Class. The Class needs to take an input file, load it into an array and be able to return those inputs.

src/PuzzleSolver.php

<?php

namespace PuzzleSolvers;

class PuzzleSolver
{
    protected $filepath;
    protected $inputs = [];

    public function __construct(string $filename)
    {
        $this->filepath = '../inputs' . $filename;
        $this->inputs = $this->readInputsFromFile();
    }

    public function getInputs(): array
    {
        return $this->inputs;
    }

    protected function readInputsFromFile(): array
    {
        return [];
    }
}

Running the tests again shows that everything is plumbed together nicely but there are no inputs being stored. The next step was to actually read the inputs from the file – in PHP there is an easy way to do this using the file() function.

protected function getInputsFromFile(): array
{
    return file($this->filepath, FILE_IGNORE_NEW_LINES);
}

Running tests again shows that we have converted the input into a handy array format broken line by line. Finally I added an output property and getter.

protected $output;

public function getOutput()
{
    return $this->output;
}

Now with that out of the way it’s finally time to dive in to Puzzle 1 – which I’ll document in the next post. Below is the full PuzzleSolver.php Class which we’ll be extending in the next part.

<?php

namespace PuzzleSolvers;

class PuzzleSolver
{
    protected $filepath;
    protected $inputs = [];
    protected $output;

    public function __construct(string $filename)
    {
        $this->filepath = 'inputs/' . $filename;
        $this->inputs = $this->readInputsFromFile();
    }

    public function getInputs(): array
    {
        return $this->inputs;
    }

    public function getOutput()
    {
        return $this->output;
    }

    protected function readInputsFromFile(): array
    {
        return file($this->filepath, FILE_IGNORE_NEW_LINES);
    }
}

To download the code at this point go here:
https://github.com/hamishwright/adventofcode2019/releases/tag/getting_started