01020304050607080910111213141516171819202122232425

Advent of Code

2023/9

Mirage Maintenance

in C#

by encse

Let's revisit the problem description here.

We are implementing an extrapolation algorithm that reminds me to my university years when we did Newton interpolation, or was it Lagrange? I don't remember anymore, but it was using a similar algorithm to this.

Part 1 and Part 2 differs only in the direction of the extrapolation, and one can be implemented using the other, just like I did it below.

namespace AdventOfCode.Y2023.Day09;

using System;
using System.Linq;

[ProblemName("Mirage Maintenance")]
class Solution : Solver {

    public object PartOne(string input) => Solve(input, ExtrapolateRight);
    public object PartTwo(string input) => Solve(input, ExtrapolateLeft);

    long Solve(string input, Func<long[], long> extrapolate) =>
        input.Split("\n").Select(ParseNumbers).Select(extrapolate).Sum();

    long[] ParseNumbers(string line) =>
        line.Split(" ").Select(long.Parse).ToArray();

    // It's a common trick to zip a sequence with the skipped version of itself
    long[] Diff(long[] numbers) =>
        numbers.Zip(numbers.Skip(1)).Select(p => p.Second - p.First).ToArray();

    // I went a bit further and recurse until there are no numbers left. It's
    // more compact this way and doesn't affect the runtime much.
    long ExtrapolateRight(long[] numbers) =>
        !numbers.Any() ? 0 : ExtrapolateRight(Diff(numbers)) + numbers.Last();

    long ExtrapolateLeft(long[] numbers) =>
       ExtrapolateRight(numbers.Reverse().ToArray());
}

Please ☆ my repo if you like it!

© 2025 Advent of Code is a registered trademark in the US Images provided by Bing image creator