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()