1.py 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. with open("input") as f:
  2. content = [x.strip() for x in f]
  3. def parse_rule(rule):
  4. name, rule = rule.split(": ")
  5. rules = rule.split(" | ")
  6. rules = [x.split(" ") for x in rules]
  7. return name, rules
  8. def validate_message(rules, rule, message, pos):
  9. if rule[0][0].startswith("\""):
  10. return rule[0][0][1] == message[pos], pos + 1
  11. elif len(rule) == 2:
  12. rv1, pos1 = validate_message(rules, [rule[0]], message, pos)
  13. rv2, pos2 = validate_message(rules, [rule[1]], message, pos)
  14. if rv1:
  15. return rv1, pos1
  16. elif rv2:
  17. return rv2, pos2
  18. else:
  19. return False, pos
  20. else:
  21. p = pos
  22. for x in rule[0]:
  23. rv, new_p = validate_message(rules, rules[x], message, p)
  24. if not rv:
  25. return False, pos
  26. p = new_p
  27. return True, p
  28. part = 0
  29. rules = {}
  30. messages = []
  31. for c in content:
  32. if not c:
  33. part += 1
  34. continue
  35. if part == 0: # parsing rules
  36. name, rule = parse_rule(c)
  37. rules[name] = rule
  38. if part == 1: # reading messages
  39. messages.append(c)
  40. retval = 0
  41. for m in messages:
  42. rv, pos = validate_message(rules, rules['0'], m, 0)
  43. if rv and pos == len(m):
  44. retval += 1
  45. print(retval)