1
0
Fork 0
2022/src/bin/day03.rs

96 lines
2.2 KiB
Rust
Raw Normal View History

use std::collections::HashSet;
use aoc_2022::*;
use color_eyre::eyre::Result;
use tracing::*;
use tracing_subscriber::EnvFilter;
type Input = Vec<(HashSet<i32>, HashSet<i32>)>;
type Output = i32;
fn part_1(input: &Input) -> Output {
input
.iter()
.map(|(left, right)| left.intersection(right).sum::<i32>())
.sum()
}
fn part_2(input: &Input) -> Output {
input
.iter()
.map(|(left, right)| left.union(right).cloned().collect())
.collect::<Vec<HashSet<i32>>>()
.chunks(3)
.map(|sets| {
// debug!("Sets: {:?}", sets);
sets.iter()
.skip(1)
.fold(sets[0].clone(), |acc, s| {
acc.intersection(s).cloned().collect()
})
.iter()
.fold(0, |acc, x| acc + *x)
})
.sum()
}
fn parse_input(pathname: &str) -> Input {
file_to_lines(pathname)
.iter()
.map(|line| {
let mut left: HashSet<i32> = HashSet::new();
let mut right: HashSet<i32> = HashSet::new();
let mid = line.len() / 2;
for (i, c) in line.chars().enumerate() {
let s = if i < mid { &mut left } else { &mut right };
s.insert(if c < 'a' {
c as i32 - 'A' as i32 + 27
} else {
c as i32 - 'a' as i32 + 1
});
}
(left, right)
})
.collect()
}
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/day03.txt");
info!("Part 1: {}", part_1(&input));
info!("Part 2: {}", part_2(&input));
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_1() {
let sample = parse_input("samples/day03.txt");
assert_eq!(part_1(&sample), 157);
}
#[test]
fn test_part_2() {
let sample = parse_input("samples/day03.txt");
assert_eq!(part_2(&sample), 70);
}
}