Day 5, Part 1!

This commit is contained in:
Eryn Wells 2022-12-05 18:17:25 -08:00
parent 3b46147c27
commit dbc711e50d
3 changed files with 651 additions and 0 deletions

133
2022/aoc2022/src/day5.rs Normal file
View file

@ -0,0 +1,133 @@
use std::fmt;
use std::io::Result;
use crate::file::line_reader_for_file;
#[derive(PartialEq)]
enum State {
StartingState,
Instructions
}
#[derive(Debug)]
struct Stacks(Vec<Vec<String>>);
impl Stacks {
fn perform(&mut self, instruction: Instruction) -> std::result::Result<(), &'static str> {
for _ in 0..instruction.quantity {
let item = self.0[instruction.from_stack].pop().unwrap();
self.0[instruction.to_stack].push(item);
}
Ok(())
}
fn tops(&self) -> impl Iterator<Item = &str> {
self.0.iter().filter_map(|s| s.last()).map(|s| s.as_str())
}
}
impl fmt::Display for Stacks {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0.iter().enumerate()
.map(|(i, v)| format!("{}: {}", i, v.join(", ")))
.collect::<Vec<String>>()
.join("\n"))
}
}
#[derive(Debug)]
struct Instruction {
quantity: usize,
from_stack: usize,
to_stack: usize
}
impl TryFrom<&str> for Instruction {
type Error = &'static str;
fn try_from(s: &str) -> std::result::Result<Instruction, Self::Error> {
let quantity: usize;
let from_stack: usize;
let to_stack: usize;
let mut split_str = s.split(" ");
if split_str.next() != Some("move") {
return Err("Missing 'move'");
}
match split_str.next().map(|s| usize::from_str_radix(s, 10)) {
Some(Ok(parsed_quantity)) => quantity = parsed_quantity,
_ => return Err("Missing quantity value"),
}
if split_str.next() != Some("from") {
return Err("Missing 'from'");
}
match split_str.next().map(|s| usize::from_str_radix(s, 10)) {
Some(Ok(parsed_from_stack)) => from_stack = parsed_from_stack - 1,
_ => return Err("Missing from value"),
}
if split_str.next() != Some("to") {
return Err("Missing 'to'");
}
match split_str.next().map(|s| usize::from_str_radix(s, 10)) {
Some(Ok(parsed_to_stack)) => to_stack = parsed_to_stack - 1,
_ => return Err("Missing to value"),
}
Ok(Instruction {
quantity: quantity,
from_stack: from_stack,
to_stack: to_stack,
})
}
}
pub fn main(filename: &str) -> Result<()> {
let mut line_reader = line_reader_for_file(filename)?.peekable();
let first_line = line_reader.peek().unwrap().as_ref().unwrap();
let number_of_stacks = (first_line.len() as f32 / 4.0).ceil() as usize;
let mut stacks = Stacks(vec![vec![]; number_of_stacks]);
let mut state = State::StartingState;
for line in line_reader {
let line = line?;
if line.is_empty() {
assert!(state == State::StartingState);
state = State::Instructions;
continue;
}
match state {
State::StartingState => {
let mut chars = line.chars().peekable();
let mut index_of_stack = 0;
while chars.peek() != None {
// Read the line in 4 character chunks.
let stack: Vec<char> = chars.by_ref().take(4).collect();
if stack[0] == '[' {
stacks.0[index_of_stack].insert(0, String::from(stack[1]));
}
index_of_stack += 1;
}
},
State::Instructions => {
let instruction = Instruction::try_from(line.as_str()).unwrap();
let _ = stacks.perform(instruction);
},
}
}
println!("{}", stacks);
println!("Part 1: tops of stacks: {}", stacks.tops().collect::<Vec<&str>>().join(""));
Ok(())
}

View file

@ -4,6 +4,7 @@ mod day1;
mod day2;
mod day3;
mod day4;
mod day5;
mod file;
fn main() {
@ -30,4 +31,9 @@ fn main() {
let day4_datafile = &args[4];
day4::main(day4_datafile.as_str())
.expect("Unable to process day4 data file");
println!("----- Day 5 -----");
let day5_datafile = &args[5];
day5::main(day5_datafile.as_str())
.expect("Unable to process day5 data file");
}