Adds Day1
This commit is contained in:
parent
a2d898e66b
commit
d3bd96f14f
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
.vscode
|
||||||
|
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -1,7 +1,25 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aoc-2024"
|
name = "aoc-2024"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
@ -4,3 +4,4 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
itertools = "0.13"
|
||||||
|
1000
resources/input1.txt
Normal file
1000
resources/input1.txt
Normal file
File diff suppressed because it is too large
Load Diff
71
src/days/day1.rs
Normal file
71
src/days/day1.rs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
use std::{collections::HashMap, iter::zip, path::Path};
|
||||||
|
|
||||||
|
use crate::{days::AdventDay, error::AdventError, input::get_lines};
|
||||||
|
|
||||||
|
pub struct Day1 {
|
||||||
|
list1: Vec<i32>,
|
||||||
|
list2: Vec<i32>,
|
||||||
|
count1: HashMap<i32, u64>,
|
||||||
|
count2: HashMap<i32, u64>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl AdventDay for Day1 {
|
||||||
|
fn new() -> Self {
|
||||||
|
Day1 {
|
||||||
|
list1: vec![],
|
||||||
|
list2: vec![],
|
||||||
|
count1: HashMap::new(),
|
||||||
|
count2: HashMap::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 l = s.next().unwrap().parse::<i32>()?;
|
||||||
|
self.list1.push(l);
|
||||||
|
if self.count1.contains_key(&l) {
|
||||||
|
*self.count1.get_mut(&l).unwrap() += 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.count2.insert(r, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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> {
|
||||||
|
Ok(self.count1.keys().into_iter().map(
|
||||||
|
|k| {
|
||||||
|
let s = *k as u64;
|
||||||
|
if self.count2.contains_key(k) {
|
||||||
|
s * self.count1[k] * self.count2[k]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}).sum())
|
||||||
|
}
|
||||||
|
}
|
11
src/days/mod.rs
Normal file
11
src/days/mod.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use crate::error::AdventError;
|
||||||
|
|
||||||
|
pub trait AdventDay {
|
||||||
|
fn new() -> Self;
|
||||||
|
|
||||||
|
fn read_input(&mut self) -> Result<(),AdventError>;
|
||||||
|
fn puzzle1(&mut self) -> Result<u64, AdventError>;
|
||||||
|
fn puzzle2(&mut self) -> Result<u64, AdventError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod day1;
|
28
src/error/mod.rs
Normal file
28
src/error/mod.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use std::{num::{ParseIntError, TryFromIntError}, convert::Infallible, io};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AdventError(pub String);
|
||||||
|
|
||||||
|
impl From<ParseIntError> for AdventError {
|
||||||
|
fn from(e: ParseIntError) -> Self {
|
||||||
|
AdventError(e.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for AdventError {
|
||||||
|
fn from(e: io::Error) -> Self {
|
||||||
|
AdventError(e.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Infallible> for AdventError {
|
||||||
|
fn from(_: Infallible) -> Self {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TryFromIntError> for AdventError {
|
||||||
|
fn from(e: TryFromIntError) -> Self {
|
||||||
|
AdventError(e.to_string())
|
||||||
|
}
|
||||||
|
}
|
29
src/input/mod.rs
Normal file
29
src/input/mod.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use std::{fs::File, io::{BufRead, BufReader, Lines, Read}, path::{Path, PathBuf}, str::FromStr};
|
||||||
|
|
||||||
|
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> {
|
||||||
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
path.push(file_path);
|
||||||
|
let file = File::open(path).expect("no such file");
|
||||||
|
let buf = BufReader::new(file);
|
||||||
|
buf.lines().map(|line| T::from_str(line?.as_str()).map_err(Into::into)).collect::<Result<Vec<T>, AdventError>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _read_into<T:FromStr>(file_path: &Path) -> Result<T, AdventError> where AdventError: From<<T as FromStr>::Err> {
|
||||||
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
path.push(file_path);
|
||||||
|
let mut file = File::open(path).expect("no such file");
|
||||||
|
let mut str: String = "".to_string();
|
||||||
|
file.read_to_string(&mut str)?;
|
||||||
|
Ok(T::from_str(str.as_str())?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_lines(file_path: &Path) -> Lines<BufReader<File>> {
|
||||||
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
path.push(file_path);
|
||||||
|
let file = File::open(path).expect("no such file");
|
||||||
|
let buf = BufReader::new(file);
|
||||||
|
let lines = buf.lines();
|
||||||
|
lines
|
||||||
|
}
|
48
src/main.rs
48
src/main.rs
@ -1,3 +1,45 @@
|
|||||||
fn main() {
|
|
||||||
println!("Hello, world!");
|
pub mod error;
|
||||||
}
|
pub mod days;
|
||||||
|
mod input;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use day1::Day1;
|
||||||
|
|
||||||
|
use crate::error::AdventError;
|
||||||
|
use crate::days::*;
|
||||||
|
|
||||||
|
fn main() -> Result<(), AdventError> {
|
||||||
|
|
||||||
|
let mut advent_days = vec!(
|
||||||
|
Day1::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))
|
||||||
|
}).enumerate().map(|(index, r): (usize, Result<(u64, u64), AdventError>)| {
|
||||||
|
match r {
|
||||||
|
Ok((res1, res2)) => println!("{}: ({}, {})", index + 1, res1, res2),
|
||||||
|
Err(e) => println!("Error: {}", e.0)
|
||||||
|
};
|
||||||
|
}).fold((), |acc, _| { acc }))
|
||||||
|
} 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()?)),
|
||||||
|
2 => Ok(println!("2: {}", &day.puzzle2()?)),
|
||||||
|
_ => return Err(AdventError("part must be either 1 or 2".into()))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(println!("{}: ({}, {})", day_index + 1, day.puzzle1()?, day.puzzle2()?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user