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"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
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
|
# 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};
|
use std::{fmt::Display, fs::read_to_string, time::Instant};
|
||||||
|
|
||||||
|
#[cfg(feature = "day1")]
|
||||||
mod day01;
|
mod day01;
|
||||||
|
#[cfg(feature = "day2")]
|
||||||
mod day02;
|
mod day02;
|
||||||
|
#[cfg(feature = "day3")]
|
||||||
mod day03;
|
mod day03;
|
||||||
|
#[cfg(feature = "day4")]
|
||||||
mod day04;
|
mod day04;
|
||||||
|
#[cfg(feature = "day5")]
|
||||||
mod day05;
|
mod day05;
|
||||||
|
#[cfg(feature = "day6")]
|
||||||
mod day06;
|
mod day06;
|
||||||
|
#[cfg(feature = "day7")]
|
||||||
|
mod day07;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
color_eyre::install().unwrap();
|
color_eyre::install().unwrap();
|
||||||
tracing_subscriber::fmt().init();
|
tracing_subscriber::fmt().init();
|
||||||
|
#[cfg(feature = "day1")]
|
||||||
solve_day(1, day01::pt1, day01::pt2);
|
solve_day(1, day01::pt1, day01::pt2);
|
||||||
|
#[cfg(feature = "day2")]
|
||||||
solve_day(2, day02::pt1, day02::pt2);
|
solve_day(2, day02::pt1, day02::pt2);
|
||||||
|
#[cfg(feature = "day3")]
|
||||||
solve_day(3, day03::pt1, day03::pt2);
|
solve_day(3, day03::pt1, day03::pt2);
|
||||||
|
#[cfg(feature = "day4")]
|
||||||
solve_day(4, day04::pt1, day04::pt2);
|
solve_day(4, day04::pt1, day04::pt2);
|
||||||
|
#[cfg(feature = "day5")]
|
||||||
solve_day(5, day05::pt1, day05::pt2);
|
solve_day(5, day05::pt1, day05::pt2);
|
||||||
|
#[cfg(feature = "day6")]
|
||||||
solve_day(6, day06::pt1, day06::pt2);
|
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)
|
fn solve_day<Fa, Fb, Ta, Tb>(day: u8, part_a: Fa, part_b: Fb)
|
||||||
|
@ -25,12 +41,17 @@ where
|
||||||
Fb: Fn(&str) -> Tb,
|
Fb: Fn(&str) -> Tb,
|
||||||
Tb: Display,
|
Tb: Display,
|
||||||
{
|
{
|
||||||
let input = read_to_string(format!("./inputs/day{day:02}/input.txt"))
|
match read_to_string(format!("./inputs/day{day:02}/input.txt")) {
|
||||||
.unwrap_or_else(|_| panic!("Missing input.txt for day{day:02}"));
|
Ok(input) => {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let result_a = part_a(&input);
|
let result_a = part_a(&input);
|
||||||
tracing::info!("[{day:02}] Part A: {result_a} \tin {:?}", start.elapsed());
|
tracing::info!("[{day:02}] Part A: {result_a} \tin {:?}", start.elapsed());
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let result_b = part_b(&input);
|
let result_b = part_b(&input);
|
||||||
tracing::info!("[{day:02}] Part B: {result_b} \tin {:?}", start.elapsed());
|
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