Library¶
namespace AdventOfCode.Lib;
public sealed record AocInput(
string Text,
IEnumerable<string> Lines,
string[] AllLines
);
public readonly record struct Point(int X, int Y)
: IAdditionOperators<Point, Point, Point>, IMultiplyOperators<Point, Point, Point>,
IMultiplyOperators<Point, int, Point>
{
public static readonly Point North = new(0, -1); // Move up
public static readonly Point NorthEast = new(1, -1); // Move diagonally up-right
public static readonly Point East = new(1, 0); // Move right
public static readonly Point SouthEast = new(1, 1); // Move diagonally down-right
public static readonly Point South = new(0, 1); // Move down
public static readonly Point SouthWest = new(-1, 1); // Move diagonally down-left
public static readonly Point West = new(-1, 0); // Move left
public static readonly Point NorthWest = new(-1, -1); // Move diagonally up-left
private static readonly Point RotationClockwise90 = new(0, 1);
public static Point operator +(Point p1, Point p2) => new(p1.X + p2.X, p1.Y + p2.Y);
public static Point operator *(Point p1, Point p2) => new(p1.X * p2.X - p1.Y * p2.Y, p1.X * p2.Y + p1.Y * p2.X);
public static Point operator *(Point p, int factor) => new(p.X * factor, p.Y * factor);
public static Point RotateRight(Point p) => p * RotationClockwise90; // new(-Y, X)
}
public static class FunctionalExtensions
{
public static TOut Pipe<TIn, TOut>(this TIn source, Func<TIn, TOut> func) => func(source);
}
module Lib =
[<Struct>]
type Point = {
X: int
Y: int
} with
static member North = { X = 0; Y = -1 }
static member NorthEast = { X = 1; Y = -1 }
static member East = { X = 1; Y = 0 }
static member SouthEast = { X = 1; Y = 1 }
static member South = { X = 0; Y = 1 }
static member SouthWest = { X = -1; Y = 1 }
static member West = { X = -1; Y = 0 }
static member NorthWest = { X = -1; Y = -1 }
static member RotationClockwise90 = { X = 0; Y = 1 }
static member (+)(p1: Point, p2: Point) = { X = p1.X + p2.X; Y = p1.Y + p2.Y }
static member (*)(p1: Point, p2: Point) = {
X = p1.X * p2.X - p1.Y * p2.Y
Y = p1.X * p2.Y + p1.Y * p2.X
}
static member (*)(p: Point, factor: int) = { X = p.X * factor; Y = p.Y * factor }
static member rotateRight(p: Point) = p * Point.RotationClockwise90
@dataclass(frozen=True)
class AocInput:
text: str
lines: list[str]
@dataclass(frozen=True, slots=True)
class Point:
x: int
y: int
def __iter__(self):
return iter(astuple(self))
@staticmethod
def North():
return Point(0, -1)
@staticmethod
def NorthEast():
return Point(1, -1)
@staticmethod
def East():
return Point(1, 0)
@staticmethod
def SouthEast():
return Point(1, 1)
@staticmethod
def South():
return Point(0, 1)
@staticmethod
def SouthWest():
return Point(-1, 1)
@staticmethod
def West():
return Point(-1, 0)
@staticmethod
def NorthWest():
return Point(-1, -1)
def __add__(self, point: "Point") -> "Point":
if isinstance(point, Point) is False:
return NotImplemented
return Point(self.x + point.x, self.y + point.y)
def __mul__(self, factor: int) -> "Point":
if isinstance(factor, int) is False:
return NotImplemented
return Point(self.x * factor, self.y * factor)