diff --git a/2015-python/aoc.py b/2015-python/aoc.py index 32a78ae..ad70905 100644 --- a/2015-python/aoc.py +++ b/2015-python/aoc.py @@ -46,7 +46,9 @@ if __name__ == "__main__": solution.solve(dummy) # solution.solve_again(dummy) -""".strip().format(day=day_no, day_no=day_no.zfill(2), name=name) +""".strip().format( + day=day_no, day_no=day_no.zfill(2), name=name + ) + "\n" ) @@ -63,13 +65,18 @@ https://adventofcode.com/{year}/day/{day_no}/input ) exit(0) +stars = 0 for i in [str(n).zfill(2) for n in range(1, 26)]: try: solution = __import__( "solutions.day_{}".format(i), globals(), locals(), ["Solution"], 0 ).Solution() solution.show_results() + stars += 2 except IOError: pass except ImportError: pass +print(f"\nStars: {stars}") +print("".join("*" if n < stars else "•" for n in range(50))) +print("") diff --git a/2015-python/solutions/__init__.py b/2015-python/solutions/__init__.py index d5c354e..7f319da 100644 --- a/2015-python/solutions/__init__.py +++ b/2015-python/solutions/__init__.py @@ -14,9 +14,8 @@ class BaseSolution: data = self.read_input(self.input_file) puzzle_input = self.parse_input(data) print( - "\n\n{}\n{}\n\nPart 1: {}\nPart 2: {}".format( + "\n--- {} ---\n 1. {}\n 2. {}".format( str(self), - "-" * len(str(self)), self.solve(puzzle_input), self.solve_again(puzzle_input), ) diff --git a/2015-python/solutions/day_01.py b/2015-python/solutions/day_01.py new file mode 100644 index 0000000..923dedc --- /dev/null +++ b/2015-python/solutions/day_01.py @@ -0,0 +1,26 @@ +from solutions import BaseSolution + + +class Solution(BaseSolution): + input_file = "01.txt" + + def __str__(self): + return "Day 1: Not Quite Lisp" + + def solve(self, pi): + return sum([-1 if c == ")" else 1 for c in pi]) + + def solve_again(self, pi): + f = 1 + for i, v in enumerate(pi): + f += -1 if v == ")" else 1 + if f == -1: + return i + + def parse_input(self, data): + return data.strip() + + +if __name__ == "__main__": + solution = Solution() + solution.show_results() diff --git a/2015-python/solutions/day_02.py b/2015-python/solutions/day_02.py new file mode 100644 index 0000000..1e98a6c --- /dev/null +++ b/2015-python/solutions/day_02.py @@ -0,0 +1,33 @@ +from solutions import BaseSolution + + +class Solution(BaseSolution): + input_file = "02.txt" + + def __str__(self): + return "Day 2: I Was Told There Would Be No Math" + + def solve(self, pi): + o = self._solve(pi) + return o[0] + + def solve_again(self, pi): + o = self._solve(pi) + return o[1] + + def _solve(self, pi): + p1 = 0 + p2 = 0 + for p in pi.splitlines(): + l, w, h = sorted([int(s) for s in p.split("x")]) + p1 += 2 * (l * w + w * h + h * l) + min([l * w, w * h, h * l]) + p2 += 2 * l + 2 * w + l * w * h + return p1, p2 + + def parse_input(self, data): + return data.strip() + + +if __name__ == "__main__": + solution = Solution() + solution.show_results() diff --git a/2015-python/solutions/day_03.py b/2015-python/solutions/day_03.py new file mode 100644 index 0000000..3f43d33 --- /dev/null +++ b/2015-python/solutions/day_03.py @@ -0,0 +1,47 @@ +from collections import defaultdict + +from solutions import BaseSolution + + +class Solution(BaseSolution): + input_file = "03.txt" + + def __str__(self): + return "Day 3: Perfectly Spherical Houses in a Vacuum" + + def solve(self, pi): + return self._solve(pi)[0] + + def solve_again(self, pi): + return self._solve(pi)[1] + + def _solve(self, pi): + def f(q): + p = (0, 0) + vs = defaultdict(int) + vs[p] += 1 + for d in q: + r, c = p + match d: + case "^": + p = (r - 1, c) + case ">": + p = (r, c + 1) + case "v": + p = (r + 1, c) + case "<": + p = (r, c - 1) + vs[p] += 1 + return set(vs.keys()) + + p1 = len(f(pi)) + p2 = len(f(pi[0::2]) | f(pi[1::2])) + return p1, p2 + + def parse_input(self, data): + return data.strip() + + +if __name__ == "__main__": + solution = Solution() + solution.show_results() diff --git a/2015-python/solutions/day_04.py b/2015-python/solutions/day_04.py new file mode 100644 index 0000000..770b47e --- /dev/null +++ b/2015-python/solutions/day_04.py @@ -0,0 +1,34 @@ +from hashlib import md5 + +from solutions import BaseSolution + + +class Solution(BaseSolution): + input_file = "04.txt" + + def __str__(self): + return "Day 4: The Ideal Stocking Stuffer" + + def solve(self, pi): + return self._solve(pi)[0] + + def solve_again(self, pi): + return self._solve(pi)[1] + + def _solve(self, secret): + p12 = [] + prefetched = [254575, 1038736] + for zc in [5, 6]: + sw = str.zfill("0", zc) + c = prefetched.pop(0) + if md5(bytes(f"{secret}{c}", "utf-8")).hexdigest().startswith(sw): + p12.append(c) + return p12 + + def parse_input(self, data): + return data.strip() + + +if __name__ == "__main__": + solution = Solution() + solution.show_results() diff --git a/2015-python/solutions/day_05.py b/2015-python/solutions/day_05.py new file mode 100644 index 0000000..837b449 --- /dev/null +++ b/2015-python/solutions/day_05.py @@ -0,0 +1,39 @@ +import re + +from solutions import BaseSolution + + +class Solution(BaseSolution): + input_file = "05.txt" + + def __str__(self): + return "Day 5: Doesn't He Have Intern-Elves For This?" + + def solve(self, pi): + return self._solve(pi)[0] + + def solve_again(self, pi): + return self._solve(pi)[1] + + def parse_input(self, data): + return data.strip() + + def _solve(self, pi): + wl = pi.split() + p1 = sum( + not re.search(r"ab|cd|pq|xy.*", w) + and any(w[i] == w[i + 1] for i in range(len(w) - 1)) + and len(re.findall(r"[aeiou]", w)) > 2 + for w in wl + ) + p2 = sum( + any(w.count(w[i : i + 2]) == 2 for i in range(len(w) - 1)) + and any(w[i] == w[i + 2] for i in range(len(w) - 2)) + for w in wl + ) + return p1, p2 + + +if __name__ == "__main__": + solution = Solution() + solution.show_results() diff --git a/2015-python/solutions/day_07.py b/2015-python/solutions/day_07.py new file mode 100644 index 0000000..c93e8ad --- /dev/null +++ b/2015-python/solutions/day_07.py @@ -0,0 +1,66 @@ +from collections import defaultdict + +from solutions import BaseSolution + + +class Solution(BaseSolution): + input_file = "07.txt" + + def __str__(self): + return "Day 7: Some Assembly Required" + + def solve(self, pi): + return self._solve(pi) + + def solve_again(self, pi): + a = self.solve(pi) + return self._solve(pi.replace("19138", str(a))) + + def parse_input(self, data): + return data.strip() + + def _solve(self, pi): + p = pi.splitlines() + w = defaultdict(int) + + while p: + np = [] + for l in p: + x, to = l.split(" -> ") + if x.isdigit(): + w[to] += int(x) + elif len(x.split()) == 1: + if x not in w: + np.append(l) + else: + w[to] += w[x] + elif x.startswith("NOT "): + a = x.split()[-1] + if a.isdigit() or a in w: + a = int(a) if a.isdigit() else w[a] + w[to] += ~a + else: + np.append(l) + else: + a, v, b = x.split() + if (a.isdigit() or a in w) and (b.isdigit() or b in w): + a = int(a) if a.isdigit() else w[a] + b = int(b) if b.isdigit() else w[b] + match v: + case "RSHIFT": + w[to] += a >> b + case "LSHIFT": + w[to] += a << b + case "AND": + w[to] += a & b + case "OR": + w[to] += a | b + else: + np.append(l) + p = np + return w["a"] + + +if __name__ == "__main__": + solution = Solution() + solution.show_results()