code.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "strings"
  8. )
  9. func readInput(file *os.File) map[string][]string {
  10. scanner := bufio.NewScanner(file)
  11. devices := make(map[string][]string)
  12. for scanner.Scan() {
  13. line := scanner.Text()
  14. if line == "" {
  15. continue
  16. }
  17. parts := strings.Split(line, ": ")
  18. if len(parts) < 2 {
  19. log.Fatalf("Bad input: %s", line)
  20. }
  21. name := parts[0]
  22. connections := strings.Split(parts[1], " ")
  23. devices[name] = connections
  24. }
  25. return devices
  26. }
  27. func part1(entry string, devices map[string][]string) int {
  28. if entry == "out" {
  29. return 1
  30. }
  31. var count int
  32. for _, device := range devices[entry] {
  33. count += part1(device, devices)
  34. }
  35. return count
  36. }
  37. func passedDACandFFT(path []string) bool {
  38. var dac, fft bool
  39. for i := range path {
  40. if path[i] == "dac" {
  41. dac = true
  42. }
  43. if path[i] == "fft" {
  44. fft = true
  45. }
  46. }
  47. return dac && fft
  48. }
  49. func part2(entry string, devices map[string][]string) int {
  50. var count int
  51. visited := make(map[string]bool)
  52. path := []string{}
  53. var dfs func(current string)
  54. dfs = func(current string) {
  55. path = append(path, current)
  56. visited[current] = true
  57. defer func() {
  58. path = path[:len(path)-1]
  59. visited[current] = false
  60. }()
  61. if current == "out" {
  62. if passedDACandFFT(path) {
  63. count++
  64. }
  65. return
  66. } else {
  67. for _, neighbor := range devices[current] {
  68. if !visited[neighbor] {
  69. dfs(neighbor)
  70. }
  71. }
  72. }
  73. }
  74. dfs(entry)
  75. return count
  76. }
  77. func main() {
  78. if len(os.Args) < 2 {
  79. log.Fatal("You need to specify a file!")
  80. }
  81. filePath := os.Args[1]
  82. file, err := os.Open(filePath)
  83. if err != nil {
  84. log.Fatalf("Failed to open %s!\n", filePath)
  85. }
  86. devices := readInput(file)
  87. fmt.Println("Part1:", part1("you", devices))
  88. fmt.Println("Part2:", part2("svr", devices))
  89. }