My solutions for Advent of Code.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
adventofcode/2020/19.py

105 lines
2.4 KiB

#!/usr/bin/env python
from aoc import get_input # AoC
import re
from functools import lru_cache
data = get_input(19)
rules = data.split("\n\n")[0].split("\n")
messages = data.split("\n\n")[1].split("\n")
rulePrim = dict()
for i, rule in enumerate(rules): # make a dict for the rules
index, val = re.split(r": ", rule)
rulePrim[int(index)] = val.replace('"', "")
#print(rulePrim)
@lru_cache
def containsPointers(ruleStr): # function to check if a rule contains a pointer
return any(char.isnumeric() for char in ruleStr)
@lru_cache
def getPointersAtPos(string, starti=0):
thing = set(re.findall( r"\d+", string[starti:] ))
return thing
# @lru_cache
# def genRegex(rule, newrule=None, pointers=None):
# #for rule, cont in rulePrim.items(): # replace everything with the chars instead of pointers
# #print("New rec")
# newrule = newrule or rulePrim[rule]
# print("NEW REC")
# pointers = pointers or getPointersAtPos(newrule)
# for i, pointer in enumerate(pointers):
# pointsTo = rulePrim[int(pointer)]
# repl = f"({rulePrim[int(pointer)]})"
# #print(f"Checking pointer {i}/{len(pointers)-1}", end="\r")
# newrule = newrule.replace(str(pointer), repl)
# #print("")
# check = getPointersAtPos(newrule)
# if(len(check) > 0):
# return genRegex(rule, newrule)
# else:
# return newrule
@lru_cache
def genRegex(rule):
cont = rulePrim[rule]
cont = cont.split(" ")
reg = "("
for char in cont:
ispointer = char.isnumeric()
if( ispointer ):
reg += genRegex(int(char))
else:
reg += char
reg += ")"
return reg
def removeSpaces(rule):
# remove spaces because they are evil
cont = rulePrim[rule]
print("########################", cont)
rulePrim[rule] = cont.replace(" ", "")
rulePrim[rule] = "^" + rulePrim[rule] + "$"
return rulePrim[rule]
# go through all messages and check
def part1(rulePrim, messages):
count = 0
mesLen = len(messages)
for i, message in enumerate(messages):
check = re.match(rulePrim[0], message)
print(f"Checking {message} [{i}/{mesLen}]")
if(check):
print("is valid")
count += 1
print("Part1:", count)
rulePrim[8] = "42 | 42 8"
rulePrim[11] = "42 31 | 42 11 31"
rulePrim[0] = genRegex(0)
print(rulePrim[0])
rulePrim[0] = removeSpaces(0)
part1(rulePrim, messages)