[TASK] Implemented Day 3

This commit is contained in:
2022-12-04 13:15:32 +01:00
parent 5a3968d50e
commit 6adca06f04
7 changed files with 475 additions and 1 deletions

127
src/day3.rs Normal file
View File

@@ -0,0 +1,127 @@
use crate::day_solver::DaySolver;
use std::fmt;
use std::fmt::Formatter;
use super::util;
struct Bag {
left: Vec<char>,
right: Vec<char>,
}
impl fmt::Display for Bag {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"{} and {}",
self.left.iter().cloned().collect::<String>(),
self.right.iter().cloned().collect::<String>()
)
}
}
const POW_MASK: [u64; 6] = [
0xAAAAAAAAAAAAAAAAu64,
0xCCCCCCCCCCCCCCCCu64,
0xF0F0F0F0F0F0F0F0u64,
0xFF00FF00FF00FF00u64,
0xFFFF0000FFFF0000u64,
0xFFFFFFFF00000000u64,
];
impl Bag {
fn priority(c: char) -> u8 {
return if c >= 'a' && c <= 'z' {
c as u8 - 'a' as u8 + 1
} else {
c as u8 - 'A' as u8 + 27
};
}
fn find_duplicate_priority(&self) -> u8 {
let left_mask = Bag::build_mask(&self.left, 0);
let right_mask = Bag::build_mask(&self.right, 0);
return Bag::match_masks(left_mask, right_mask);
}
fn build_full_mask(&self) -> u64 {
return Bag::build_mask(&self.right, Bag::build_mask(&self.left, 0));
}
fn build_mask(chars: &Vec<char>, initial: u64) -> u64 {
let mut mask = initial;
for c in chars {
mask = mask | (1 << Bag::priority(c.to_owned()));
}
mask
}
fn match_masks(mask1: u64, mask2: u64) -> u8 {
Bag::find_set_bit(mask1 & mask2)
}
fn find_set_bit(v: u64) -> u8 {
let mut r: u8 = 0;
let mut i: u8 = 0;
for m in POW_MASK {
if v & m != 0 {
r |= 1 << i;
}
i += 1;
}
// println!("log2 {} = {}", v, r);
r
}
}
pub struct Day3 {
bags: Vec<Bag>,
}
impl Day3 {
pub fn create() -> Self {
// let lines = util::read_file("input/day3_example.txt");
let lines = util::read_file("input/day3.txt");
// Put the input into the day struct
return Day3 {
bags: lines
.iter()
.map(|s| {
let (left_str, right_str) = s.split_at(s.len() / 2);
assert_eq!(left_str.len(), right_str.len());
Bag {
left: left_str.chars().collect(),
right: right_str.chars().collect(),
}
})
.collect(),
};
}
}
impl DaySolver for Day3 {
fn solve_part1(&mut self) -> String {
self.bags
.iter()
.map(|b| b.find_duplicate_priority() as u64)
.sum::<u64>()
.to_string()
}
fn solve_part2(&mut self) -> String {
return self
.bags
.chunks(3)
.map(|bags| {
Bag::find_set_bit(
bags[0].build_full_mask()
& bags[1].build_full_mask()
& bags[2].build_full_mask(),
) as u64
})
.sum::<u64>()
.to_string();
}
}

View File

@@ -1,12 +1,14 @@
use std::time::Instant;
use crate::day1::Day1;
use crate::day2::Day2;
use crate::day3::Day3;
use crate::day_solver::DaySolver;
mod util;
mod day1;
mod day_solver;
mod day2;
mod day3;
const MAX_DAY: u8 = 2;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
@@ -74,6 +76,7 @@ fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
match day {
1 => Some(Box::new(Day1::create())),
2 => Some(Box::new(Day2::create())),
3 => Some(Box::new(Day3::create())),
_ => None
}
}