80 lines
2.1 KiB
Rust
80 lines
2.1 KiB
Rust
#![feature(iterator_try_collect, iter_collect_into)]
|
|
|
|
use std::collections::HashSet;
|
|
use std::fs;
|
|
use std::io::{self, BufRead};
|
|
|
|
fn main() {
|
|
let filename = "etc/p03.txt";
|
|
let file = fs::File::open(filename).expect("Can't open file");
|
|
let reader = io::BufReader::new(file);
|
|
|
|
println!("PART ONE ---------------");
|
|
let lines: Vec<String> = reader
|
|
.lines()
|
|
.try_collect()
|
|
.expect("Expected all lines to be valid");
|
|
part1(&lines);
|
|
|
|
println!("\n PART TWO ---------------");
|
|
part2(&lines);
|
|
}
|
|
|
|
fn to_priority(c: char) -> Result<u32, &'static str> {
|
|
if c.is_ascii_uppercase() {
|
|
Ok(c as u32 - 'A' as u32 + 26 + 1)
|
|
} else if c.is_ascii_lowercase() {
|
|
Ok(c as u32 - 'a' as u32 + 1)
|
|
} else {
|
|
Err("Can't convert non-alphanumeric")
|
|
}
|
|
}
|
|
|
|
fn part1(lines: &[String]) {
|
|
let mut sum: u32 = 0;
|
|
let mut left_set = HashSet::<char>::new();
|
|
for line in lines {
|
|
let (left, right) = line.split_at(line.len() / 2);
|
|
left.chars().collect_into(&mut left_set);
|
|
let outlier = right
|
|
.chars()
|
|
.find(|c| left_set.contains(c))
|
|
.expect("Expected at least one duplicate item");
|
|
|
|
let priority = to_priority(outlier).unwrap();
|
|
dbg!(outlier, priority);
|
|
sum += priority;
|
|
|
|
left_set.clear();
|
|
}
|
|
|
|
println!("Sum: {}", sum);
|
|
}
|
|
|
|
fn part2(lines: &[String]) {
|
|
const GROUP_SIZE: usize = 3;
|
|
let mut sets = Vec::with_capacity(GROUP_SIZE - 1);
|
|
for _ in 0..GROUP_SIZE - 1 {
|
|
sets.push(HashSet::<char>::new())
|
|
}
|
|
|
|
let mut sum: u32 = 0;
|
|
for chunk in lines.chunks(GROUP_SIZE) {
|
|
for i in 0..GROUP_SIZE - 1 {
|
|
sets[i].clear();
|
|
chunk[i].chars().collect_into(&mut sets[i]);
|
|
}
|
|
|
|
let outlier = chunk[GROUP_SIZE - 1]
|
|
.chars()
|
|
.find(|c| sets[0..GROUP_SIZE - 1].iter().all(|s| s.contains(c)))
|
|
.expect("Expect at least one outlier");
|
|
|
|
let priority = to_priority(outlier).unwrap();
|
|
dbg!(outlier, priority);
|
|
sum += priority;
|
|
}
|
|
|
|
println!("Sum: {}", sum);
|
|
}
|