const ROCK: char = '#'; const AIR: char = '.'; #[derive(Clone,PartialEq)] struct Pos { x: u32, y: u32, } #[derive(Clone,PartialEq)] enum RockType { Bar,Cross,Ell,VBar,Square } enum Direction { Down,Left,Right } #[derive(Clone,PartialEq)] struct Rock { rtype: RockType, pos: Pos, } impl Rock { pub fn mv(self, dir: Direction, grid: &Vec>) -> Self { // Check we _can_ move // Then move self } pub fn solidify(self, grid: &mut Vec>) { // as it says, transform squares covered by ourselves into solid rock } } fn rock_height(grid: &Vec>) -> usize { 0 } fn run(input: String) { let initial_height = 6; let width = 7; let rocks = vec![RockType::Bar,RockType::Cross,RockType::Ell,RockType::VBar,RockType::Square].into_iter().cycle(); let gas_jets = input.chars().cycle(); let mut grid: Vec> = (0..initial_height).map(|_| { (0..width).map(|_| {AIR}).collect() }).collect(); let mut rock = Rock{ rtype: rocks.next().unwrap(), pos: Pos{x: 2, y: 3} }; let mut rocks_count: usize = 1; 'lp: loop { let mv = match gas_jets.next().unwrap() { '>' => Direction::Right, '<' => Direction::Left, dir => panic!("Unexpected jet direction! {}", dir) }; // apply jet, ignore if it didn't move let r2 = rock.mv(mv, &grid); // apply gravity let r3 = r2.mv(Direction::Down, &grid); if rock == r3 { // We didn't move, solidify! rock.solidify(&mut grid); if rocks_count == 2022 { break 'lp; } // Measure height... let max_rock = rock_height(&grid); // Extend grid to max_rock + 7 (enough room for any new rocks) grid.extend((0..(max_rock+7)).map(|_| { (0..width).map(|_| { AIR }).collect() })); // Spawn new rock rock = Rock { rtype: rocks.next().unwrap(), pos: Pos{x: 2, y: 3} }; // remember how many rocks we did rocks_count += 1; } else { rock = r3; } } println!("Day 17: {}", rock_height(&grid)); }