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() {
 | 
					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}");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue