From db2e82f64c83601f123f90a43b4840f95f559204 Mon Sep 17 00:00:00 2001 From: OMGeeky <39029799+OMGeeky@users.noreply.github.com> Date: Tue, 30 Jan 2024 09:36:21 +0000 Subject: [PATCH] day 19 part 2 try --- Cargo.toml | 1 + src/day19.rs | 116 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/main.rs | 2 +- 3 files changed, 115 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 62135ca..1fd6810 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ serde_json = "1.0.68" paste ={ version = "1.0" } cached="0.46" itertools="0.12" +rayon="1" [dev-dependencies] rstest = "0.18" diff --git a/src/day19.rs b/src/day19.rs index 814be9f..8f7bb78 100644 --- a/src/day19.rs +++ b/src/day19.rs @@ -1,5 +1,8 @@ use std::collections::HashMap; +use itertools::{Itertools, repeat_n}; +use rayon::iter::{IntoParallelIterator, ParallelBridge, ParallelIterator}; + use crate::*; pub struct Day19; @@ -42,7 +45,7 @@ hdj{m>838:A,pv} sum += match result { RuleResult::Accepted => { println!("Part {:?} has been accepted", element); - element.a+element.m+element.s+element.x + element.a + element.m + element.s + element.x } RuleResult::Rejected => { println!("Part {:?} has been rejected", element); @@ -55,6 +58,84 @@ hdj{m>838:A,pv} sum.try_into().unwrap() } } +impl DayPart2 for Day19 { + fn run_part2(data: Self::Input) -> Self::Output { + let data = Game::from_str_p1(data); + + let limit = 4000; + let result = calculate_accepted_amount(limit, &data); + result + } + + fn get_test_result_part2() -> Self::Output { + 167409079868000 + } + + fn get_test_data_part2() -> Self::Input { + Self::get_test_data() + } +} + +fn calculate_accepted_amount(limit: isize, data: &Game) -> usize { + let result: usize = (1..=limit).par_bridge() + // .into_par_iter() + .map(|x| { + (1..=limit).par_bridge() + // .into_par_iter() + .map(|m| { + (1..=limit).par_bridge() + // .into_par_iter() + .map(|a| { + (1..=limit).par_bridge() + // .into_par_iter() + .map(|s| { + let element = Element { x, m, a, s }; + let result = data.get_result_p1(&element); + match result { + RuleResult::Accepted => 1, + RuleResult::Rejected => 0, + RuleResult::Workflow(_) => todo!(), + } + }) + .sum::() + }) + .sum::() + }) + .sum::() + }) + .sum::(); + result +} + +fn calculate_accepted_amount_v2(limit: isize, data: &Game) -> usize { + // let total = limit * limit * limit*limit; + let v = repeat_n(1..=limit, 4).multi_cartesian_product() + // .collect::>() + ; + // println!("limit: {limit}"); + // println!("should have {total} permutations"); + // println!("got {}", v.len()); + // dbg!(&v); + // assert_eq!(total as usize, v.len()); + let result: usize = v.par_bridge() + // .par_bridge() + .map(|i| { + let x = i[0]; + let m = i[1]; + let a = i [2]; + let s = i [3]; + // println!("{} {} {} {}", x, m, a, s); + let element = Element { x, m, a, s }; + let result = data.get_result_p1(&element); + match result { + RuleResult::Accepted => 1, + RuleResult::Rejected => 0, + RuleResult::Workflow(_) => todo!(), + } + }) + .sum::(); + result +} impl Game { fn from_str_p1(data: ::Input) -> Self { let mut data = data.lines().into_iter(); @@ -81,13 +162,13 @@ impl Game { fn get_result_p1(&self, element: &Element) -> RuleResult { let mut current = self.workflows.get("in").unwrap(); loop { - 'rules_loop: for rule in ¤t.rules { + 'rules_loop: for rule in ¤t.rules { if let Some(x) = rule.matches_element(element) { match x { RuleResult::Accepted => return RuleResult::Accepted, RuleResult::Rejected => return RuleResult::Rejected, RuleResult::Workflow(workflow) => { - println!("switching workflow from {} to {}", current.id, workflow); + // println!("switching workflow from {} to {}", current.id, workflow); // dbg!(¤t); // dbg!(&element); current = self.workflows.get(&workflow).unwrap(); @@ -274,4 +355,33 @@ mod tests { let actual_result = game.get_result_p1(&element); assert_eq!(actual_result, expected_result); } + #[rstest] + fn v1_v2(game: super::Game) { + println!("Running v1"); + let result = calculate_accepted_amount(LIMIT, &game); + println!("Running v2"); + let result2 = calculate_accepted_amount_v2(LIMIT, &game); + println!("Got results."); + dbg!(&result, &result2); + assert_eq!(result, result2); + } + extern crate test; + use test::Bencher; + const LIMIT: isize = 25; + #[bench] + fn bench_mapping(b: &mut Bencher) { + let game = game(); + b.iter(|| { + let result = calculate_accepted_amount(LIMIT, &game); + println!("{}", result); + }) + } + #[bench] + fn bench_mapping_v2(b: &mut Bencher) { + let game = game(); + b.iter(|| { + let result = calculate_accepted_amount_v2(LIMIT, &game); + println!("{}", result); + }) + } } diff --git a/src/main.rs b/src/main.rs index 7a47968..2cbea5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ fn main() { //Day06::run_all(); //Day07::run_all(); //Day19::run_all(); - Day19::part1(); + Day19::part2(); // utils::run!(01); // utils::run!(02);