[TASK] Implemented Day 3
This commit is contained in:
127
src/day3.rs
Normal file
127
src/day3.rs
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user