feat: day 7
allow to only run specific days
This commit is contained in:
parent
506fec4365
commit
8d74075bd9
11
Cargo.toml
11
Cargo.toml
|
@ -3,6 +3,17 @@ name = "aoc2024"
|
|||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
full = ["day1", "day2", "day3", "day4", "day5", "day6", "day7"]
|
||||
default = ["full"]
|
||||
day1 = []
|
||||
day2 = []
|
||||
day3 = []
|
||||
day4 = []
|
||||
day5 = []
|
||||
day6 = []
|
||||
day7 = []
|
||||
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
9
inputs/day07/example.txt
Normal file
9
inputs/day07/example.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
190: 10 19
|
||||
3267: 81 40 27
|
||||
83: 17 5
|
||||
156: 15 6
|
||||
7290: 6 8 6 15
|
||||
161011: 16 10 13
|
||||
192: 17 8 14
|
||||
21037: 9 7 18 13
|
||||
292: 11 6 16 20
|
92
src/day07.rs
Normal file
92
src/day07.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
pub fn pt1(input: &str) -> usize {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| line.split_once(": ").unwrap())
|
||||
.map(|(res, args)| {
|
||||
(
|
||||
res.parse::<usize>().unwrap(),
|
||||
args.split(' ')
|
||||
.flat_map(str::parse::<usize>)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.filter(can_calibrate)
|
||||
.map(|(val, _)| val)
|
||||
.sum()
|
||||
}
|
||||
fn can_calibrate((res, args): &(usize, Vec<usize>)) -> bool {
|
||||
(0..(2usize << args.len())).any(|mut i| {
|
||||
let mut arg_clone = args.iter();
|
||||
let mut current_res = *arg_clone.next().unwrap();
|
||||
for arg in arg_clone {
|
||||
let op = i & 1;
|
||||
if op == 1 {
|
||||
current_res += arg;
|
||||
} else {
|
||||
current_res *= arg;
|
||||
}
|
||||
i >>= 1;
|
||||
}
|
||||
current_res == *res
|
||||
})
|
||||
}
|
||||
|
||||
fn can_calibrate_concat((res, args): &(usize, Vec<usize>)) -> bool {
|
||||
(0..(3usize.pow(u32::try_from(args.len()).unwrap()))).any(|mut i| {
|
||||
let mut arg_clone = args.iter();
|
||||
let mut current_res = *arg_clone.next().unwrap();
|
||||
for arg in arg_clone {
|
||||
let op = i % 3;
|
||||
match op {
|
||||
0 => current_res += arg,
|
||||
1 => current_res *= arg,
|
||||
2 => {
|
||||
current_res *= 10usize.pow(u32::try_from(arg.to_string().len()).unwrap());
|
||||
current_res += arg;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
i /= 3;
|
||||
if current_res > *res {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
current_res == *res
|
||||
})
|
||||
}
|
||||
pub fn pt2(input: &str) -> usize {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| line.split_once(": ").unwrap())
|
||||
.map(|(res, args)| {
|
||||
(
|
||||
res.parse::<usize>().unwrap(),
|
||||
args.split(' ')
|
||||
.flat_map(str::parse::<usize>)
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.filter(can_calibrate_concat)
|
||||
.map(|(val, _)| val)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{pt1, pt2};
|
||||
use std::fs::read_to_string;
|
||||
|
||||
#[test]
|
||||
pub fn test_pt1() {
|
||||
let input =
|
||||
read_to_string("./inputs/day07/example.txt").expect("Missing example.txt for day07");
|
||||
assert_eq!(pt1(&input), 3749)
|
||||
}
|
||||
#[test]
|
||||
pub fn test_pt2() {
|
||||
let input =
|
||||
read_to_string("./inputs/day07/example.txt").expect("Missing example.txt for day07");
|
||||
|
||||
assert_eq!(pt2(&input), 11387)
|
||||
}
|
||||
}
|
37
src/main.rs
37
src/main.rs
|
@ -1,21 +1,37 @@
|
|||
use std::{fmt::Display, fs::read_to_string, time::Instant};
|
||||
|
||||
#[cfg(feature = "day1")]
|
||||
mod day01;
|
||||
#[cfg(feature = "day2")]
|
||||
mod day02;
|
||||
#[cfg(feature = "day3")]
|
||||
mod day03;
|
||||
#[cfg(feature = "day4")]
|
||||
mod day04;
|
||||
#[cfg(feature = "day5")]
|
||||
mod day05;
|
||||
#[cfg(feature = "day6")]
|
||||
mod day06;
|
||||
#[cfg(feature = "day7")]
|
||||
mod day07;
|
||||
|
||||
fn main() {
|
||||
color_eyre::install().unwrap();
|
||||
tracing_subscriber::fmt().init();
|
||||
#[cfg(feature = "day1")]
|
||||
solve_day(1, day01::pt1, day01::pt2);
|
||||
#[cfg(feature = "day2")]
|
||||
solve_day(2, day02::pt1, day02::pt2);
|
||||
#[cfg(feature = "day3")]
|
||||
solve_day(3, day03::pt1, day03::pt2);
|
||||
#[cfg(feature = "day4")]
|
||||
solve_day(4, day04::pt1, day04::pt2);
|
||||
#[cfg(feature = "day5")]
|
||||
solve_day(5, day05::pt1, day05::pt2);
|
||||
#[cfg(feature = "day6")]
|
||||
solve_day(6, day06::pt1, day06::pt2);
|
||||
#[cfg(feature = "day7")]
|
||||
solve_day(7, day07::pt1, day07::pt2);
|
||||
}
|
||||
|
||||
fn solve_day<Fa, Fb, Ta, Tb>(day: u8, part_a: Fa, part_b: Fb)
|
||||
|
@ -25,12 +41,17 @@ where
|
|||
Fb: Fn(&str) -> Tb,
|
||||
Tb: Display,
|
||||
{
|
||||
let input = read_to_string(format!("./inputs/day{day:02}/input.txt"))
|
||||
.unwrap_or_else(|_| panic!("Missing input.txt for day{day:02}"));
|
||||
let start = Instant::now();
|
||||
let result_a = part_a(&input);
|
||||
tracing::info!("[{day:02}] Part A: {result_a} \tin {:?}", start.elapsed());
|
||||
let start = Instant::now();
|
||||
let result_b = part_b(&input);
|
||||
tracing::info!("[{day:02}] Part B: {result_b} \tin {:?}", start.elapsed());
|
||||
match read_to_string(format!("./inputs/day{day:02}/input.txt")) {
|
||||
Ok(input) => {
|
||||
let start = Instant::now();
|
||||
let result_a = part_a(&input);
|
||||
tracing::info!("[{day:02}] Part A: {result_a} \tin {:?}", start.elapsed());
|
||||
let start = Instant::now();
|
||||
let result_b = part_b(&input);
|
||||
tracing::info!("[{day:02}] Part B: {result_b} \tin {:?}", start.elapsed());
|
||||
}
|
||||
Err(_) => {
|
||||
tracing::warn!("could not open ./inputs/day{day:02}/input.txt");
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue