Day 19 part 2.
This commit is contained in:
@@ -65,7 +65,6 @@ fn part2(input: &Field) -> usize {
|
|||||||
current.into_iter().flatten().filter(|x| *x).count()
|
current.into_iter().flatten().filter(|x| *x).count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn count_neighbors(field: &Field, x: usize, y: usize) -> usize {
|
fn count_neighbors(field: &Field, x: usize, y: usize) -> usize {
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
if field[x - 1][y - 1] {
|
if field[x - 1][y - 1] {
|
||||||
|
|||||||
80
src/day19.rs
80
src/day19.rs
@@ -1,4 +1,5 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::{HashSet, VecDeque};
|
||||||
|
|
||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
|
||||||
type Transformation = (String, String);
|
type Transformation = (String, String);
|
||||||
@@ -6,27 +7,35 @@ type Transformation = (String, String);
|
|||||||
#[aoc_generator(day19)]
|
#[aoc_generator(day19)]
|
||||||
fn parse(input: &str) -> (Vec<Transformation>, String) {
|
fn parse(input: &str) -> (Vec<Transformation>, String) {
|
||||||
let (a, b) = input.split_once("\n\n").unwrap();
|
let (a, b) = input.split_once("\n\n").unwrap();
|
||||||
let t = a.lines().map(|line| {
|
let t = a
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
let (lhs, rhs) = line.split_once(" => ").unwrap();
|
let (lhs, rhs) = line.split_once(" => ").unwrap();
|
||||||
(lhs.to_string(), rhs.to_string())
|
(lhs.to_string(), rhs.to_string())
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
(t, b.to_string())
|
(t, b.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc(day19, part1)]
|
#[aoc(day19, part1)]
|
||||||
fn part1((transformations, start): &(Vec<Transformation>, String)) -> usize {
|
fn part1((transformations, start): &(Vec<Transformation>, String)) -> usize {
|
||||||
let all: HashSet<String> = transformations.iter()
|
let all = possibilities(transformations, start);
|
||||||
|
all.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn possibilities(transformations: &[Transformation], start: &str) -> HashSet<String> {
|
||||||
|
let all: HashSet<String> = transformations
|
||||||
|
.iter()
|
||||||
.flat_map(|(from, to)| {
|
.flat_map(|(from, to)| {
|
||||||
let start_indexes = starts(start, from);
|
let start_indexes = starts(start, from);
|
||||||
start_indexes.into_iter()
|
start_indexes.into_iter().map(|si| {
|
||||||
.map(|si| {
|
let mut s = start.to_string();
|
||||||
let mut s = start.clone();
|
s.replace_range(si..si + from.len(), to);
|
||||||
s.replace_range(si..si+from.len(), to);
|
|
||||||
s
|
s
|
||||||
})
|
})
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
all.len()
|
all
|
||||||
}
|
}
|
||||||
|
|
||||||
fn starts(a: &str, pattern: &str) -> Vec<usize> {
|
fn starts(a: &str, pattern: &str) -> Vec<usize> {
|
||||||
@@ -39,6 +48,29 @@ fn starts(a: &str, pattern: &str) -> Vec<usize> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[aoc(day19, part2)]
|
||||||
|
fn part2((transformations, target): &(Vec<Transformation>, String)) -> usize {
|
||||||
|
search("e", transformations, target)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search(base: &str, transformations: &[Transformation], target: &str) -> usize {
|
||||||
|
let mut seen = HashSet::new();
|
||||||
|
seen.insert(base.to_string());
|
||||||
|
let mut queue = VecDeque::new();
|
||||||
|
queue.push_back((base.to_string(), 0));
|
||||||
|
while let Some((from, depth)) = queue.pop_front() {
|
||||||
|
for possibility in possibilities(transformations, &from) {
|
||||||
|
if possibility == target {
|
||||||
|
return depth + 1;
|
||||||
|
}
|
||||||
|
if seen.insert(possibility.clone()) {
|
||||||
|
queue.push_back((possibility, depth + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unreachable!("No solution was found");
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
#[test]
|
#[test]
|
||||||
@@ -48,6 +80,30 @@ H => OH
|
|||||||
O => HH
|
O => HH
|
||||||
|
|
||||||
HOH";
|
HOH";
|
||||||
assert_eq!(super::part1(& super::parse(input)), 4);
|
assert_eq!(super::part1(&super::parse(input)), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2a() {
|
||||||
|
let input = "e => H
|
||||||
|
e => O
|
||||||
|
H => HO
|
||||||
|
H => OH
|
||||||
|
O => HH
|
||||||
|
|
||||||
|
HOH";
|
||||||
|
assert_eq!(super::part2(&super::parse(input)), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2b() {
|
||||||
|
let input = "e => H
|
||||||
|
e => O
|
||||||
|
H => HO
|
||||||
|
H => OH
|
||||||
|
O => HH
|
||||||
|
|
||||||
|
HOHOHO";
|
||||||
|
assert_eq!(super::part2(&super::parse(input)), 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user