Day 25: Sea Cucumber

Simple array manipulation. Not interesting!


Setup and Part 1 (there was no Part 2)

use crate::Answer;
use std::{collections::BTreeSet as Set, fmt::Write};

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Point {
	row: usize,
	col: usize,
}

#[derive(Debug, Clone)]
struct SeaGarden {
	width: usize,
	height: usize,
	rights: Set<Point>,
	downs: Set<Point>,
}

impl SeaGarden {
	fn from_str(input: &str) -> Self {
		let mut rights = Set::new();
		let mut downs = Set::new();

		let mut width = 0;
		let mut height = 0;

		for (row, line) in input.lines().enumerate() {
			height += 1;
			width = line.chars().count();
			for (col, c) in line.chars().enumerate() {
				let loc = Point { row, col };
				match c {
					'>' => rights.insert(loc),
					'v' => downs.insert(loc),
					'.' => continue,
					_ => unreachable!(),
				};
			}
		}
		Self {
			width,
			height,
			rights,
			downs,
		}
	}

	fn tick(&mut self) -> bool {
		let mut any_cucumbers_did_move = false;

		let mut new_rights = Set::new();

		for old_loc @ &Point { row, col } in &self.rights {
			let new_loc = Point {
				row,
				col: (col + 1) % self.width,
			};
			if self.rights.contains(&new_loc) || self.downs.contains(&new_loc) {
				new_rights.insert(*old_loc);
			} else {
				new_rights.insert(new_loc);
				any_cucumbers_did_move = true;
			}
		}

		let new_rights = new_rights;
		let mut new_downs = Set::new();

		for old_loc @ &Point { row, col } in &self.downs {
			let new_loc = Point {
				row: (row + 1) % self.height,
				col,
			};
			if new_rights.contains(&new_loc) || self.downs.contains(&new_loc) {
				new_downs.insert(*old_loc);
			} else {
				new_downs.insert(new_loc);
				any_cucumbers_did_move = true;
			}
		}

		self.rights = new_rights;
		self.downs = new_downs;

		any_cucumbers_did_move
	}

	fn run_until_no_movement(&mut self) -> usize {
		let mut n = 1;
		while self.tick() {
			n += 1;
		}
		n
	}
}

fn ans_for_input(input: &str) -> Answer<usize, usize> {
	let mut garden = SeaGarden::from_str(input);
	(25, (pt1(&mut garden), 0)).into()
}
pub fn ans() -> Answer<usize, usize> {
	ans_for_input(include_str!("input.txt"))
}

fn pt1(garden: &mut SeaGarden) -> usize {
	garden.run_until_no_movement()
}

This page was built using Antora with a theme forked from the default UI. Search is powered by Lunr.

The source code for this UI is licensed under the terms of the MPL-2.0 license.