Adds Day2

This commit is contained in:
Dennis Brentjes 2024-12-02 22:09:19 +01:00
parent d3bd96f14f
commit 6397ed0092
6 changed files with 1199 additions and 30 deletions

1000
resources/input2.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +1,60 @@
use std::{collections::HashMap, iter::zip, path::Path};
use crate::{days::AdventDay, error::AdventError, input::get_lines};
use crate::{error::AdventError, input::get_lines};
pub struct Day1 {
use super::*;
pub struct Day1Part1 {
list1: Vec<i32>,
list2: Vec<i32>,
}
pub struct Day1Part2 {
count1: HashMap<i32, u64>,
count2: HashMap<i32, u64>
}
pub struct Day1 {
part1: Day1Part1,
part2: Day1Part2
}
impl Day1 {
pub fn new() -> Self {
Day1 {
part1: Day1Part1::new(),
part2: Day1Part2::new()
}
}
}
impl AdventDay for Day1 {
fn puzzle1(&mut self) -> Result<u64, AdventError> {
self.part1.read_input()?;
self.part1.solve()
}
fn puzzle2(&mut self) -> Result<u64, AdventError> {
self.part2.read_input()?;
self.part2.solve()
}
}
impl Day1Part2 {
fn new() -> Self {
Day1 {
list1: vec![],
list2: vec![],
Day1Part2 {
count1: HashMap::new(),
count2: HashMap::new()
}
}
}
impl AdventDayPart2 for Day1Part2 {
fn read_input(&mut self) -> Result<(),AdventError> {
for line in get_lines(Path::new("resources/input1.txt")) {
let line = line?;
let mut s = line.split(" ");
let mut s = line.split_whitespace();
let l = s.next().unwrap().parse::<i32>()?;
self.list1.push(l);
if self.count1.contains_key(&l) {
*self.count1.get_mut(&l).unwrap() += 1;
}
@ -33,7 +62,6 @@ impl AdventDay for Day1 {
self.count1.insert(l, 1);
}
let r = s.next().unwrap().parse::<i32>()?;
self.list2.push(r);
if self.count2.contains_key(&r) {
*self.count2.get_mut(&r).unwrap() += 1;
}
@ -44,19 +72,7 @@ impl AdventDay for Day1 {
Ok(())
}
fn puzzle1(&mut self) -> Result<u64, AdventError> {
self.list1.sort();
self.list2.sort();
Ok(zip(self.list1.clone(), self.list2.clone())
.map(|(l, r)| {
(l - r).abs() as u64
})
.sum::<u64>())
}
fn puzzle2(&mut self) -> Result<u64, AdventError> {
fn solve(&mut self) -> Result<u64, AdventError> {
Ok(self.count1.keys().into_iter().map(
|k| {
let s = *k as u64;
@ -68,4 +84,36 @@ impl AdventDay for Day1 {
}
}).sum())
}
}
impl Day1Part1 {
fn new() -> Self {
Day1Part1 {
list1: vec![],
list2: vec![],
}
}
}
impl AdventDayPart1 for Day1Part1 {
fn read_input(&mut self) -> Result<(),AdventError> {
for line in get_lines(Path::new("resources/input1.txt")) {
let line = line?;
let mut s = line.split_whitespace();
self.list1.push(s.next().unwrap().parse::<i32>()?);
self.list2.push(s.next().unwrap().parse::<i32>()?);
}
Ok(())
}
fn solve(&mut self) -> Result<u64, AdventError> {
self.list1.sort();
self.list2.sort();
Ok(zip(self.list1.clone(), self.list2.clone())
.map(|(l, r)| {
(l - r).abs() as u64
})
.sum::<u64>())
}
}

113
src/days/day2.rs Normal file
View File

@ -0,0 +1,113 @@
use std::{path::Path, str::FromStr};
use crate::input::read_into_vec;
use super::*;
struct Report(Vec<i32>);
impl FromStr for Report {
type Err = AdventError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Report(s.split_whitespace()
.map(|s| -> Result<i32, AdventError> { Ok(s.parse::<i32>()?)})
.collect::<Result<Vec<i32>, AdventError>>()?
))
}
}
impl Report {
fn safe1(&self) -> bool {
let diff_vec: Vec<i32> = self.0.iter().zip(self.0.iter().skip(1)).map(|(l, r)| l - r).collect();
diff_vec.iter().all(|x| {*x >= -3 && *x <= -1}) || diff_vec.iter().all(|x| *x >= 1 && *x <= 3)
}
fn safe2(&self) -> bool {
let diff_vec: Vec<i32> = self.0.iter().zip(self.0.iter().skip(1)).map(|(l, r)| l - r).collect();
if diff_vec.iter().all(|x| {*x >= -3 && *x <= -1}) || diff_vec.iter().all(|x| *x >= 1 && *x <= 3) {
return true;
}
for i in 0..(self.0.len()) {
let mut new_vec = self.0.clone();
new_vec.remove(i);
let new_diff_vec : Vec<i32> = new_vec.iter().zip(new_vec.iter().skip(1)).map(|(l, r)| l - r).collect();
println!("{:?}", new_vec);
if new_diff_vec.iter().all(|x| {*x >= -3 && *x <= -1}) || new_diff_vec.iter().all(|x| *x >= 1 && *x <= 3) {
return true;
}
}
return false;
}
}
struct Day2Part1 {
reports: Vec<Report>
}
struct Day2Part2 {
reports: Vec<Report>
}
pub struct Day2 {
part1: Day2Part1,
part2: Day2Part2
}
impl Day2 {
pub fn new() -> Self {
Day2 {
part1: Day2Part1::new(),
part2: Day2Part2::new()
}
}
}
impl AdventDay for Day2 {
fn puzzle1(&mut self) -> Result<u64, AdventError> {
self.part1.read_input()?;
self.part1.solve()
}
fn puzzle2(&mut self) -> Result<u64, AdventError> {
self.part2.read_input()?;
self.part2.solve()
}
}
impl Day2Part1 {
fn new() -> Self {
Day2Part1 {
reports: vec!()
}
}
}
impl AdventDayPart1 for Day2Part1 {
fn read_input(&mut self) -> Result<(),AdventError> {
Ok(self.reports = read_into_vec::<Report>(Path::new("resources/input2.txt"))?)
}
fn solve(&mut self) -> Result<u64, AdventError> {
Ok(self.reports.iter().filter(|x| x.safe1()).count().try_into().unwrap())
}
}
impl Day2Part2 {
fn new() -> Self {
Day2Part2 {
reports: vec!()
}
}
}
impl AdventDayPart2 for Day2Part2 {
fn read_input(&mut self) -> Result<(),AdventError> {
Ok(self.reports = read_into_vec::<Report>(Path::new("resources/input2.txt"))?)
}
fn solve(&mut self) -> Result<u64, AdventError> {
Ok(self.reports.iter().filter(|x| x.safe2()).count().try_into().unwrap())
}
}

View File

@ -1,11 +1,19 @@
use crate::error::AdventError;
pub trait AdventDay {
fn new() -> Self;
pub trait AdventDayPart1 {
fn read_input(&mut self) -> Result<(),AdventError>;
fn solve(&mut self) -> Result<u64, AdventError>;
}
pub trait AdventDayPart2 {
fn read_input(&mut self) -> Result<(),AdventError>;
fn solve(&mut self) -> Result<u64, AdventError>;
}
pub trait AdventDay {
fn puzzle1(&mut self) -> Result<u64, AdventError>;
fn puzzle2(&mut self) -> Result<u64, AdventError>;
}
pub mod day1;
pub mod day1;
pub mod day2;

View File

@ -2,7 +2,7 @@ use std::{fs::File, io::{BufRead, BufReader, Lines, Read}, path::{Path, PathBuf}
use crate::error::AdventError;
pub fn _read_into_vec<T:FromStr>(file_path : &Path) -> Result<Vec<T>, AdventError> where AdventError: From<<T as FromStr>::Err> {
pub fn read_into_vec<T:FromStr>(file_path : &Path) -> Result<Vec<T>, AdventError> where AdventError: From<<T as FromStr>::Err> {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push(file_path);
let file = File::open(path).expect("no such file");

View File

@ -6,19 +6,20 @@ mod input;
use std::env;
use day1::Day1;
use day2::Day2;
use crate::error::AdventError;
use crate::days::*;
fn main() -> Result<(), AdventError> {
let mut advent_days = vec!(
Day1::new()
let mut advent_days: Vec<Box::<dyn AdventDay>> = vec!(
Box::new(Day1::new()),
Box::new(Day2::new())
);
if env::args().len() == 1 {
Ok(advent_days.into_iter().map(|mut day| {
day.read_input()?;
let one_result = day.puzzle1()?;
let two_result = day.puzzle2()?;
Ok((one_result, two_result))
@ -31,7 +32,6 @@ fn main() -> Result<(), AdventError> {
} else {
let day_index = env::args().nth(1).ok_or(AdventError("Failed to parse day".into()))?.parse::<usize>()? - 1;
let day = &mut advent_days[day_index];
day.read_input()?;
if env::args().len() == 3 {
match env::args().nth(2).unwrap().parse::<usize>()? {
1 => Ok(println!("1: {}", &day.puzzle1()?)),