feat: tiny refactor for part two which we're solving using Kruskal's algorithm
This commit is contained in:
@@ -60,26 +60,21 @@ func (uf *UnionFind) Find(junctionBox int) int {
|
|||||||
return uf.parent[junctionBox]
|
return uf.parent[junctionBox]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uf *UnionFind) Union(junctionBox1, junctionBox2 int) bool {
|
func (uf *UnionFind) Union(junctionBox1, junctionBox2 int) (bool, int) {
|
||||||
root1 := uf.Find(junctionBox1)
|
root1 := uf.Find(junctionBox1)
|
||||||
root2 := uf.Find(junctionBox2)
|
root2 := uf.Find(junctionBox2)
|
||||||
if root1 == root2 {
|
if root1 == root2 {
|
||||||
return false
|
return false, root1
|
||||||
}
|
}
|
||||||
if uf.size[root1] < uf.size[root2] {
|
if uf.size[root1] < uf.size[root2] {
|
||||||
root1, root2 = root2, root1
|
root1, root2 = root2, root1
|
||||||
}
|
}
|
||||||
uf.parent[root2] = root1
|
uf.parent[root2] = root1
|
||||||
uf.size[root1] += uf.size[root2]
|
uf.size[root1] += uf.size[root2]
|
||||||
return true
|
return true, root1
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseInput(filepath string) []string {
|
func parseJunctionBoxes(data []string) []JunctionBox {
|
||||||
content, _ := os.ReadFile(filepath)
|
|
||||||
return strings.Split(string(content), "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func PartOne(data []string) int {
|
|
||||||
var junctionBoxes []JunctionBox
|
var junctionBoxes []JunctionBox
|
||||||
for _, line := range data {
|
for _, line := range data {
|
||||||
parts := strings.Split(line, ",")
|
parts := strings.Split(line, ",")
|
||||||
@@ -88,14 +83,38 @@ func PartOne(data []string) int {
|
|||||||
z, _ := strconv.Atoi(parts[2])
|
z, _ := strconv.Atoi(parts[2])
|
||||||
junctionBoxes = append(junctionBoxes, JunctionBox{X: x, Y: y, Z: z})
|
junctionBoxes = append(junctionBoxes, JunctionBox{X: x, Y: y, Z: z})
|
||||||
}
|
}
|
||||||
|
return junctionBoxes
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateAllConnections(junctionBoxes []JunctionBox) []Connection {
|
||||||
junctionBoxCount := len(junctionBoxes)
|
junctionBoxCount := len(junctionBoxes)
|
||||||
targetPairs := 1000
|
connections := make([]Connection, 0, junctionBoxCount*(junctionBoxCount-1)/2)
|
||||||
if junctionBoxCount <= 20 {
|
|
||||||
targetPairs = 10
|
for i := range junctionBoxCount {
|
||||||
|
for j := i + 1; j < junctionBoxCount; j++ {
|
||||||
|
dx := junctionBoxes[i].X - junctionBoxes[j].X
|
||||||
|
dy := junctionBoxes[i].Y - junctionBoxes[j].Y
|
||||||
|
dz := junctionBoxes[i].Z - junctionBoxes[j].Z
|
||||||
|
squaredDistance := dx*dx + dy*dy + dz*dz
|
||||||
|
|
||||||
|
connections = append(connections, Connection{
|
||||||
|
firstJunctionBox: i,
|
||||||
|
secondJunctionBox: j,
|
||||||
|
squaredDistance: squaredDistance,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionHeap := make(ConnectionHeap, 0, targetPairs)
|
slices.SortFunc(connections, func(a, b Connection) int {
|
||||||
|
return cmp.Compare(a.squaredDistance, b.squaredDistance)
|
||||||
|
})
|
||||||
|
|
||||||
|
return connections
|
||||||
|
}
|
||||||
|
|
||||||
|
func findKSmallestConnections(junctionBoxes []JunctionBox, k int) []Connection {
|
||||||
|
junctionBoxCount := len(junctionBoxes)
|
||||||
|
connectionHeap := make(ConnectionHeap, 0, k)
|
||||||
heap.Init(&connectionHeap)
|
heap.Init(&connectionHeap)
|
||||||
|
|
||||||
for i := range junctionBoxCount {
|
for i := range junctionBoxCount {
|
||||||
@@ -111,7 +130,7 @@ func PartOne(data []string) int {
|
|||||||
squaredDistance: squaredDistance,
|
squaredDistance: squaredDistance,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(connectionHeap) < targetPairs {
|
if len(connectionHeap) < k {
|
||||||
heap.Push(&connectionHeap, connection)
|
heap.Push(&connectionHeap, connection)
|
||||||
} else if connection.squaredDistance < connectionHeap[0].squaredDistance {
|
} else if connection.squaredDistance < connectionHeap[0].squaredDistance {
|
||||||
heap.Pop(&connectionHeap)
|
heap.Pop(&connectionHeap)
|
||||||
@@ -129,13 +148,32 @@ func PartOne(data []string) int {
|
|||||||
return cmp.Compare(a.squaredDistance, b.squaredDistance)
|
return cmp.Compare(a.squaredDistance, b.squaredDistance)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return connections
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseInput(filepath string) []string {
|
||||||
|
content, _ := os.ReadFile(filepath)
|
||||||
|
return strings.Split(string(content), "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func PartOne(data []string) int {
|
||||||
|
junctionBoxes := parseJunctionBoxes(data)
|
||||||
|
junctionBoxCount := len(junctionBoxes)
|
||||||
|
|
||||||
|
targetPairs := 1000
|
||||||
|
if junctionBoxCount <= 20 {
|
||||||
|
targetPairs = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
connections := findKSmallestConnections(junctionBoxes, targetPairs)
|
||||||
|
|
||||||
uf := NewUnionFind(junctionBoxCount)
|
uf := NewUnionFind(junctionBoxCount)
|
||||||
for _, connection := range connections {
|
for _, connection := range connections {
|
||||||
uf.Union(connection.firstJunctionBox, connection.secondJunctionBox)
|
uf.Union(connection.firstJunctionBox, connection.secondJunctionBox)
|
||||||
}
|
}
|
||||||
|
|
||||||
circuitSizes := make(map[int]int)
|
circuitSizes := make(map[int]int)
|
||||||
for idx := 0; idx < len(junctionBoxes); idx++ {
|
for idx := range junctionBoxes {
|
||||||
root := uf.Find(idx)
|
root := uf.Find(idx)
|
||||||
circuitSizes[root] = uf.size[root]
|
circuitSizes[root] = uf.size[root]
|
||||||
}
|
}
|
||||||
@@ -152,5 +190,21 @@ func PartOne(data []string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func PartTwo(data []string) int {
|
func PartTwo(data []string) int {
|
||||||
return 0
|
junctionBoxes := parseJunctionBoxes(data)
|
||||||
|
connections := generateAllConnections(junctionBoxes)
|
||||||
|
|
||||||
|
uf := NewUnionFind(len(junctionBoxes))
|
||||||
|
var lastConnection Connection
|
||||||
|
|
||||||
|
for _, connection := range connections {
|
||||||
|
merged, root := uf.Union(connection.firstJunctionBox, connection.secondJunctionBox)
|
||||||
|
if merged {
|
||||||
|
lastConnection = connection
|
||||||
|
if uf.size[root] == len(junctionBoxes) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return junctionBoxes[lastConnection.firstJunctionBox].X * junctionBoxes[lastConnection.secondJunctionBox].X
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user