mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Refactor out common code
This commit is contained in:
@@ -14,7 +14,12 @@ fn can_travel(from: u8, to: u8) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
fn parts_common(
|
||||||
|
input: &[u8],
|
||||||
|
starting_symbol: u8,
|
||||||
|
is_end: impl Fn(u8) -> bool,
|
||||||
|
accessible: impl Fn(u8, u8) -> bool,
|
||||||
|
) -> Result<String> {
|
||||||
let width = input
|
let width = input
|
||||||
.iter()
|
.iter()
|
||||||
.position(|&c| c == b'\n')
|
.position(|&c| c == b'\n')
|
||||||
@@ -23,7 +28,7 @@ pub fn part1(input: &[u8]) -> Result<String> {
|
|||||||
|
|
||||||
let starting_pos = input
|
let starting_pos = input
|
||||||
.iter()
|
.iter()
|
||||||
.position(|&c| c == b'S')
|
.position(|&c| c == starting_symbol)
|
||||||
.context("Could not find starting position")?;
|
.context("Could not find starting position")?;
|
||||||
|
|
||||||
let mut visited = IndexSet::with_capacity(input.len());
|
let mut visited = IndexSet::with_capacity(input.len());
|
||||||
@@ -32,12 +37,12 @@ pub fn part1(input: &[u8]) -> Result<String> {
|
|||||||
todo.push_back((0, starting_pos));
|
todo.push_back((0, starting_pos));
|
||||||
|
|
||||||
while let Some((dist, pos)) = todo.pop_front() {
|
while let Some((dist, pos)) = todo.pop_front() {
|
||||||
if input[pos] == b'E' {
|
if is_end(input[pos]) {
|
||||||
return Ok(dist.to_string());
|
return Ok(dist.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut add_todo = |new: usize| {
|
let mut add_todo = |new: usize| {
|
||||||
if can_travel(input[pos], input[new]) && visited.insert(new) {
|
if accessible(input[pos], input[new]) && visited.insert(new) {
|
||||||
todo.push_back((dist + 1, new));
|
todo.push_back((dist + 1, new));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -62,52 +67,17 @@ pub fn part1(input: &[u8]) -> Result<String> {
|
|||||||
anyhow::bail!("Did not find a valid route")
|
anyhow::bail!("Did not find a valid route")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn part1(input: &[u8]) -> Result<String> {
|
||||||
|
parts_common(input, b'S', |b| b == b'E', can_travel)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
pub fn part2(input: &[u8]) -> Result<String> {
|
||||||
let width = input
|
parts_common(
|
||||||
.iter()
|
input,
|
||||||
.position(|&c| c == b'\n')
|
b'E',
|
||||||
.context("No newlines in input")?
|
|b| b == b'a' || b == b'S',
|
||||||
+ 1;
|
|a, b| can_travel(b, a),
|
||||||
|
)
|
||||||
let starting_pos = input
|
|
||||||
.iter()
|
|
||||||
.position(|&c| c == b'E')
|
|
||||||
.context("Could not find starting position")?;
|
|
||||||
|
|
||||||
let mut visited = IndexSet::with_capacity(input.len());
|
|
||||||
|
|
||||||
let mut todo = VecDeque::new();
|
|
||||||
todo.push_back((0, starting_pos));
|
|
||||||
|
|
||||||
while let Some((dist, pos)) = todo.pop_front() {
|
|
||||||
if input[pos] == b'a' || input[pos] == b'S' {
|
|
||||||
return Ok(dist.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut add_todo = |new: usize| {
|
|
||||||
if can_travel(input[new], input[pos]) && visited.insert(new) {
|
|
||||||
todo.push_back((dist + 1, new));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if pos % width != 0 {
|
|
||||||
add_todo(pos - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if pos % width != width - 1 {
|
|
||||||
add_todo(pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if pos >= width {
|
|
||||||
add_todo(pos - width);
|
|
||||||
}
|
|
||||||
|
|
||||||
if pos + width < input.len() {
|
|
||||||
add_todo(pos + width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anyhow::bail!("Did not find a valid route")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user