using System.Collections.Generic;
var response = await new HttpClient().GetStringAsync("https://tompafireadventofcode.free.beeceptor.com/day5");
var lines = response.Split("\n").Select(line =>
var parts = line.Split(" -> ");
var coordinate1Parts = parts.First().Split(',').Select(int.Parse);
var coordinate2Parts = parts.Last().Split(',').Select(int.Parse);
var coordinate1 = new Coordinate(coordinate1Parts.First(), coordinate1Parts.Last());
var coordinate2 = new Coordinate(coordinate2Parts.First(), coordinate2Parts.Last());
return new Line(coordinate1, coordinate2);
var straightLines = lines.Where(line =>
line.Start.X == line.End.X ||
line.Start.Y == line.End.Y
var pointsCovered = straightLines.SelectMany(line => GetPointsCovered(line));
var pointsWithAtLeast2Crossings = pointsCovered.GroupBy(c => c).Count(x => x.Count() >= 2);
Console.WriteLine(pointsWithAtLeast2Crossings);
var straightOrDiagonalLines = lines.Where(line =>
line.Start.X == line.End.X ||
line.Start.Y == line.End.Y ||
Math.Abs(line.End.X - line.Start.X) == Math.Abs(line.End.Y - line.Start.Y)
var pointsCoveredPart2 = straightOrDiagonalLines.SelectMany(line => GetPointsCovered(line));
var pointsWithAtLeast2CrossingsPart2 = pointsCoveredPart2.GroupBy(c => c).Count(x => x.Count() >= 2);
Console.WriteLine(pointsWithAtLeast2CrossingsPart2);
IEnumerable<Coordinate> GetPointsCovered(Line line)
Func<int, int> operationX = line switch
{ } when line.Start.X < line.End.X => v => ++v,
{ } when line.Start.X > line.End.X => v => --v,
Func<int, int> operationY = line switch
{ } when line.Start.Y < line.End.Y => v => ++v,
{ } when line.Start.Y > line.End.Y => v => --v,
var current = line.Start;
current = current with { X = operationX(current.X), Y = operationY(current.Y) };
public record struct Coordinate(int X, int Y);
public record struct Line(Coordinate Start, Coordinate End);