d19
This commit is contained in:
		
							parent
							
								
									823b56e695
								
							
						
					
					
						commit
						68fa0587fe
					
				
					 3 changed files with 172 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -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}
 | 
			
		||||
							
								
								
									
										157
									
								
								src/days/d19.rs
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								src/days/d19.rs
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,16 +1,163 @@
 | 
			
		|||
use std::fs;
 | 
			
		||||
use std::{collections::HashMap, fs};
 | 
			
		||||
 | 
			
		||||
use rayon::prelude::*;
 | 
			
		||||
use regex::Regex;
 | 
			
		||||
 | 
			
		||||
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 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}");
 | 
			
		||||
 | 
			
		||||
    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}");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,8 +5,8 @@ extern crate scan_fmt;
 | 
			
		|||
use std::time::Instant;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    days::d17::solve()
 | 
			
		||||
    //_all_days()
 | 
			
		||||
    //days::d19::solve()
 | 
			
		||||
    _all_days()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[allow(unreachable_code, unused)]
 | 
			
		||||
| 
						 | 
				
			
			@ -85,11 +85,11 @@ fn _all_days() {
 | 
			
		|||
    days::d18::solve();
 | 
			
		||||
    time = _print_elapsed(time);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    println!("\nDay 19");
 | 
			
		||||
    days::d19::solve();
 | 
			
		||||
    time = _print_elapsed(time);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    println!("\nDay 20");
 | 
			
		||||
    days::d20::solve();
 | 
			
		||||
    time = _print_elapsed(time);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue