namespace Day16; public interface IRay { bool IsHorizontal { get; } bool IsVertical { get; } (int X, int Y) Apply(Tile t); IRay Rotate(); IRay AntiRotate(); } public static class Rays { public static IRay North { get; } = new Ray(0, -1); public static IRay East { get; } = new Ray(1, 0); public static IRay South { get; } = new Ray(0, 1); public static IRay West { get; } = new Ray(-1, 0); private static readonly IList _rays = new List { North, West, South, East }; private class Ray : IRay { private readonly int _dX; private readonly int _dY; public bool IsHorizontal => _dX != 0; public bool IsVertical => _dY != 0; public Ray(int dX, int dY) { _dX = dX; _dY = dY; } public (int X, int Y) Apply(Tile t) { return (t.X + _dX, t.Y + _dY); } public IRay Rotate() { var index = _rays.IndexOf(this); return _rays[(index + 1) % _rays.Count]; } public IRay AntiRotate() { var index = _rays.IndexOf(this); return _rays[(index + _rays.Count - 1) % _rays.Count]; } public override string ToString() { return $"{_dX}/{_dY}"; } } }