From 2f316a4691f4f374f5f28ddc2616c709ca5318f1 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 Nov 2024 23:43:17 +0100 Subject: [PATCH] day 24 --- Cargo.lock | 16 +++++++++++ Cargo.toml | 3 +- src/day24.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++++------ src/lib.rs | 1 + 4 files changed, 89 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 915a2c2..7b17fb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,7 @@ version = "0.1.0" dependencies = [ "aoc-runner", "aoc-runner-derive", + "itertools", "json", "regex", ] @@ -50,6 +51,21 @@ dependencies = [ "serde_json", ] +[[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", +] + [[package]] name = "itoa" version = "0.4.3" diff --git a/Cargo.toml b/Cargo.toml index 187a1f4..425079e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,5 @@ bench = false aoc-runner = "0.3.0" aoc-runner-derive = "0.3.0" regex = "1.10.2" -json = "0.12.4" \ No newline at end of file +json = "0.12.4" +itertools = "0.13.0" diff --git a/src/day24.rs b/src/day24.rs index 11fa780..453e01f 100644 --- a/src/day24.rs +++ b/src/day24.rs @@ -1,18 +1,79 @@ use aoc_runner_derive::{aoc, aoc_generator}; +use itertools::Itertools; -type Input = (); +type Input = Vec; -#[aoc_generator(day22)] +#[aoc_generator(day24)] fn parse(input: &str) -> Input { - todo!() + input.lines().map(|l| l.parse().unwrap()).collect() } -#[aoc(day22, part1)] -fn part1(_: &Input) -> usize { - 0 +#[aoc(day24, part1)] +fn part1(input: &Input) -> u64 { + foo(input, 3, &two_part) } -#[aoc(day22, part2)] -fn part2(_: &Input) -> usize { - 0 +#[aoc(day24, part2)] +fn part2(input: &Input) -> u64 { + foo(input, 4, &three_part) +} + +fn foo(list: &Vec, groups: u64, f: &dyn Fn(Vec, u64) -> bool) -> u64 { + let sum: u64 = list.iter().sum(); + let target = sum / groups; + println!("sum: {sum}, target: {target}"); + (2..) + .map(|group_size| { + let x: Vec<(Vec, u64)> = list + .iter() + .combinations(group_size) + .filter(|group1| { + group1.iter().map(|i| **i).sum::() == target + && f( + list.iter() + .filter(|v| !group1.contains(v)) + .cloned() + .collect(), + target, + ) + }) + .map(|group1| { + ( + group1.iter().map(|v| **v).collect(), + group1.iter().fold(1, |a, b| a * **b), + ) + }) + .collect(); + x.into_iter() + .min_by_key(|(_, v)| *v) + .inspect(|(g, v)| println!("for size {group_size}: QE {v} for {g:?}")) + .map(|(_, v)| v) + }) + .filter(|x| x.is_some()) + .map(|x| x.unwrap()) + .next() + .unwrap() +} + +fn two_part(list: Vec, target: u64) -> bool { + (2..list.len() / 2).any(|group_size| { + list.iter() + .combinations(group_size) + .any(|group1| group1.iter().map(|i| **i).sum::() == target) + }) +} + +fn three_part(list: Vec, target: u64) -> bool { + (2..list.len() / 3).any(|group_size| { + list.iter().combinations(group_size).any(|group1| { + group1.iter().map(|i| **i).sum::() == target + && two_part( + list.iter() + .filter(|v| !group1.contains(v)) + .cloned() + .collect(), + target, + ) + }) + }) } diff --git a/src/lib.rs b/src/lib.rs index 41efe44..0080f29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,5 +16,6 @@ mod day20; mod day21; mod day22; mod day23; +mod day24; aoc_lib! { year = 2015 }