package main import "sync" // returns the number of unique nodes (reducing multiple nodes with different directions to one) func uniqueNodes(move *mover) int { uniqueCoords := []coords{} for _, node := range move.nodes { if !coordInCoords(node.coords, uniqueCoords) { uniqueCoords = append(uniqueCoords, node.coords) } } return len(uniqueCoords) } // spawn invoked a single runner with a single mover func spawn(i, j, direction int, lines []string) int { m := newMover(newNode(i, j, direction)) runner(m, lines) return uniqueNodes(m) } var wg sync.WaitGroup // two returns the highest energized value for any beam spawn point/direction func two(lines []string) int { res := 0 n := 0 for i := 0; i < len(lines[0]); i++ { wg.Add(1) go func(x int) { defer wg.Done() n = spawn(x, 0, S, lines) if n > res { res = n } }(i) wg.Add(1) go func(x int) { defer wg.Done() n = spawn(x, len(lines[0])-1, N, lines) if n > res { res = n } }(i) } for i := 0; i < len(lines); i++ { wg.Add(1) go func(y int) { defer wg.Done() n = spawn(0, y, E, lines) if n > res { res = n } }(i) wg.Add(1) go func(y int) { defer wg.Done() n = spawn(len(lines[0])-1, y, W, lines) if n > res { res = n } }(i) } wg.Wait() return res }