2023 Complete!

This commit is contained in:
Brian Buller 2023-12-28 13:48:29 -06:00
parent bdba3a2268
commit 6578d5123f
3 changed files with 196 additions and 8 deletions

View File

@ -2,21 +2,186 @@ package main
import ( import (
"fmt" "fmt"
"math/rand"
"strings"
h "git.bullercodeworks.com/brian/adventofcode/helpers" h "git.bullercodeworks.com/brian/adventofcode/helpers"
) )
type component struct {
id string
connections map[string]component
conns map[string]bool
}
type components struct {
all map[string]component
edges []connections
}
type connections struct {
from, to string
track []string
}
func main() { func main() {
inp := h.StdinToStringSlice() lines := h.StdinToStringSlice()
part1(inp)
fmt.Println() var comps components
part2(inp) var edges []connections
var counter int
var tries int
for tries < 100 {
counter = 0
for {
counter++
compsS := components{all: make(map[string]component)}
for _, line := range lines {
connect(&compsS, line)
}
cc := minCut(compsS)
cuts := len(cc.edges)
edges = cc.edges
comps = compsS
if cuts == 3 {
break
}
if counter >= 100 {
break
}
}
tries++
if counter < 100 {
break
}
}
total := cutInGroups(&comps, edges)
fmt.Println(total)
} }
func part1(inp []string) { func connect(comps *components, line string) {
fmt.Println("# Part 1") split := strings.Split(line, ": ")
nodeName := split[0]
connectionsNames := strings.Split(split[1], " ")
node := component{id: nodeName, connections: make(map[string]component), conns: make(map[string]bool)}
if _, ok := comps.all[nodeName]; !ok {
comps.all[nodeName] = node
}
for _, neighborName := range connectionsNames {
neighbor := component{id: neighborName, connections: make(map[string]component), conns: make(map[string]bool)}
if _, ok := comps.all[neighborName]; !ok {
comps.all[neighborName] = neighbor
}
comps.all[nodeName].connections[neighborName] = neighbor
comps.all[nodeName].conns[neighborName] = true
comps.all[neighborName].connections[nodeName] = node
comps.all[neighborName].conns[nodeName] = true
comps.edges = append(comps.edges, connections{
from: nodeName,
to: neighborName,
track: []string{nodeName, neighborName},
})
}
} }
func part2(inp []string) { func minCut(comps components) components {
fmt.Println("# Part 2") cc := components{
all: make(map[string]component),
edges: comps.edges,
}
for key, val := range comps.all {
cc.all[key] = val
}
for len(cc.all) > 2 {
u, v := randomComps(&cc)
contract(&cc, u, v)
}
return cc
}
func randomComps(comps *components) (component, component) {
randomN := rand.Intn(len(comps.edges))
edge := comps.edges[randomN]
comps.edges = append(comps.edges[:randomN], comps.edges[randomN+1:]...)
randCorn := rand.Intn(2)
var nameU, nameV string
if randCorn == 0 {
nameU = edge.from
nameV = edge.to
} else {
nameU = edge.to
nameV = edge.from
}
u, v := comps.all[nameU], comps.all[nameV]
return u, v
}
func contract(comps *components, u component, v component) {
delete(comps.all, v.id)
delete(comps.all[u.id].connections, v.id)
for _, node := range comps.all {
if _, ok := node.connections[v.id]; ok {
delete(node.connections, v.id)
node.connections[u.id] = u
comps.all[u.id].connections[node.id] = node
}
}
for i := 0; i < len(comps.edges); {
if comps.edges[i].from == v.id {
comps.edges[i].from = u.id
}
if comps.edges[i].to == v.id {
comps.edges[i].to = u.id
}
if comps.edges[i].from == comps.edges[i].to {
comps.edges = append(comps.edges[:i], comps.edges[i+1:]...)
continue
}
i++
}
}
func cutInGroups(comps *components, edges []connections) int {
var final1, final2 string
for i, edge := range edges {
cut1 := edge.track[0]
cut2 := edge.track[1]
delete(comps.all[cut1].conns, cut2)
delete(comps.all[cut2].conns, cut1)
if i == len(edges)-1 {
final1 = cut1
final2 = cut2
}
}
group1 := countN(comps, final1)
group2 := countN(comps, final2)
return group1 * group2
}
func countN(comps *components, start string) int {
visited := make(map[string]bool)
counter := 0
entry := start
path := []string{entry}
for len(path) > 0 {
currentPath := path[0]
path = path[1:]
if _, ok := visited[currentPath]; ok {
continue
}
counter++
currentcomponent := comps.all[currentPath]
visited[currentPath] = true
for key := range currentcomponent.conns {
if _, ok := visited[key]; ok {
continue
}
path = append(path, key)
}
}
return counter
} }

13
2023/day25/testinput Normal file
View File

@ -0,0 +1,13 @@
jqt: rhn xhk nvd
rsh: frs pzl lsr
xhk: hfx
cmg: qnr nvd lhk bvb
rhn: xhk bvb hfx
bvb: xhk hfx
pzl: lsr hfx nvd
qnr: nvd
ntq: jqt hfx bvb xhk
nvd: lhk
lsr: lhk
rzs: qnr cmg lsr rsh
frs: qnr lhk lsr

View File

@ -1,5 +1,7 @@
package aoc package aoc
import "fmt"
type Queue[T any] struct { type Queue[T any] struct {
items []T items []T
} }
@ -80,3 +82,11 @@ func (q *Queue[T]) Insert(item T, location int) {
func (q *Queue[T]) InsertVector(items []T, location int) { func (q *Queue[T]) InsertVector(items []T, location int) {
q.items = append(q.items[:location], append(items, q.items[location:]...)...) q.items = append(q.items[:location], append(items, q.items[location:]...)...)
} }
func (q Queue[T]) String() string {
res := "[ "
for i := range q.items {
res = fmt.Sprintf("%s %v", res, q.items[i])
}
return fmt.Sprintf("%s ]", res)
}