diff --git a/src/main.rs b/src/main.rs index c819d59..a54c547 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,14 @@ #![feature(test)] extern crate test; -const INPUTS: [&str; 2] = [ - include_str!("../inputs/sample.txt"), - include_str!("../inputs/input.txt"), +const INPUTS: [&[u8]; 2] = [ + include_bytes!("../inputs/sample.txt"), + include_bytes!("../inputs/input.txt"), ]; #[derive(Debug)] struct Stack { - stacks: Vec>, + stacks: Vec>, instructions: Vec, } @@ -19,63 +19,79 @@ struct Instruction { to: usize, } -fn parse(input: &'static str) -> Stack { - let mut v = input.split("\n\n"); +fn parse(input: &[u8]) -> Stack { + let mut stacks = vec![]; - let mut stack_input = v - .next() - .unwrap() - .lines() - .map(|c| c.chars().collect::>()) - .rev(); - let mut stacks: Vec> = vec![]; + let mut input = input.splitn(2, |&c| c == b'\n'); + let mut line = input.next().unwrap(); + let mut rest = input.next().unwrap(); - let stack_names = stack_input.next().unwrap(); + while rest[0] != b'\n' { + let mut i = 1; - let containers: Vec> = stack_input.collect(); - - for (i, v) in stack_names.into_iter().enumerate() { - if v == ' ' { - continue; - } - let v: usize = (v as u8 - b'0') as usize; - - if stacks.len() <= v - 1 { - stacks.push(vec![]); - } - - for container in containers.iter() { - if container[i] == ' ' { - continue; + while (3 * (i - 1) + i) < line.len() { + if stacks.len() < i { + stacks.push(vec![]); } - stacks[v - 1].push(container[i]); + + if (b'A'..=b'Z').contains(&line[3 * (i - 1) + i]) { + stacks[i - 1].push(line[3 * (i - 1) + i]); + } + + i += 1; + } + + let mut temp = rest.splitn(2, |&c| c == b'\n'); + line = temp.next().unwrap(); + rest = temp.next().unwrap(); + } + rest = &rest[1..]; + let stacks: Vec> = stacks + .into_iter() + .map(|c| c.into_iter().rev().collect()) + .collect(); + + let mut input = rest.splitn(2, |&c| c == b'\n'); + let mut line = input.next(); + let mut rest = input.next(); + + let mut instructions = vec![]; + + while let Some(l) = line { + let l: Vec = l + .iter() + .filter(|&c| (b'0'..=b'9').contains(c) || c == &b' ') + .cloned() + .collect(); + + if l.is_empty() { + break; + } + + let numbers: Vec = l + .split(|&c| c == b' ') + .filter(|c| !c.is_empty()) + .map(|c| { + c.get(1) + .map_or(c[0] - b'0', |a| (c[0] - b'0') * 10 + a - b'0') + }) + .collect(); + + instructions.push(Instruction { + count: numbers[0] as usize, + from: numbers[1] as usize, + to: numbers[2] as usize, + }); + + if let Some(r) = rest { + let mut input = r.splitn(2, |&c| c == b'\n'); + line = input.next(); + rest = input.next(); + } else { + break; } } - let instructions: Vec = v - .next() - .unwrap() - .lines() - .map(|line: &str| { - let line: String = line - .chars() - .filter(|c| c.is_numeric() | c.is_whitespace()) - .collect(); - - let numbers: Vec = line - .split(' ') - .filter(|c| !c.is_empty()) - .map(|c| c.parse::().unwrap()) - .collect(); - - Instruction { - count: numbers[0] as usize, - from: numbers[1] as usize, - to: numbers[2] as usize, - } - }) - .collect(); - Stack { instructions, stacks, @@ -95,7 +111,7 @@ fn solution(mut input: Stack) -> String { for ins in input.instructions { let l = input.stacks[ins.from - 1].len(); - let crates: Vec = input.stacks[ins.from - 1] + let crates: Vec = input.stacks[ins.from - 1] .drain(l.saturating_sub(ins.count)..l) .collect(); @@ -109,6 +125,7 @@ fn solution(mut input: Stack) -> String { .into_iter() .filter(|c| !c.is_empty()) .map(|c| *c.last().unwrap()) + .map(|c| c as char) .collect() }