Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import time
- filename = "data"
- try:
- with open(filename, "r") as file:
- lines = file.read().splitlines()
- print("File opened successfully.\n")
- except:
- input("File '{filename}' not found. Program will now exit.\n")
- exit()
- for i, line in enumerate(lines):
- lines[i] = [char for char in line]
- y_range = range(len(lines))
- x_range = range(len(lines[0]))
- x_max = max(x_range)
- y_max = max(y_range)
- def tilt_old(_dir):
- if -1 in _dir:
- y = 0
- for line in lines:
- x = 0
- for char in line:
- if char not in "#.":
- _y = y
- _x = x
- while ((_y + _dir[0]) in y_range) and ((_x + _dir[1]) in x_range) and lines[_y + _dir[0]][_x + _dir[1]] == '.':
- lines[_y][_x] = '.'
- lines[_y + _dir[0]][_x + _dir[1]] = 'O'
- _y += _dir[0]
- _x += _dir[1]
- x += 1
- y += 1
- else:
- y = y_max
- for line in reversed(lines):
- x = x_max
- for char in reversed(line):
- if char not in "#.":
- _y = y
- _x = x
- while ((_y + _dir[0]) in y_range) and ((_x + _dir[1]) in x_range) and lines[_y + _dir[0]][_x + _dir[1]] == '.':
- lines[_y][_x] = '.'
- lines[_y + _dir[0]][_x + _dir[1]] = 'O'
- _y += _dir[0]
- _x += _dir[1]
- x -= 1
- y -= 1
- def tilt(_dir):
- if _dir == [-1, 0]:
- for x in x_range:
- y = 0
- while y < y_max:
- #amount of rocks
- rocks = 0
- start = y
- while y <= y_max and lines[y][x] != '#':
- if lines[y][x] == 'O':
- rocks += 1
- y += 1
- #print the stuff
- end = y
- for _y in range(start, end):
- if _y < rocks+start:
- lines[_y][x] = 'O'
- else:
- lines[_y][x] = '.'
- y += 1
- elif _dir == [1, 0]:
- for x in x_range:
- y = y_max
- #print(f"\nx: {x}")
- while y >= 0:
- #amount of rocks
- rocks = 0
- start = y
- while y >= 0 and lines[y][x] != '#':
- if lines[y][x] == 'O':
- rocks += 1
- y -= 1
- #print the stuff
- end = y
- #print(f"{rocks} rocks from {start} to {end}")
- _y = start
- while _y > end:
- if _y > start-rocks:
- lines[_y][x] = 'O'
- else:
- lines[_y][x] = '.'
- _y -= 1
- y -= 1
- elif _dir == [0, -1]:
- for y in y_range:
- x = 0
- while x < x_max:
- #amount of rocks
- rocks = 0
- start = x
- while x <= x_max and lines[y][x] != '#':
- if lines[y][x] == 'O':
- rocks += 1
- x += 1
- #print the stuff
- end = x
- for _x in range(start, end):
- if _x < rocks+start:
- lines[y][_x] = 'O'
- else:
- lines[y][_x] = '.'
- x += 1
- elif _dir == [0, 1]:
- for y in y_range:
- x = x_max
- #print(f"\nx: {x}")
- while x >= 0:
- #amount of rocks
- rocks = 0
- start = x
- while x >= 0 and lines[y][x] != '#':
- if lines[y][x] == 'O':
- rocks += 1
- x -= 1
- #print the stuff
- end = x
- #print(f"{rocks} rocks from {start} to {end}")
- _x = start
- while _x > end:
- if _x > start-rocks:
- lines[y][_x] = 'O'
- else:
- lines[y][_x] = '.'
- _x -= 1
- x -= 1
- def cycle():
- tilt([-1, 0])
- tilt([0, -1])
- tilt([1, 0])
- tilt([0, 1])
- def print_map():
- for line in lines:
- string = ""
- for char in line:
- string += char
- print(string)
- print("\n")
- def print_index(i):
- for line in states[i]:
- string = ""
- for char in line:
- string += char
- print(string)
- print("\n")
- def copy_2d_list(_list):
- new = []
- for sub_list in _list:
- new.append(sub_list.copy())
- return new
- #save the current data for use in part 2
- lines2 = copy_2d_list(lines)
- start = time.time()
- tilt([-1, 0])
- result = 0
- distance = len(lines)
- for line in lines:
- for char in line:
- if char == "O": result += distance
- distance -= 1
- end = time.time()
- time_needed = end-start
- print(f"Part 1:\n Time needed: {round(time_needed, 3)}s\n Load: {result}\n")
- #load the saved data
- lines = copy_2d_list(lines2)
- start = time.time()
- cycles_max = 1000000000
- states = []
- cycles = 0
- while True:
- cycle()
- if lines in states:
- cycle_start = states.index(lines)
- cycle_end = cycles
- cycle_length = cycle_end - cycle_start
- break
- states.append(copy_2d_list(lines))
- cycles += 1
- left_over = (cycles_max - cycle_start) % cycle_length
- lines = states[cycle_start + left_over-1]
- result = 0
- distance = len(lines)
- for line in lines:
- for char in line:
- if char == "O": result += distance
- distance -= 1
- end = time.time()
- time_needed = end-start
- print(f"Part 2:\n Time needed: {round(time_needed, 3)}s\n Load: {result}\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement