main.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package main
  2. import (
  3. "bufio"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "log"
  8. "os"
  9. "strconv"
  10. "strings"
  11. )
  12. const MAX_LOOP = 1_000_000
  13. var (
  14. MAX_INT int = int(^uint(0) >> 1)
  15. INT_SZ int = 0
  16. )
  17. func init() {
  18. tmp := MAX_INT
  19. for tmp > 0 {
  20. INT_SZ++
  21. tmp >>= 1
  22. }
  23. }
  24. func trim(bs []byte) []byte {
  25. last := len(bs) - 1
  26. if last >= 0 && bs[last] == '\n' {
  27. return bs[:last]
  28. }
  29. return bs
  30. }
  31. func main() {
  32. rules := make(map[string][]string)
  33. validUpdates := make([][]string, 0, 16)
  34. r := bufio.NewReader(os.Stdin)
  35. var fs []string
  36. // Read rules
  37. for i := 0; i < MAX_LOOP; i++ {
  38. line, err := r.ReadString('\n')
  39. if errors.Is(err, io.EOF) {
  40. break
  41. }
  42. if err != nil {
  43. log.Fatalf("While reading rule %#v: %v", line, err)
  44. }
  45. line = string(trim([]byte(line)))
  46. if line == "" {
  47. break
  48. }
  49. fs = strings.SplitN(line, "|", 2)
  50. if len(fs) != 2 {
  51. log.Fatalf("Unexpected format for rule %#v", line)
  52. }
  53. if _, ok := rules[fs[1]]; !ok {
  54. rules[fs[1]] = make([]string, 0, 8)
  55. }
  56. rules[fs[1]] = append(rules[fs[1]], fs[0])
  57. }
  58. // Read updates
  59. for i := 0; i < MAX_LOOP; i++ {
  60. line, err := r.ReadString('\n')
  61. if errors.Is(err, io.EOF) {
  62. break
  63. }
  64. if err != nil {
  65. log.Fatalf("While reading update %#v: %v", line, err)
  66. }
  67. line = string(trim([]byte(line)))
  68. if line == "" {
  69. continue
  70. }
  71. fs = strings.Split(line, ",")
  72. if len(fs) == 0 {
  73. log.Fatalf("Unexpected format for update %#v", line)
  74. }
  75. forbidden := make(map[string]struct{})
  76. var invalid bool
  77. for _, f := range fs {
  78. if _, ok := forbidden[f]; ok {
  79. invalid = true
  80. break
  81. }
  82. for _, r := range rules[f] {
  83. forbidden[r] = struct{}{}
  84. }
  85. }
  86. if invalid {
  87. continue
  88. }
  89. validUpdates = append(validUpdates, fs)
  90. }
  91. // Sum middle numbers of valid updates
  92. sum := 0
  93. for _, u := range validUpdates {
  94. i := len(u) >> 1
  95. u_i, err := strconv.ParseInt(u[i], 10, INT_SZ)
  96. if err != nil {
  97. log.Fatalf("Unable to parse page number %#v in update %s", u[i], strings.Join(u, ","))
  98. }
  99. sum += int(u_i)
  100. }
  101. fmt.Printf("%d\n", sum)
  102. }