[TASK] Solved day 19 (haven't solved day 18 yet tho, coming up!)

This commit is contained in:
2020-12-19 10:55:48 +01:00
parent 9967283916
commit ff2a2c5bb3
5 changed files with 712 additions and 7 deletions

View File

@@ -13,7 +13,7 @@ pub fn solve() {
let lower = Vec4::of(-cycles-1, -cycles-1, -cycles-1, -cycles-1);
let upper = Vec4::of(initial_width + cycles+1, initial_height + cycles+1, cycles + 2, cycles + 2);
let mut initial_state = BoolGrid3D::new(lower, upper);
let mut initial_state = BoolGrid4D::new(lower, upper);
for y in 0..initial_height {
let mut line_chars = lines[y as usize].chars();
@@ -36,7 +36,7 @@ pub fn solve() {
println!("Day 17 Part 2: {}", part2);
}
fn run_conway_cube_simulation(initial_state: &BoolGrid3D, cycles: u32, restrict_fourth_dimension: bool) -> BoolGrid3D {
fn run_conway_cube_simulation(initial_state: &BoolGrid4D, cycles: u32, restrict_fourth_dimension: bool) -> BoolGrid4D {
let mut prev_state = initial_state.clone();
let mut next_state = initial_state.clone();
@@ -120,7 +120,7 @@ impl Vec4 {
}
#[derive(Clone)]
struct BoolGrid3D {
struct BoolGrid4D {
data: BitArray,
lower: Vec4,
@@ -128,9 +128,9 @@ struct BoolGrid3D {
size: Vec4,
}
impl BoolGrid3D {
impl BoolGrid4D {
fn new(lower: Vec4, upper: Vec4) -> BoolGrid3D {
fn new(lower: Vec4, upper: Vec4) -> BoolGrid4D {
assert!(lower.x < upper.x && lower.y < upper.y && lower.z < upper.z);
@@ -141,7 +141,7 @@ impl BoolGrid3D {
w: upper.w - lower.w
};
return BoolGrid3D {
return BoolGrid4D {
data: BitArray::new((size.x * size.y * size.z * size.w) as usize, false),
lower, upper, size
}

112
src/day19.rs Normal file
View File

@@ -0,0 +1,112 @@
use super::util;
use regex::Regex;
use crate::day19::RuleType::{Letter, Options};
use std::collections::{HashMap, HashSet};
pub fn solve() {
let lines = util::read_file("input/day19.txt");
let mut rules_map = HashMap::new();
lines.iter()
.take_while(|s| s != &&String::from(""))
.for_each(|s| {
let mut line_split = s.split(": ");
let idx = line_split.next().unwrap().parse::<usize>().unwrap();
let rule = Rule::parse(line_split.next().unwrap());
rules_map.insert(idx, rule);
});
let messages: Vec<&String> = lines[(rules_map.len() + 1)..].iter().collect();
println!("{:?}", try_match(&messages[0], &0, &rules_map));
let part1 = messages.iter().filter(|m| try_match(m, &0, &rules_map).contains(&m.len())).count();
println!("Day X Part 1: {}", part1);
// We update the rules to include the loops:
rules_map.insert(8, Rule::parse("42 | 42 8"));
rules_map.insert(11, Rule::parse("42 31 | 42 11 31"));
let part2 = messages.iter().filter(|m| try_match(m, &0, &rules_map).contains(&m.len())).count();
println!("Day X Part 2: {}", part2);
}
/// Calculates and returns until when the string was matched
fn try_match(message: &str, rule_idx: &usize, rules: &HashMap<usize, Rule>) -> HashSet<usize> {
let rule = rules.get(&rule_idx).unwrap();
if rule.rule_type == Letter {
if message.starts_with(rule.letters.as_ref().unwrap()) {
let mut res = HashSet::new();
// Note: kind of a hack here, all the "letter" based matchers are of length 1
res.insert(rule.letters.as_ref().unwrap().len().clone());
return res;
} else {
return HashSet::new();
}
} else {
return rule.options.as_ref().unwrap().iter()
.flat_map(|options| {
let mut try_from = HashSet::new();
try_from.insert(0);
let mut next_try_from = HashSet::new();
for option_rule_idx in options {
for start_idx in try_from {
try_match(&message[start_idx..], &option_rule_idx, rules)
.iter()
.for_each(|m| { if m != &0 { next_try_from.insert(start_idx + m); () }})
}
try_from = next_try_from.clone();
if try_from.is_empty() { break; }
next_try_from.clear();
}
return try_from;
}).collect();
}
}
#[derive(Debug, Clone)]
struct Rule {
rule_type: RuleType,
letters: Option<String>,
options: Option<Vec<Vec<usize>>>
}
impl Rule {
fn parse(input: &str) -> Rule {
lazy_static! {
static ref LETTER_RULE_MATCHER: Regex = Regex::new(r###"^"([a-z])"$"###).unwrap();
}
return if LETTER_RULE_MATCHER.is_match(input) {
Rule {
rule_type: Letter,
letters: Option::Some(LETTER_RULE_MATCHER.captures(input).unwrap().get(1).map(|m| String::from(m.as_str())).unwrap()),
options: Option::None,
}
} else {
let options =
input.split(" | ")
.map(|s| s.split(" ").map(|o| o.parse::<usize>().unwrap()).collect::<Vec<_>>()).collect::<Vec<_>>();
Rule {
rule_type: Options,
letters: Option::None,
options: Option::Some(options)
}
}
}
}
#[derive(Debug, PartialEq, Clone)]
enum RuleType {
Letter, Options
}

View File

@@ -19,8 +19,9 @@ mod day14;
mod day15;
mod day16;
mod day17;
mod day19;
const MAX_DAY: u8 = 17;
const MAX_DAY: u8 = 19;
const BENCHMARK_AMOUNT: u32 = 100;
fn solve(day: u8) {
@@ -42,6 +43,8 @@ fn solve(day: u8) {
15 => day15::solve(),
16 => day16::solve(),
17 => day17::solve(),
// 18 => day18::solve(),
19 => day19::solve(),
_ => println!("This day is not yet implemented")
}
}