0 Comments Posted in:

Day 14 of the Advent of Code challenge saw us racing reindeer. Here’s my solution video as usual in C# and F#.

Here’s my C# code, after a bit of refactoring. I’m actually quite pleased with the way this came out in the end, and it was one of the more compact solutions for any of the languages on the advent of code subreddit, which is quite rare for C#. To help us solve part b, we need to track the progress of each reindeer in each second, and yet again MoreLINQ to the rescue with the Scan method which is ideal for calculating running totals.

var lookup = File.ReadAllLines("day14.txt").Select(s => s.Split(' '))
    .Select(g => new { Speed = int.Parse(g[3]), Duration = int.Parse(g[6]), Rest = int.Parse(g[13]) })
    .Select(r => 
        Enumerable.Range(0, 2503)
        .Select(t => t % (r.Duration + r.Rest) < r.Duration ? r.Speed : 0)
        .Scan(0, (a, b) => a + b).Skip(1).ToArray())
    .ToArray();

lookup.Max(v => v[v.Length-1]).Dump("a"); // 2640
lookup.Max(v => v.Select((n,t) => n == lookup.Max(q => q[t]) ? 1 : 0).Sum()).Dump("b"); // 1102

And in F# I take the same approach. One slight niggle I have with F# is that the Seq.max function doesn’t let you pass in a selector like LINQ’s equivalent, so I had to make my own (called smax). In this example, it seems C# may just beat F# for conciseness (although of course I may be missing a few tricks).

let dist (speed,dur,rest) t = if t % (dur + rest) < dur then speed else 0

let progress n x = [0..n-1] |> Seq.map (dist x) |> Seq.scan (+) 0 |> Seq.skip 1 |> Seq.toArray

let lookup = "day14.txt" |> File.ReadAllLines |> Array.map (fun s -> s.Split(' '))
                |> Array.map (fun a -> (int a.[3], int a.[6], int a.[13]))
                |> Array.map (progress 2503) 
    
let smax f = Seq.map f >> Seq.max
lookup |> smax (fun v -> v.[v.Length - 1]) |> printfn "a: %d" // 2640

let getPoints = Seq.mapi (fun t n -> if n = (lookup |> smax (fun f->f.[t])) then 1 else 0) >> Seq.sum
lookup |> smax getPoints |> printfn "b: %d" // 1102
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.
Vote on HN