From 15b4f24087b9d96e8aed984e690dab63c54284b3 Mon Sep 17 00:00:00 2001 From: augustin64 Date: Sun, 24 Dec 2023 10:10:09 +0100 Subject: [PATCH] Add 2023 day 24 --- 2022/day17.py | 130 +++----------------------------------------------- 2023/day24.py | 92 +++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 123 deletions(-) create mode 100755 2023/day24.py diff --git a/2022/day17.py b/2022/day17.py index 94beece..28cc57c 100755 --- a/2022/day17.py +++ b/2022/day17.py @@ -1,136 +1,20 @@ #!/usr/bin/python3 """ Jour 17 du défi Advent Of Code pour l'année 2022 - """ - -PRINT = True -ROCKS = [ - [ - ["@", "@", "@", "@"] - ], - [ - [".", "@", "."], - ["@", "@", "@"], - [".", "@", "."] - ], - [ - [".", ".", "@"], - [".", ".", "@"], - ["@", "@", "@"] - ], - [ - ["@"], - ["@"], - ["@"], - ["@"] - ], - [ - ["@", "@"], - ["@", "@"], - ] -] - +import os def read_sample(): """récupère les entrées depuis le fichier texte correspondant""" - with open('inputs/day17.txt', 'r') as f: - return f.read() - - -def print_puzzle(heights, rock, left_down_corner): - if not PRINT: - return - for i in range(len(rock)): - print("|"+"."*left_down_corner[1]+"".join(rock[i])+"."*(7-len(rock[i])-left_down_corner[1])+"|") - for i in range(left_down_corner[0]-max(heights)): - print("|"+"."*7+"|") - for i in range(max(heights)): - print("|", end="") - for j in range(len(heights)): - if heights[j] >= (max(heights)-i): - print("#", end="") - else: - print(".", end="") - print("|") - print("+"+"-"*7+"+") - print() - - -def gas_jet(direction, pos, rock, largeur): - if direction == '>': - if pos[1]+max([len(j) for j in rock]) < largeur: #Move - pos = (pos[0], pos[1]+1) - print("Move right:") - else: - print("Failed to move right:") - else: - if pos[1] > 0: #Move - pos = (pos[0], pos[1]-1) - print("Move left:") - else: - print("Failed to move left:") - return pos + filename = os.path.join(os.path.dirname(__file__ ), "inputs", "day17.txt") + with open(filename, 'r') as f: + sample = f.read().split('\n') + sample = [ i for i in sample if i != '' ] + return sample def part1(sample): """Partie 1 du défi""" - largeur = 7 - heights = [0 for i in range(largeur)] - stream_pos = 0 - for i in range(2022): - print(f"rock {i}") - rock = ROCKS[(i)%len(ROCKS)] - - left_down_corner = (max(heights)+3, 2) - falling = True - while falling: - - left_down_corner = gas_jet(sample[stream_pos%len(sample)], left_down_corner, rock, largeur) - stream_pos += 1 - - print_puzzle(heights, rock, left_down_corner) - - print("falls 1 unit:") - left_down_corner = (left_down_corner[0]-1, left_down_corner[1]) - - print_puzzle(heights, rock, left_down_corner) - # Check si en bas - if left_down_corner[0] <= 0: - falling = False - elif left_down_corner[0] <= max(heights)+1: - print("Potentially blocked") - for j in range(len(rock[0])): - print(f"trying on rock[*][{j}]") - if (len(rock)-1) - max([k for k in range(len(rock)) if rock[k][j] != '.']) + left_down_corner[0] == heights[j+left_down_corner[1]]: - falling = False - print("blocked") - break - - - if falling: - print_puzzle(heights, rock, left_down_corner) - - left_down_corner = gas_jet(sample[stream_pos%len(sample)], left_down_corner, rock, largeur) - stream_pos += 1 - - print_puzzle(heights, rock, left_down_corner) - for j in range(len(rock[0])): - (len(rock)-1) - max([k for k in range(len(rock)) if rock[k][j] != '.']) + left_down_corner[0] - print(j+left_down_corner[1], left_down_corner[0], 1+min([k for k in range(len(rock)) if rock[k][j] != '.'])) - - if heights[j+left_down_corner[1]] > left_down_corner[0] + len(rock)-(min([k for k in range(len(rock)) if rock[k][j] != '.'])): - print(heights[j+left_down_corner[1]], left_down_corner[0] + len(rock)-(min([k for k in range(len(rock)) if rock[k][j] != '.'])), "Error!") - print_puzzle(heights, rock, left_down_corner) - print(heights) - print(left_down_corner) - print(len(rock)) - print(min([k for k in range(len(rock)) if rock[k][j] != '.'])) - raise Exception - heights[j+left_down_corner[1]] = left_down_corner[0] + len(rock)-(min([k for k in range(len(rock)) if rock[k][j] != '.'])) - - print("## ignore rock:") - print_puzzle(heights, rock, left_down_corner) - return max(heights) + return NotImplementedError def part2(sample): """Partie 2 du défi""" diff --git a/2023/day24.py b/2023/day24.py new file mode 100755 index 0000000..9cad69f --- /dev/null +++ b/2023/day24.py @@ -0,0 +1,92 @@ +#!/usr/bin/python3 +""" +Jour 24 du défi Advent Of Code pour l'année 2023 +""" +import os +import z3 + +def read_sample(): + """récupère les entrées depuis le fichier texte correspondant""" + filename = os.path.join(os.path.dirname(__file__ ), "inputs", "day24.txt") + with open(filename, 'r') as f: + sample = f.read().split('\n') + sample = [ i for i in sample if i != '' ] + return sample + +class Hailstone: + def __init__(self, text): + self.px = int(text.split(" @ ")[0].split(", ")[0]) + self.py = int(text.split(" @ ")[0].split(", ")[1]) + self.pz = int(text.split(" @ ")[0].split(", ")[2]) + + self.dx = int(text.split(" @ ")[1].split(", ")[0]) + self.dy = int(text.split(" @ ")[1].split(", ")[1]) + self.dz = int(text.split(" @ ")[1].split(", ")[2]) + + def __repr__(self): + return f"{self.px}, {self.py}, {self.pz} @ {self.dx}, {self.dy}, {self.dz}" + + +def intersection(h1, h2): + try: + # ax+b + # cx+d + b, a = h1.py - (h1.px/h1.dx)*h1.dy, h1.dy/h1.dx + d, c = h2.py - (h2.px/h2.dx)*h2.dy, h2.dy/h2.dx + + x = (d - b) / (a - c) + y = a*x+b + + if (x-h1.px)/h1.dx < 0: + return None + if (x-h2.px)/h2.dx < 0: + return None + except ZeroDivisionError: + return None + + return x, y + + + +def part1(sample, left=200000000000000, right=400000000000000): + """Partie 1 du défi""" + hailstones = [Hailstone(i) for i in sample] + + count = 0 + for i in range(len(hailstones)): + for j in range(i): + res = intersection(hailstones[i], hailstones[j]) + if res is not None: + x, y = res + if left <= x and x <= right and left <= y and y <= right: + count += 1 + + return count + +def part2(sample): + """Partie 2 du défi""" + hailstones = [Hailstone(i) for i in sample] + + px, py, pz, dx, dy, dz = z3.Ints("px py pz dx dy dz") + collision = [z3.Int("t"+str(i)) for i in range(len(hailstones))] + solver = z3.Solver() + for i in range(len(hailstones)): + h = hailstones[i] + solver.add(px + dx*collision[i] == h.px + h.dx*collision[i]) + solver.add(py + dy*collision[i] == h.py + h.dy*collision[i]) + solver.add(pz + dz*collision[i] == h.pz + h.dz*collision[i]) + + solver.check() + + + return solver.model().evaluate(px + py + pz) + + +def main(): + """Fonction principale""" + sample = read_sample() + print(f"part1: {part1(sample)}") + print(f"part2: {part2(sample)}") + +if __name__ == "__main__": + main() \ No newline at end of file