diff --git a/2024/15/solution.py b/2024/15/solution.py index 7e84949..4cabbc6 100644 --- a/2024/15/solution.py +++ b/2024/15/solution.py @@ -238,7 +238,7 @@ def part2(): print(prepend+grid[idx][jdx], end=' ') else: if grid[idx][jdx] == '.': - print(prepend+colored(grid[idx][jdx],'blue',attrs=["concealed"]),end='') + print(prepend+colored(grid[idx][jdx],'blue'),end='') elif grid[idx][jdx] == 'O': print(prepend+colored(grid[idx][jdx],'red'),end='') elif grid[idx][jdx] == '#': @@ -277,10 +277,7 @@ def part2(): start = () - for r,row in enumerate(grid): - for c, col in enumerate(row): - if grid[r][c] == '@': - start = (r,c) + # translate arrows to something get_value_in_direction can use directions = { @@ -288,28 +285,71 @@ def part2(): 'v':('down',(1, 0)), '>':('right',(0, 1)), '<':('left',(0, -1)), + 'up-left': (-1, -1), + 'up-right': (-1, 1), + 'down-left': (1, -1), + 'down-right': (1, 1), + 'up': (-1, 0), + 'down': (1, 0), + 'left': (0, -1), + 'right': (0, 1), } - pos = start nprint(grid) #print(grid) grid = resizeGrid(grid) + + + for r,row in enumerate(grid): + for c, col in enumerate(row): + if grid[r][c] == '@': + start = (r,c) + + pos = start + print() - nprint2(grid) + nprint2(grid,pos) #print(grid) - print() + input() + + def canBeMoved(pos,dir,boxes2move): + if pos not in boxes2move: + current = get_value_in_direction(grid,pos) + print('Checking if',current,pos,'in direction',dir,'can move') + if get_value_in_direction(grid,pos) == '#': + return '#' + else: + if current in ['[',']']: + boxes2move.append(pos) + if current == '[': + if dir == 'up': #left side of box + # boxes2move += canBeMoved(addTuples(pos,directions[dir+'-right']),dir,boxes2move) + # boxes2move += canBeMoved(addTuples(pos,directions[dir]),dir,boxes2move) + # boxes2move += canBeMoved(addTuples(pos,directions['right']),dir,boxes2move) + return canBeMoved(addTuples(pos,directions[dir+'-right']),dir,boxes2move) or canBeMoved(addTuples(pos,directions[dir]),dir,boxes2move) or canBeMoved(addTuples(pos,directions['right']),dir,boxes2move) + + if current == ']': + if dir == 'up': #left side of box + # boxes2move += canBeMoved(addTuples(pos,directions[dir+'-left']),dir,boxes2move) + # boxes2move += canBeMoved(addTuples(pos,directions[dir]),dir,boxes2move) + # boxes2move += canBeMoved(addTuples(pos,directions['left']),dir,boxes2move) + + return canBeMoved(addTuples(pos,directions[dir+'-left']),dir,boxes2move) or canBeMoved(addTuples(pos,directions[dir]),dir,boxes2move) or canBeMoved(addTuples(pos,directions['left']),dir,boxes2move) + + return boxes2move + return [] for idx, inst in enumerate(instructions): - #print('Move',inst,'(',len(instructions)-idx,')') + print('Move',inst,'('+str(len(instructions)-idx)+')') dir = directions[inst][0] next = get_value_in_direction(grid,pos,dir) # If wall, don't do anything if next == '#': - #nprint(grid,pos) - #input() + nprint2(grid,pos) + input() continue # If free space, move there @@ -319,37 +359,113 @@ def part2(): grid[pos[0]][pos[1]] = '@' # If box, move the box and the stack of boxes. - if next == 'O': - #print('@',pos) - prev = pos - next_chars = ['@'] - next_poss = [pos] - skip = False - while True: - nextPos = addTuples(pos,directions[inst][1]) - nextChar = get_value_in_direction(grid,nextPos) - #print(nextPos,nextChar) - if nextChar == 'O': - next_chars.append(nextChar) - next_poss.append(nextPos) - pos = nextPos - if nextChar == '.': - next_chars.append(nextChar) - next_poss.append(nextPos) - break - if nextChar == '#': - skip = True - pos = prev - break + if next in ['[',']']: #part 2, also check the sides, if theres a full box [] move the whole box - #input() - if not skip: - for ndx,n in enumerate(next_poss): - if ndx == 0: - grid[n[0]][n[1]] = '.' - pos = next_poss[ndx+1] - else: - grid[n[0]][n[1]] = next_chars[ndx-1] + if inst in ['<','>']: + #print('@',pos) + prev = pos + next_chars = ['@'] + next_poss = [pos] + skip = False + while True: + nextPos = addTuples(pos,directions[inst][1]) + nextChar = get_value_in_direction(grid,nextPos) + #print(nextPos,nextChar) + if nextChar in ['[',']']: + next_chars.append(nextChar) + next_poss.append(nextPos) + pos = nextPos + if nextChar == '.': + next_chars.append(nextChar) + next_poss.append(nextPos) + break + if nextChar == '#': + skip = True + pos = prev + break + + #input() + if not skip: + for ndx,n in enumerate(next_poss): + if ndx == 0: + grid[n[0]][n[1]] = '.' + pos = next_poss[ndx+1] + else: + grid[n[0]][n[1]] = next_chars[ndx-1] + + else: + if dir == 'up': #Up works. Need to implement down too. + + boxes2move = [] #list of boxes (set coords) to move + print('next is',next,'im at',pos) + # boxes2move += canBeMoved(addTuples(pos,directions[inst][1]),dir,boxes2move) + boxes2move.append(canBeMoved(addTuples(pos,directions[inst][1]),dir,boxes2move)) + if next == '[': + # boxes2move += canBeMoved(addTuples(pos,directions[dir+'-right']),dir,boxes2move) + boxes2move.append(canBeMoved(addTuples(pos,directions[dir+'-right']),dir,boxes2move)) + if next == ']': + # boxes2move += canBeMoved(addTuples(pos,directions[dir+'-left']),dir,boxes2move) + boxes2move.append(canBeMoved(addTuples(pos,directions[dir+'-left']),dir,boxes2move)) + # boxes2move += canBeMoved(addTuples(pos,directions[inst][1]),dir,boxes2move) + boxes2move.append(canBeMoved(addTuples(pos,directions[inst][1]),dir,boxes2move)) + #boxes2move = list(set(boxes2move)) + if '#' in boxes2move: + continue + boxes2move = [i for i in boxes2move if i is not None] + boxes2move = sorted(boxes2move) + print(boxes2move) + + prevValues = {} + newValues = {} + for b in boxes2move: + prevValues[b] = grid[b[0]][b[1]] + print(prevValues) + for b in boxes2move: + + tmp = addTuples(b,directions[inst][1]) + grid[b[0]][b[1]] = '.' + grid[tmp[0]][tmp[1]] = prevValues[b] + #nprint2(grid,pos) + #input() + + grid[pos[0]][pos[1]] = '.' + pos = addTuples(pos,directions[inst][1]) + grid[pos[0]][pos[1]] = '@' + + + # print('@',pos) + # prev = pos + # next_chars = ['@'] + # next_poss = [pos] + # skip = False + # while True: + # nextPos = addTuples(pos,directions[inst][1]) + # nextChar = get_value_in_direction(grid,nextPos) + # print(nextPos,nextChar) + # if nextChar == '[' or nextChar == ']': + # next_chars.append(nextChar) + # next_poss.append(nextPos) + # pos = nextPos + # if nextChar == '.': + # next_chars.append(nextChar) + # next_poss.append(nextPos) + # break + # if nextChar == '#': + # skip = True + # pos = prev + # break + + + # if not skip: + # for ndx,n in enumerate(next_poss): + # if ndx == 0: + # grid[n[0]][n[1]] = '.' + # pos = next_poss[ndx+1] + # else: + # grid[n[0]][n[1]] = next_chars[ndx-1] + nprint2(grid,pos) + input() + start_time = time.time() print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms') \ No newline at end of file