aboutsummaryrefslogtreecommitdiff
path: root/2020/19
diff options
context:
space:
mode:
Diffstat (limited to '2020/19')
-rw-r--r--2020/19/.gitignore1
-rw-r--r--2020/19/Makefile8
-rwxr-xr-x2020/19/puzzle-1.py59
-rw-r--r--[-rwxr-xr-x]2020/19/puzzles.py (renamed from 2020/19/puzzle-2.py)37
4 files changed, 30 insertions, 75 deletions
diff --git a/2020/19/.gitignore b/2020/19/.gitignore
new file mode 100644
index 0000000..ffc46fe
--- /dev/null
+++ b/2020/19/.gitignore
@@ -0,0 +1 @@
+puzzle-[12].py
diff --git a/2020/19/Makefile b/2020/19/Makefile
new file mode 100644
index 0000000..247194a
--- /dev/null
+++ b/2020/19/Makefile
@@ -0,0 +1,8 @@
+all:
+ sed '/START PART 2/,/END PART 2/d' puzzles.py >puzzle-1.py
+ sed '/START PART 1/,/END PART 1/d' puzzles.py >puzzle-2.py
+ chmod +x puzzle-[12].py
+
+.PHONY: clean
+clean:
+ rm -f puzzle-[12].py
diff --git a/2020/19/puzzle-1.py b/2020/19/puzzle-1.py
deleted file mode 100755
index 8ca7eb2..0000000
--- a/2020/19/puzzle-1.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python3
-
-from collections import OrderedDict
-
-
-def main() -> None:
- with open("input", "r") as f:
- data = f.readlines()
-
- i = 0
- rules: list[tuple[str]] = []
- while data[i] != "\n":
- rules.append(tuple(x for x in tuple(data[i].split(": "))))
- i += 1
-
- tests: list[str] = []
- for line in data:
- tests.append(line.strip())
-
- patterns: dict[str, list[str]] = {}
-
- # Get "a" and "b" out of the way to do less comparisons in the next loop. Also make use of
- # this loop to strip newlines off of all the rules.
- for rule in rules:
- rules[rules.index(rule)] = (rule[0], rule[1].strip())
- if len(rule[1]) == 4:
- patterns[rule[0]] = [rule[1][1]]
-
- while len(patterns) != len(rules):
- for rule in rules:
- if rule[0] in patterns:
- continue
-
- res = rule[1].split(" | ")
- req_rules = list(OrderedDict.fromkeys(" ".join(res).split(" ")))
- all_in = True
- for req in req_rules:
- if req not in patterns:
- all_in = False
- break
- if all_in == True:
- all_combos: list[str] = []
- for re in res:
- re = re.split(" ")
- if len(re) == 1:
- all_combos.extend(patterns[re[0]])
- else:
- for x in patterns[re[0]]:
- for y in patterns[re[1]]:
- all_combos.append(f"{x}{y}")
- all_combos = list(OrderedDict.fromkeys(all_combos))
-
- patterns[rule[0]] = all_combos
-
- print(len([test for test in tests if test in patterns["0"]]))
-
-
-if __name__ == "__main__":
- main()
diff --git a/2020/19/puzzle-2.py b/2020/19/puzzles.py
index b0efe15..f2a4bcf 100755..100644
--- a/2020/19/puzzle-2.py
+++ b/2020/19/puzzles.py
@@ -1,6 +1,9 @@
#!/usr/bin/env python3
from collections import OrderedDict
+from itertools import product
+
+# START PART 2
from re import search
@@ -28,8 +31,11 @@ def string_divide(string: str, div: int) -> list[str]:
return l
+# END PART 2
+
+
def main() -> None:
- with open("input", "r") as f:
+ with open("input", "r", encoding="utf-8") as f:
data = f.readlines()
i = 0
@@ -38,10 +44,7 @@ def main() -> None:
rules.append(tuple(x for x in tuple(data[i].split(": "))))
i += 1
- tests: list[str] = []
- for line in data:
- tests.append(line.strip())
-
+ tests = [line.strip() for line in data]
patterns: dict[str, list[str]] = {}
# Get "a" and "b" out of the way to do less comparisons in the next loop. Also make use of
@@ -57,28 +60,30 @@ def main() -> None:
continue
res = rule[1].split(" | ")
- req_rules = list(OrderedDict.fromkeys(" ".join(res).split(" ")))
- all_in = True
- for req in req_rules:
- if req not in patterns:
- all_in = False
- break
- if all_in == True:
+ if all(req in patterns for req in list(OrderedDict.fromkeys(" ".join(res).split(" ")))):
all_combos: list[str] = []
for re in res:
re = re.split(" ")
if len(re) == 1:
all_combos.extend(patterns[re[0]])
else:
- for x in patterns[re[0]]:
- for y in patterns[re[1]]:
- all_combos.append(f"{x}{y}")
- all_combos = list(OrderedDict.fromkeys(all_combos))
+ all_combos = list(
+ OrderedDict.fromkeys(
+ all_combos
+ + [f"{x}{y}" for x, y in product(patterns[re[0]], patterns[re[1]])]
+ )
+ )
patterns[rule[0]] = all_combos
+ # START PART 1
+ print(len([test for test in tests if test in patterns["0"]]))
+ # END PART 1 START PART 2
print(len([test for test in tests if check(test, patterns)]))
+# END PART 2
+
+
if __name__ == "__main__":
main()