In case you missed it, a lot of the good folks in the F# community has been doing the Advent of Code the past 2 weeks. I’m a bit late to the game, but have done a lot of catching up this weekend, and here’s my solutions for the day 1–6.

p.s. you can find all my solution on github, but the input is different for everyone.

## Day 1

Starting off nice and simple, we can solve this problem with a **fold**.

The only caveat I encountered with this problem was in fact, trying to capture the input into a string value:

which for some reason seems to upset F# interactive:

Which is why I defined the *input* in a source file (*day01.fs*) whilst keeping the actual solution in the script (*day01.fsx*).

After you solve the question, the second part of the challenge is revealed (the same theme runs throughout all the challenges).

### Day 1 (Part 2)

This requires a slight twist to our approach to part 1 – we need the **intermediate steps** of the *fold* instead of the final value.

Fortunately Seq.scan does just that!

Another thing to note is that, since *Seq.scan* returns the initial value (0 in this case) as part of the returned sequence, it means we didn’t have to shift our index system from 0-based to 1-based.

## Day 2

First, bear in mind that the input looks like this:

20x3x11

15x27x5

6x29x7

30x15x9

19x29x21

10x4x15

…

so let’s add a helper to make splitting strings easier (and prettier):

### Day 2 (Part 2)

To find the shortest distance around the smallest side, we just have to sort the dimensions then pick the first 2. So our solution only needs a small tweak from part 1:

## Day 3

Starting with an implied position of (0, 0), in order to find the number of houses that received **at least one present** we need to find the number of **distinct** positions that Santa has traversed.

Again, **fold** to the rescue!

### Day 3 (Part 2)

First, let’s extract our *fold* logic out from part 1:

Now, we need to massage the input (e.g. ^v^v^v^v^v) into two sequences, i.e.:

input : seq { ‘^’; ‘v’; ‘^’; ‘v’; ‘^’; ‘v’; ‘^’; ‘v’; ‘^’; ‘v’ }

we want :

seq {

seq { ‘^’; ‘^’; ‘^’; ‘^’; ‘^’ } // for Santa

seq { ‘v’; ‘v’; ‘v’; ‘v’; ‘v’ } // for Robot-Santa

}

which is what the first 4 LOC does:

so, to explain, we start with “^v^v^v^v” which is really just a sequence of chars:

seq { ‘^’; ‘v’; ‘^’; ‘v’; ‘^’; ‘v’; ‘^’; ‘v’; ‘^’; ‘v’ }

=> seq { (0, ‘^’); (1, ‘v’); (0, ‘^’); (1, ‘v’); … }

=> seq {

(0, seq { (0, ‘^’); (0, ‘^’); (0, ‘^’); … })

(1, seq { (1, ‘v’); (1, ‘v’); (1, ‘v’); … }) }

=> seq {

seq { ‘^’; ‘^’; ‘^’; … }

seq { ‘v’; ‘v’; ‘v’; … } }

after we’ve done that, we

- apply the same
*fold*logic we did previously against each of the inner sequences; - collect the result (i.e. the positions traversed) into a unified sequence
- count the distinct positions traversed by both Santa and Robot-Santa

and job done!

## Day 4

In .Net you can use *System.Security.Cryptography.MD5* to create a MD5 hash (as a byte[]) for some input byte[].

You can then use *BitConverter.ToString* to get back a string representation of the hex-decimal value for the hash.

Or, you can take a shortcut, and take advantage of binary-to-hex conversion where every 4 bits = 1 hex value:

### Day 4 (Part 2)

Because of the approach we took for part 1, the change here becomes as trivial as checking if the 3rd byte is also 0uy!

## Day 5

First, let’s capture the three requirements for a nice string.

At least 3 vowels, check.

At least 1 letter that appear twice in a row, check.

Does not contain certain strings, check (in a more generic way).

Then, let’s create a helper to make it easier for us to compose these three requirements later:

and finally let’s put everything together:

Voila!

**aside :** *I think the <&&> operator makes the code easier to read here. I’m usually not a fan of special operators, I find they often gets in the way of discoverability and raises the barrier to entry for a library if there are too many special operators one has to remember. **I think it’s ok in this case given that the scope is really small.*

### Day 5 (Part 2)

Again, let’s capture the 2 new requirements as functions.

At least one pair of letters that appear twice without overlap, check.

Here, I’m taking advantage of the fact that all the strings contains only alphabet characters and replacing the pair of characters currently being considered with ‘-’. However, it still feels as though I’m taking the scenic route to express the requirement here, if you have a better way, please let me know in the comments.

At least one letter that repeats with exactly one letter in between, check.

Like before, we just need to compose the two together to solve this challenge.

## Day 6

First, let’s look at the input for this challenge.

turn on 489,959 through 759,964

turn off 820,516 through 871,914

turn off 427,423 through 929,502

toggle 756,965 through 812,992

so, we have coordinates – int, int – and three different actions – turn on, turn off, toggle – that we need to deal with:

For each line, the format is:

{action} {start_coordinate} through {end_coordinate}

so we can write a simple function to parse it:

After the first split, we’ll end up an array consisting of the two coordinates, e.g.

[| “ 489,959 ”; “ 759,964 ” |]

splitting each by ‘,’ again gives us an array of arrays, e.g.:

[| [| “489”; “959” |]; [| “759”; “964” |] |]

which is why we needed to further massage the inner arrays in to *int* tuples.

[| (489, 959); (759, 964) |]

Next, let’s have some lights!

And we also need a function to perform the parsed *Action* against the corresponding coordinate rages:

and then hook everything together:

Finally, let’s count how many of the lights are turned on after performing all the actions. Unfortunately, there’s no built-in *sum*, or *sumBy* functions in the *Array2D* module.. so for simplicity sake let’s just resort to using mutable state again.

### Day 6 (Part 2)

We can reuse most of what we had done for part 1 of the challenge, the main thing that has to change is the *perform* function:

and also how we calculate the final result:

and that’s it!

From Day 7, the challenges start to get more challenging, so watch this space for more solutions to come.