diff --git a/rust/src/main.rs b/rust/src/main.rs index a6f65b6..ff28d6c 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -687,7 +687,9 @@ mod day18 { mod day19 { use std::collections::BTreeMap as HashMap; - use std::time::Duration; + use std::fs::File; + use std::io::{BufWriter, Write}; + use std::time::{Duration, Instant}; #[derive(Debug)] enum Rhs { @@ -733,63 +735,76 @@ mod day19 { Some((rules, messages)) } - pub fn run(_print: bool) -> Duration { - let input = std::fs::read_to_string("../inputs/19").unwrap(); + fn generate(rules: &Rules, messages: &Vec<&str>, filename: &str) -> std::io::Result<()> { + let write_file = File::create(filename)?; + let mut w = BufWriter::new(&write_file); - println!("from typing import Tuple"); - println!(); - - let (rules, messages) = parse(&input).unwrap(); + writeln!(&mut w, "from typing import Tuple")?; + writeln!(&mut w)?; for (i, rule) in rules.iter() { - println!("def rule_{}(s: str) -> Tuple[bool, str]:", i); + writeln!(&mut w, "def rule_{}(s):", i)?; + writeln!(&mut w, " if s != '':")?; + match rule { Rhs::Terminal(terminal) => { - println!(" if s[0] == '{}':", terminal); - println!(" return True, s[1:]"); - println!(" return False, s"); + writeln!(&mut w, " if s[0] == '{}':", terminal)?; + writeln!(&mut w, " yield s[1:]")?; } Rhs::Variables(variables) => { for term in variables { - println!(" r = s"); - for (j, variable) in term.iter().enumerate() { - println!(" valid_{}, r = rule_{}(r)", j, variable); + for (j, rule) in term.iter().enumerate() { + if j == 0 { + writeln!(&mut w, " v{} = rule_{}(s)", j, rule)?; + } else { + writeln!( + &mut w, + " v{} = (out for inp in v{} for out in rule_{}(inp))", + j, + j - 1, + rule, + )?; + } } - println!(" if all(("); - for j in 0..term.len() { - println!(" valid_{}, ", j); - } - println!(" )):"); - println!(" return True, r"); - println!(); + writeln!(&mut w, " yield from v{}", term.len() - 1)?; + writeln!(&mut w)?; } - println!(" return False, s"); } } - println!(); - println!(); + writeln!(&mut w)?; } - println!("def validate(s):"); - for i in 0..rules.len() { - println!(" if rule_{}(s) == (True, ''):", i); - println!(" return True"); - } - println!(" return False"); + writeln!(&mut w, "def validate(s):")?; + writeln!(&mut w, " return any(x == '' for x in rule_0(s))")?; - println!(); - println!("if __name__ == '__main__':"); - println!(" part1 = 0"); + writeln!(&mut w)?; + writeln!(&mut w, "if __name__ == '__main__':")?; + writeln!(&mut w, " result = 0")?; for message in messages { - println!(" if (result := validate('{}')):", message); - println!(" part1 += 1"); - println!(" print('{}:', result)", message); - println!(); + writeln!(&mut w, " success = validate('{}')", message)?; + // writeln!(&mut w, " print('{}:', success)", message)?; + writeln!(&mut w, " if success:")?; + writeln!(&mut w, " result += 1")?; + writeln!(&mut w)?; } - println!(" print('Part 1:', part1)"); + writeln!(&mut w, " print('Result:', result)")?; - Duration::new(0, 0) + Ok(()) + } + + pub fn run(_print: bool) -> Duration { + let input = std::fs::read_to_string("../inputs/19").unwrap(); + let instant = Instant::now(); + + let (mut rules, messages) = parse(&input).unwrap(); + generate(&rules, &messages, "/tmp/day19-1.py").unwrap(); + + rules.insert(8, Rhs::Variables(vec![vec![42], vec![42, 8]])); + rules.insert(11, Rhs::Variables(vec![vec![42, 31], vec![42, 11, 31]])); + generate(&rules, &messages, "/tmp/day19-2.py").unwrap(); + + instant.elapsed() } }