package main import ( "bufio" "errors" "fmt" "io" "log" "os" "strconv" "strings" ) const MAX_LOOP = 1_000_000 var ( MAX_INT int = int(^uint(0) >> 1) INT_SZ int = 0 ) func init() { tmp := MAX_INT for tmp > 0 { INT_SZ++ tmp >>= 1 } } func trim(bs []byte) []byte { last := len(bs) - 1 if last >= 0 && bs[last] == '\n' { return bs[:last] } return bs } func main() { rules := make(map[string][]string) validUpdates := make([][]string, 0, 16) r := bufio.NewReader(os.Stdin) var fs []string // Read rules for i := 0; i < MAX_LOOP; i++ { line, err := r.ReadString('\n') if errors.Is(err, io.EOF) { break } if err != nil { log.Fatalf("While reading rule %#v: %v", line, err) } line = string(trim([]byte(line))) if line == "" { break } fs = strings.SplitN(line, "|", 2) if len(fs) != 2 { log.Fatalf("Unexpected format for rule %#v", line) } if _, ok := rules[fs[1]]; !ok { rules[fs[1]] = make([]string, 0, 8) } rules[fs[1]] = append(rules[fs[1]], fs[0]) } // Read updates for i := 0; i < MAX_LOOP; i++ { line, err := r.ReadString('\n') if errors.Is(err, io.EOF) { break } if err != nil { log.Fatalf("While reading update %#v: %v", line, err) } line = string(trim([]byte(line))) if line == "" { continue } fs = strings.Split(line, ",") if len(fs) == 0 { log.Fatalf("Unexpected format for update %#v", line) } forbidden := make(map[string]struct{}) var invalid bool for _, f := range fs { if _, ok := forbidden[f]; ok { invalid = true break } for _, r := range rules[f] { forbidden[r] = struct{}{} } } if invalid { continue } validUpdates = append(validUpdates, fs) } // Sum middle numbers of valid updates sum := 0 for _, u := range validUpdates { i := len(u) >> 1 u_i, err := strconv.ParseInt(u[i], 10, INT_SZ) if err != nil { log.Fatalf("Unable to parse page number %#v in update %s", u[i], strings.Join(u, ",")) } sum += int(u_i) } fmt.Printf("%d\n", sum) }