mirror of
https://github.com/OMGeeky/advent-of-code-2023.git
synced 2026-02-23 15:38:26 +01:00
day 19 part 2 try
This commit is contained in:
@@ -13,6 +13,7 @@ serde_json = "1.0.68"
|
|||||||
paste ={ version = "1.0" }
|
paste ={ version = "1.0" }
|
||||||
cached="0.46"
|
cached="0.46"
|
||||||
itertools="0.12"
|
itertools="0.12"
|
||||||
|
rayon="1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rstest = "0.18"
|
rstest = "0.18"
|
||||||
|
|||||||
116
src/day19.rs
116
src/day19.rs
@@ -1,5 +1,8 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use itertools::{Itertools, repeat_n};
|
||||||
|
use rayon::iter::{IntoParallelIterator, ParallelBridge, ParallelIterator};
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub struct Day19;
|
pub struct Day19;
|
||||||
@@ -42,7 +45,7 @@ hdj{m>838:A,pv}
|
|||||||
sum += match result {
|
sum += match result {
|
||||||
RuleResult::Accepted => {
|
RuleResult::Accepted => {
|
||||||
println!("Part {:?} has been accepted", element);
|
println!("Part {:?} has been accepted", element);
|
||||||
element.a+element.m+element.s+element.x
|
element.a + element.m + element.s + element.x
|
||||||
}
|
}
|
||||||
RuleResult::Rejected => {
|
RuleResult::Rejected => {
|
||||||
println!("Part {:?} has been rejected", element);
|
println!("Part {:?} has been rejected", element);
|
||||||
@@ -55,6 +58,84 @@ hdj{m>838:A,pv}
|
|||||||
sum.try_into().unwrap()
|
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::<usize>()
|
||||||
|
})
|
||||||
|
.sum::<usize>()
|
||||||
|
})
|
||||||
|
.sum::<usize>()
|
||||||
|
})
|
||||||
|
.sum::<usize>();
|
||||||
|
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::<Vec<_>>()
|
||||||
|
;
|
||||||
|
// 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::<usize>();
|
||||||
|
result
|
||||||
|
}
|
||||||
impl Game {
|
impl Game {
|
||||||
fn from_str_p1(data: <Day19 as Day>::Input) -> Self {
|
fn from_str_p1(data: <Day19 as Day>::Input) -> Self {
|
||||||
let mut data = data.lines().into_iter();
|
let mut data = data.lines().into_iter();
|
||||||
@@ -81,13 +162,13 @@ impl Game {
|
|||||||
fn get_result_p1(&self, element: &Element) -> RuleResult {
|
fn get_result_p1(&self, element: &Element) -> RuleResult {
|
||||||
let mut current = self.workflows.get("in").unwrap();
|
let mut current = self.workflows.get("in").unwrap();
|
||||||
loop {
|
loop {
|
||||||
'rules_loop: for rule in ¤t.rules {
|
'rules_loop: for rule in ¤t.rules {
|
||||||
if let Some(x) = rule.matches_element(element) {
|
if let Some(x) = rule.matches_element(element) {
|
||||||
match x {
|
match x {
|
||||||
RuleResult::Accepted => return RuleResult::Accepted,
|
RuleResult::Accepted => return RuleResult::Accepted,
|
||||||
RuleResult::Rejected => return RuleResult::Rejected,
|
RuleResult::Rejected => return RuleResult::Rejected,
|
||||||
RuleResult::Workflow(workflow) => {
|
RuleResult::Workflow(workflow) => {
|
||||||
println!("switching workflow from {} to {}", current.id, workflow);
|
// println!("switching workflow from {} to {}", current.id, workflow);
|
||||||
// dbg!(¤t);
|
// dbg!(¤t);
|
||||||
// dbg!(&element);
|
// dbg!(&element);
|
||||||
current = self.workflows.get(&workflow).unwrap();
|
current = self.workflows.get(&workflow).unwrap();
|
||||||
@@ -274,4 +355,33 @@ mod tests {
|
|||||||
let actual_result = game.get_result_p1(&element);
|
let actual_result = game.get_result_p1(&element);
|
||||||
assert_eq!(actual_result, expected_result);
|
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);
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ fn main() {
|
|||||||
//Day06::run_all();
|
//Day06::run_all();
|
||||||
//Day07::run_all();
|
//Day07::run_all();
|
||||||
//Day19::run_all();
|
//Day19::run_all();
|
||||||
Day19::part1();
|
Day19::part2();
|
||||||
|
|
||||||
// utils::run!(01);
|
// utils::run!(01);
|
||||||
// utils::run!(02);
|
// utils::run!(02);
|
||||||
|
|||||||
Reference in New Issue
Block a user