advent-of-code/2022/python/day09.py

153 lines
3.9 KiB
Python

from pprint import pprint as pp
import shared
import matrix
MATRIX_SIZE = 500
#MATRIX_SIZE = 40 # sample
HALF = MATRIX_SIZE // 2
H = [HALF,HALF]
T = [HALF,HALF]
# returns (x,y) - so remember to take dx,dy lower
DIRS = {
'U': matrix.M_U, # (0, -1)
'D': matrix.M_D,
'L': matrix.M_L,
'R': matrix.M_R,
'UR': matrix.M_UR, # (+1, -1)
'DR': matrix.M_DR,
'UL': matrix.M_UL,
'DL': matrix.M_DL,
}
def part1(steps):
field = matrix.matrix_of_size(MATRIX_SIZE,MATRIX_SIZE)
for direction, amount in steps:
# move HEAD
amount = int(amount)
for x in range(amount):
dx,dy = DIRS[direction]
H[0] += dy
H[1] += dx
HY,bX = H
# head is in new position
kY,kX = T
field[kY][kX] = 1 # 'T'
# Check if same
if kY == HY and kX == bX:
continue
touching = False
for _, d in DIRS.items():
dx,dy = d
t_y, t_x = H[0]+dy, H[1]+dx
if kY == t_y and kX == t_x:
touching = True
break
if touching:
continue
# assume the same row/column, no movement needed
tY = 0
tX = 0
# if Head X is less than Tail X, move Tail X 1 left
if bX < kX:
tX = -1
# if Head X is greater than Tail X, move Tail X 1 left
elif bX > kX:
tX = 1
# if Head Y is less than Tail Y, move Tail Y 1 up
if HY < kY:
tY = -1
# if Head Y is greater than Tail Y, move Tail Y 1 down
elif HY > kY:
tY = 1
T[0] += tY
T[1] += tX
field[T[0]][T[1]] = 1 # mark visited tails
print(matrix.sum_matrix(field))
def part2(steps):
field = matrix.matrix_of_size(MATRIX_SIZE,MATRIX_SIZE)
S = [[HALF,HALF],] # HEAD ONLY
for x in range(9):
S.append([HALF,HALF])
for direction, amount in steps:
# move HEAD
amount = int(amount)
for x in range(amount):
HEAD_dx,HEAD_dy = DIRS[direction]
S[0][0] += HEAD_dy
S[0][1] += HEAD_dx
#print(HEAD_dy,HEAD_dx, S)
# HEAD MOVED one step
for knot_idx, _ in enumerate(S):
if knot_idx == 0:
# Skip Head
continue
knot = S[knot_idx]
kY,kX = knot
bY,bX = S[knot_idx-1]
# Check if same
if kY == bY and kX == bX:
continue
touching = False
for _, d in DIRS.items():
dx,dy = d
t_y, t_x = S[knot_idx-1][0]+dy, S[knot_idx-1][1]+dx
if kY == t_y and kX == t_x:
touching = True
break
if touching:
continue
# assume the same row/column, no movement needed
tY, tX = 0,0
# if Head X is less than Tail X, move Tail X 1 left
if bX < kX:
tX = -1
# if Head X is greater than Tail X, move Tail X 1 left
elif bX > kX:
tX = 1
# if Head Y is less than Tail Y, move Tail Y 1 up
if bY < kY:
tY = -1
# if Head Y is greater than Tail Y, move Tail Y 1 down
elif bY > kY:
tY = 1
S[knot_idx][0] += tY
S[knot_idx][1] += tX
field[S[-1][0]][S[-1][1]] = 1 # mark visited tails
print(matrix.sum_matrix(field))
def main():
rows = [x.split(" ") for x in shared.load_rows(9)]
part1(rows)
part2(rows)
if __name__ == "__main__":
main()