01020304050607080910111213141516171819202122232425

Advent of Code

2021/8

Seven Segment Search

in C#

by encse

You barely reach the safety of the cave when the whale smashes into the cave mouth, collapsing it. Sensors indicate another exit to this cave at a much greater depth, so you have no choice but to press on.

As your submarine slowly makes its way through the cave system, you notice that the four-digit seven-segment displays in your submarine are malfunctioning; they must have been damaged during the escape. You'll be in a lot of trouble without them, so you'd better figure out what's wrong.

Read the full puzzle.

using System.Collections.Generic;
using System.Linq;

namespace AdventOfCode.Y2021.Day08;

[ProblemName("Seven Segment Search")]
class Solution : Solver {

   /*
              0:      1:      2:      3:      4:      5:      6:      7:      8:      9:
             aaaa    ....    aaaa    aaaa    ....    aaaa    aaaa    aaaa    aaaa    aaaa
            b    c  .    c  .    c  .    c  b    c  b    .  b    .  .    c  b    c  b    c
            b    c  .    c  .    c  .    c  b    c  b    .  b    .  .    c  b    c  b    c
             ....    ....    dddd    dddd    dddd    dddd    dddd    ....    dddd    dddd
            e    f  .    f  e    .  .    f  .    f  .    f  e    f  .    f  e    f  .    f
            e    f  .    f  e    .  .    f  .    f  .    f  e    f  .    f  e    f  .    f
             gggg    ....    gggg    gggg    ....    gggg    gggg    ....    gggg    gggg
    */

    public object PartOne(string input) {

        // we can identify digits 1, 7, 4 and 8 by their active segments count:
        var segmentCounts = new[] { "cd", "acf", "bcdf", "abcdefg" }.Select(x => x.Length).ToHashSet();

        return (
            from line in input.Split("\n")
            let parts = line.Split(" | ")
            from segment in parts[1].Split(" ")
            where segmentCounts.Contains(segment.Length)
            select 1
        ).Count();
    }

    public object PartTwo(string input) {
        var res = 0;
        foreach(var line in input.Split("\n")) {
            var parts = line.Split(" | ");
            var patterns = parts[0].Split(" ").Select(x => x.ToHashSet()).ToArray();

            // let's figure out what segments belong to each digit
            var digits = new HashSet<char>[10];

            // we can do these by length:
            digits[1] = patterns.Single(pattern => pattern.Count() == "cf".Length);
            digits[4] = patterns.Single(pattern => pattern.Count() == "bcdf".Length);

            // it turns out that the following tripplet uniquely identifies the rest:
            var lookup = (int segmentCount, int commonWithOne, int commonWithFour) =>
                patterns.Single(pattern => 
                    pattern.Count() == segmentCount && 
                    pattern.Intersect(digits[1]).Count() == commonWithOne && 
                    pattern.Intersect(digits[4]).Count() == commonWithFour
                );
            
            digits[0] = lookup(6, 2, 3);  
            digits[2] = lookup(5, 1, 2);
            digits[3] = lookup(5, 2, 3);
            digits[5] = lookup(5, 1, 3);
            digits[6] = lookup(6, 1, 3);
            digits[7] = lookup(3, 2, 2);
            digits[8] = lookup(7, 2, 4);
            digits[9] = lookup(6, 2, 4);
                    
            var decode = (string v) => 
                Enumerable.Range(0, 10).Single(i => digits[i].SetEquals(v));

            // Decode the number, Horner would like this.
            res += parts[1].Split(" ").Aggregate(0, (n, digit) => n * 10 + decode(digit));
        }
        return res;
    }
}

Please ☆ my repo if you like it!

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