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() next([]string{}, nodes, set.New(), cliquesChan, networks) }() 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() { next(append(R, v), P.Intersection(networks[v]), X.Intersection(networks[v]), cliquesChan, networks) P.Remove(v) X.Add(v) } }