# Advent of Code Day 6 Solved in C# and F#

December 10. 2015 0 Comments Posted in:

So I’m still just about managing to keep up with the Advent of Code challenges. Here’s me talking through my solution to day 6’s problem:

Here’s my solution to part a done in three stages in C#

```
var instructions = File.ReadAllLines("day6.txt");
var pattern = @"(turn on|toggle|turn off)\ (\d+)\,(\d+)\ through\ (\d+)\,(\d+)";
var instructionsFlattened = instructions
.Select(i => Regex.Match(i, pattern).Groups)
.Select(g => new
{
Action = g[1].Value,
From = new {
X = int.Parse(g[2].Value),
Y = int.Parse(g[3].Value) },
To = new {
X = int.Parse(g[4].Value),
Y = int.Parse(g[5].Value) }
})
.SelectMany(i =>
from x in Enumerable.Range(i.From.X, 1 + i.To.X - i.From.X)
from y in Enumerable.Range(i.From.Y, 1 + i.To.Y - i.From.Y)
select new { i.Action, x, y });
// apply the instructions
var lights = new bool[1000, 1000];
foreach (var i in instructionsFlattened)
{
if (i.Action == "turn on")
lights[i.x, i.y] = true;
else if (i.Action == "turn off")
lights[i.x, i.y] = false;
else if (i.Action == "toggle")
lights[i.x, i.y] = !lights[i.x, i.y];
}
// count the lights on
(from x in Enumerable.Range(0, 1000)
from y in Enumerable.Range(0, 1000)
where lights[x, y]
select 1).Sum().Dump("lights on");
```

But I decided I wanted to solve this in a single LINQ expression, and this is possible using LINQ’s Aggregate method, so here’s part b solved in C# with Aggregate

```
File.ReadAllLines("day6.txt")
.Select(i => Regex.Match(i,
@"(turn on|toggle|turn off)\ (\d+)\,(\d+)\ through\ (\d+)\,(\d+)").Groups)
.Select(g => new
{
Action = g[1].Value,
From = new { X = int.Parse(g[2].Value), Y = int.Parse(g[3].Value) },
To = new { X = int.Parse(g[4].Value), Y = int.Parse(g[5].Value) }
})
.SelectMany(i =>
from x in Enumerable.Range(i.From.X, 1 + i.To.X - i.From.X)
from y in Enumerable.Range(i.From.Y, 1 + i.To.Y - i.From.Y)
select new { i.Action, x, y })
.Aggregate(new int[1000,1000], (acc, next) => {
var brightness = acc[next.x,next.y];
if (next.Action == "turn on")
brightness+=1;
else if (next.Action == "turn off")
brightness = Math.Max(0, brightness - 1);
else if (next.Action == "toggle")
brightness += 2;
acc[next.x, next.y] = brightness;
return acc;
})
.Cast<int>() // flattens a multi-dimensional array
.Sum()
// brightness is 14687245
```

And finally of course, as part of my on-going bid to improve my F# skills, I made an F# version of this solution:

```
let instructions = File.ReadAllLines("day6.txt")
let turnOn n = n + 1
let turnOff n = max (n - 1) 0
let toggle n = n + 2
let selectAction = function
| "turn on" -> turnOn
| "turn off" -> turnOff
| "toggle" -> toggle
let parseInstruction actionSelector i =
let pattern = @"(turn on|toggle|turn off)\ (\d+)\,(\d+)\ through\ (\d+)\,(\d+)"
let groups = Regex.Match(i, pattern).Groups
let action = actionSelector groups.[1].Value
let fromPos = (int groups.[2].Value), (int groups.[3].Value)
let toPos = (int groups.[4].Value), (int groups.[5].Value)
(action, fromPos, toPos)
let expandPositions (x0,y0) (x1,y1) =
seq { for x in x0 .. x1 do
for y in y0 .. y1 do
yield (x,y) }
let applyAction (acc:int[,]) (action,(x,y)) =
acc.[x,y] <- action acc.[x,y]
acc
let calculate actionSelector (input:string[]) =
let startState = Array2D.create 1000 1000 0
input
|> Seq.map (parseInstruction actionSelector)
|> Seq.collect (fun (action,fromPos,toPos) ->
seq { for pos in (expandPositions fromPos toPos) do
yield (action,pos) })
|> Seq.fold applyAction startState
|> Seq.cast<int> // same trick works to flatten 2d array
|> Seq.sum
calculate selectAction instructions |> Dump
let turnOnA n = 1
let turnOffA n = 0
let toggleA n = if n = 0 then 1 else 0
let selectActionA = function
| "turn on" -> turnOnA
| "turn off" -> turnOffA
| "toggle" -> toggleA
calculate selectActionA instructions |> Dump
```

As always, comments on ways I could improve my solutions are very welcome.

Want to learn more about LINQ? Be sure to check out my Pluralsight course More Effective LINQ. I'm also speaking on LINQ at Techorama Netherlands 2018 on 3rd October, so I'd love to see you there if you can make it.