add day 13
This commit is contained in:
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day13"
|
||||||
|
version = "0.1.0"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day13"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
use std::{
|
||||||
|
collections::{HashSet, VecDeque},
|
||||||
|
vec,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
const INPUT: usize = 10;
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
const INPUT: usize = 1362;
|
||||||
|
|
||||||
|
const MAX_X: usize = 100;
|
||||||
|
const MAX_Y: usize = 100;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let maze = generate_maze(INPUT);
|
||||||
|
|
||||||
|
let result = bfs(&maze, (1, 1), (31, 39));
|
||||||
|
|
||||||
|
println!("{result}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
|
fn generate_maze(input: usize) -> Vec<Vec<WallOrSpace>> {
|
||||||
|
let mut result = vec![vec![WallOrSpace::default(); MAX_Y]; MAX_X];
|
||||||
|
for x in 0..MAX_X {
|
||||||
|
for y in 0..MAX_Y {
|
||||||
|
let equation = calculate_equation(x, y);
|
||||||
|
let sum = equation + input;
|
||||||
|
let binary = format!("{:b}", sum);
|
||||||
|
let ones = binary.chars().filter(|c| *c == '1').count();
|
||||||
|
if ones % 2 == 1 {
|
||||||
|
result[x][y] = WallOrSpace::Wall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bfs(maze: &[Vec<WallOrSpace>], start: (usize, usize), goal: (usize, usize)) -> usize {
|
||||||
|
let mut queue = VecDeque::new();
|
||||||
|
|
||||||
|
let mut visited = HashSet::new();
|
||||||
|
visited.insert(start);
|
||||||
|
|
||||||
|
let mut reachable_in_50_steps = HashSet::new();
|
||||||
|
reachable_in_50_steps.insert(start);
|
||||||
|
|
||||||
|
queue.push_back((start, 0_usize));
|
||||||
|
|
||||||
|
while let Some(((xi, yi), distance)) = queue.pop_front() {
|
||||||
|
if (xi, yi) == goal {
|
||||||
|
println!("{}", reachable_in_50_steps.len());
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if distance <= 50 {
|
||||||
|
reachable_in_50_steps.insert((xi, yi));
|
||||||
|
}
|
||||||
|
|
||||||
|
for neighbor in get_valid_neighbors(maze, (xi, yi)) {
|
||||||
|
if !visited.contains(&neighbor) {
|
||||||
|
visited.insert(neighbor);
|
||||||
|
queue.push_back((neighbor, distance + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("goal unreachable");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_valid_neighbors(
|
||||||
|
maze: &[Vec<WallOrSpace>],
|
||||||
|
(x, y): (usize, usize),
|
||||||
|
) -> impl Iterator<Item = (usize, usize)> {
|
||||||
|
let mut result = vec![];
|
||||||
|
|
||||||
|
if x == 0 && y == 0 {
|
||||||
|
result.push((x + 1, y));
|
||||||
|
result.push((x, y + 1));
|
||||||
|
} else if x == 0 && y != 0 {
|
||||||
|
result.push((x + 1, y));
|
||||||
|
result.push((x, y - 1));
|
||||||
|
result.push((x, y + 1));
|
||||||
|
} else if x != 0 && y == 0 {
|
||||||
|
result.push((x - 1, y));
|
||||||
|
result.push((x + 1, y));
|
||||||
|
result.push((x, y + 1));
|
||||||
|
} else {
|
||||||
|
// x != 0 && y != 0
|
||||||
|
result.push((x - 1, y));
|
||||||
|
result.push((x + 1, y));
|
||||||
|
result.push((x, y - 1));
|
||||||
|
result.push((x, y + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
.into_iter()
|
||||||
|
.filter(|(x, y)| *x < MAX_X && *y < MAX_Y)
|
||||||
|
.filter(|(x, y)| maze[*x][*y].is_space())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_equation(x: usize, y: usize) -> usize {
|
||||||
|
x * x + 3 * x + 2 * x * y + y + y * y
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
enum WallOrSpace {
|
||||||
|
#[default]
|
||||||
|
Space,
|
||||||
|
Wall,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WallOrSpace {
|
||||||
|
fn is_space(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
WallOrSpace::Space => true,
|
||||||
|
WallOrSpace::Wall => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_range_loop, dead_code)]
|
||||||
|
fn print_maze(maze: &[Vec<WallOrSpace>]) {
|
||||||
|
for x in 0..MAX_X {
|
||||||
|
for y in 0..MAX_Y {
|
||||||
|
let c = match maze[x][y] {
|
||||||
|
WallOrSpace::Space => '.',
|
||||||
|
WallOrSpace::Wall => '#',
|
||||||
|
};
|
||||||
|
print!("{c}");
|
||||||
|
}
|
||||||
|
println!()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user