From 594226320db44974ef5094d90a1912cdd9834c08 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Sun, 18 Dec 2022 21:21:14 +0100 Subject: [PATCH] Implement 2022 day 17 part 1 --- 2022/inputs/17.txt | 1 + 2022/src/common.rs | 9 +++ 2022/src/day17.rs | 119 +++++++++++++++++++++++++++++++++++++++- 2022/src/samples/17.txt | 1 + 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 2022/inputs/17.txt create mode 100644 2022/src/samples/17.txt diff --git a/2022/inputs/17.txt b/2022/inputs/17.txt new file mode 100644 index 0000000..8b7d0b1 --- /dev/null +++ b/2022/inputs/17.txt @@ -0,0 +1 @@ +>><>>><<<>>><<>>>><<<>>>><<><>>><<<<>><<<><<<>><<<<>><<>>>><<>><<<><>><><<<>><<<<>>>><<>>><><<>>><<><<<<>>><<>>><>><<<<>><<<<>><<><<>>>><<<>>><<>>>><<<><><><<>>>><<>><<>><>>><<<>><<>>><<<<>>><><<<><<<<><<<<><<<<>>>><>>>><<<>>>><>>><>>><<<<>>><<<<><<<<>>><>>>><<>>>><<<<>>>><<<><<><<<>>>><>>><<<<>>><<<><<>>><<<<>>>><<<>><>><>><<<<>>>><><>>>><<<<>>>><<><<<<><<<<>>>><<>>><<>><<<><<<><<<<>>><<<>>><<>>>><<<>>>><>>>><<<>><<<>>><<<<>>><<>>><<<<>><<>>>><><<<<>>><><>><>><<<>>><<<>><>>>><<<<>>><<<<>>><<<<>><<<<>>><<>>>><>>>><<<>>><<<<><<<>><><<<<>>>><<<>><<<<>>>><<>><<<><<<<><<<<>>>><<<>>>><<>><><<<>><<>>>><<<>><<<>>>><>>>><><<<<><><<>>><<<>><<>>>><<<>><<>>>><<>>><<<<><<<><<>><<<>><>><<<>>>><><>>>><<<><>>>><<<>>>><<>><<>><<<<><<<>>><<<>><<<<>>><>><<>>><<<<>>>><<<><<><<>><<<<>>><<><<<<>>><>>><<>>><<>><<><><<>>>><<><<<<>>><<<<>>><<<<>>>><<>>>><>><<<<>><<<<>>><>><<<>>>><<><<<>>>><<>>><<>><<<<>><<<><<<<>>><<><<<<>>>><<>>><<<>>>><<<>><<<>>>><>>>><>>><>>><>>><>>><<>>><<><<<<>><<>><<>><>>>><<<<>>><<><<>>>><<<><<>>><<><<<>>><<>><>><<><<<>>><<>>>><<<<>><<><<>><>>>><><<<<>>>><<><<><<>><<<<>><<<><<>>>><<<<>>><>><<>>><>><<<<>><<>>><><<<>>><<<>>>><>>><<<>>><><<<><<<><<<>><>>>><<><<>>><<<<>>>><<>>><<>>>><<<<>>><<>><<<<>><<<<>>><><<><<<>><<>>><><>>>><<<><>>>><<>>>><<<>>><<>><>>>><>><<>>>><<<<>><<<>><<>><>>><<<<>>>><><<<<>>><<<<>>><>>><<<<>>>><>>><<<<>>>><><<>>><<><<<>>><<<>>><>>><<>>>><><<<<>><<>>>><<>>>><<>>><<>><<><>>>><<>>>><<<<>>><<<<><<<<><<>>><<<>><<<>>>><<><<<<>>>><<<<>>>><<<>>><><<<>>><<<>><<<>><<<<>>><<>>><<>><<<>>>><<<<>><><><<<>>>><<<>>><<>>>><<>>>><<<><><<<>>>><<<>>><>><<<>>>><<<<><<<<>>>><<<>>><<>><>>><<>><>>>><<>>><<>><<<>>><><<<>><<<>><><><<<<><<<<><<<<>><>>>><<>>><>><<<>>>><<>><<<>>><<>><<<>>><>>><<<>>>><>><<>><<<>><>><<>>>><>>>><<<><<<<>><>>>><>>>><>>><<<><<>>>><<>>>><<<<><<>>>><<<<><<>>>><<>>><<>><<<>><<>>><><<<<><>>>><>>><<<>><<<<><>>><<<<>>><>>>><><<>>>><<<<>>>><>><>>>><<<<><<<<>>>><>>>><<<>>><><<><<>>>><<<>><<<<><<<<>>><<>>><<<<>>>><<<<>><><<>>><>><<<>>><<>><<>>><><<>><<<<>>>><<<><<<<>>>><<><<<>>>><<<<><<>>>><>>>><<<<>>>><>>>><<<>><><<<>><<<<><<<>><>>><<<<>><<<<>>><<>><>>><><<<<>>><<><<<<>>>><>>><>><<<<><<<>>><>><<<>><<<><<>><>><<<<>>><<<>>><><>>>><><>><<<>>><<><<>>>><<<>>>><><>>><<<><<>><><<<><<>>>><<<>><<><>><<<>><<<<>>><<>>><<>><<<>><><<>>><<>>>><<<>><>><<>>>><<<>>>><<>>><<>>>><<>>><>><>><<<>>><<>>>><>><<>>>><<<<>><<<><<<<>><>>><<>>><<<<><<<>><><<<<>><<><<<>><<<>><>>>><<><>><<<<>>>><>>>><<><><<<<>>>><<<>>>><<<>><<><<<<>>>><<<<>><<<>>>><<<<>>>><<>><<<<>>>><>>><<><<<>>>><<>>><>>>><>><>><>><<>>>><<<><>><<<>>>><<<<>>>><<<<><<<>><><<><<>>>><<<<>><<<<>><><<<<>>>><<<<>><><<>>>><<>><<>>>><<><<><<<><<>>><<><<<><<><<<>>>><<<<>>><><<<<><<>>>><>><<<>>>><<>>><<>>><>>><>>>><<<>>><<>><<>>>><<<>>>><<<<>><<<>><<<><<<><><<<<>>><<>>><<<>><<>>>><><<<<>><<<<>>>><<<<>>><<<<><<>><<>>><<<<><<<><<<<>><<<>><<<><<<>><<<>><<<<>>>><<<>>><>>><<<<>><<<>><<<>>><>>>><<<<>><<<<><<><>><>><<><<<>>>><<<<><<>>><><<<<>><<<>>>><<<<>>><<>>>><<>>>><<<>>><<>>>><<>><>>><<><<<<>>><<<<>><<<<>><<<<>>><<<<><<><><<<><>><<<<>><<<>>>><<<<>>>><<<<>>><<><<><>><<>><<><<<<><<><>><>><<<>><<>>><>>>><<<><<<>><<<>>>><<>>><<>>>><<<<>>><<<<>><<<<>>>><<>><>>><><>><<<<>>>><<<>><<>>><<<>>>><>>>><<<<>>><<>>>><<<><<<<>>>><<><>>>><<<>>>><<><<<<>><<<<>><<><<<<>>>><<<>>>><<<<>><<>><>><<><<>>>><<>>>><<><<>><<<<>>><<<<>>>><>>><<<><>>>><<<>><<<>>><<>>><<<<>>>><><<<<>><>><<>>><<<>>>><<<<>><><>><<<<><<<<>>><<<<>>>><<<>>><<<<>>>><<>>>><<<><<>>><<>>><<<><>><>>>><<<<>>><<<<>>>><<<>><<>>><>>>><<<<>>><<>>>><<<>>>><<<><<<<>><>>><<><><<<>><<<>>><<><<<<>>>><<<<><<<<><<<>>>><<<<><<>><<<<>><<>>>><>><<<<><>>><<<><<<><<>>>><>><<<><<<<><<>>>><<>><<<<>>>><<>><<<<>><<<>><<><>>><>><<><<>>><<><<<<>><><<>>><<<>>><>>><<>>><<<><<<>>>><<<<>>><<<<>>>><<<<>>><<<<>>><<<>>>><<<>><<>><<<<>>>><<<<><<>>>><<>>><<<><<><<>>><<<<>>><<<<><<<>>><>>><<<>>>><>>><<>>><<>>>><>>><<<>>><<<><<<<>><<><<<>>><<<>>><<>>>><<><<>>><<><<<<>>>><<<>><<<<>>><<<<>>><>>>><><<<>><<<<>>>><>><<<>>><<>>>><<<<><<<>>><<<>>><><>>>><>><<<>>><<<<><<<>><<<<>>>><<<<><><<>><><>><<<><<<<><<<>>><<>>>><<<>>><<>>><<>>><<>>><<<>>>><<><<>>>><<<<>>>><<<>><<<><<<<>>><<>>>><<<<>>>><<><<>>><<>><<<>>>><<<>>>><>><<<<>>>><>>>><>>><<<<>><<<<>>><<<><<<>>><<<>><<<>><<<><>>><>><<<<>><<<<>>>><<>><<>><<<>>>><<<>><<<<>>><<>>>><<<<><><<<>>><>>><<<<>>><<>>><<<<>><<<>>><<<<>><>>>><<>>><><<<>>>><<<<>>>><>><<<>>>><<<>>>><>><>>><<<>>>><><>>>><<<<><>>><<<>><<<<>>><<<>>><<><<>>>><<<><<<><<<>>><<<><>><>>><><<<<>>><<<<>>><>>>><<<<>>>><>>><<<>>><>>><>>><<<><<><<><<<<><<<<>>>><<<>>>><<<>>>><<<<><<<><<>>>><>>>><<<>><<<>>><<>><<<<><><>><<><<<>>><<<<>>>><><<><<<>><>>>><<<<>>>><<>>><<<<><<<>>>><<>>><<<<>>>><<<<>><<>>><<<>>>><<<<>><<<><<>><>><<>><>><<>>><<>>>><<<<>><<><<<><<<<>><<<<>><>>><><<<<>><<>><<<<>><<<>>><><<<><<<>>><<><<<<>><<<<>>><<><<>><><<<<><<<>><<<><<<<>>><<<<><<>>><<<>>><<<>><<<<><<>>>><<<<>>><<<<>>><<<<><>>>><<><>><>>><<>>>><><<<><><>>><<<<><<><<<>>><>>><><<<><<>><>>><<<<>><<<>>><<>>>><<>>>><>>>><<<>>><>><<<<>><<<>>><<<>>>><>>><<><<><<<<>>>><<<><>>>><<>>>><<<>>>><<>>>><>><<<<>>>><<><<<<>>>><<>><<<>>>><>><<><<<<>><>>>><<<<>><<>>><<<<>><<<<>>><<<<>>><<>><<<<><><<<>>>><<>>>><<<>>><<<><<<>>><<<>>><<>>><><<<>>><<>><<>>>><><<<<>>><<<>><<><<>>>><<<><<><<<<>><><><<>>>><<<<>>><<<<>><<><<><>>>><<<>>><<<>>>><<<>>><<<<>>>><<<<>>><<<<><<><<<<>>><>>><<<<><>>><>>>><<>>><<>>>><<<<>>><<<>>><<<<><<>>>><>>><<<>>><<<<><><<>>><<<>>><<<>><<<>>>><<<><<>>>><<>>><>><<<>>>><<>>><<>><<<>>>><<><<<<>>>><<>>>><<<<><<>>><<>><>>>><<<>>><<<><<<><<<>>>><<>>>><<>>>><<<<>>><><<<>>>><<<<>><<>>>><><>><<<>><<<<>><>>>><><<<>>>><>><<<<>>><<<<>><<<>><<>>>><>>><<<>>>><>>>><>>>><<>><<<<>>>><<><<<<>>>><><<><>><<<>>><>>>><<>>><<<>><<<>>>><<><<<<><<<>>>><<<<>><<>><<>><<>>>><>>><<<>>><<<><<<<>>>><>>><>><<>>>><>>>><<<<>><<<>>>><<<>><<<<>>><<>><<><<>>>><>><>>><><<>><<><<><<<>>><<<>><>><<<<>>><<<<>>>><<<<><>>>><<>>>><<<<>><<<<>><<<>>>><>><<<>>><<<<>>>><<<<>>><<<><><<><<<<>><<<<><<>><<<<>>>><>><>>>><<<>><<>><<<<>>><<<<><<<><>><>>>><>><>>><<>>>><<<<>><<>>>><<<<>>><<<>><>><<<<>>><<<<>>><<><<<<>>>><<<<>>><<<>>><>><<<><<>>>><<>><<<<>><<<>><><<<>>><<<>><<<<>>>><><<<>>>><<<<>><<<<>>>><<<<>>><<<><>>><<<<>>><>><>>><<>><<><<<>>>><><<<<>>>><<<<>>><<<<>>><<>><>><<>><<<>>><<<<>>><<>>><<<>>><<<<><>>>><>>><<<<>>><<<><>><<>>><<>><<>>>><>>><<<<>><<>><<<>><><<><>><<<<>>><<<<><<>>><>>>><<>><<<>><<>>><<>>>><<<><<<><<<<>><<<>><<>>><><>><<<><<><>>>><<<>>>><<<>>>><>><<><<<<><<<<>>>><<<>>><<><<<<>>><<<>><<>><>>><<>><<<>>>><><><<<>><>>>><<>>>><>>><<<>><>>>><<<<>><<<<><<<<>><<<<>><<<<>>>><<<<>>><<<><<<<>>>><<>>>><<<>><<>>>><<<>>><<<>>><<>><<<>><<<<><<<>><><>>><<><<>>>><<>>><>>><<<>><<><<><<<>>>><<<<><<<><<<<>><<<<><<<>><<>>><<<<>>>><<<>>>><<><<>>>><><<<>><><>>>><<<<>>><><><<<>>>><<<><<<><<>>><<>><<<>><<<>>>><<<>><<>><<<<>><<>>><><<<<><<><<>><<<>>>><<<><<<>>>><<>><<<<>><<<<><<<>>>><<<<>><<<><<<<>>>><>>>><<<><<><><<<><<<>>><<>>><<<<><<>>>><<<>>><<<<>>><<><<>><<>>>><><<<<>>>><><>>><<<>>><<>>><<<<>>>><<<<>><<<>>>><>>><<>>>><>><<<>><<<><<<<>>><>><<<>><<>>>><<><<<>><<><<<><<<<>>>><><<>>>><<<>>><<<<>><>>>><<>><>>><<<<>>><<<<><<<<>><<<<>><<<><<<<><>>>><><<<>>>><<>><<>>><><<<>>><><<<<><>><<<>>>><<><<<<>>>><<<><<<>>>><>>><<<><<<<>>>><<<<><>>><<<>>><<>><<><<<<>>><<<<>>><><>>><<<<><<>>><<>><<<><>><<<<>>><<>><<<>>><<<<>>><<<>>><<<><<<<><<<<>><<><<<>>><<>><<<>><><<<>>>><<><<>>><<<>>>><<>><<<<>>>><>>><<<<><><<<<>><>>><<<>>><<<>>><<<>><>>>><>>><<<<><<<>><>>>><<<>>><><<><>>><<<>>>><>><<<>><<<<><>><<>>><<<><>>><<<>><><<<<>>>><<<><<<>><>><<<>>><>>>><<<>>><<>>>><<<>>>><>>>><<<<>>><<><<>><<<<>>>><>>><<<><<<<>>>><<<>>><<>>><<<>><<<<>>><<<<><>>>><<>>>><<>>><<>><<<<>><<<>>><<<>>>><<<<>>>><>>><><<>>>><<<>>><<><><<>>>><<<>>>><<>><<<<>><<<<>>><<<><<<><<><<<><<<>>>><<<<>>><<<<>><<<<>><<<<>>>><<<><<>><<>>>><<>>><<<<>>>><<<>>>><><>>>><<<<>>>><<<<>><<<>>><<<<>><<<>>><<<<><<<><<<<>>><<<>>><<>>>><>>>><<<<><<<<>><<>>>><<<<><>>><><<>>><>>>><<<>>>><<<<><<><<<<><><<<<><<<<>>>><<<<>>><<<>>><<<<>>>><<<<>><>>>><<>><<>><<>><<<>><>>><>><>><<><>><<<>>><<<>>><>>><<>><<<><>><<>><<<>><<<>><>>>><>>>><<<>><>>>><<>>>><>><<>>>><>><<<<>><<>>><<<<>>><<>><<<>>>><<>><<>><<<<><<<><<<<>>><>>><<>><>><<<>><<<>>><>>>><<>>>><>>><<>>>><><>><<>><<<<><<>>>><<<><<>>>><<>><<<>>>><>><<>>>><>>><><><<<><>><<><>><<<><<<<>>><<>>>><><<>>>><<>>><<>>>><<<<>>>><>>><><>><>>><><<<<>>>><<<<>>><<<<>>>><<>>>><<>>>><<<>>>><<<<>>>><<<>>><<<>>>><<<<><<<>>><<<<><<>>><<>>>><<<<>><>>>><<><><<<<><<<>>><<<>><<><<<<>>>><<>><><<<>>>><<<>>><<<<>>><>>><<<<>>>><<<<>>><<><<>>>><<<><>>>><<<<>>><>><>>>><<<<>><<>>>><>><<<>><<>>><<<<><<<>>><<<><>>><<<><><<<>>><<<>>>><><>>><<<><<<<>>><>>><>><<<><<<<>>><>>>><<<<>>><<<<>>><<<>><<>>><<<<>>>><<>><<<<>><>>><<<>><>><<<<><<<<>><<<><<<>>>><><>><<>>>><<<<><<<>>>><<<<>><<>>><<<><>>>><<<<><><>>>><<>>><<<>>><<<<>>>><<>>><><<<>>><<>>>><<<<>>><<<<>><><<<<>>>><<<<>><<<><<><<<<>>><<<<><<>><<<>>><<<>>><><>>><<<>>><<>><<<>>><<<<>><>>><>>>><>>><<<<>>><>>><<><<<<>>>><<<<>>><<<<>>>><<<>>><>>><>><<<>>>><>>><<<<>>>><<<<>>><<<<>>>><<<>><<<>><<>><>><<<<>>><>>>><<<<>><<<<><<<<>>><>><>><<<>>>><<<><>>><<><<<<>>>><<<<>><<<<>>>><<<>><<<><<<>>>><<<<><<<>><><<<<>>>><<>>>><<<<>>><<>>><>>><<><<<<><<<><<><<<<>>><>>>><<<<><<<<>>>><<<<>>><<>>>><<>>>><>>>><<><<<<><>><<>>>><<<>>><<<<>><<>>><<<>>>><<<>><<<<>><<<><>>><><<<>>><<<>>><<<><<>><<<>><<<>>>><<>><<>>><<<>><>>>><<>>><<<<><><<<>>><<>>><>><<<<>>><<<>>><<>><<<<><<>>><<>>>><<>><>>><<<<><<<<><<<><<<<>>><<>>><<<<>>><<>>>><>>>><<<<>>>><<<>><<<>><<<><>><>>>><<<><<<>>><>>><<<><<>>>><>>>><>>><><<<>>>><<<>>><>><<>>>><<>>><<>>>><<<<>>>><<>>>><<>>><<<>><<<<>>><><<<>>><<<><<<><<<>>>><>>>><><<>>>><<<>><><<<<>>>><<<<>>><<<<>><>><>>>><<<><><>>><<<>>><<<>>>><<>>>><<<<>>><><<>>>><>>><<><<<>>>><<<>>>><<<>>>><>>><>>>><>>><>>><>>><<<<><>>><<<>>><>><<<>>><>>>><<<<>>><<>>>><<><<>>><<><<<<>>><<>>><<><<<<>>><<>><<>>>><<<>>>><<<><><<<<><<<><<><>><<<<>><<>><<<<>><<>>>><<<>>>><<<<>>>><>>>><<<<>><<<>>>><<>>>><<><<>>><<<<><>>>><<<>>>><<<<><<<<>><>>><<<>>><<<<><>><<<><<>>><<>>>><<<><<<>><<<>>><<<>>><<<<>>><<<<>>>><<<>>>><<<><<<<>><<<<>>><<<>><<<>>><>>><<>><>>>><>>>><<<>>><<<>>>><<>>><<<><><<<>>>><<<><<<<>>><<<>>>><><<>>><<>>><<<>>><<<<>>><<<>>>><<<>>>><>>>><<<><<><>>>><<>>>><<<<>><<<><<<<>>><> diff --git a/2022/src/common.rs b/2022/src/common.rs index 53156a2..d52e041 100644 --- a/2022/src/common.rs +++ b/2022/src/common.rs @@ -176,6 +176,15 @@ impl IndexSet { true } } + + pub fn contains(&self, index: usize) -> bool { + let (entry, pos) = Self::index(index); + + self.0 + .get(entry) + .map(|&entry| (entry & (1 << pos) != 0)) + .unwrap_or(false) + } } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] diff --git a/2022/src/day17.rs b/2022/src/day17.rs index acd2238..1d9faf5 100644 --- a/2022/src/day17.rs +++ b/2022/src/day17.rs @@ -1,9 +1,124 @@ use anyhow::Result; -pub fn part1(_input: &[u8]) -> Result { - anyhow::bail!("not implemented") +use crate::common::IndexSet; + +const SHAPES: [&[&[bool]]; 5] = [ + &[&[true; 4]], + &[&[false, true, false], &[true; 3], &[false, true, false]], + &[&[false, false, true], &[false, false, true], &[true; 3]], + &[&[true], &[true], &[true], &[true]], + &[&[true; 2], &[true; 2]], +]; + +const WIDTH: usize = 7; + +#[allow(unused)] +fn print_cavern(cavern: &IndexSet, max_height: usize) { + for y in (0..=max_height).rev() { + for x in 0..7 { + print!( + "{}", + if cavern.contains(y * WIDTH + x) { + '#' + } else { + '.' + } + ); + } + println!(); + } +} + +pub fn part1(input: &[u8]) -> Result { + // Poor man's trim() + let input = if input[input.len() - 1] == b'\n' { + &input[..input.len() - 1] + } else { + input + }; + + let mut cavern = IndexSet::default(); + let mut max_height = 0; + + let mut gusts = input + .iter() + .cycle() + .map(|&b| if b == b'<' { -1 } else { 1 }); + + for &shape in SHAPES.iter().cycle().take(2022) { + let mut x = 2usize; + let mut y = max_height + shape.len() + 2; + + // Acquire gust of wind + 'falling: for offset in gusts.by_ref() { + if let Some(nx) = x.checked_add_signed(offset) { + let mut should_move = true; + + 'collision: for (row, line) in shape.iter().enumerate() { + if nx + line.len() > WIDTH { + should_move = false; + break 'collision; + } + + for (col, &on) in line.iter().enumerate() { + if on && cavern.contains((y - row) * WIDTH + nx + col) { + should_move = false; + break 'collision; + } + } + } + + if should_move { + x = nx; + } + } else { + // Hit the left wall + } + + // Move down if possible + if y >= shape.len() { + let ny = y - 1; + for (row, line) in shape.iter().enumerate() { + // No width check, should not hit that on the way down. + for (col, &on) in line.iter().enumerate() { + if on && cavern.contains((ny - row) * WIDTH + x + col) { + break 'falling; + } + } + } + y = ny; + } else { + break 'falling; + } + } + + // If we get here we've successfully stopped falling + max_height = max_height.max(y + 1); + + for (row, line) in shape.iter().enumerate() { + for (col, &on) in line.iter().enumerate() { + if on { + cavern.insert((y - row) * WIDTH + x + col); + } + } + } + } + + Ok(max_height.to_string()) } pub fn part2(_input: &[u8]) -> Result { anyhow::bail!("not implemented") } + +#[cfg(test)] +mod tests { + use super::*; + + const SAMPLE: &[u8] = include_bytes!("samples/17.txt"); + + #[test] + fn sample_part1() { + assert_eq!(part1(SAMPLE).unwrap(), "3068"); + } +} diff --git a/2022/src/samples/17.txt b/2022/src/samples/17.txt new file mode 100644 index 0000000..97a1aa1 --- /dev/null +++ b/2022/src/samples/17.txt @@ -0,0 +1 @@ +>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>