add part2

This commit is contained in:
Daniel Bulant 2024-12-01 11:40:15 +01:00
parent 60ce3c117d
commit 7082fbb005
No known key found for this signature in database
4 changed files with 48 additions and 16 deletions

1
2024/data/01/1.part2.out Normal file
View file

@ -0,0 +1 @@
31

View file

@ -1,17 +1,20 @@
use std::{fs::File, io::{BufRead, BufReader}}; use std::{collections::HashSet, fs::File, io::{BufRead, BufReader}};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use aoc2024::{Context, Day}; use aoc2024::{Context, Day};
use itertools::Itertools; use itertools::Itertools;
fn part1(ctx: &Context) -> Result<String> { fn tuples(ctx: &Context) -> Result<impl Iterator<Item = Result<(u32, u32)>>> {
let tuples = BufReader::new(File::open(&ctx.args.input)?).lines().map(|line| -> Result<_> { Ok(BufReader::new(File::open(&ctx.args.input)?).lines().map(|line| -> Result<_> {
let line = line?; let line = line?;
let nums = line.split_whitespace().map(|n| n.parse::<u32>()).filter_map(|n| n.ok()).collect_tuple::<(u32, u32)>().ok_or(anyhow!("Invalid input"))?; let nums = line.split_whitespace().map(|n| n.parse::<u32>()).filter_map(|n| n.ok()).collect_tuple::<(u32, u32)>().ok_or(anyhow!("Invalid input"))?;
Ok(nums) Ok(nums)
}); }))
}
fn part1(ctx: &Context) -> Result<String> {
let tuples = tuples(ctx)?;
let mut first = Vec::new(); let mut first = Vec::new();
let mut second = Vec::new(); let mut second = Vec::new();
for res in tuples { for res in tuples {
@ -26,6 +29,22 @@ fn part1(ctx: &Context) -> Result<String> {
Ok(sum.to_string()) Ok(sum.to_string())
} }
fn part2(ctx: &Context) -> Result<String> {
let tuples = tuples(ctx)?;
let mut first = HashSet::new();
let mut second = Vec::new();
for res in tuples {
let (x, y) = res?;
first.insert(x);
second.push(y);
}
let sum = second.iter().filter(|y| first.contains(&y)).sum::<u32>();
Ok(sum.to_string())
}
fn main() { fn main() {
Day::new().part1(part1).run(); Day::new().part1(part1).part2(part2).run();
} }

View file

@ -19,7 +19,8 @@ pub struct Args {
pub struct Context { pub struct Context {
pub args: Args, pub args: Args,
pub day: u8, pub day: u8,
pub output: String pub output1: String,
pub output2: String,
} }
impl Context { impl Context {
@ -33,15 +34,25 @@ impl Context {
.unwrap() .unwrap()
.parse() .parse()
.unwrap(); .unwrap();
let mut output = args.input.clone(); let mut output1 = args.input.clone();
if let Some(pos) = output.rfind('.') { let mut output2 = args.input.clone();
output.replace_range(pos.., ".out"); if let Some(pos) = output1.rfind('.') {
output1.replace_range(pos.., ".part1.out");
output2.replace_range(pos.., ".part2.out");
} }
Self { args, day, output } Self { args, day, output1, output2 }
} }
fn read_output(&self) -> Option<String> { fn output(&self, part: u8) -> &str {
std::fs::read_to_string(&self.output).ok() match part {
1 => &self.output1,
2 => &self.output2,
_ => unreachable!()
}
}
fn read_output(&self, part: u8) -> Option<String> {
std::fs::read_to_string(&self.output(part)).ok()
} }
} }
@ -78,7 +89,7 @@ impl Day {
fn verify_part(&self, part: u8, ctx: &Context) -> Result<()> { fn verify_part(&self, part: u8, ctx: &Context) -> Result<()> {
println!("Day {} Part {}", ctx.day, part); println!("Day {} Part {}", ctx.day, part);
let expected = ctx.read_output(); let expected = ctx.read_output(part);
let start = std::time::Instant::now(); let start = std::time::Instant::now();
let result = match part { let result = match part {
1 => self.part1.as_ref().unwrap()(ctx), 1 => self.part1.as_ref().unwrap()(ctx),
@ -97,8 +108,9 @@ impl Day {
} }
} else { } else {
println!("{}", result); println!("{}", result);
std::fs::write(ctx.output.to_string() + ".run", &result)?; let path = ctx.output(part).to_string() + ".run";
println!("Output written to {}", ctx.output.to_string() + ".run"); std::fs::write(&path, &result)?;
println!("Output written to {} - no example output provided, nothing to diff.", path);
} }
println!("OK"); println!("OK");
Ok(()) Ok(())