Cleaned up

This commit is contained in:
Daniel Flanagan 2022-12-05 00:16:53 -06:00
parent cf69f9f93d
commit b13a6a8221
Signed by: lytedev
GPG Key ID: 5B2020A0F9921EF4
1 changed files with 47 additions and 61 deletions

View File

@ -1,58 +1,54 @@
mod common; mod common;
#[derive(Debug)] #[derive(Clone)]
struct Move { struct Move {
amount: i32, amount: i32,
from: usize, from: usize,
to: usize, to: usize,
} }
#[derive(Debug)] #[derive(Clone)]
struct Crates { struct Crates {
stacks: Vec<Vec<char>>, stacks: Vec<Vec<char>>,
moves: Vec<Move>, moves: Vec<Move>,
} }
const NUM_STACKS: usize = 9;
type Input = Crates; type Input = Crates;
type Result = String; type Result = String;
fn processed_input(input: &str) -> Input { fn processed_input(input: &str) -> Input {
let mut stacks: Vec<Vec<char>> = vec![];
let mut moves: Vec<Move> = vec![]; let mut moves: Vec<Move> = vec![];
for _ in 0..NUM_STACKS { // scan for the line that denotes the stack numbers (it's the line that starts with " 1")
stacks.push(vec![]); let stacks_index = input.find("\n 1").unwrap() + 1;
} let first_slice = &input[stacks_index..];
// calculate the number of stacks based on the length of that line
// we do this by subtracting 3 (" 1 ") and then dividing by 4 (" 2 ", " 3 ", ... " 9 ")
// the last stack number includes the trailing space, so this math holds up
let end_head_index = first_slice.find('\n').unwrap();
let num_stacks = ((&first_slice[0..end_head_index].len() - 3) / 4) + 1;
let mut stacks: Vec<Vec<char>> = (0..num_stacks).map(|_| vec![]).collect();
let mut parsing_stacks = true; // parse the stacks from the bottom up
for l in input.lines() { for l in input[0..stacks_index].lines().rev() {
if l.trim() == "" || l.chars().skip(1).next().unwrap() == '1' { let mut x = 0;
parsing_stacks = false; for c in l.chars().skip(1).step_by(4) {
continue; x += 1;
} else if parsing_stacks { if c == ' ' {
let mut x = 0; continue;
for c in l.chars().skip(1).step_by(4) {
x += 1;
if c == ' ' {
continue;
}
stacks[x - 1].push(c);
} }
} else { stacks[x - 1].push(c);
let words: Vec<&str> = l.split_whitespace().collect();
println!("words: {:?}", words);
moves.push(Move {
amount: words[1].parse().unwrap(),
from: words[3].parse::<usize>().unwrap() - 1,
to: words[5].parse::<usize>().unwrap() - 1,
})
} }
} }
for s in &mut stacks[..] { // parse the moves
s.reverse(); for l in input[stacks_index + end_head_index + 2..].lines() {
let words: Vec<&str> = l.split_whitespace().collect();
moves.push(Move {
amount: words[1].parse().unwrap(),
from: words[3].parse::<usize>().unwrap() - 1,
to: words[5].parse::<usize>().unwrap() - 1,
})
} }
Crates { stacks, moves } Crates { stacks, moves }
@ -61,63 +57,54 @@ fn processed_input(input: &str) -> Input {
fn perform_moves(crates: &mut Crates) { fn perform_moves(crates: &mut Crates) {
let stacks = &mut crates.stacks; let stacks = &mut crates.stacks;
for Move { amount, from, to } in &crates.moves { for Move { amount, from, to } in &crates.moves {
println!("move: {} {} {}", amount, from, to);
for _ in 0..*amount { for _ in 0..*amount {
let popped = stacks[*from].pop().unwrap(); let popped = stacks[*from].pop().unwrap();
stacks[*to].push(popped); stacks[*to].push(popped);
} }
println!("{:?}", stacks);
} }
} }
fn part1(input: &mut Input) -> Result { fn part1(input: &mut Input) -> Result {
println!("{:?}", input);
perform_moves(input); perform_moves(input);
let mut r = String::from(""); input
for s in &input.stacks { .stacks
r.push(s.last().unwrap_or(&' ').clone()) .iter()
} .map(|s| s.last().unwrap_or(&' ').clone())
r.trim().to_string() .collect::<String>()
.trim()
.to_string()
} }
fn perform_moves2(crates: &mut Crates) { fn perform_moves2(crates: &mut Crates) {
let stacks = &mut crates.stacks; let stacks = &mut crates.stacks;
for Move { amount, from, to } in &crates.moves { for Move { amount, from, to } in &crates.moves {
println!("move: {} {} {}", amount, from, to); let f = &mut stacks[*from];
let l = stacks[*from].len(); let ra = (f.len() - (*amount as usize))..;
println!("len: {:?}", l); let mut popped: Vec<char> = f.splice(ra, vec![]).collect();
let ra = l - (*amount as usize)..l;
let mut popped: Vec<char> = stacks[*from].splice(ra, vec![]).collect();
stacks[*to].append(&mut popped); stacks[*to].append(&mut popped);
println!("{:?}", stacks);
} }
} }
fn part2(input: &mut Input) -> Result { fn part2(input: &mut Input) -> Result {
println!("{:?}", input);
perform_moves2(input); perform_moves2(input);
let mut r = String::from(""); input
for s in &input.stacks { .stacks
r.push(s.last().unwrap_or(&' ').clone()) .iter()
} .map(|s| s.last().unwrap_or(&' ').clone())
r.trim().to_string() .collect::<String>()
.trim()
.to_string()
} }
fn main() { fn main() {
let input_text = common::day_input(5); let input_text = common::day_input(5);
eprintln!("{}\n\nAbove is your input file.\n\n", input_text);
let mut input = processed_input(&input_text); let mut input = processed_input(&input_text);
let mut input2 = processed_input(&input_text); let mut input2 = input.clone();
common::show_answers(&part1(&mut input), &part2(&mut input2)) common::show_answers(&part1(&mut input), &part2(&mut input2))
// common::show_both_answers(&both_parts(&input))
} }
// fn both_parts(input: &Input) -> (Result, Result) {
// (0, 0)
// }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -135,9 +122,8 @@ move 1 from 1 to 2";
#[test] #[test]
fn test() { fn test() {
let mut input = processed_input(TEST_INPUT); let mut input = processed_input(TEST_INPUT);
let mut input2 = input.clone();
assert_eq!(part1(&mut input), "CMZ"); assert_eq!(part1(&mut input), "CMZ");
let mut input = processed_input(TEST_INPUT); assert_eq!(part2(&mut input2), "MCD");
assert_eq!(part2(&mut input), "MCD");
// assert_eq!(both_parts(&input), (0, 0));
} }
} }