Add day15 part 1
This commit is contained in:
parent
4f5c52e553
commit
b813526dfe
16
day15/Cargo.lock
generated
Normal file
16
day15/Cargo.lock
generated
Normal file
@ -0,0 +1,16 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "day15"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"glam",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.29.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677"
|
||||
7
day15/Cargo.toml
Normal file
7
day15/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "day15"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
glam = "0.29.2"
|
||||
161
day15/src/main.rs
Normal file
161
day15/src/main.rs
Normal file
@ -0,0 +1,161 @@
|
||||
use std::{collections::VecDeque, fmt::Display};
|
||||
|
||||
use glam::IVec2;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum Tile {
|
||||
Wall,
|
||||
Robot,
|
||||
Box,
|
||||
Empty,
|
||||
}
|
||||
use Tile::*;
|
||||
|
||||
impl Display for Tile {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Wall => write!(f, "#"),
|
||||
Robot => write!(f, "@"),
|
||||
Box => write!(f, "O"),
|
||||
Empty => write!(f, "."),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
use Direction::*;
|
||||
|
||||
impl Direction {
|
||||
fn as_vec(&self) -> IVec2 {
|
||||
match self {
|
||||
Up => IVec2::new(-1, 0),
|
||||
Down => IVec2::new(1, 0),
|
||||
Left => IVec2::new(0, -1),
|
||||
Right => IVec2::new(0, 1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct State {
|
||||
map: Vec<Vec<Tile>>,
|
||||
directions: VecDeque<Direction>,
|
||||
robot_pos: IVec2,
|
||||
}
|
||||
|
||||
impl Display for State {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
self.map
|
||||
.iter()
|
||||
.map(|l| l.iter().map(|t| t.to_string()).collect::<String>() + "\n")
|
||||
.collect::<String>()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(input: &str) -> State {
|
||||
let (map, directions) = input.split_once("\n\n").unwrap();
|
||||
let mut robot_pos = IVec2::new(0, 0);
|
||||
State {
|
||||
map: map
|
||||
.lines()
|
||||
.enumerate()
|
||||
.map(|(l_idx, l)| {
|
||||
l.chars()
|
||||
.enumerate()
|
||||
.map(|(c_idx, c)| match c {
|
||||
'#' => Wall,
|
||||
'@' => {
|
||||
robot_pos.x = l_idx as i32;
|
||||
robot_pos.y = c_idx as i32;
|
||||
Robot
|
||||
}
|
||||
'O' => Box,
|
||||
_ => Empty,
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect(),
|
||||
directions: directions
|
||||
.replace("\n", "")
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
'<' => Left,
|
||||
'^' => Up,
|
||||
'>' => Right,
|
||||
'v' => Down,
|
||||
_ => panic!(),
|
||||
})
|
||||
.collect(),
|
||||
robot_pos,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_tile<'a>(map: &'a mut [Vec<Tile>], idx: &IVec2) -> &'a mut Tile {
|
||||
&mut map[idx.x as usize][idx.y as usize]
|
||||
}
|
||||
|
||||
fn do_move(state: &mut State) {
|
||||
let dir = state.directions.pop_front().unwrap().as_vec();
|
||||
let pos_in_front = state.robot_pos + dir;
|
||||
|
||||
if get_tile(&mut state.map, &pos_in_front) == &Wall {
|
||||
return;
|
||||
}
|
||||
|
||||
if get_tile(&mut state.map, &pos_in_front) == &Empty {
|
||||
*get_tile(&mut state.map, &pos_in_front) = Robot;
|
||||
*get_tile(&mut state.map, &state.robot_pos) = Empty;
|
||||
state.robot_pos = pos_in_front;
|
||||
return;
|
||||
}
|
||||
|
||||
let mut curr = pos_in_front;
|
||||
while get_tile(&mut state.map, &curr) != &Wall && get_tile(&mut state.map, &curr) != &Empty {
|
||||
curr += dir;
|
||||
}
|
||||
if get_tile(&mut state.map, &curr) == &Wall {
|
||||
return;
|
||||
}
|
||||
*get_tile(&mut state.map, &curr) = Box;
|
||||
*get_tile(&mut state.map, &pos_in_front) = Robot;
|
||||
*get_tile(&mut state.map, &state.robot_pos) = Empty;
|
||||
state.robot_pos = pos_in_front;
|
||||
}
|
||||
|
||||
fn part1(state: &mut State) -> usize {
|
||||
while !state.directions.is_empty() {
|
||||
do_move(state);
|
||||
}
|
||||
state
|
||||
.map
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(l_idx, l)| {
|
||||
l.iter().enumerate().map(
|
||||
move |(t_idx, t)| {
|
||||
if t == &Box {
|
||||
100 * l_idx + t_idx
|
||||
} else {
|
||||
0
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut input = parse(include_str!("../input.txt"));
|
||||
println!("{}", part1(&mut input));
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user