You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							112 lines
						
					
					
						
							3.2 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							112 lines
						
					
					
						
							3.2 KiB
						
					
					
				
								#!/usr/bin/env python3
							 | 
						|
								
							 | 
						|
								import sys, os, time
							 | 
						|
								from copy import deepcopy
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								def show(m):
							 | 
						|
								    for line in m:
							 | 
						|
								        sys.stdout.write("\r"+''.join(line)+'\n') 
							 | 
						|
								    sys.stdout.flush()
							 | 
						|
								    time.sleep(0.2)
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								def gps(x, y):
							 | 
						|
								    return 100*y + x
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								def move_stone(m, x, y, move):
							 | 
						|
								    dir = {'^': (0,-1), '>': (1,0), 'v': (0,1), '<': (-1,0)}
							 | 
						|
								    nx, ny = x+dir[move][0], y+dir[move][1]
							 | 
						|
								    if m[ny][nx] == '#': return
							 | 
						|
								    if m[ny][nx] == 'O': move_stone(m, nx, ny, move)
							 | 
						|
								    if m[ny][nx] == '.':
							 | 
						|
								        m[ny][nx] = 'O'
							 | 
						|
								        m[y][x] = '.'
							 | 
						|
								        return
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								def move_box_h(m, x, y, move):
							 | 
						|
								    dir = {'^': (0,-1), '>': (1,0), 'v': (0,1), '<': (-1,0)}
							 | 
						|
								    nx, ny = x+dir[move][0], y
							 | 
						|
								    sym = m[y][x]
							 | 
						|
								    if m[ny][nx] == '#': return
							 | 
						|
								    if m[ny][nx] in ['[', ']']: move_box_h(m, nx, ny, move)
							 | 
						|
								    if m[ny][nx] == '.':
							 | 
						|
								        m[ny][nx] = sym
							 | 
						|
								        m[y][x] = '.'
							 | 
						|
								    return
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								def move_box_v(m, x, y, move):
							 | 
						|
								    dir = {'^': (0,-1), '>': (1,0), 'v': (0,1), '<': (-1,0)}
							 | 
						|
								    if m[y][x] == '[': x1, x2 = x, x+1
							 | 
						|
								    else: x1, x2 = x-1, x
							 | 
						|
								    nx1, nx2, ny = x1+dir[move][0], x2+dir[move][0], y+dir[move][1]
							 | 
						|
								    if m[ny][nx1] == '#' or m[ny][nx2] == '#': return m
							 | 
						|
								    if m[ny][nx1] == ']' and m[ny][nx2] == '[':
							 | 
						|
								        mp = deepcopy(m)
							 | 
						|
								        mp = move_box_v(mp, nx1, ny, move)
							 | 
						|
								        mp = move_box_v(mp, nx2, ny, move)
							 | 
						|
								        if mp[ny][nx1] == '.' and mp[ny][nx2] == '.': m = deepcopy(mp)
							 | 
						|
								    elif m[ny][nx1] in ['[', ']']: m = move_box_v(m, nx1, ny, move)
							 | 
						|
								    elif m[ny][nx2] in ['[', ']']: m = move_box_v(m, nx2, ny, move)
							 | 
						|
								    if m[ny][nx1] == '.' and m[ny][nx2] == '.':
							 | 
						|
								        m[ny][nx1] = '['
							 | 
						|
								        m[ny][nx2] = ']'
							 | 
						|
								        m[y][x1] = '.'
							 | 
						|
								        m[y][x2] = '.'
							 | 
						|
								        return m
							 | 
						|
								    return m
							 | 
						|
								 
							 | 
						|
								
							 | 
						|
								def move(m, x, y, move):
							 | 
						|
								    dir = {'^': (0,-1), '>': (1,0), 'v': (0,1), '<': (-1,0)}
							 | 
						|
								    nx, ny = x+dir[move][0], y+dir[move][1]
							 | 
						|
								    if m[ny][nx] == '#': return m, x, y
							 | 
						|
								    if m[ny][nx] == 'O': move_stone(m, nx, ny, move)
							 | 
						|
								    if m[ny][nx] in ['[',']'] and move in ['v', '^']: 
							 | 
						|
								        m = move_box_v(m, nx, ny, move)
							 | 
						|
								    elif m[ny][nx] in ['[',']'] and move in ['<', '>']: 
							 | 
						|
								        move_box_h(m, nx, ny, move)
							 | 
						|
								    if m[ny][nx] == '.':
							 | 
						|
								        m[ny][nx] = '@'
							 | 
						|
								        m[y][x] = '.'
							 | 
						|
								        return m, nx, ny
							 | 
						|
								    else: return m, x, y
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								if __name__ == '__main__':
							 | 
						|
								    mp, moves = open(sys.argv[1]).read().split('\n\n')
							 | 
						|
								    mp = [list(y.strip('\n')) for y in mp.split('\n')]
							 | 
						|
								    moves = list(''.join([m.strip('\n') for m in moves]))
							 | 
						|
								    wm = []
							 | 
						|
								    for y, l in enumerate(mp):
							 | 
						|
								        line = []
							 | 
						|
								        for x, r in enumerate(l):
							 | 
						|
								            if r == '#': line += ['#', '#']
							 | 
						|
								            elif r == '.': line += ['.', '.']
							 | 
						|
								            elif r == 'O': line += ['[', ']']
							 | 
						|
								            elif r == '@':
							 | 
						|
								                wrx, wry = len(line), y
							 | 
						|
								                line += ['@', '.']
							 | 
						|
								                rx, ry = x, y
							 | 
						|
								        wm.append(line)
							 | 
						|
								    for mov in moves:
							 | 
						|
								        mp, rx, ry = move(mp, rx, ry, mov)
							 | 
						|
								        wm, wrx, wry = move(wm, wrx, wry, mov)
							 | 
						|
								
							 | 
						|
								    # challenge 1
							 | 
						|
								    res1 = 0
							 | 
						|
								    for y, m in enumerate(mp):
							 | 
						|
								        for x, t in enumerate(m):
							 | 
						|
								            if t == 'O': res1 += gps(x, y)
							 | 
						|
								    print(f"challenge 1:\n{res1}\n")
							 | 
						|
								
							 | 
						|
								    # challenge 2
							 | 
						|
								    res2 = 0
							 | 
						|
								    for y, m in enumerate(wm):
							 | 
						|
								        for x, t in enumerate(m):
							 | 
						|
								            if t == '[': res2 += gps(x, y)
							 | 
						|
								    print(f"challenge 2:\n{res2}")
							 | 
						|
								
							 | 
						|
								
							 |