Advent of Code Day 2: Finding Invalid Product IDs

On Day 2 of Advent of Code, we’re helping the Elves find invalid IDs.

I considered a string-based solution, but that felt like cheating. So I tried a “numeric” one instead.

Let’s start with a bottom-up approach.

Finding if a product ID is invalid

First, I count the digits of a number, then split the number in half using powers of 10.

I borrowed this StackOverflow answer to count digits.

And since a product ID is invalid if it has a sequence repeated twice, product IDs with an odd number of digits are valid.

static bool IsAnInvalidId(int n)
    => HasSequenceRepeatedTwice(n);

static bool HasSequenceRepeatedTwice(int n)
{
    var digitCount = (int)(Math.Log10(n) + 1);
    if (digitCount % 2 != 0)
    {
        return false;
    }

    var firstHalf = n / (int)Math.Pow(10, digitCount / 2);
    var secondHalf = n % (int)Math.Pow(10, digitCount / 2);

    return firstHalf == secondHalf;
}

Once we check for repeated sequences, the only task left is counting IDs in each range.

Counting invalid product IDs

I’m creating a function to enumerate a range, Enumerate(), and a LINQ query to find and count invalid IDs.

Here’s my full solution:

var ranges = new[]
{
    new Range(11, 22),
    new Range(95, 115),
    new Range(998, 1012),
    new Range(1188511880, 1188511890),
    new Range(222220, 222224),
    new Range(1698522, 1698528),
    new Range(446443, 446449),
    new Range(38593856, 38593862),
    new Range(565653, 565659),
    new Range(824824821, 824824827),
    new Range(2121212118, 2121212124),
};

var sum = ranges.SelectMany(Enumerate)
                .Where(IsAnInvalidId)
                .Sum();
Console.WriteLine(sum);
Console.ReadLine();

static IEnumerable<int> Enumerate(Range r)
    => Enumerable.Range(r.Left, r.Right - r.Left + 1);

static bool IsAnInvalidId(int n)
    => HasSequenceRepeatedTwice(n);

static bool HasSequenceRepeatedTwice(int n)
{
    var digitCount = (int)(Math.Log10(n) + 1);
    if (digitCount % 2 != 0)
    {
        return false;
    }

    var firstHalf = n / (int)Math.Pow(10, digitCount / 2);
    var secondHalf = n % (int)Math.Pow(10, digitCount / 2);

    return firstHalf == secondHalf;
}

record Range(int Left, int Right);

Et voilà!

Advent of Code sharpens your coding skills. But coding is more than typing symbols fast. It’s also about teamwork, collaboration, and many skills I share in my book, Street-Smart Coding: 30 Ways to Get Better at Coding. That’s the roadmap I wish I’d known from day one.

Get your copy of Street-Smart Coding here