123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- 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)
- }
|