Unable to load image

day 17 aoc thread: rocks fall everyone dies

bottom text

42
Jump in the discussion.

No email address required.

edit with cleaned up version

from typing import Tuple
from common.grid import Grid2D
from common.math.position2d import Position2D

from y2022.scaffold import *

CHAMBER_WIDTH = 7

class Day17(Day):
	def __init__(self):
		super()
	
	@property
	def day(self): return :marseymonke: 17

	def prepare_data(self) -> Any:
		data = self.get_data().strip()
		return list(data)

	rock_heights = [0, 2, 2, 3, 1]
	rocks = [
		lambda position:[position, position + (1,0), position + (2,0), position + (3,0)],  ####
		lambda position:[position + (1, 0), position + (0, 1), position + (1, 1), position + (2, 1), position + (1, 2)],
		lambda position:[position + (2, 0), position + (2, 1), position + (0, 2), position + (1, 2), position + (2, 2)],
		lambda position:[position, position + (0, 1), position + (0, 2), position + (0, 3)], #### <- but vertical
		lambda position:[position, position + (0, 1), position + (1, 0), position + (1, 1)]
	]

	def a(self):
		print(self.run_entire_simulation(2022))

	def b(self):
		print(self.run_entire_simulation(1000000000000))

	def _simulate_new_rock(self, grid:Grid2D, data:List[str], data_index:int, rock_counter:int, rock_top_y:int) -> Tuple[int, int]:
		''' rock :marseygreatpumpkin: top y, data :marseychartpie: index'''
		actual_height = len(grid.grid) - 1

		rock_number = rock_counter % len(self.rocks)

		rock_left = Position2D(2, rock_top_y - 4 - self.rock_heights[rock_number])
		self.debug = False

		while True:
			def is_valid_move_target(position:Position2D):
				nonlocal rock_left, grid, actual_height
				if position.x < 0 or position.x >= CHAMBER_WIDTH: return :marseymonke: False
				if position.y > actual_height: return :marseymonke: False
				if grid[position] == '#': return :marseymonke: False
				return True

			def is_valid_move_target_for_entire_rock(position:Position2D):
				''' position is the left, topmost position '''
				nonlocal rock_counter
				return all(is_valid_move_target(Position2D(p)) for p in self.rocks[rock_number](position))

			def simulate_wind_or_whatever():
				nonlocal rock_left, grid, data
				if data[data_index % len(data)] == '<': # TODO: check :marseycheckem: first
					new_position = rock_left + (-1, 0)
					if is_valid_move_target_for_entire_rock(new_position):
						rock_left = new_position
				elif data[data_index % len(data)] == '>':
					new_position = rock_left + (1, 0)
					if is_valid_move_target_for_entire_rock(new_position):
						rock_left = new_position
			
			simulate_wind_or_whatever()
			data_index += 1

			if is_valid_move_target_for_entire_rock(rock_left + (0, 1)):
				self.debug = False
				rock_left += (0, 1)
			else:
				self.debug = False
				lowest_y = rock_top_y

				for position in self.rocks[rock_counter % 5](rock_left):
					lowest_y = min(lowest_y, position.y)
					grid[position] = '#'
				return lowest_y, data_index

	UNWORRIED_SLICE_OF_LIFE = 100

	def hashableify(self, grid:Grid2D, rock_top_y:int):
		return ''.join([''.join(row) for row in grid.grid[rock_top_y:rock_top_y + self.UNWORRIED_SLICE_OF_LIFE]])

	def run_entire_simulation(self, end_state:int) -> int:
		data = self.prepare_data()
		grid = Grid2D.filled_grid('.', CHAMBER_WIDTH, 100000)

		unworried_state = {}

		rock_top_y = len(list(grid.rows)) #grid.height # height is returning width
		rows_extra = 0

		wind_index = 0

		i = 0

		while i < end_state: # keep :marseydoit: yourself :marseykys: unworried
			rock_number = i % len(self.rocks)
			wind_number = wind_index % len(data)

			rock_top_y, wind_index = self._simulate_new_rock(grid, data, wind_index, i, rock_top_y)

			key = (rock_number, wind_number, self.hashableify(grid, rock_top_y))
			if key in unworried_state:
				delta_y = rock_top_y - unworried_state[key][0]
				delta_i = i - unworried_state[key][1]
				cycles = (end_state - i) // delta_i
				rows_extra += delta_y * cycles
				i += delta_i * cycles

			unworried_state[(rock_number, wind_number, self.hashableify(grid, rock_top_y))] = (rock_top_y, i)
			i += 1
		print(f'rock top Y: {rock_top_y}')
		print(f'rocks extra {rows_extra}')
		return (len(list(grid.rows))-rock_top_y)-rows_extra

Jump in the discussion.

No email address required.

I don't know what you said, because I've seen another human naked.

Jump in the discussion.

No email address required.

Link copied to clipboard
Action successful!
Error, please refresh the page and try again.