Simplified solution

This commit is contained in:
Dreaded_X 2022-12-06 00:47:50 +01:00
parent 381ecb2f85
commit 5554cfedb3
Signed by: Dreaded_X
GPG Key ID: 76BDEC4E165D8AD9

View File

@ -49,7 +49,7 @@ impl fmt::Display for Boat {
for i in 0..self.stacks.len() { for i in 0..self.stacks.len() {
match self.top(i+1) { match self.top(i+1) {
Some(cr) => write!(f, "{}", cr.letter)?, Some(cr) => write!(f, "{}", cr.letter)?,
None => panic!("No crate in stack") None => write!(f, " ")?,
} }
} }
@ -75,23 +75,26 @@ impl Boat {
} }
// Because of how we load the data, each stack is upside down // Because of how we load the data, each stack is upside down
boat.reverse(); for stack in boat.stacks.iter_mut() {
stack.1.reverse()
}
return boat; return boat;
} }
fn push(&mut self, index: usize, cr: Crate) { fn take(&mut self, index: usize, amount: usize) -> Vec<Crate> {
let stack = self.stacks.entry(index).or_insert(vec![]); let stack = self.stacks.entry(index).or_default();
stack.push(cr); stack.split_off(stack.len()-amount)
} }
fn pop(&mut self, index: usize) -> Option<Crate> { fn put(&mut self, index: usize, mut vec: Vec<Crate>) {
let stack = match self.stacks.get_mut(&index) { let stack = self.stacks.entry(index).or_default();
Some(s) => s, stack.append(&mut vec);
None => return None, }
};
stack.pop() fn push(&mut self, index: usize, cr: Crate) {
let stack = self.stacks.entry(index).or_default();
stack.push(cr);
} }
fn top(&self, index: usize) -> Option<&Crate> { fn top(&self, index: usize) -> Option<&Crate> {
@ -102,16 +105,9 @@ impl Boat {
stack.last() stack.last()
} }
fn reverse(&mut self) {
for stack in self.stacks.iter_mut() {
stack.1.reverse()
}
}
} }
// -- Helpers -- // -- Helpers --
fn parse_instruction(s: &str) -> (usize, usize, usize) { fn parse_instruction(s: &str) -> (usize, usize, usize) {
lazy_static! { lazy_static! {
static ref RE: Regex = Regex::new(r"move (?P<amount>[0-9]+) from (?P<from>[0-9]) to (?P<to>[0-9])").unwrap(); static ref RE: Regex = Regex::new(r"move (?P<amount>[0-9]+) from (?P<from>[0-9]) to (?P<to>[0-9])").unwrap();
@ -127,6 +123,31 @@ fn parse_instruction(s: &str) -> (usize, usize, usize) {
(amount, from, to) (amount, from, to)
} }
fn solution(input: &str, reverse: bool) -> Output {
// The current layout description ends with an empty line
let mut boat = Boat::new(&input
.lines()
.take_while(|line| !line.is_empty())
.collect());
// Each instruction starts with an 'm'
input
.lines()
.skip_while(|line| !line.starts_with('m'))
.map(parse_instruction)
.for_each(|(amount, from, to)| {
let mut taken = boat.take(from, amount);
// The order needs to be reversed in part due to the crates being moves one at the time
// instead of the whole stack at once as happens in part 2
if reverse {
taken.reverse();
}
boat.put(to, taken);
});
Output::String(boat.to_string())
}
// -- Solution -- // -- Solution --
pub struct Day; pub struct Day;
impl aoc::Solver for Day { impl aoc::Solver for Day {
@ -135,55 +156,10 @@ impl aoc::Solver for Day {
} }
fn part1(input: &str) -> Output { fn part1(input: &str) -> Output {
// The current layout description ends with an empty line solution(input, true)
let mut boat = Boat::new(&input
.lines()
.take_while(|line| !line.is_empty())
.collect());
// Each instruction starts with an 'm'
input
.lines()
.skip_while(|line| !line.starts_with('m'))
.map(parse_instruction)
.for_each(|(amount, from, to)| {
for _ in 0..amount {
let cr = boat.pop(from).unwrap();
boat.push(to, cr);
}
});
Output::String(boat.to_string())
} }
fn part2(input: &str) -> Output { fn part2(input: &str) -> Output {
// The current layout description ends with an empty line solution(input, false)
let mut boat = Boat::new(&input
.lines()
.take_while(|line| !line.is_empty())
.collect());
// Each instruction starts with an 'm'
input
.lines()
.skip_while(|line| !line.starts_with('m'))
.map(parse_instruction)
.for_each(|(amount, from, to)| {
// @TODO Is there a nicer way to do this?
let mut temp = vec![];
for _ in 0..amount {
let cr = boat.pop(from).unwrap();
temp.push(cr);
}
temp.reverse();
for cr in temp {
boat.push(to, cr);
}
});
Output::String(boat.to_string())
} }
} }