This commit is contained in:
JonOfUs 2023-12-19 23:09:03 +01:00
parent 823b56e695
commit 68fa0587fe
3 changed files with 172 additions and 8 deletions

View file

@ -0,0 +1,17 @@
px{a<2006:qkq,m>2090:A,rfg}
pv{a>1716:R,A}
lnx{m>1548:A,A}
rfg{s<537:gd,x>2440:R,A}
qs{s>3448:A,lnx}
qkq{x<1416:A,crn}
crn{x>2662:A,R}
in{s<1351:px,qqz}
qqz{s>2770:qs,m<1801:hdj,R}
gd{a>3333:R,R}
hdj{m>838:A,pv}
{x=787,m=2655,a=1222,s=2876}
{x=1679,m=44,a=2067,s=496}
{x=2036,m=264,a=79,s=2244}
{x=2461,m=1339,a=466,s=291}
{x=2127,m=1623,a=2188,s=1013}

View file

@ -1,16 +1,163 @@
use std::fs; use std::{collections::HashMap, fs};
use rayon::prelude::*;
use regex::Regex;
pub fn solve() { pub fn solve() {
let path = "res/19/example"; let path = "res/19/input";
let mut _contents = fs::read_to_string(path).expect("I/O error, wrong path?"); let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
//let contents = BufReader::new(fs::File::open(path).expect("I/O error, wrong path?")); //let contents = BufReader::new(fs::File::open(path).expect("I/O error, wrong path?"));
let result: usize = 0; let (rules, parts) = contents.split_once("\n\n").unwrap();
let rules: HashMap<&str, (Vec<(u8, bool, usize, String)>, String)> = rules
.lines()
.map(|line| {
let (name, rest) = line.split_once("{").unwrap();
let rest = rest.replace("}", "");
let mut rules: Vec<&str> = rest.split(",").collect();
let default = String::from(rules.pop().unwrap());
let rules: Vec<(u8, bool, usize, String)> = rules
.iter()
.map(|rule| {
let re = Regex::new(
r"^(?P<var>[a-z])(?P<op>[><])(?P<num>\d+):(?P<target>[a-zA-Z]+)$",
)
.unwrap();
let captures = re.captures(rule).unwrap();
let var = captures["var"].to_string();
let op = captures["op"].to_string();
let num = captures["num"].parse::<usize>().unwrap();
let target = captures["target"].to_string();
let var = match var.as_ref() {
"x" => 0,
"m" => 1,
"a" => 2,
_ => 3,
};
(var, op == String::from(">"), num, target)
})
.collect();
(name, (rules, default))
})
.collect();
let parts: Vec<[usize; 4]> = parts
.lines()
.map(|line| {
let (x, m, a, s) = scan_fmt!(
line,
"{{x={d},m={d},a={d},s={d}}}",
usize,
usize,
usize,
usize
)
.unwrap();
[x, m, a, s]
})
.collect();
let result: usize = parts
.par_iter()
.map(|part| {
let mut curr = "in";
while curr != "A" && curr != "R" {
let rule = &rules[&curr];
let mut applied = false;
rule.0.iter().for_each(|r| {
if applied {
return;
}
match r.1 {
false => {
// <
if part[r.0 as usize] < r.2 {
curr = r.3.as_ref();
applied = true;
}
}
true => {
// >
if part[r.0 as usize] > r.2 {
curr = r.3.as_ref();
applied = true;
}
}
}
});
if !applied {
curr = rule.1.as_ref()
}
}
if curr == "A" {
return part.iter().sum();
}
0
})
.sum();
println!("Result 1: {result}"); println!("Result 1: {result}");
let result: usize = 0; //let mut ranges: HashMap<&str, Vec<(&str, [(usize,usize);4])>> = HashMap::new();
let mut ranges: Vec<(&str, [(usize, usize); 4])> = vec![("in", [(1, 4000); 4])];
let mut accept: Vec<[(usize, usize); 4]> = vec![];
while !ranges.is_empty() {
let (curr, mut vals) = ranges.pop().unwrap();
if curr == "A" {
accept.push(vals);
continue;
}
if curr == "R" {
continue;
}
let rule = &rules[&curr];
rule.0.iter().for_each(|r| {
if vals[r.0 as usize] == (0, 0) {
return;
}
match r.1 {
false => {
// <
if vals[r.0 as usize].0 < r.2 {
let mut new_ranges = vals.clone();
new_ranges[r.0 as usize].1 = vals[r.0 as usize].1.min(r.2 - 1);
ranges.push((r.3.as_ref(), new_ranges));
if vals[r.0 as usize].1 < r.2 {
vals[r.0 as usize] = (0, 0)
} else {
vals[r.0 as usize].0 = r.2
}
}
}
true => {
// >
if vals[r.0 as usize].1 > r.2 {
let mut new_ranges = vals.clone();
new_ranges[r.0 as usize].0 = vals[r.0 as usize].0.max(r.2 + 1);
ranges.push((r.3.as_ref(), new_ranges));
if vals[r.0 as usize].0 > r.2 {
vals[r.0 as usize] = (0, 0)
} else {
vals[r.0 as usize].1 = r.2
}
}
}
}
});
if vals.iter().any(|p| *p != (0, 0)) {
ranges.push((rule.1.as_ref(), vals))
}
}
let result: usize = accept
.iter()
.map(|vals| vals.iter().map(|(l, u)| *u - *l + 1).product::<usize>())
.sum();
println!("Result 2: {result}"); println!("Result 2: {result}");
} }

View file

@ -5,8 +5,8 @@ extern crate scan_fmt;
use std::time::Instant; use std::time::Instant;
fn main() { fn main() {
days::d17::solve() //days::d19::solve()
//_all_days() _all_days()
} }
#[allow(unreachable_code, unused)] #[allow(unreachable_code, unused)]
@ -85,11 +85,11 @@ fn _all_days() {
days::d18::solve(); days::d18::solve();
time = _print_elapsed(time); time = _print_elapsed(time);
/*
println!("\nDay 19"); println!("\nDay 19");
days::d19::solve(); days::d19::solve();
time = _print_elapsed(time); time = _print_elapsed(time);
/*
println!("\nDay 20"); println!("\nDay 20");
days::d20::solve(); days::d20::solve();
time = _print_elapsed(time); time = _print_elapsed(time);