103 lines
2.6 KiB
Rust
103 lines
2.6 KiB
Rust
use aoc_runner_derive::{aoc, aoc_generator};
|
|
use itertools::Itertools;
|
|
|
|
fn get_many_mut<T>(vec: &mut [T], i: [usize; 2]) -> [&mut T; 2] {
|
|
if i[0] == i[1] {
|
|
panic!("no")
|
|
} else {
|
|
let a = &mut vec[i[0]];
|
|
let a = unsafe { &mut *(a as *mut T) };
|
|
let b = &mut vec[i[1]];
|
|
[a, b]
|
|
}
|
|
}
|
|
|
|
struct Instruction {
|
|
count: u32,
|
|
from: u32,
|
|
to: u32,
|
|
}
|
|
|
|
impl Instruction {
|
|
fn execute_part1(&self, state: &mut [Vec<char>]) {
|
|
let [from, to] = get_many_mut(state, [self.from as usize - 1, self.to as usize - 1]);
|
|
|
|
for _ in 0..self.count {
|
|
to.push(from.pop().unwrap());
|
|
}
|
|
}
|
|
|
|
fn execute_part2(&self, state: &mut [Vec<char>]) {
|
|
let [from, to] = get_many_mut(state, [self.from as usize - 1, self.to as usize - 1]);
|
|
|
|
let iter = from.drain((from.len() - self.count as usize)..);
|
|
to.extend(iter);
|
|
}
|
|
}
|
|
|
|
struct PuzzleInput {
|
|
initial_state: Vec<Vec<char>>,
|
|
instructions: Vec<Instruction>,
|
|
}
|
|
|
|
#[aoc_generator(day5)]
|
|
fn generator(s: &str) -> PuzzleInput {
|
|
let (s1, s2) = s.split_once("\n\n").unwrap();
|
|
|
|
let mut initial_state = Vec::new();
|
|
|
|
for l in s1.lines().rev().skip(1) {
|
|
initial_state.resize((l.len() + 1) / 4, Vec::new());
|
|
|
|
for (i, mut craate) in l.chars().chunks(4).into_iter().enumerate() {
|
|
let craate = craate.nth(1).unwrap();
|
|
|
|
if craate != ' ' {
|
|
initial_state[i].push(craate);
|
|
}
|
|
}
|
|
}
|
|
|
|
let instructions = s2
|
|
.lines()
|
|
.map(|l| {
|
|
let mut split = l.split(' ');
|
|
assert_eq!(split.next(), Some("move"));
|
|
let count = split.next().unwrap().parse().unwrap();
|
|
assert_eq!(split.next(), Some("from"));
|
|
let from = split.next().unwrap().parse().unwrap();
|
|
assert_eq!(split.next(), Some("to"));
|
|
let to = split.next().unwrap().parse().unwrap();
|
|
|
|
Instruction { count, from, to }
|
|
})
|
|
.collect();
|
|
|
|
PuzzleInput {
|
|
initial_state,
|
|
instructions,
|
|
}
|
|
}
|
|
|
|
#[aoc(day5, part1)]
|
|
fn part1(input: &PuzzleInput) -> String {
|
|
let mut state = input.initial_state.clone();
|
|
|
|
for inst in &input.instructions {
|
|
inst.execute_part1(&mut state);
|
|
}
|
|
|
|
state.iter().map(|v| v.last().unwrap()).collect::<String>()
|
|
}
|
|
|
|
#[aoc(day5, part2)]
|
|
fn part2(input: &PuzzleInput) -> String {
|
|
let mut state = input.initial_state.clone();
|
|
|
|
for inst in &input.instructions {
|
|
inst.execute_part2(&mut state);
|
|
}
|
|
|
|
state.iter().map(|v| v.last().unwrap()).collect::<String>()
|
|
}
|