01020304050607080910111213141516171819202122232425

Advent of Code

2020/17

Conway Cubes

in C#

by encse

As your flight slowly drifts through the sky, the Elves at the Mythical Information Bureau at the North Pole contact you. They'd like some help debugging a malfunctioning experimental energy source aboard one of their super-secret imaging satellites.

The experimental energy source is based on cutting-edge technology: a set of Conway Cubes contained in a pocket dimension! When you hear it's having problems, you can't help but agree to take a look.

Read the full puzzle.

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

namespace AdventOfCode.Y2020.Day17;

[ProblemName("Conway Cubes")]
class Solution : Solver {
    public object PartOne(string input) {
        var ds = (from dx in new[] { -1, 0, 1 }
                  from dy in new[] { -1, 0, 1 }
                  from dz in new[] { -1, 0, 1 }
                  where dx != 0 || dy != 0 || dz != 0
                  select (dx, dy, dz)).ToArray();
        return Solve(
            input,
            (x, y) => (x: x, y: y, z: 0),
            (p) => ds.Select(d => (p.x + d.dx, p.y + d.dy, p.z + d.dz)));
    }

    public object PartTwo(string input) {
        var ds = (from dx in new[] { -1, 0, 1 }
                  from dy in new[] { -1, 0, 1 }
                  from dz in new[] { -1, 0, 1 }
                  from dw in new[] { -1, 0, 1 }
                  where dx != 0 || dy != 0 || dz != 0 || dw != 0
                  select (dx, dy, dz, dw)).ToArray();

        return Solve(
            input,
            (x, y) => (x: x, y: y, z: 0, w: 0),
            (p) => ds.Select(d => (p.x + d.dx, p.y + d.dy, p.z + d.dz, p.w + d.dw)));
    }

    private int Solve<T>(string input, Func<int, int, T> create, Func<T, IEnumerable<T>> neighbours) {
        var lines = input.Split("\n");
        var (width, height) = (lines[0].Length, lines.Length);
        var activePoints = new HashSet<T>(
            from x in Enumerable.Range(0, width) 
            from y in Enumerable.Range(0, height) 
            where lines[y][x] == '#' 
            select create(x,y)
        );
        
        for (var i = 0; i < 6; i++) {
            var newActivePoints = new HashSet<T>();
            var inactivePoints = new Dictionary<T, int>();

            foreach (var point in activePoints) {
                var activeNeighbours = 0;
                foreach (var neighbour in neighbours(point)) {
                    if (activePoints.Contains(neighbour)) {
                        activeNeighbours++;
                    } else {
                        inactivePoints[neighbour] = inactivePoints.GetValueOrDefault(neighbour) + 1;
                    }
                }

                if (activeNeighbours == 2 || activeNeighbours == 3) {
                    newActivePoints.Add(point);
                }
            }

            foreach (var (point, activeNeighbours) in inactivePoints) {
                if (activeNeighbours == 3) {
                    newActivePoints.Add(point);
                }
            }
            activePoints = newActivePoints;
        }
        return activePoints.Count();
    }
}

Please ☆ my repo if you like it!

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