Advent-of-Code/year25/day9/day9.go
2025-12-24 23:03:25 +02:00

99 lines
2.3 KiB
Go

package day9
import (
"bytes"
"cmp"
"fmt"
"slices"
"strconv"
"git.bizdoc.ro/gabi-public/Advent-of-Code.git/aoc"
"git.bizdoc.ro/private/devkit.git/collections/geometry/v2"
)
type Rectangle struct {
Point1, Point2 int
Top, Bottom geometry.Point
Area float64
}
func (r Rectangle) String() string {
v := r.Vertices()
var b bytes.Buffer
fmt.Fprintln(&b, r.Top, r.Bottom)
for _, v := range v {
fmt.Fprintf(&b, "[{x:%2d y:%2d} -> {x:%2d y:%2d}] ", v.Start.Line, v.Start.Col, v.End.Line, v.End.Col)
}
fmt.Fprintf(&b, " a = %f", r.Area)
return b.String()
}
func (r Rectangle) Vertices() (v [4]Vertex) {
v[0] = Vertex{
Start: r.Top,
End: geometry.NewPoint(r.Top.Line, r.Bottom.Col),
Facing: geometry.DirectionRight,
}
v[1] = Vertex{
Start: v[0].End,
End: r.Bottom,
Facing: geometry.DirectionDown,
}
v[2] = Vertex{
Start: v[1].End,
End: geometry.NewPoint(r.Bottom.Line, r.Top.Col),
Facing: geometry.DirectionLeft,
}
v[3] = Vertex{
Start: v[2].End,
End: r.Top,
Facing: geometry.DirectionUp,
}
return
}
func Part1(ctx aoc.Context) (int, error) {
g, err := geometry.ScannerToGrid(ctx.Scanner(), ",", strconv.Atoi)
if err != nil {
return 0, fmt.Errorf("day9: failed to parse intput %w", err)
}
points := geometry.UnsafeGridData(g)
for _, point := range points {
point[1], point[0] = point[0], point[1]
}
return int(day9FindRectangles(points)[0].Area), nil
}
func day9FindRectangles(points [][]int) []Rectangle {
const lineIndex = 0
const colIndex = 1
var pairs []Rectangle
var abs = func(a int) int {
if a < 0 {
a = -a
}
return a
}
for i, p1 := range points {
for j, p2 := range points[i+1:] {
x := abs(p1[colIndex]-p2[colIndex]) + 1
y := abs(p1[lineIndex]-p2[lineIndex]) + 1
d := float64(x) * float64(y)
//fmt.Printf("%d,%d - %d,%d (%d-%d)%g\n", p1[colIndex], p1[lineIndex], p2[colIndex], p2[lineIndex], x, y, d)
pairs = append(pairs, Rectangle{
Point1: i,
Point2: i + 1 + j,
Top: geometry.NewPoint(min(p1[lineIndex], p2[lineIndex]), min(p1[colIndex], p2[colIndex])),
Bottom: geometry.NewPoint(max(p1[lineIndex], p2[lineIndex]), max(p1[colIndex], p2[colIndex])),
Area: d,
})
}
}
slices.SortFunc(pairs, func(a, b Rectangle) int {
return cmp.Compare(b.Area, a.Area) // reverse order
})
return pairs
}