aoc2024/day-23/internal/two/solve.go

81 lines
1.5 KiB
Go
Raw Normal View History

2024-12-23 19:56:13 +00:00
package two
import (
"bytes"
"slices"
"strings"
"sync"
"github.com/onyx-and-iris/aoc2024/day-23/internal/set"
log "github.com/sirupsen/logrus"
)
func Solve(buf []byte) (string, error) {
r := bytes.NewReader(buf)
connections, err := parseLines(r)
if err != nil {
return "", err
}
networks := make(map[string]*set.Set)
nodes := set.New()
for _, connection := range connections {
if _, found := networks[connection[0]]; !found {
networks[connection[0]] = set.New()
}
networks[connection[0]].Add(connection[1])
if _, found := networks[connection[1]]; !found {
networks[connection[1]] = set.New()
}
networks[connection[1]].Add(connection[0])
nodes.Add(connection[0])
nodes.Add(connection[1])
}
cliquesChan := make(chan clique)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
2024-12-23 20:02:00 +00:00
next([]string{}, nodes, set.New(), cliquesChan, networks)
2024-12-23 19:56:13 +00:00
}()
go func() {
wg.Wait()
close(cliquesChan)
}()
var maxLen int
var maxLenClique []string
for c := range cliquesChan {
if c.Len() > maxLen {
maxLen = c.Len()
maxLenClique = c.sorted()
log.Debug(c)
}
}
return strings.Join(maxLenClique, ","), nil
}
func next(
R []string,
P, X *set.Set,
cliquesChan chan<- clique,
networks map[string]*set.Set,
) {
if P.Size() == 0 && X.Size() == 0 {
cliquesChan <- clique{slices.Clone(R)}
return
}
for _, v := range P.List() {
2024-12-23 23:17:10 +00:00
next(append(R, v), P.Intersection(networks[v]), X.Intersection(networks[v]), cliquesChan, networks)
2024-12-23 19:56:13 +00:00
P.Remove(v)
X.Add(v)
}
}