This commit is contained in:
2025-02-14 15:14:03 +00:00
parent a529516bab
commit 759b9c9544
23 changed files with 11146 additions and 6 deletions

242
2024/go/day23/day23.go Normal file
View File

@@ -0,0 +1,242 @@
package day23
import (
"fmt"
"regexp"
"sort"
"strings"
)
type Lan struct {
nodes []*Node
}
type Node struct {
key string
adjacent []*Node
loops [][]*Node
}
func Part1(input string) int {
total := 0
lan := &Lan{}
pattern := `^([a-z]{2})-([a-z]{2})$`
re := regexp.MustCompile(pattern)
lines := strings.Split(input, "\n")
for _, line := range lines {
matches := re.FindAllStringSubmatch(line, -1)
for _, match := range matches {
lan.AddNode(match[1])
lan.AddNode(match[2])
lan.AddConnection(match[1], match[2])
lan.AddConnection(match[2], match[1])
}
}
for _, node := range lan.nodes {
if node.key[0] == 't' {
connections := node.adjacent
for _, connection := range connections {
c := lan.getNode(connection.key)
for _, n1 := range c.adjacent {
for _, n2 := range connections {
if n1.key == n2.key {
already_found := false
for _, loop := range node.loops {
if contains(loop, c.key) && contains(loop, n2.key) {
already_found = true
break
}
}
for _, loop := range c.loops {
if contains(loop, node.key) && contains(loop, n2.key) {
already_found = true
break
}
}
for _, loop := range n2.loops {
if contains(loop, c.key) && contains(loop, node.key) {
already_found = true
break
}
}
if !already_found {
already_found = true
total++
loop := make([]*Node, 0)
loop = append(loop, node)
loop = append(loop, c)
loop = append(loop, n2)
node.loops = append(node.loops, loop)
fmt.Printf("%v,%v,%v\n", node.key, c.key, n2.key)
}
}
}
}
}
}
}
lan.Print()
t := 0
for _, node := range lan.nodes {
if node.key[0] == 't' {
t += len(node.loops)
fmt.Printf("Node: %v\n", node.key)
for _, loop := range node.loops {
for _, n := range loop {
fmt.Printf(" %v ", n.key)
}
fmt.Println()
}
}
}
fmt.Printf("Total: %d\n", t)
return total
}
func Part2(input string) int {
total := 0
lan := &Lan{}
pattern := `^([a-z]{2})-([a-z]{2})$`
re := regexp.MustCompile(pattern)
lines := strings.Split(input, "\n")
for _, line := range lines {
matches := re.FindAllStringSubmatch(line, -1)
for _, match := range matches {
lan.AddNode(match[1])
lan.AddNode(match[2])
lan.AddConnection(match[1], match[2])
lan.AddConnection(match[2], match[1])
}
}
for _, node := range lan.nodes {
connections := node.adjacent
for _, connection := range connections {
c := lan.getNode(connection.key)
for _, n1 := range c.adjacent {
for _, n2 := range connections {
if n1.key == n2.key {
already_found := false
for _, loop := range node.loops {
if contains(loop, c.key) && contains(loop, n2.key) {
already_found = true
break
}
}
for _, loop := range c.loops {
if contains(loop, node.key) && contains(loop, n2.key) {
already_found = true
break
}
}
for _, loop := range n2.loops {
if contains(loop, c.key) && contains(loop, node.key) {
already_found = true
break
}
}
if !already_found {
already_found = true
total++
loop := make([]*Node, 0)
loop = append(loop, node)
loop = append(loop, c)
loop = append(loop, n2)
node.loops = append(node.loops, loop)
fmt.Printf("%v,%v,%v\n", node.key, c.key, n2.key)
}
}
}
}
}
}
lan.Print()
maxLoop := 0
var maxNode *Node
for _, node := range lan.nodes {
if len(node.loops) > maxLoop {
maxLoop = len(node.loops)
maxNode = node
}
}
fmt.Printf("Max: %d\n", len(maxNode.loops))
nodeList := make([]*Node, 0)
keyList := make([]string, 0)
for _, loop := range maxNode.loops {
for _, l := range loop {
if !contains(nodeList, l.key) {
nodeList = append(nodeList, l)
keyList = append(keyList, l.key)
}
}
}
sort.Strings(keyList)
fmt.Println(strings.Join(keyList, ","))
return len(nodeList)
}
func (g *Lan) AddNode(key string) {
if !contains(g.nodes, key) {
g.nodes = append(g.nodes, &Node{key: key})
}
}
func (g *Lan) AddConnection(from, to string) {
fromNode := g.getNode(from)
toNode := g.getNode(to)
if fromNode == nil || toNode == nil {
err := fmt.Errorf("Error: Invalid edge (%v --> %v)", from, to)
fmt.Println(err.Error())
} else if contains(fromNode.adjacent, to) {
err := fmt.Errorf("Error: Existing edge (%v --> %v)", from, to)
fmt.Println(err.Error())
} else {
fromNode.adjacent = append(fromNode.adjacent, toNode)
}
}
func (g *Lan) getNode(key string) *Node {
for i, v := range g.nodes {
if v.key == key {
return g.nodes[i]
}
}
return nil
}
func (g *Lan) Print() {
for _, v := range g.nodes {
fmt.Printf("\nNode %v : ", v.key)
for _, v := range v.adjacent {
fmt.Printf(" %v ", v.key)
}
fmt.Println()
for _, loop := range v.loops {
for _, v := range loop {
if v != nil {
fmt.Printf(" %v ", v.key)
}
}
fmt.Println()
}
}
}
func contains(list []*Node, key string) bool {
for _, v := range list {
if key == v.key {
return true
}
}
return false
}

View File

@@ -0,0 +1,79 @@
package day23
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1(`kh-tc
qp-kh
de-cg
ka-co
yn-aq
qp-ub
cg-tb
vc-aq
tb-ka
wh-tc
yn-cg
kh-ub
ta-co
de-co
tc-td
tb-wq
wh-td
ta-ka
td-qp
aq-cg
wq-ub
ub-vc
de-ta
wq-aq
wq-vc
wh-yn
ka-de
kh-ta
co-tc
wh-qp
tb-vc
td-yn`)
require.Equal(t, 7, r)
}
func TestPart2(t *testing.T) {
r := Part2(`kh-tc
qp-kh
de-cg
ka-co
yn-aq
qp-ub
cg-tb
vc-aq
tb-ka
wh-tc
yn-cg
kh-ub
ta-co
de-co
tc-td
tb-wq
wh-td
ta-ka
td-qp
aq-cg
wq-ub
ub-vc
de-ta
wq-aq
wq-vc
wh-yn
ka-de
kh-ta
co-tc
wh-qp
tb-vc
td-yn`)
require.Equal(t, "co,de,ka,ta", r)
}

3380
2024/go/day23/input.txt Normal file

File diff suppressed because it is too large Load Diff