module advent_of_code.tasks.day_9.Star2 // UNFINISHED. Submission was found manually. open System open System.IO let stream = new StreamReader("tasks/day-9/input.txt") type Point2D = struct val X: int64 val Y: int64 new(s: string) = let splitS = s.Split(',') |> Array.Parallel.map int64 let x, y = splitS[0], splitS[1] { X = x Y = y } new(x: int64, y: int64) = { X = x Y = y } override this.ToString() = $"Point2D with x = {this.X} y = {this.Y}" end let getRect(p: Point2D * Point2D) = let p1, p2 = p.Deconstruct() abs (p1.X - p2.X + (1 |> int64)) * abs (p1.Y - p2.Y + (1 |> int64)) let notSame (p: Point2D * Point2D) = let p1, p2 = p.Deconstruct() p1.X <> p2.X && p1.Y <> p2.Y let linesIntersect (l1: Point2D * Point2D) (l2: Point2D * Point2D) = let (p1, p2) = l1.Deconstruct() let (q1, q2) = l2.Deconstruct() if q1.X = q2.X then q1.X > min p1.X p2.X && q1.X < max p1.X p2.X && min q1.Y q2.Y < max p1.Y p2.Y && max q1.Y q2.Y > min p1.Y p2.Y else max q1.X q2.X > min p1.X p2.X && min q1.X q2.X < max p1.X p2.X && q1.Y < max p1.Y p2.Y && q1.Y > min p1.Y p2.Y let isInPoly (polygon: Point2D list) (p: Point2D * Point2D) = let edges = List.pairwise polygon @ [List.last polygon, List.head polygon] |> Array.ofList edges |> Array.Parallel.forall (linesIntersect p >> not) let main = let points = stream.ReadToEnd().Split('\n') |> Array.Parallel.map Point2D let pointList = points |> List.ofArray let allRects = (Array.allPairs points points) |> Array.Parallel.filter notSame |> Array.Parallel.filter (isInPoly pointList) allRects |> Array.Parallel.maxBy getRect |> getRect