refactor: edge and rectangle in separate packages

This commit is contained in:
Stevan Freeborn
2025-12-19 19:01:44 -06:00
parent c5abf62fff
commit 5b7f652dee
5 changed files with 373 additions and 68 deletions
+83
View File
@@ -0,0 +1,83 @@
// Package rectangle provides a model and methods for representing and manipulating rectangles.
package rectangle
import (
"math"
"github.com/StevanFreeborn/advent-of-code-2025/internal/position"
)
type Rectangle interface {
Corners() []position.Position
MaxRow() int
MaxColumn() int
MinRow() int
MinColumn() int
Area() int
Center() position.Position
}
type rectangle struct {
corners []position.Position
maxRow int
maxColumn int
minRow int
minColumn int
area int
center position.Position
}
func From(cornerOne position.Position, cornerTwo position.Position) Rectangle {
thirdCorner := position.From(cornerOne.Row(), cornerTwo.Column())
fourthCorner := position.From(cornerTwo.Row(), cornerOne.Column())
corners := []position.Position{cornerOne, cornerTwo, thirdCorner, fourthCorner}
maxRow := math.Max(float64(cornerOne.Row()), float64(cornerTwo.Row()))
maxColumn := math.Max(float64(cornerOne.Column()), float64(cornerTwo.Column()))
minRow := math.Min(float64(cornerOne.Row()), float64(cornerTwo.Row()))
minColumn := math.Min(float64(cornerOne.Column()), float64(cornerTwo.Column()))
area := int((maxRow - minRow + 1) * (maxColumn - minColumn + 1))
centerRow := (maxRow + minRow) / 2
centerColumn := (maxColumn + minColumn) / 2
center := position.From(int(centerRow), int(centerColumn))
return rectangle{
corners: corners,
maxRow: int(maxRow),
maxColumn: int(maxColumn),
minRow: int(minRow),
minColumn: int(minColumn),
area: area,
center: center,
}
}
func (r rectangle) Corners() []position.Position {
return r.corners
}
func (r rectangle) MaxRow() int {
return r.maxRow
}
func (r rectangle) MinRow() int {
return r.minRow
}
func (r rectangle) MaxColumn() int {
return r.maxColumn
}
func (r rectangle) MinColumn() int {
return r.minColumn
}
func (r rectangle) Area() int {
return r.area
}
func (r rectangle) Center() position.Position {
return r.center
}
+105
View File
@@ -0,0 +1,105 @@
package rectangle_test
import (
"slices"
"testing"
"github.com/StevanFreeborn/advent-of-code-2025/cmd/09/rectangle"
"github.com/StevanFreeborn/advent-of-code-2025/internal/position"
)
func TestFrom(t *testing.T) {
cornerOne := position.From(1, 2)
cornerTwo := position.From(3, 4)
expectedCorners := []position.Position{
cornerOne,
cornerTwo,
position.From(1, 4),
position.From(3, 2),
}
result := rectangle.From(cornerOne, cornerTwo)
if slices.Equal(result.Corners(), expectedCorners) == false {
t.Errorf("Expected corners %v, but got %v", expectedCorners, result.Corners())
}
}
func TestMaxRow(t *testing.T) {
expectedMaxRow := 3
cornerOne := position.From(1, 2)
cornerTwo := position.From(3, 4)
result := rectangle.From(cornerOne, cornerTwo).MaxRow()
if result != expectedMaxRow {
t.Errorf("Expected max row %d, but got %d", expectedMaxRow, result)
}
}
func TestMinRow(t *testing.T) {
expectedMinRow := 1
cornerOne := position.From(1, 2)
cornerTwo := position.From(3, 4)
result := rectangle.From(cornerOne, cornerTwo).MinRow()
if result != expectedMinRow {
t.Errorf("Expected min row %d, but got %d", expectedMinRow, result)
}
}
func TestMaxColumn(t *testing.T) {
expectedMaxColumn := 4
cornerOne := position.From(1, 2)
cornerTwo := position.From(3, 4)
result := rectangle.From(cornerOne, cornerTwo).MaxColumn()
if result != expectedMaxColumn {
t.Errorf("Expected max column %d, but got %d", expectedMaxColumn, result)
}
}
func TestMinColumn(t *testing.T) {
expectedMinColumn := 2
cornerOne := position.From(1, 2)
cornerTwo := position.From(3, 4)
result := rectangle.From(cornerOne, cornerTwo).MinColumn()
if result != expectedMinColumn {
t.Errorf("Expected min column %d, but got %d", expectedMinColumn, result)
}
}
func TestArea(t *testing.T) {
expectedArea := 9
cornerOne := position.From(1, 2)
cornerTwo := position.From(3, 4)
result := rectangle.From(cornerOne, cornerTwo).Area()
if result != expectedArea {
t.Errorf("Expected area %d, but got %d", expectedArea, result)
}
}
func TestCenter(t *testing.T) {
expectedCenter := position.From(2, 3)
cornerOne := position.From(1, 2)
cornerTwo := position.From(3, 4)
result := rectangle.From(cornerOne, cornerTwo).Center()
if result != expectedCenter {
t.Errorf("Expected center %v, but got %v", expectedCenter, result)
}
}