[TASK] Solved day 19 (haven't solved day 18 yet tho, coming up!)
This commit is contained in:
12
src/day17.rs
12
src/day17.rs
@@ -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
112
src/day19.rs
Normal 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
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user