diff --git a/Cargo.toml b/Cargo.toml index 3b1d557..70b3943 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,4 @@ default-run = "p05" [dependencies] num-traits = "0.2" -num-derive = "0.2" +num-derive = "0.2" \ No newline at end of file diff --git a/src/bin/p05.rs b/src/bin/p05.rs index 4cb8770..6d5deec 100644 --- a/src/bin/p05.rs +++ b/src/bin/p05.rs @@ -50,6 +50,30 @@ impl FromStr for CrateStack { #[derive(Debug)] struct Dock(Vec); +impl Dock { + fn perform_directive(&mut self, directive: &MoveDirective) -> bool { + if directive.source >= self.0.len() { + return false; + } + + if directive.dest >= self.0.len() { + return false; + } + + for _ in 0..directive.number { + if let Some(s) = self.0[directive.source].pop() { + self.0[directive.dest].push(s) + } + } + + true + } + + fn tops(&self) -> impl Iterator> { + self.0.iter().map(|s| s.0.iter().last()) + } +} + impl FromStr for Dock { type Err = &'static str; @@ -77,25 +101,73 @@ impl FromStr for Dock { } } } - dbg!(&result); - Ok(Dock(result)) } } +#[derive(Debug)] +struct MoveDirective { + number: u32, + source: usize, + dest: usize, +} + +#[derive(Debug, Clone)] +struct MoveError; + +impl FromStr for MoveDirective { + type Err = MoveError; + + fn from_str(s: &str) -> Result { + let (count, movement_str) = s + .trim_start_matches("move ") + .split_once(" from ") + .ok_or(MoveError)?; + let (first, second) = movement_str.split_once(" to ").ok_or(MoveError)?; + + let source: usize = first.parse().map_err(|_| MoveError)?; + let dest: usize = second.parse().map_err(|_| MoveError)?; + + Ok(MoveDirective { + number: count.parse().map_err(|_| MoveError)?, + source: source - 1, + dest: dest - 1, + }) + } +} + fn main() { let filename = "etc/p05.txt"; let string = fs::read_to_string(filename).expect("Can't open file"); - let dock: Dock = string.split("\n\n").next().expect("first section").parse::().expect("can't parse dock"); - dbg!(dock); + let mut split = string.split("\n\n"); + + let dock: Dock = split + .next() + .expect("first section") + .parse::() + .expect("can't parse dock"); + + let moves: Vec = split + .next() + .expect("Can't find moves") + .lines() + .map(|l| l.parse::().expect("Can't parse move")) + .collect(); println!("PART ONE ---------------"); + part1(dock, &moves); println!("\n PART TWO ---------------"); } -fn part1() {} +fn part1(mut dock: Dock, moves: &[MoveDirective]) { + for m in moves { + dock.perform_directive(m); + } + + dbg!(dock.tops().flatten().map(|c| c.0).collect::()); +} fn part2() {}