Day 5, puzzle 1

This commit is contained in:
jazzpi 2022-12-13 16:38:31 +01:00
parent d1a30ea629
commit a4299a1fc5
3 changed files with 123 additions and 0 deletions

25
src/bin/d5p1.rs Normal file
View File

@ -0,0 +1,25 @@
use aoc22::{day5, util};
pub fn main() {
let mut arrangement = day5::parse_arrangement(&util::parse_input());
for inst in &arrangement.instructions {
for _ in 0..inst.num {
let box_ = arrangement
.stacks
.get_mut(inst.from)
.unwrap()
.pop_back()
.unwrap();
arrangement.stacks.get_mut(inst.to).unwrap().push_back(box_);
}
}
let top_boxes: String = arrangement
.stacks
.iter()
.map(|s| s.iter().next_back().unwrap())
.collect();
println!("The top boxes are {}", top_boxes);
}

97
src/day5.rs Normal file
View File

@ -0,0 +1,97 @@
use std::collections::VecDeque;
use regex::Regex;
#[derive(Debug)]
pub struct Instruction {
pub num: usize,
pub from: usize,
pub to: usize,
}
#[derive(Debug)]
pub struct Arrangement {
pub stacks: Vec<VecDeque<char>>,
pub instructions: Vec<Instruction>,
}
fn parse_stack(line: &str) -> impl Iterator<Item = Option<char>> + '_ {
line.as_bytes().chunks(4).map(|b| -> Option<char> {
if *b.get(0).unwrap() as char == '[' {
Some(*b.get(1).unwrap() as char)
} else {
None
}
})
}
fn parse_instruction(line: &str) -> Instruction {
let re = Regex::new(r"move (\d+) from (\d+) to (\d+)").unwrap();
let captures = re.captures(line).unwrap();
Instruction {
num: captures.get(1).unwrap().as_str().parse().unwrap(),
from: captures.get(2).unwrap().as_str().parse::<usize>().unwrap() - 1,
to: captures.get(3).unwrap().as_str().parse::<usize>().unwrap() - 1,
}
}
#[derive(Debug, Clone, Copy)]
enum ParseState {
Stacks,
StackNumbers,
Instructions,
}
pub fn parse_arrangement(input: &String) -> Arrangement {
let lines: Vec<_> = input.lines().collect();
let first_line = lines.get(0).unwrap();
let length = first_line.len();
// Each stack is 3 characters long, all but the last have a space following
// them.
assert!(length % 4 == 3);
let n_stacks = (length - 3) / 4 + 1;
let mut stacks: Vec<VecDeque<char>> = Vec::with_capacity(n_stacks);
for _ in 0..n_stacks {
stacks.push(VecDeque::new());
}
let mut instructions = Vec::new();
let mut state = ParseState::Stacks;
for line in lines.iter() {
state = match state {
ParseState::Stacks => {
if line.contains('[') {
ParseState::Stacks
} else {
ParseState::StackNumbers
}
}
ParseState::StackNumbers => {
if line.starts_with("move") {
ParseState::Instructions
} else {
ParseState::StackNumbers
}
}
ParseState::Instructions => ParseState::Instructions,
};
match state {
ParseState::Stacks => {
for (i, box_) in parse_stack(line).enumerate() {
if let Some(c) = box_ {
stacks.get_mut(i).unwrap().push_front(c);
}
}
}
ParseState::StackNumbers => { /* Nothing to do here */ }
ParseState::Instructions => instructions.push(parse_instruction(line)),
}
}
Arrangement {
stacks,
instructions,
}
}

View File

@ -2,4 +2,5 @@ pub mod day1;
pub mod day2;
pub mod day3;
pub mod day4;
pub mod day5;
pub mod util;