day 17 closer
This commit is contained in:
parent
3c195b2ea2
commit
3e822d7f55
1
2022/full/day17.txt
Normal file
1
2022/full/day17.txt
Normal file
File diff suppressed because one or more lines are too long
212
2022/python/day17.py
Normal file
212
2022/python/day17.py
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
import matrix
|
||||||
|
import shared
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Tuple
|
||||||
|
import operator
|
||||||
|
|
||||||
|
|
||||||
|
# ####
|
||||||
|
FLAT = ((0,0),(0,1),(0,2),(0,3))
|
||||||
|
# .#.
|
||||||
|
# ###
|
||||||
|
# .#.
|
||||||
|
CROSS = (
|
||||||
|
(-2,1),
|
||||||
|
(-1,0),(-1,1),(-1,2),
|
||||||
|
(0,1))
|
||||||
|
# ..#
|
||||||
|
# ..#
|
||||||
|
# ###
|
||||||
|
J = ( (-2,2),
|
||||||
|
(-1,2),
|
||||||
|
(0,0),(0,1),(0,2))
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
I = ((0,0),(-1,0),(-2,0),(-3,0))
|
||||||
|
# ##
|
||||||
|
# ##
|
||||||
|
SQUARE = (
|
||||||
|
(-1,0),(-1,1),
|
||||||
|
(0,0),(0,1),
|
||||||
|
)
|
||||||
|
|
||||||
|
ORDER = (('-',FLAT), ('+',CROSS), ('j',J), ('I',I), ('□',SQUARE))
|
||||||
|
|
||||||
|
OPS = {'>':operator.add, '<':operator.sub}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Shape:
|
||||||
|
rock:int
|
||||||
|
y:int
|
||||||
|
x:int
|
||||||
|
shape: Tuple[str,Tuple[Tuple[int,int]]] # ('j', ((0,0),....))
|
||||||
|
moving: bool = True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def char(self):
|
||||||
|
if self.moving:
|
||||||
|
return '@'
|
||||||
|
return '#'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def str(self):
|
||||||
|
return self.shape[0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def offsets(self):
|
||||||
|
return self.shape[1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def coords(self):
|
||||||
|
actual_coords = []
|
||||||
|
for y,x in self.shape[1]:
|
||||||
|
actual_coords.append((y+self.y,x+self.x))
|
||||||
|
return actual_coords
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: check left/right movement into an object
|
||||||
|
|
||||||
|
|
||||||
|
def find_highest(shapes, default_height):
|
||||||
|
if not shapes:
|
||||||
|
return default_height
|
||||||
|
all_y = []
|
||||||
|
for s in shapes:
|
||||||
|
for y,_ in s.coords:
|
||||||
|
all_y.append(y)
|
||||||
|
return min(all_y)
|
||||||
|
|
||||||
|
def all_coords(shapes):
|
||||||
|
coords = set()
|
||||||
|
for s in shapes:
|
||||||
|
for c in s.coords:
|
||||||
|
coords.add(c)
|
||||||
|
return coords
|
||||||
|
|
||||||
|
def collision_at(shapes, row, col, shape):
|
||||||
|
if shape is None:
|
||||||
|
raise Exception("Please provide a list of coordinate offsets from Y,X to draw")
|
||||||
|
|
||||||
|
# Take in all existing coordinates
|
||||||
|
for y,x in shape.coords:
|
||||||
|
if (y+row,x+col) in all_coords(shapes[:-1]):
|
||||||
|
breakpoint()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def out_of_bounds(row, col, height, width, shape=None):
|
||||||
|
if shape is None:
|
||||||
|
raise Exception("Please provide a list of coordinate offsets from Y,X to draw")
|
||||||
|
for y,x in shape:
|
||||||
|
#print(f"\t{row}+{y} > {height}\t", f"{col}+{x} > {width}\t", f"{col}+{x} < 0")
|
||||||
|
if row+y > height-1:
|
||||||
|
return True
|
||||||
|
if col+x >= width:
|
||||||
|
return True
|
||||||
|
if col+x < 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# @shared.profile
|
||||||
|
def part1(rows):
|
||||||
|
print(rows)
|
||||||
|
instructions = [r for r in rows]
|
||||||
|
height = 8
|
||||||
|
#height = 2022*4+4
|
||||||
|
width = 7
|
||||||
|
view = height - 20
|
||||||
|
|
||||||
|
rock = 0
|
||||||
|
shapes = []
|
||||||
|
spawning = True
|
||||||
|
while rock < 2:
|
||||||
|
if spawning:
|
||||||
|
print("Spawn rock #", rock)
|
||||||
|
X = 2
|
||||||
|
Y = find_highest(shapes, height) - 4
|
||||||
|
shape = Shape(rock=rock, y=Y, x=X, shape=ORDER[rock%len(ORDER)])
|
||||||
|
shapes.append(shape)
|
||||||
|
spawning = False
|
||||||
|
render(width, height, shapes)
|
||||||
|
print("~"*20)
|
||||||
|
|
||||||
|
|
||||||
|
# loop through instructions
|
||||||
|
try:
|
||||||
|
next_move = instructions.pop(0)
|
||||||
|
except IndexError:
|
||||||
|
instructions = [r for r in rows]
|
||||||
|
next_move = instructions.pop(0)
|
||||||
|
|
||||||
|
|
||||||
|
# Try to move right/left
|
||||||
|
print("Jet of gas pushes rock", next_move)
|
||||||
|
|
||||||
|
# TODO: make COLLISION_AT TAKE AN OFFSET
|
||||||
|
next_x = OPS[next_move](shapes[-1].x, 1) # Try Move left or right
|
||||||
|
if not out_of_bounds(shapes[-1].y, next_x, height, width, shapes[-1].offsets) and
|
||||||
|
not collision_at(shapes, shapes[-1].y, next_x, shape):
|
||||||
|
shapes[-1].x = next_x
|
||||||
|
else:
|
||||||
|
print("but nothing happens")
|
||||||
|
|
||||||
|
# check if hit bottom
|
||||||
|
next_y = shapes[-1].y + 1
|
||||||
|
if out_of_bounds(next_y, next_x, height, width, shapes[-1].offsets):
|
||||||
|
print("rock comes to rest")
|
||||||
|
# hit bottom dont move down
|
||||||
|
shapes[-1].moving = False
|
||||||
|
spawning = True
|
||||||
|
rock += 1
|
||||||
|
|
||||||
|
if collision_at(shapes, next_y, next_x, shape):
|
||||||
|
# Hit another Block dont move down
|
||||||
|
shapes[-1].moving = False
|
||||||
|
spawning = True
|
||||||
|
rock += 1
|
||||||
|
else:
|
||||||
|
# can move down
|
||||||
|
shapes[-1].y += 1
|
||||||
|
print("rock falls one unit")
|
||||||
|
|
||||||
|
print("-"*15)
|
||||||
|
render(width, height, shapes)
|
||||||
|
|
||||||
|
print(shapes[0], height, shapes[0].coords)
|
||||||
|
|
||||||
|
print("LAST ROCK COUNT", rock+1)
|
||||||
|
print(height - find_highest(shapes, height))
|
||||||
|
|
||||||
|
|
||||||
|
def render(width, height, shapes):
|
||||||
|
print("-"*15)
|
||||||
|
mx = matrix.matrix_of_size(width, height)
|
||||||
|
for s in shapes:
|
||||||
|
matrix.draw_shape_at(mx, s.y, s.x, s.offsets, s.char)
|
||||||
|
print(matrix.ppmx(mx,pad=False,space=False))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# @shared.profile
|
||||||
|
def part2(rows):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
rows = [row for row in shared.load_rows(17)][0]
|
||||||
|
with shared.elapsed_timer() as elapsed:
|
||||||
|
part1(rows)
|
||||||
|
print("🕒", elapsed())
|
||||||
|
with shared.elapsed_timer() as elapsed:
|
||||||
|
part2(rows)
|
||||||
|
print("🕒", elapsed())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -342,3 +342,34 @@ def highlight(matrix, red=[], green=[], blue=[], blink_green=[]):
|
|||||||
new = f"{colors.BLINK}{colors.GREEN}{mx[y][x]}{colors.ENDC}"
|
new = f"{colors.BLINK}{colors.GREEN}{mx[y][x]}{colors.ENDC}"
|
||||||
mx[y][x] = new
|
mx[y][x] = new
|
||||||
print(ppmx(mx, pad=False, space=True, zero="0"))
|
print(ppmx(mx, pad=False, space=True, zero="0"))
|
||||||
|
|
||||||
|
|
||||||
|
def draw_shape_at(mx, row, col, shape=None, value=1):
|
||||||
|
if shape is None:
|
||||||
|
raise Exception("Please provide a list of coordinate offsets from Y,X to draw")
|
||||||
|
for y,x in shape:
|
||||||
|
mx[row+y][col+x] = value
|
||||||
|
|
||||||
|
|
||||||
|
def collision_at(mx, row, col, shape=None):
|
||||||
|
if shape is None:
|
||||||
|
raise Exception("Please provide a list of coordinate offsets from Y,X to draw")
|
||||||
|
for y,x in shape:
|
||||||
|
if mx[row+y][col+x] != 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def out_of_bounds(mx, row, col, shape=None):
|
||||||
|
|
||||||
|
if shape is None:
|
||||||
|
raise Exception("Please provide a list of coordinate offsets from Y,X to draw")
|
||||||
|
height, width = get_size(mx)
|
||||||
|
for y,x in shape:
|
||||||
|
if row+y > height-1:
|
||||||
|
return True
|
||||||
|
if col+x >= width:
|
||||||
|
return True
|
||||||
|
if col+x < 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
1
2022/samples/day17.txt
Normal file
1
2022/samples/day17.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
Loading…
Reference in New Issue
Block a user