So this time around we’re working with strings.

The first part asks to build a simple checksum type algorithm to ensure the box ids are correct. I ended up solving it with basically just LINQ in C#.

var counts = ids.Select(s => s.GroupBy(c => c).Select(g => g.Count()))
    .Select(cs =>
    {
        var csl = cs.ToList();
        return new[] {csl.Contains(2), csl.Contains(3)};
    })
    .ToList();
return (counts.Count(c => c[0]) * counts.Count(c => c[1])).ToString();

The first Select returns the number of each character for each id. The second Select returns whether those counts contain 2 and 3, meaning the id contains a character twice or contains a character thrice. The last part just multiplies the number of ids containing a multiple of 2 by the number of ids containing a multiple of 3.

The second part asks us to find the two matching boxes by finding the two ids that differ by only 1 character. Here I went with a simple brute force of checking all the pairs and returning the first one that matches the criteria.

foreach (var id1 in ids)
{
    foreach (var id2 in ids)
    {
        if (id1 == id2)
            continue;
            var commonLetters = string.Concat(id1.Zip(id2, (c1, c2) => c1 == c2 ? c1 : ' ').Where(c => c != ' '));
            if (commonLetters.Length == id1.Length - 1)
                return commonLetters;
    }
}

I opted again for LINQ to calculate the matching characters. If the two characters match, I return it, otherwise I replace it with a space character which I then remove. The first pair which has 1 less common letters than the number of letters in the id is the one we want. I was afraid running a O(n²) algorithm would require too much compute time, but the input was small enough that I didn’t need any optimization.