1
0
Fork 0

day(05): add initial version

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2022-12-05 11:24:15 +01:00
parent 6199872dcd
commit 95df0a175e
Signed by: mfocko
GPG key ID: 7C47D46246790496
2 changed files with 164 additions and 0 deletions

9
samples/day05.txt Normal file
View file

@ -0,0 +1,9 @@
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

155
src/bin/day05.rs Normal file
View file

@ -0,0 +1,155 @@
use std::cmp::max;
use std::str::FromStr;
use aoc_2022::*;
use color_eyre::eyre::{Report, Result};
use itertools::Itertools;
use tracing::*;
use tracing_subscriber::EnvFilter;
#[derive(Debug)]
struct Move {
count: usize,
from: usize,
to: usize,
}
impl FromStr for Move {
type Err = Report;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let split_str: Vec<_> = s.split_whitespace().collect();
let ints = vec![split_str[1], split_str[3], split_str[5]]
.iter()
.map(|x| x.parse::<usize>().unwrap())
.collect_vec();
let (count, from, to) = (ints[0], ints[1], ints[2]);
Ok(Move { count, from, to })
}
}
#[derive(Debug)]
struct Ship(Vec<Vec<char>>, Vec<Move>);
impl FromStr for Ship {
type Err = Report;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let split_s = s.split("\n\n").collect_vec();
let (stacks_str, moves_str) = (split_s[0], split_s[1]);
let mut stacks: Vec<Vec<char>> = Vec::new();
stacks_str
.lines()
.rev()
.skip(1)
.map(|l| l.to_string() + " ")
.for_each(|l| {
l.chars().skip(1).step_by(4).enumerate().for_each(|(i, c)| {
if i >= stacks.len() {
stacks.push(Vec::new());
}
if c != ' ' {
stacks[i].push(c);
}
});
});
let moves = strings_to_structs(moves_str.lines());
Ok(Ship(stacks, moves))
}
}
type Input = Ship;
type Output = String;
fn part_1(input: &Input) -> Output {
let Ship(stacks, moves) = input;
let mut stacks = stacks.clone();
moves.iter().for_each(|m| {
for _ in 0..m.count {
if stacks[m.from - 1].is_empty() {
break;
}
let popped = stacks[m.from - 1].pop().unwrap();
stacks[m.to - 1].push(popped);
}
});
stacks.iter().fold(String::new(), |acc, stack| {
if let Some(c) = stack.last() {
acc + &c.to_string()
} else {
acc
}
})
}
fn part_2(input: &Input) -> Output {
let Ship(stacks, moves) = input;
let mut stacks = stacks.clone();
moves.iter().for_each(|m| {
let size = stacks[m.from - 1].len();
let mut s = stacks[m.from - 1].split_off(max(0, size - m.count));
stacks[m.to - 1].append(&mut s);
});
stacks.iter().fold(String::new(), |acc, stack| {
if let Some(c) = stack.last() {
acc + &c.to_string()
} else {
acc
}
})
}
fn parse_input(pathname: &str) -> Input {
file_to_string(pathname).parse::<Input>().unwrap()
}
fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_target(false)
.with_file(true)
.with_line_number(true)
.without_time()
.compact()
.init();
color_eyre::install()?;
let input = parse_input("inputs/day05.txt");
info!("Part 1: {}", part_1(&input));
info!("Part 2: {}", part_2(&input));
Ok(())
}
#[cfg(test)]
mod day_05 {
use super::*;
#[test]
fn test_part_1() {
let sample = parse_input("samples/day05.txt");
assert_eq!(part_1(&sample), "CMZ".to_string());
}
#[test]
fn test_part_2() {
let sample = parse_input("samples/day05.txt");
assert_eq!(part_2(&sample), "MCD".to_string());
}
}