feat: solve day 8 part 1...twice
This commit is contained in:
@@ -33,7 +33,7 @@ go test ./cmd/01
|
|||||||
| 05 | [Problem](https://adventofcode.com/2025/day/5) | [Solution](./cmd/05/) | Part 1 was fairly straight forward. Merging ranges was trickiest bit. I feel like I'm being led into a trap with how straight forward today was. |
|
| 05 | [Problem](https://adventofcode.com/2025/day/5) | [Solution](./cmd/05/) | Part 1 was fairly straight forward. Merging ranges was trickiest bit. I feel like I'm being led into a trap with how straight forward today was. |
|
||||||
| 06 | [Problem](https://adventofcode.com/2025/day/6) | [Solution](./cmd/06/) | Part 1 I don't think it is the best solution, but it does solve it. I kicked ass on part 2. 🥳 |
|
| 06 | [Problem](https://adventofcode.com/2025/day/6) | [Solution](./cmd/06/) | Part 1 I don't think it is the best solution, but it does solve it. I kicked ass on part 2. 🥳 |
|
||||||
| 07 | [Problem](https://adventofcode.com/2025/day/7) | [Solution](./cmd/07/) | FIFO for life. 🤣. Fuck me...part 2 I found really difficult and the use of DFS was obvious, but doing the memoizing was not. |
|
| 07 | [Problem](https://adventofcode.com/2025/day/7) | [Solution](./cmd/07/) | FIFO for life. 🤣. Fuck me...part 2 I found really difficult and the use of DFS was obvious, but doing the memoizing was not. |
|
||||||
| 08 | [Problem](https://adventofcode.com/2025/day/8) | [Solution](./cmd/08/) | |
|
| 08 | [Problem](https://adventofcode.com/2025/day/8) | [Solution](./cmd/08/) | Part 1 had me down bad. I was on the right track with my original solution, but ended up doing it in a brute force way then figuring out my mistake with the original. |
|
||||||
| 09 | [Problem](https://adventofcode.com/2025/day/9) | [Solution](./cmd/09/) | |
|
| 09 | [Problem](https://adventofcode.com/2025/day/9) | [Solution](./cmd/09/) | |
|
||||||
| 10 | [Problem](https://adventofcode.com/2025/day/10) | [Solution](./cmd/10/) | |
|
| 10 | [Problem](https://adventofcode.com/2025/day/10) | [Solution](./cmd/10/) | |
|
||||||
| 11 | [Problem](https://adventofcode.com/2025/day/11) | [Solution](./cmd/11/) | |
|
| 11 | [Problem](https://adventofcode.com/2025/day/11) | [Solution](./cmd/11/) | |
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// Package box provides a model and methods for junction boxes.
|
||||||
|
package box
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Box interface {
|
||||||
|
Y() int
|
||||||
|
X() int
|
||||||
|
Z() int
|
||||||
|
DistanceFrom(neighbor Box) float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type box struct {
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
z int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b box) X() int {
|
||||||
|
return b.x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b box) Y() int {
|
||||||
|
return b.y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b box) Z() int {
|
||||||
|
return b.z
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b box) DistanceFrom(neighbor Box) float64 {
|
||||||
|
xDiff := math.Pow(float64(b.x-neighbor.X()), 2)
|
||||||
|
yDiff := math.Pow(float64(b.y-neighbor.Y()), 2)
|
||||||
|
zDiff := math.Pow(float64(b.z-neighbor.Z()), 2)
|
||||||
|
|
||||||
|
return math.Sqrt(xDiff + yDiff + zDiff)
|
||||||
|
}
|
||||||
|
|
||||||
|
func From(str string) Box {
|
||||||
|
parts := strings.Split(str, ",")
|
||||||
|
|
||||||
|
if len(parts) != 3 {
|
||||||
|
panic("invalid junction box")
|
||||||
|
}
|
||||||
|
|
||||||
|
x, _ := strconv.Atoi(parts[0])
|
||||||
|
y, _ := strconv.Atoi(parts[1])
|
||||||
|
z, _ := strconv.Atoi(parts[2])
|
||||||
|
|
||||||
|
return box{
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
z: z,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package box_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/box"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFrom(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string
|
||||||
|
expected box.Box
|
||||||
|
}{
|
||||||
|
{"1,2,3", box.From("1,2,3")},
|
||||||
|
{"0,0,0", box.From("0,0,0")},
|
||||||
|
{"-1,-2,-3", box.From("-1,-2,-3")},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
result := box.From(test.input)
|
||||||
|
|
||||||
|
if result != test.expected {
|
||||||
|
t.Errorf("From(%q) = %v; want %v", test.input, result, test.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDistanceFrom(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
box1 box.Box
|
||||||
|
box2 box.Box
|
||||||
|
expected float64
|
||||||
|
}{
|
||||||
|
{box.From("0,0,0"), box.From("1,1,1"), 1.7320508075688772},
|
||||||
|
{box.From("1,2,3"), box.From("4,5,6"), 5.196152422706632},
|
||||||
|
{box.From("-1,-2,-3"), box.From("1,2,3"), 7.483314773547883},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
result := test.box1.DistanceFrom(test.box2)
|
||||||
|
|
||||||
|
if result != test.expected {
|
||||||
|
t.Errorf("DistanceFrom(%v, %v) = %v; want %v", test.box1, test.box2, result, test.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
// Package circuitMap provides a data structure to manage and track connected junction boxes.
|
||||||
|
package circuitMap
|
||||||
|
|
||||||
|
import "github.com/StevanFreeborn/advent-of-code-2025/cmd/08/box"
|
||||||
|
|
||||||
|
type CircuitMap interface {
|
||||||
|
Length() int
|
||||||
|
GetValueFor(b box.Box) (CircuitMapValue, bool)
|
||||||
|
UpdateValueFor(b box.Box, value CircuitMapValue)
|
||||||
|
FindRootBoxFor(b box.Box) box.Box
|
||||||
|
Entries() map[box.Box]CircuitMapValue
|
||||||
|
}
|
||||||
|
|
||||||
|
type CircuitMapValue interface {
|
||||||
|
Parent() box.Box
|
||||||
|
Size() int
|
||||||
|
UpdateParent(newParent box.Box)
|
||||||
|
IncreaseSize(by int)
|
||||||
|
}
|
||||||
|
|
||||||
|
type circuitMap map[box.Box]CircuitMapValue
|
||||||
|
|
||||||
|
func From(boxes []box.Box) CircuitMap {
|
||||||
|
circuitsMap := circuitMap{}
|
||||||
|
|
||||||
|
for _, b := range boxes {
|
||||||
|
circuitsMap[b] = &circuitMapValue{
|
||||||
|
parent: b,
|
||||||
|
size: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return circuitsMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c circuitMap) Length() int {
|
||||||
|
return len(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c circuitMap) GetValueFor(b box.Box) (CircuitMapValue, bool) {
|
||||||
|
v, exists := c[b]
|
||||||
|
return v, exists
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c circuitMap) UpdateValueFor(b box.Box, value CircuitMapValue) {
|
||||||
|
c[b] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c circuitMap) FindRootBoxFor(b box.Box) box.Box {
|
||||||
|
root := b
|
||||||
|
|
||||||
|
for c[root].Parent() != root {
|
||||||
|
root = c[root].Parent()
|
||||||
|
}
|
||||||
|
|
||||||
|
current := b
|
||||||
|
|
||||||
|
for current != root {
|
||||||
|
item := c[current]
|
||||||
|
next := item.Parent()
|
||||||
|
item.UpdateParent(root)
|
||||||
|
c[current] = item
|
||||||
|
current = next
|
||||||
|
}
|
||||||
|
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c circuitMap) Entries() map[box.Box]CircuitMapValue {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type circuitMapValue struct {
|
||||||
|
parent box.Box
|
||||||
|
size int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *circuitMapValue) Parent() box.Box {
|
||||||
|
return c.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *circuitMapValue) Size() int {
|
||||||
|
return c.size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *circuitMapValue) UpdateParent(newParent box.Box) {
|
||||||
|
c.parent = newParent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *circuitMapValue) IncreaseSize(by int) {
|
||||||
|
c.size += by
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package circuitMap_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/box"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/circuitMap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFrom(t *testing.T) {
|
||||||
|
boxes := []box.Box{
|
||||||
|
box.From("0,0,0"),
|
||||||
|
box.From("1,1,1"),
|
||||||
|
}
|
||||||
|
expectedNumOfEntries := len(boxes)
|
||||||
|
|
||||||
|
result := circuitMap.From(boxes)
|
||||||
|
|
||||||
|
if result.Length() != expectedNumOfEntries {
|
||||||
|
t.Errorf("CreateMap() returned map with %d entries; expected %d", result.Length(), expectedNumOfEntries)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, b := range boxes {
|
||||||
|
_, exists := result.GetValueFor(b)
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
t.Errorf("CreateMap() result missing entry for box %v", b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetAndUpdateValueFor(t *testing.T) {
|
||||||
|
b := box.From("2,2,2")
|
||||||
|
cMap := circuitMap.From([]box.Box{b})
|
||||||
|
|
||||||
|
value, exists := cMap.GetValueFor(b)
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
t.Fatalf("GetValueFor() did not find value for box %v", b)
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.Parent() != b {
|
||||||
|
t.Errorf("GetValueFor() returned value with Parent() = %v; expected %v", value.Parent(), b)
|
||||||
|
}
|
||||||
|
|
||||||
|
newParent := box.From("3,3,3")
|
||||||
|
|
||||||
|
value.UpdateParent(newParent)
|
||||||
|
cMap.UpdateValueFor(b, value)
|
||||||
|
|
||||||
|
updatedValue, exists := cMap.GetValueFor(b)
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
t.Fatalf("GetValueFor() after UpdateValueFor() did not find value for box %v", b)
|
||||||
|
}
|
||||||
|
|
||||||
|
if updatedValue.Parent() != newParent {
|
||||||
|
t.Errorf("After UpdateValueFor(), GetValueFor() returned value with Parent() = %v; expected %v", updatedValue.Parent(), newParent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindRootBoxFor(t *testing.T) {
|
||||||
|
b1 := box.From("0,0,0")
|
||||||
|
b2 := box.From("1,1,1")
|
||||||
|
b3 := box.From("2,2,2")
|
||||||
|
|
||||||
|
cMap := circuitMap.From([]box.Box{b1, b2, b3})
|
||||||
|
|
||||||
|
// Manually create connections
|
||||||
|
value2, _ := cMap.GetValueFor(b2)
|
||||||
|
value2.UpdateParent(b1)
|
||||||
|
cMap.UpdateValueFor(b2, value2)
|
||||||
|
|
||||||
|
value3, _ := cMap.GetValueFor(b3)
|
||||||
|
value3.UpdateParent(b2)
|
||||||
|
cMap.UpdateValueFor(b3, value3)
|
||||||
|
|
||||||
|
root := cMap.FindRootBoxFor(b3)
|
||||||
|
|
||||||
|
if root != b1 {
|
||||||
|
t.Errorf("FindRootBoxFor(%v) = %v; expected %v", b3, root, b1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEntries(t *testing.T) {
|
||||||
|
b1 := box.From("0,0,0")
|
||||||
|
b2 := box.From("1,1,1")
|
||||||
|
|
||||||
|
cMap := circuitMap.From([]box.Box{b1, b2})
|
||||||
|
entries := cMap.Entries()
|
||||||
|
|
||||||
|
if len(entries) != 2 {
|
||||||
|
t.Errorf("Entries() returned %d entries; expected 2", len(entries))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, b := range []box.Box{b1, b2} {
|
||||||
|
if _, exists := entries[b]; !exists {
|
||||||
|
t.Errorf("Entries() missing entry for box %v", b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Package connection provides a model and methods for connections between junction boxes.
|
||||||
|
package connection
|
||||||
|
|
||||||
|
import "github.com/StevanFreeborn/advent-of-code-2025/cmd/08/box"
|
||||||
|
|
||||||
|
type Connection interface {
|
||||||
|
Start() box.Box
|
||||||
|
End() box.Box
|
||||||
|
Distance() float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type connection struct {
|
||||||
|
start box.Box
|
||||||
|
end box.Box
|
||||||
|
distance float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c connection) Start() box.Box {
|
||||||
|
return c.start
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c connection) End() box.Box {
|
||||||
|
return c.end
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c connection) Distance() float64 {
|
||||||
|
return c.distance
|
||||||
|
}
|
||||||
|
|
||||||
|
func From(start box.Box, end box.Box) Connection {
|
||||||
|
return connection{
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
distance: start.DistanceFrom(end),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package connection_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/box"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/connection"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFrom(t *testing.T) {
|
||||||
|
start := box.From("1,2,3")
|
||||||
|
end := box.From("4,5,6")
|
||||||
|
expectedDistance := start.DistanceFrom(end)
|
||||||
|
|
||||||
|
conn := connection.From(start, end)
|
||||||
|
|
||||||
|
if conn.Start() != start {
|
||||||
|
t.Errorf("Connection Start() = %v; want %v", conn.Start(), start)
|
||||||
|
}
|
||||||
|
|
||||||
|
if conn.End() != end {
|
||||||
|
t.Errorf("Connection End() = %v; want %v", conn.End(), end)
|
||||||
|
}
|
||||||
|
|
||||||
|
if conn.Distance() != expectedDistance {
|
||||||
|
t.Errorf("Connection Distance() = %v; want %v", conn.Distance(), expectedDistance)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
// Package estimator provides model and methods
|
||||||
|
// for answering questions about cable needs
|
||||||
|
// for connecting junction boxes.
|
||||||
|
package estimator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/box"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/circuitMap"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/connection"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Estimator interface {
|
||||||
|
PossibleConnections() []connection.Connection
|
||||||
|
CreateMap() circuitMap.CircuitMap
|
||||||
|
}
|
||||||
|
|
||||||
|
type estimator struct {
|
||||||
|
possibleConnections []connection.Connection
|
||||||
|
boxes []box.Box
|
||||||
|
}
|
||||||
|
|
||||||
|
func From(boxes []box.Box) Estimator {
|
||||||
|
return estimator{
|
||||||
|
boxes: boxes,
|
||||||
|
possibleConnections: createAllPossibleConnections(boxes),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e estimator) PossibleConnections() []connection.Connection {
|
||||||
|
return e.possibleConnections
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e estimator) CreateMap() circuitMap.CircuitMap {
|
||||||
|
return circuitMap.From(e.boxes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createAllPossibleConnections(boxes []box.Box) []connection.Connection {
|
||||||
|
connections := []connection.Connection{}
|
||||||
|
numOfBoxes := len(boxes)
|
||||||
|
|
||||||
|
for i := range numOfBoxes {
|
||||||
|
for j := i + 1; j < numOfBoxes; j++ {
|
||||||
|
start := boxes[i]
|
||||||
|
end := boxes[j]
|
||||||
|
conn := connection.From(start, end)
|
||||||
|
connections = append(connections, conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.SortFunc(connections, func(a connection.Connection, b connection.Connection) int {
|
||||||
|
return int(a.Distance() - b.Distance())
|
||||||
|
})
|
||||||
|
|
||||||
|
return connections
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package estimator_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/box"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/estimator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFrom(t *testing.T) {
|
||||||
|
result := estimator.From([]box.Box{})
|
||||||
|
|
||||||
|
if result == nil {
|
||||||
|
t.Errorf("estimator.From returned nil; expected non-nil value")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result.PossibleConnections()) != 0 {
|
||||||
|
t.Errorf("estimator.From returned estimator with PossibleConnections() = %d; expected 0", result.PossibleConnections())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPossibleConnections(t *testing.T) {
|
||||||
|
expectedNumOfConnections := 1
|
||||||
|
|
||||||
|
est := estimator.From([]box.Box{
|
||||||
|
box.From("0,0,0"),
|
||||||
|
box.From("1,1,1"),
|
||||||
|
})
|
||||||
|
|
||||||
|
result := est.PossibleConnections()
|
||||||
|
|
||||||
|
if len(result) != expectedNumOfConnections {
|
||||||
|
t.Errorf("PossibleConnections() returned %d connections; expected %d", len(result), expectedNumOfConnections)
|
||||||
|
}
|
||||||
|
}
|
||||||
+150
@@ -0,0 +1,150 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/box"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/08/estimator"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/file"
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/queue"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SolvePartOne(filePath string, numOfConnections int) int {
|
||||||
|
boxes := []box.Box{}
|
||||||
|
|
||||||
|
for line := range file.ReadLines(filePath) {
|
||||||
|
boxes = append(boxes, box.From(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
estimator := estimator.From(boxes)
|
||||||
|
circuitsMap := estimator.CreateMap()
|
||||||
|
|
||||||
|
for _, connection := range estimator.PossibleConnections()[:numOfConnections] {
|
||||||
|
startRoot := circuitsMap.FindRootBoxFor(connection.Start())
|
||||||
|
endRoot := circuitsMap.FindRootBoxFor(connection.End())
|
||||||
|
|
||||||
|
if startRoot == endRoot {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
startRootValue, _ := circuitsMap.GetValueFor(startRoot)
|
||||||
|
endRootValue, _ := circuitsMap.GetValueFor(endRoot)
|
||||||
|
|
||||||
|
if startRootValue.Size() < endRootValue.Size() {
|
||||||
|
startRootValue.UpdateParent(endRoot)
|
||||||
|
endRootValue.IncreaseSize(startRootValue.Size())
|
||||||
|
} else {
|
||||||
|
endRootValue.UpdateParent(startRoot)
|
||||||
|
startRootValue.IncreaseSize(endRootValue.Size())
|
||||||
|
}
|
||||||
|
|
||||||
|
circuitsMap.UpdateValueFor(startRoot, startRootValue)
|
||||||
|
circuitsMap.UpdateValueFor(endRoot, endRootValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
circuitSizes := []int{}
|
||||||
|
|
||||||
|
for root, circuit := range circuitsMap.Entries() {
|
||||||
|
if circuit.Parent() != root {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
circuitSizes = append(circuitSizes, circuit.Size())
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.SortFunc(circuitSizes, func(a int, b int) int {
|
||||||
|
return b - a
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(circuitSizes) < 3 {
|
||||||
|
panic("not enough circuits")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := 1
|
||||||
|
|
||||||
|
for i := range 3 {
|
||||||
|
result *= circuitSizes[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func SolvePartOneAgain(filePath string, numOfConnections int) int {
|
||||||
|
boxes := []box.Box{}
|
||||||
|
|
||||||
|
for line := range file.ReadLines(filePath) {
|
||||||
|
boxes = append(boxes, box.From(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
estimator := estimator.From(boxes)
|
||||||
|
|
||||||
|
neighbors := map[box.Box][]box.Box{}
|
||||||
|
|
||||||
|
for _, b := range boxes {
|
||||||
|
neighbors[b] = []box.Box{}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, connection := range estimator.PossibleConnections()[:numOfConnections] {
|
||||||
|
startNeighbors := neighbors[connection.Start()]
|
||||||
|
endNeighbors := neighbors[connection.End()]
|
||||||
|
|
||||||
|
startNeighbors = append(startNeighbors, connection.End())
|
||||||
|
endNeighbors = append(endNeighbors, connection.Start())
|
||||||
|
|
||||||
|
neighbors[connection.Start()] = startNeighbors
|
||||||
|
neighbors[connection.End()] = endNeighbors
|
||||||
|
}
|
||||||
|
|
||||||
|
circuits := [][]box.Box{}
|
||||||
|
visited := map[box.Box]bool{}
|
||||||
|
|
||||||
|
for _, b := range boxes {
|
||||||
|
if visited[b] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
currentCircuit := []box.Box{}
|
||||||
|
boxesQueue := queue.New[box.Box]()
|
||||||
|
boxesQueue.Enqueue(b)
|
||||||
|
visited[b] = true
|
||||||
|
|
||||||
|
for boxesQueue.IsEmpty() == false {
|
||||||
|
current, _ := boxesQueue.Dequeue()
|
||||||
|
currentCircuit = append(currentCircuit, current)
|
||||||
|
currentNeighbors := neighbors[current]
|
||||||
|
|
||||||
|
for _, n := range currentNeighbors {
|
||||||
|
if visited[n] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
visited[n] = true
|
||||||
|
boxesQueue.Enqueue(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
circuits = append(circuits, currentCircuit)
|
||||||
|
}
|
||||||
|
|
||||||
|
circuitSizes := []int{}
|
||||||
|
|
||||||
|
for _, c := range circuits {
|
||||||
|
circuitSizes = append(circuitSizes, len(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.SortFunc(circuitSizes, func(a int, b int) int {
|
||||||
|
return b - a
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(circuitSizes) < 3 {
|
||||||
|
panic("not enough circuits")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := 1
|
||||||
|
|
||||||
|
for i := range 3 {
|
||||||
|
result *= circuitSizes[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package main_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
solution "github.com/StevanFreeborn/advent-of-code-2025/cmd/08"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSolvePartOneWithExampleInput(t *testing.T) {
|
||||||
|
expected := 40
|
||||||
|
|
||||||
|
result := solution.SolvePartOne("EXAMPLE.txt", 10)
|
||||||
|
|
||||||
|
if result != expected {
|
||||||
|
t.Errorf("SolvePartOne returned %d, expected %d", result, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSolvePartOneWithInput(t *testing.T) {
|
||||||
|
expected := 62186
|
||||||
|
|
||||||
|
result := solution.SolvePartOne("INPUT.txt", 1000)
|
||||||
|
|
||||||
|
if result != expected {
|
||||||
|
t.Errorf("SolvePartOne returned %d, expected %d", result, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSolvePartOneAgainWithExampleInput(t *testing.T) {
|
||||||
|
expected := 40
|
||||||
|
|
||||||
|
result := solution.SolvePartOneAgain("EXAMPLE.txt", 10)
|
||||||
|
|
||||||
|
if result != expected {
|
||||||
|
t.Errorf("SolvePartOneAgain returned %d, expected %d", result, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSolvePartOneAgainWithInput(t *testing.T) {
|
||||||
|
expected := 62186
|
||||||
|
|
||||||
|
result := solution.SolvePartOneAgain("INPUT.txt", 1000)
|
||||||
|
|
||||||
|
if result != expected {
|
||||||
|
t.Errorf("SolvePartOneAgain returned %d, expected %d", result, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user