Finished aoc day 17 part 1, freakin tetris
This commit is contained in:
32
advent_of_code/2022/17/Cargo.lock
generated
Normal file
32
advent_of_code/2022/17/Cargo.lock
generated
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "main"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
9
advent_of_code/2022/17/Cargo.toml
Normal file
9
advent_of_code/2022/17/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "main"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nom = "7.1.2"
|
||||||
1
advent_of_code/2022/17/input.txt
Normal file
1
advent_of_code/2022/17/input.txt
Normal file
File diff suppressed because one or more lines are too long
218
advent_of_code/2022/17/src/main.rs
Normal file
218
advent_of_code/2022/17/src/main.rs
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
use std::cmp::max;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use nom::{branch::alt, character::complete::char, multi::many1, IResult, Parser};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
enum Dir {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
use Dir::*;
|
||||||
|
|
||||||
|
struct Jets {
|
||||||
|
dirs: Vec<Dir>,
|
||||||
|
current_jet_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Jets {
|
||||||
|
fn next(&mut self) -> Dir {
|
||||||
|
let dir = self.dirs[self.current_jet_index];
|
||||||
|
self.current_jet_index = (self.current_jet_index + 1) % self.dirs.len();
|
||||||
|
dir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Shape {
|
||||||
|
HorLine,
|
||||||
|
Plus,
|
||||||
|
LShape,
|
||||||
|
VerLine,
|
||||||
|
Block,
|
||||||
|
}
|
||||||
|
use Shape::*;
|
||||||
|
|
||||||
|
impl Shape {
|
||||||
|
fn next(&self) -> Shape {
|
||||||
|
match self {
|
||||||
|
HorLine => Plus,
|
||||||
|
Plus => LShape,
|
||||||
|
LShape => VerLine,
|
||||||
|
VerLine => Block,
|
||||||
|
Block => HorLine,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn height(&self) -> u32 {
|
||||||
|
self.left().len() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn width(&self) -> u32 {
|
||||||
|
self.under().len() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn under(&self) -> Vec<u32> {
|
||||||
|
match self {
|
||||||
|
HorLine => vec![0, 0, 0, 0],
|
||||||
|
Plus => vec![1, 0, 1],
|
||||||
|
LShape => vec![0, 0, 0],
|
||||||
|
VerLine => vec![0],
|
||||||
|
Block => vec![0, 0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn left(&self) -> Vec<u32> {
|
||||||
|
match self {
|
||||||
|
HorLine => vec![0],
|
||||||
|
Plus => vec![1, 0, 1],
|
||||||
|
LShape => vec![0, 2, 2],
|
||||||
|
VerLine => vec![0, 0, 0, 0],
|
||||||
|
Block => vec![0, 0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn right(&self) -> Vec<u32> {
|
||||||
|
match self {
|
||||||
|
HorLine => vec![0],
|
||||||
|
Plus => vec![1, 0, 1],
|
||||||
|
LShape => vec![0, 0, 0],
|
||||||
|
VerLine => vec![0, 0, 0, 0],
|
||||||
|
Block => vec![0, 0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shape(&self) -> Vec<(u32, u32)> {
|
||||||
|
match self {
|
||||||
|
HorLine => vec![(0, 0), (1, 0), (2, 0), (3, 0)],
|
||||||
|
Plus => vec![(1, 0), (0, 1), (1, 1), (2, 1), (1, 2)],
|
||||||
|
LShape => vec![(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)],
|
||||||
|
VerLine => vec![(0, 0), (0, 1), (0, 2), (0, 3)],
|
||||||
|
Block => vec![(0, 0), (0, 1), (1, 0), (1, 1)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(input: &str) -> IResult<&str, Jets> {
|
||||||
|
let (input, dirs) = many1(alt((char('<').map(|_| Left), char('>').map(|_| Right))))(input)?;
|
||||||
|
|
||||||
|
let jets = Jets {
|
||||||
|
dirs,
|
||||||
|
current_jet_index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((input, jets))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_cave(cave_map: &HashSet<(u32, u32)>, falling_shape: &Shape, shape_coord: &(u32, u32)) {
|
||||||
|
let shape_coords: Vec<(u32, u32)> = falling_shape
|
||||||
|
.shape()
|
||||||
|
.iter()
|
||||||
|
.map(|&(x, y)| (shape_coord.0 + x, shape_coord.1 + y))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let max_height = shape_coord.1 + falling_shape.height() - 1;
|
||||||
|
|
||||||
|
for height in 0..max_height {
|
||||||
|
let y = max_height - height;
|
||||||
|
|
||||||
|
print!("|");
|
||||||
|
|
||||||
|
for x in 1..=7 {
|
||||||
|
if cave_map.contains(&(x, y)) {
|
||||||
|
print!("#");
|
||||||
|
} else if shape_coords.contains(&(x, y)) {
|
||||||
|
print!("@");
|
||||||
|
} else {
|
||||||
|
print!(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("|");
|
||||||
|
}
|
||||||
|
println!("+-------+");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fall(
|
||||||
|
cave_map: &mut HashSet<(u32, u32)>,
|
||||||
|
jetstream: &mut Jets,
|
||||||
|
falling_shape: &Shape,
|
||||||
|
highest_unit: u32,
|
||||||
|
) -> u32 {
|
||||||
|
let mut rock_coord = (3, highest_unit + 4);
|
||||||
|
let shape_under = falling_shape.under();
|
||||||
|
let shape_right = falling_shape.right();
|
||||||
|
let shape_left = falling_shape.left();
|
||||||
|
let shape_width = falling_shape.width();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// First, move the shape to the left or right
|
||||||
|
let jet_dir = jetstream.next();
|
||||||
|
// match jet_dir {
|
||||||
|
// Right => println!("Jet: Right"),
|
||||||
|
// Left => println!("Jet: Left"),
|
||||||
|
// }
|
||||||
|
|
||||||
|
if jet_dir == Left {
|
||||||
|
if rock_coord.0 > 1 {
|
||||||
|
let move_result = shape_left.iter().enumerate().any(|(index, &indent)| {
|
||||||
|
cave_map.contains(&(rock_coord.0 + indent - 1, rock_coord.1 + index as u32))
|
||||||
|
});
|
||||||
|
if !move_result {
|
||||||
|
rock_coord = (rock_coord.0 - 1, rock_coord.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if rock_coord.0 + shape_width < 8 {
|
||||||
|
let move_result = shape_right.iter().enumerate().any(|(index, &indent)| {
|
||||||
|
cave_map.contains(&(
|
||||||
|
rock_coord.0 + shape_width - indent,
|
||||||
|
rock_coord.1 + index as u32,
|
||||||
|
))
|
||||||
|
});
|
||||||
|
if !move_result {
|
||||||
|
rock_coord = (rock_coord.0 + 1, rock_coord.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw_cave(&cave_map, &falling_shape, &rock_coord);
|
||||||
|
|
||||||
|
// Then, move the shape down
|
||||||
|
if rock_coord.1 > 1
|
||||||
|
&& !shape_under.iter().enumerate().any(|(index, &indent)| {
|
||||||
|
cave_map.contains(&(rock_coord.0 + index as u32, rock_coord.1 + indent - 1))
|
||||||
|
})
|
||||||
|
{
|
||||||
|
rock_coord = (rock_coord.0, rock_coord.1 - 1);
|
||||||
|
} else {
|
||||||
|
for (x_indent, y_indent) in falling_shape.shape() {
|
||||||
|
cave_map.insert((rock_coord.0 + x_indent, rock_coord.1 + y_indent));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw_cave(&cave_map, &falling_shape, &rock_coord);
|
||||||
|
|
||||||
|
max(rock_coord.1 + falling_shape.height() - 1, highest_unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input_text = include_str!("../input.txt");
|
||||||
|
let (_rest, mut jetstream) = parse_input(input_text).unwrap();
|
||||||
|
|
||||||
|
let mut number_of_rocks = 2022;
|
||||||
|
let mut cave_map: HashSet<(u32, u32)> = HashSet::new();
|
||||||
|
let mut highest_unit = 0;
|
||||||
|
let mut falling_rock = HorLine;
|
||||||
|
|
||||||
|
while number_of_rocks > 0 {
|
||||||
|
highest_unit = fall(&mut cave_map, &mut jetstream, &falling_rock, highest_unit);
|
||||||
|
|
||||||
|
falling_rock = falling_rock.next();
|
||||||
|
number_of_rocks -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Height of the rock pile: {highest_unit}");
|
||||||
|
}
|
||||||
1
advent_of_code/2022/17/test.txt
Normal file
1
advent_of_code/2022/17/test.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
||||||
Reference in New Issue
Block a user