DEV Community

Cover image for Solving Advent of Code Day 7: Splitting Tachyon Beams
Cesar Aguirre
Cesar Aguirre

Posted on • Originally published at canro91.github.io

Solving Advent of Code Day 7: Splitting Tachyon Beams

I originally posted this post on my blog.

This year, I'm following the Advent of Code. I challenged myself to write "functionalish" solutions. Here's one of the puzzles I've liked the most.


On Day 7 of Advent of Code, we're studying tachyon beams while we're stuck in a teleporter.

We're stuck in a teleporter because we've been trying to help the elves with all the Christmas preparation. But each step has complicated things even more, making it a mission impossible. I feel like in an episode of The Mandalorian. But anyway, back to code...

I imagine this puzzle as a game where each iteration moves the beam until it hits the end of the manifold.

Here's my solution.

Moving a beam

A Beam is a list of positions in the manifold at a given iteration.

record Position(int X, int Y);
record Beam(IEnumerable<Position> Locations);
Enter fullscreen mode Exit fullscreen mode

A manifold is an array of array of strings. Each cell could be an empty space or a splitter.

Like this,

var manifold = new string[][]
{
    [ ".", ".", "S", ".", "." ],
    [ ".", ".", ".", ".", "." ],
    [ ".", ".", "^", ".", "." ],
    [ ".", ".", ".", ".", "." ]
};
Enter fullscreen mode Exit fullscreen mode

Here's the method to move a beam,

static Beam Move(string[][] manifold, Beam beam)
{
    var newLocations = new HashSet<Position>();

    foreach (var current in beam.Locations)
    {
        var downward = manifold[current.X + 1][current.Y];
        if (downward == ".")
        {
            newLocations.Add(new Position(current.X + 1, current.Y));
        }
        else if (downward == "^")
        {
            newLocations.Add(new Position(current.X + 1, current.Y - 1));
            newLocations.Add(new Position(current.X + 1, current.Y + 1));
        }
    }

    return new Beam(newLocations);
}
Enter fullscreen mode Exit fullscreen mode

After moving a beam, I need the entry position of a beam,

static Beam Start(string[][] manifold)
{
    for (int i = 0; i < manifold[0].Length; i++)
    {
        if (manifold[0][i] == "S")
        {
            return new Beam([new Position(0, i)]);
        }
    }

    return new Beam([]);
}
Enter fullscreen mode Exit fullscreen mode

With those two methods, a beam enters and moves downward,

var start = Start(manifold);
var newPosition = Move(manifold, start);
newPosition = Move(manifold, newPosition);
Enter fullscreen mode Exit fullscreen mode

All that's left is to count splits and move the beam to the end.

Counting splits

Next, I create HasReachedTheEnd() to move the beam on its own, like this,

var beam = Start(manifold);
while (!HasReachedTheEnd(manifold, beam))
{
    beam = Move(manifold, beam);
}
Enter fullscreen mode Exit fullscreen mode

The next step is to count when a beam splits. I do that inside Move().

And here's my full solution. (We're supposed to parse the input manifold. But I'm lazy, so I'm harcoding a sample input.)

var manifold = new string[][]
{
    [ ".", ".", ".", ".", ".", ".", ".", "S", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", "^", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", "^", ".", "^", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", "^", ".", "^", ".", "^", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", "^", ".", "^", ".", ".", ".", "^", ".", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", ".", "^", ".", "^", ".", ".", ".", "^", ".", "^", ".", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", ".", "^", ".", ".", ".", "^", ".", ".", ".", ".", ".", "^", ".", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "." ],
    [ ".", "^", ".", "^", ".", "^", ".", "^", ".", "^", ".", ".", ".", "^", "." ],
    [ ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "." ]
};

var beam = Start(manifold);
while (!HasReachedTheEnd(manifold, beam))
{
    beam = Move(manifold, beam);
}

Console.WriteLine(beam.SplitCount);
Console.ReadLine();

static Beam Start(string[][] manifold)
{
    for (int i = 0; i < manifold[0].Length; i++)
    {
        if (manifold[0][i] == "S")
        {
            return new Beam(0, [new Position(0, i)]);
        }
    }

    return new Beam(0, []);
}

static bool HasReachedTheEnd(string[][] manifold, Beam beam)
{
    var anyBeam = beam.Locations.First();
    return anyBeam.X >= manifold.Length - 1;
}

static Beam Move(string[][] manifold, Beam beam)
{
    var splits = 0;
    var newLocations = new HashSet<Position>();

    foreach (var current in beam.Locations)
    {
        var downward = manifold[current.X + 1][current.Y];
        if (downward == ".")
        {
            newLocations.Add(new Position(current.X + 1, current.Y));
        }
        else if (downward == "^")
        {
            splits++;

            newLocations.Add(new Position(current.X + 1, current.Y - 1));
            newLocations.Add(new Position(current.X + 1, current.Y + 1));
        }
    }

    return new Beam(beam.SplitCount + splits, newLocations);
}

record Position(int X, int Y);
record Beam(int SplitCount, IEnumerable<Position> Locations);
Enter fullscreen mode Exit fullscreen mode

I thought a "tachyon" was a made-up word until I Googled it. TIL what a tachyon is. Win-win.

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

Top comments (1)

Collapse
 
baltasarq profile image
Baltasar García Perez-Schofield

Great resolution, that advent of coding. I, however, tend to distrust so lengthy exercises, after my experience in HackerRank. Great solution BTW !