Day 5, puzzle 1
This commit is contained in:
parent
d1a30ea629
commit
a4299a1fc5
25
src/bin/d5p1.rs
Normal file
25
src/bin/d5p1.rs
Normal 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
97
src/day5.rs
Normal 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,
|
||||
}
|
||||
}
|
@ -2,4 +2,5 @@ pub mod day1;
|
||||
pub mod day2;
|
||||
pub mod day3;
|
||||
pub mod day4;
|
||||
pub mod day5;
|
||||
pub mod util;
|
||||
|
Loading…
x
Reference in New Issue
Block a user