Add day3 part2
This commit is contained in:
parent
efe7c0f1e1
commit
57c6e61b8e
|
@ -6,13 +6,24 @@ use std::collections::HashSet;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
|
|
||||||
|
// Map a character (indicating an "item") to its "priority".
|
||||||
|
fn char_to_prio(c: char) -> u32 {
|
||||||
|
// Fortunately we can cast all chars to u32, which makes this a matter of some simple
|
||||||
|
// arithmetic.
|
||||||
|
match c {
|
||||||
|
'a'..='z' => c as u32 - 'a' as u32 + 1,
|
||||||
|
'A'..='Z' => c as u32 - 'A' as u32 + 27,
|
||||||
|
_ => panic!("Got non-ascii alphabetic char!"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> StdError<()> {
|
fn main() -> StdError<()> {
|
||||||
// Open the input file and split all the lines.
|
// Open the input file and split all the lines.
|
||||||
let lines: Vec<_> = BufReader::new(File::open("input/day3.txt")?)
|
let lines: Vec<_> = BufReader::new(File::open("input/day3.txt")?)
|
||||||
.lines()
|
.lines()
|
||||||
.collect::<Result<_, _>>()?; // "Short circuit" any Errors in the iterator
|
.collect::<Result<_, _>>()?; // "Short circuit" any Errors in the iterator
|
||||||
|
|
||||||
let sum: u32 = lines
|
let part1: u32 = lines
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| {
|
.map(|l| {
|
||||||
assert!(l.len() % 2 == 0); // We won't be able to evenly split a odd-length line!
|
assert!(l.len() % 2 == 0); // We won't be able to evenly split a odd-length line!
|
||||||
|
@ -22,17 +33,35 @@ fn main() -> StdError<()> {
|
||||||
HashSet::<char>::from_iter(one.chars())
|
HashSet::<char>::from_iter(one.chars())
|
||||||
// ... then calculate the intersection, giving us the "items" (chars) in common
|
// ... then calculate the intersection, giving us the "items" (chars) in common
|
||||||
.intersection(&HashSet::from_iter(two.chars()))
|
.intersection(&HashSet::from_iter(two.chars()))
|
||||||
.map(|c| match c {
|
.map(|c| char_to_prio(*c))
|
||||||
// Now, we map our "items" to their "priorities".
|
|
||||||
// Fortunately we can cast all chars to u32, which makes this a matter of some
|
|
||||||
// simple arithmetic.
|
|
||||||
'a'..='z' => (*c as u32) - 'a' as u32 + 1,
|
|
||||||
'A'..='Z' => (*c as u32) - 'A' as u32 + 27,
|
|
||||||
_ => panic!("Got non-ascii alphabetic char!"),
|
|
||||||
})
|
|
||||||
.sum::<u32>() // Sum the priorities of items in common in each "rucksack"
|
.sum::<u32>() // Sum the priorities of items in common in each "rucksack"
|
||||||
})
|
})
|
||||||
.sum(); // Sum all the rucksacks' priorities
|
.sum(); // Sum all the rucksacks' priorities
|
||||||
println!("Part 1: {}", sum);
|
println!("Part 1: {}", part1);
|
||||||
|
|
||||||
|
let part2: u32 = lines
|
||||||
|
// First, map our lines to hashsets of their chars
|
||||||
|
.iter()
|
||||||
|
.map(|l| HashSet::from_iter(l.chars()))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
// Then split them into chunks of 3
|
||||||
|
.chunks(3)
|
||||||
|
.map(|c: &[HashSet<_>]| {
|
||||||
|
// And reduce each chunk of 3 into a single intersection of chars...
|
||||||
|
let common: Vec<char> = c
|
||||||
|
.into_iter()
|
||||||
|
.cloned()
|
||||||
|
.reduce(|acc, s| acc.intersection(&s).cloned().collect())
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.collect();
|
||||||
|
// ... which should only be one!
|
||||||
|
assert!(common.len() == 1);
|
||||||
|
common[0]
|
||||||
|
})
|
||||||
|
.map(char_to_prio)
|
||||||
|
.sum();
|
||||||
|
println!("Part 2: {}", part2);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue