code.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "strings"
  8. )
  9. const (
  10. AND = iota
  11. OR
  12. XOR
  13. )
  14. type Gate struct {
  15. id string
  16. left, right string
  17. op int
  18. value int
  19. }
  20. func readInput(file *os.File) (map[string]Gate, map[string]Gate) {
  21. scanner := bufio.NewScanner(file)
  22. zs := make(map[string]Gate)
  23. gates := make(map[string]Gate)
  24. readingRegisters := true
  25. for scanner.Scan() {
  26. line := scanner.Text()
  27. if line == "" {
  28. if readingRegisters {
  29. readingRegisters = false
  30. continue
  31. }
  32. break
  33. }
  34. var gate Gate
  35. if readingRegisters {
  36. parts := strings.Split(line, ": ")
  37. if len(parts) != 2 {
  38. log.Fatalf("Bad register line: %s", line)
  39. }
  40. gate.id = parts[0]
  41. n, err := fmt.Sscanf(parts[1], "%d", &gate.value)
  42. if n != 1 || err != nil {
  43. log.Fatalf("Bad input %s: %s", parts[1], err)
  44. }
  45. } else {
  46. var op string
  47. n, err := fmt.Sscanf(line, "%s %s %s -> %s", &gate.left, &op, &gate.right, &gate.id)
  48. if n != 4 || err != nil {
  49. log.Fatalf("Bad input %s: %s", line, err)
  50. }
  51. switch op {
  52. case "AND":
  53. gate.op = AND
  54. case "OR":
  55. gate.op = OR
  56. case "XOR":
  57. gate.op = XOR
  58. }
  59. gate.value = -1
  60. }
  61. if gate.id[0] == 'z' {
  62. zs[gate.id] = gate
  63. } else {
  64. gates[gate.id] = gate
  65. }
  66. }
  67. return gates, zs
  68. }
  69. func main() {
  70. if len(os.Args) < 2 {
  71. log.Fatal("You need to specify a file!")
  72. }
  73. filePath := os.Args[1]
  74. file, err := os.Open(filePath)
  75. if err != nil {
  76. log.Fatalf("Failed to open %s!\n", filePath)
  77. }
  78. gates, zs := readInput(file)
  79. fmt.Println(gates, zs)
  80. }