day 3
This commit is contained in:
parent
86eb94514e
commit
3bc97158bc
@ -15,6 +15,10 @@ path = "src/day1.rs"
|
||||
name = "day2"
|
||||
path = "src/day2.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "day3"
|
||||
path = "src/day3.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
103
2022/src/day3.rs
Normal file
103
2022/src/day3.rs
Normal file
@ -0,0 +1,103 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
|
||||
const DATA: &'static str = include_str!("../data/day3.txt");
|
||||
// const DATA: &'static str = "
|
||||
// vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
// jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
// PmmdzqPrVvPwwTWBwg
|
||||
// wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
// ttgJtRGJQctTZtZT
|
||||
// CrZsJsPPZsGzwwsLwLmpwMDw
|
||||
// ";
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
enum DataError {
|
||||
Imbalanced,
|
||||
UnknownValue,
|
||||
NoDuplicate,
|
||||
NoTriplicate,
|
||||
ShortGroup,
|
||||
}
|
||||
|
||||
|
||||
struct Rucksack {
|
||||
left: Vec<u8>,
|
||||
right: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Rucksack {
|
||||
fn find_duplicate(&self) -> Option<u8> {
|
||||
// pretty sure this is faster than hash set, given the sizes involved
|
||||
self.left.iter()
|
||||
.find(|c| self.right.contains(c))
|
||||
.map(|c| *c)
|
||||
}
|
||||
|
||||
fn iter_all(&self) -> impl Iterator<Item = &u8> {
|
||||
self.left.iter().chain(self.right.iter())
|
||||
}
|
||||
|
||||
fn contains(&self, v: u8) -> bool {
|
||||
self.left.contains(&v) || self.right.contains(&v)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Rucksack {
|
||||
type Err = DataError;
|
||||
|
||||
fn from_str(line: &str) -> Result<Rucksack, DataError> {
|
||||
let line = line.trim();
|
||||
if line.len() % 2 != 0 {
|
||||
return Err(DataError::Imbalanced);
|
||||
}
|
||||
let (a, b) = line.as_bytes().split_at(line.len() / 2);
|
||||
Ok(Rucksack {
|
||||
left: a.into(),
|
||||
right: b.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn priority(c: u8) -> Result<u64, DataError> {
|
||||
match c {
|
||||
// lowercase
|
||||
97..=122 => Ok(c as u64 - 96),
|
||||
// uppercase
|
||||
65..=90 => Ok(c as u64 - 38),
|
||||
_ => Err(DataError::UnknownValue),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() -> Result<(), DataError> {
|
||||
let mut dup_total = 0;
|
||||
let rucks = DATA.trim()
|
||||
.split("\n")
|
||||
.map(|line| Rucksack::from_str(line))
|
||||
.collect::<Result<Vec<Rucksack>, DataError>>()?;
|
||||
|
||||
for ruck in rucks.iter() {
|
||||
let dup = ruck.find_duplicate()
|
||||
.ok_or(DataError::NoDuplicate)?;
|
||||
dup_total += priority(dup)?;
|
||||
}
|
||||
println!("Part 1: {dup_total}");
|
||||
|
||||
let mut groups_total = 0;
|
||||
for (idx, ruck) in rucks.iter().enumerate().step_by(3) {
|
||||
if idx > rucks.len() - 3 {
|
||||
return Err(DataError::ShortGroup);
|
||||
}
|
||||
|
||||
let badge = *ruck.iter_all()
|
||||
.find(|&v| rucks[idx + 1].contains(*v) && rucks[idx + 2].contains(*v))
|
||||
.ok_or(DataError::NoTriplicate)?;
|
||||
groups_total += priority(badge)?;
|
||||
}
|
||||
println!("Part 2: {groups_total}");
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! get_data {
|
||||
($filename: literal) => {
|
||||
include_str!(concat!("../data/", $filename, ".txt"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn main() {
|
||||
todo!();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user