2.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. # print(f"validating rule {rule} on {message}:{pos}")
  10. if rules['11'] == rule:
  11. count = 0
  12. retval = True
  13. while retval:
  14. retval, new_p = validate_message(rules, rules['42'], message, pos)
  15. if retval:
  16. pos = new_p
  17. count += 1
  18. if count < 2:
  19. return False, pos
  20. count2 = 0
  21. retval = True
  22. while retval:
  23. retval, new_p = validate_message(rules, rules['31'], message, pos)
  24. if retval:
  25. pos = new_p
  26. count2 += 1
  27. if count2 < 1 or count2 >= count:
  28. return False, pos
  29. return True, pos
  30. elif rule[0][0].startswith("\""):
  31. if pos >= len(message):
  32. return False, pos
  33. return rule[0][0][1] == message[pos], pos + 1
  34. elif len(rule) == 2:
  35. rv1, pos1 = validate_message(rules, [rule[0]], message, pos)
  36. rv2, pos2 = validate_message(rules, [rule[1]], message, pos)
  37. if rv1:
  38. return rv1, pos1
  39. elif rv2:
  40. return rv2, pos2
  41. else:
  42. return False, pos
  43. else:
  44. p = pos
  45. for x in rule[0]:
  46. rv, new_p = validate_message(rules, rules[x], message, p)
  47. if not rv:
  48. return False, new_p
  49. p = new_p
  50. return True, p
  51. part = 0
  52. rules = {}
  53. messages = []
  54. for c in content:
  55. if not c:
  56. part += 1
  57. continue
  58. if part == 0: # parsing rules
  59. name, rule = parse_rule(c)
  60. rules[name] = rule
  61. if part == 1: # reading messages
  62. messages.append(c)
  63. retval = 0
  64. for m in messages:
  65. rv, pos = validate_message(rules, rules['11'], m, 0)
  66. if rv and pos == len(m):
  67. print(m)
  68. retval += 1
  69. print(retval)