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.