#!/usr/bin/env python3 import re, sys ''' {'0': [['4', '1', '5']], '1': [['2', '3'], ['3', '2']], '2': [['4', '4'], ['5', '5']], '3': [['4', '5'], ['5', '4']], '4': [['"a"']], '5': [['"b"']]} ''' def regex(rules, n, d=0): #print(' '*d, n) if d > 100: # approx length of strings, way overkill return '' if type(n) == str: if not n[0] == '"': # 42 ret = regex(rules, rules[n], d+1) else: # "a" ret = n[1] elif type(n) == list: if type(n[0]) == list: # [[x,y],[u,v]]; always OR ret = '(' + '|'.join([regex(rules, r, d+1) for r in n]) + ')' elif type(n[0]) == str: # [x,y]; always AND ret = ''.join([regex(rules, r, d+1) for r in n]) else: ret = 'OMG? %s' % n else: ret = 'WTF? %s' % n return ret def mkrule(l): me, rest = l.split(': ') rest = [[side for side in n.split(' ')] for n in rest.split(' | ')] print(me,rest) q = re.findall(r'(.*): | (.*)( \| |$)', l) print(q) return me, rest def mkthing(l): return l fn = sys.argv[1] if len(sys.argv) > 1 else 'input%s' % 19 with open(fn) as f: header, footer = f.read().split('\n\n') rules = {a: b for a, b in (mkrule(l) for l in header.strip().split('\n'))} zero = regex(rules, '0') r = re.compile('^' + zero + '$') things = [mkthing(l) for l in footer.strip().split('\n')] #for t in things: # print('GOOD' if r.match(t) else 'FAIL', t) print(sum(1 for t in things if r.match(t))) _, rules['8'] = mkrule('8: 42 | 42 8') _, rules['11'] = mkrule('11: 42 31 | 42 11 31') zero = regex(rules, '0') r = re.compile('^' + zero + '$') print(sum(1 for t in things if r.match(t)))