0 Comments

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.
Vote on HN
comments powered by Disqus