01020304050607080910111213141516171819202122232425

Advent of Code

2020/12

Rain Risk

in C#

by encse

Your ferry made decent progress toward the island, but the storm came in faster than anyone expected. The ferry needs to take evasive actions!

Unfortunately, the ship's navigation computer seems to be malfunctioning; rather than giving a route directly to safety, it produced extremely circuitous instructions. When the captain uses the PA system to ask if anyone can help, you quickly volunteer.

Read the full puzzle.

using System;
using System.Linq;
using System.Numerics;

namespace AdventOfCode.Y2020.Day12;

record State(Complex pos, Complex dir);

[ProblemName("Rain Risk")]
class Solution : Solver {

    public object PartOne(string input) => MoveShip(input, true);
    public object PartTwo(string input) => MoveShip(input, false);

    double MoveShip(string input, bool part1) =>
        input
            .Split("\n")
            .Select(line => (line[0], int.Parse(line.Substring(1))))
            .Aggregate(
                new State(pos: Complex.Zero, dir: part1 ? Complex.One : new Complex(10, 1)), 
                (state, line) => 
                    line switch {
                        ('N', var arg) when part1 => state with {pos = state.pos + arg * Complex.ImaginaryOne},
                        ('N', var arg)            => state with {dir = state.dir + arg * Complex.ImaginaryOne},
                        ('S', var arg) when part1 => state with {pos = state.pos - arg * Complex.ImaginaryOne},
                        ('S', var arg)            => state with {dir = state.dir - arg * Complex.ImaginaryOne},
                        ('E', var arg) when part1 => state with {pos = state.pos + arg},
                        ('E', var arg)            => state with {dir = state.dir + arg},
                        ('W', var arg) when part1 => state with {pos = state.pos - arg},
                        ('W', var arg)            => state with {dir = state.dir - arg},
                        ('F', var arg)            => state with {pos = state.pos + arg * state.dir},
                        ('L', 90)  or ('R', 270)  => state with {dir =  state.dir * Complex.ImaginaryOne},
                        ('L', 270) or ('R', 90)   => state with {dir = -state.dir * Complex.ImaginaryOne},
                        ('L', 180) or ('R', 180)  => state with {dir = -state.dir},
                        _ => throw new Exception()
                    }, 
                state => Math.Abs(state.pos.Imaginary) + Math.Abs(state.pos.Real));
}

Please ☆ my repo if you like it!

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