Completed day 19 part 2
Terribly inefficient algorithm but at this point I don't care.
This commit is contained in:
parent
2fb9b4ed4a
commit
c248cb0bbd
@ -1,15 +1,7 @@
|
|||||||
0: 1 | 2
|
0: 1 2
|
||||||
1: 3 | 3 1
|
1: 3 | 3 1
|
||||||
2: 3 4 | 3 2 4
|
2: 3 4 | 3 2 4
|
||||||
3: "a"
|
3: "a"
|
||||||
4: "b"
|
4: "b"
|
||||||
|
|
||||||
a
|
aaaaabb
|
||||||
aa
|
|
||||||
aaa
|
|
||||||
b
|
|
||||||
ab
|
|
||||||
aabb
|
|
||||||
aaabbb
|
|
||||||
aaaabbb
|
|
||||||
aaabbbb
|
|
||||||
|
@ -60,48 +60,58 @@ fn string_matches_rule<'a>(
|
|||||||
rules: &HashMap<usize, Rule>,
|
rules: &HashMap<usize, Rule>,
|
||||||
rule: &Rule,
|
rule: &Rule,
|
||||||
ends: bool,
|
ends: bool,
|
||||||
) -> (&'a str, bool) {
|
) -> Vec<(&'a str, bool)> {
|
||||||
if s.is_empty() {
|
|
||||||
return (s, false);
|
|
||||||
}
|
|
||||||
match rule {
|
match rule {
|
||||||
Rule::Char(c) => {
|
Rule::Char(c) => {
|
||||||
if s.len() < 1 {
|
if s.len() < 1 {
|
||||||
(s, false)
|
vec![(s, false)]
|
||||||
} else if s.chars().next().expect("non-empty string") == *c {
|
} else if s.chars().next().expect("non-empty string") == *c {
|
||||||
let rest = &s[1..];
|
let rest = &s[1..];
|
||||||
if !ends || (ends && rest.is_empty()) {
|
if !ends || (ends && rest.is_empty()) {
|
||||||
(rest, true)
|
vec![(rest, true)]
|
||||||
} else {
|
} else {
|
||||||
(rest, false)
|
vec![(rest, false)]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(s, false)
|
vec![(s, false)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rule::Seq(seq) => {
|
Rule::Seq(seq) => {
|
||||||
let mut rest = s;
|
let mut possibilities: Vec<(&'a str, bool)> = Vec::new();
|
||||||
for (i, rule_index) in seq.iter().enumerate() {
|
for (i, rule_index) in seq.iter().enumerate() {
|
||||||
let result = string_matches_rule(
|
if i == 0 {
|
||||||
rest,
|
possibilities = string_matches_rule(
|
||||||
|
s,
|
||||||
rules,
|
rules,
|
||||||
&rules[rule_index],
|
&rules[rule_index],
|
||||||
if i == seq.len() - 1 { ends } else { false },
|
if i == seq.len() - 1 { ends } else { false },
|
||||||
);
|
);
|
||||||
if !result.1 {
|
} else {
|
||||||
return result;
|
let mut new_possibilities = Vec::new();
|
||||||
|
for possibility in possibilities {
|
||||||
|
if possibility.1 {
|
||||||
|
new_possibilities.append(&mut string_matches_rule(
|
||||||
|
possibility.0,
|
||||||
|
rules,
|
||||||
|
&rules[rule_index],
|
||||||
|
if i == seq.len() - 1 { ends } else { false },
|
||||||
|
));
|
||||||
}
|
}
|
||||||
rest = result.0;
|
|
||||||
}
|
}
|
||||||
(rest, true)
|
possibilities = new_possibilities;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
possibilities
|
||||||
}
|
}
|
||||||
Rule::Or((left, right)) => {
|
Rule::Or((left, right)) => {
|
||||||
let result = string_matches_rule(s, rules, &Rule::Seq(left.to_vec()), ends);
|
let mut possibilities = string_matches_rule(s, rules, &Rule::Seq(left.to_vec()), ends);
|
||||||
if result.1 {
|
possibilities.append(&mut string_matches_rule(
|
||||||
return result;
|
s,
|
||||||
}
|
rules,
|
||||||
let result = string_matches_rule(s, rules, &Rule::Seq(right.to_vec()), ends);
|
&Rule::Seq(right.to_vec()),
|
||||||
result
|
ends,
|
||||||
|
));
|
||||||
|
possibilities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,8 +136,8 @@ fn solve_part1(input_path: &str) -> Result<usize> {
|
|||||||
Ok(strings
|
Ok(strings
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|s| {
|
.filter(|s| {
|
||||||
let result = string_matches_rule(&s, &rules, &rules[&0], true);
|
let results = string_matches_rule(&s, &rules, &rules[&0], true);
|
||||||
result.1 && result.0.is_empty()
|
results.iter().any(|result| result.1 && result.0.is_empty())
|
||||||
})
|
})
|
||||||
.count())
|
.count())
|
||||||
}
|
}
|
||||||
@ -158,8 +168,8 @@ fn solve_part2(input_path: &str) -> Result<usize> {
|
|||||||
Ok(strings
|
Ok(strings
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|s| {
|
.filter(|s| {
|
||||||
let result = string_matches_rule(&s, &rules, &rules[&0], true);
|
let results = string_matches_rule(&s, &rules, &rules[&0], true);
|
||||||
result.1 && result.0.is_empty()
|
results.iter().any(|result| result.1 && result.0.is_empty())
|
||||||
})
|
})
|
||||||
.count())
|
.count())
|
||||||
}
|
}
|
||||||
@ -214,7 +224,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn solves_part2() {
|
fn solves_part2() {
|
||||||
assert_eq!(solve_part1(TEST_INPUT2).unwrap(), 3);
|
assert_eq!(solve_part1(TEST_INPUT2).unwrap(), 3);
|
||||||
assert_eq!(solve_part1(TEST_INPUT3).unwrap(), 6);
|
assert_eq!(solve_part1(TEST_INPUT3).unwrap(), 1);
|
||||||
assert_eq!(solve_part2(TEST_INPUT2).unwrap(), 12);
|
assert_eq!(solve_part2(TEST_INPUT2).unwrap(), 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user