Add 2023 day 24
This commit is contained in:
parent
ee031bdf67
commit
15b4f24087
130
2022/day17.py
130
2022/day17.py
@ -1,136 +1,20 @@
|
||||
#!/usr/bin/python3
|
||||
"""
|
||||
Jour 17 du défi Advent Of Code pour l'année 2022
|
||||
<!-- NE FONCTIONNE PAS --!>
|
||||
"""
|
||||
|
||||
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"""
|
||||
|
92
2023/day24.py
Executable file
92
2023/day24.py
Executable file
@ -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()
|
Loading…
Reference in New Issue
Block a user