Skip to content

Commit

Permalink
gamp
Browse files Browse the repository at this point in the history
  • Loading branch information
mirsella committed Dec 17, 2023
1 parent 7ae976d commit beb3f01
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 1 deletion.
2 changes: 1 addition & 1 deletion 2023/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ members = [
"day14",
"day15",
"day16",
# "day17",
"day17",
# "day18",
# "day19",
# "day20",
Expand Down
19 changes: 19 additions & 0 deletions 2023/day17/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
input.txt
flamegraph.svg
perf.data*
### Rust
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

10 changes: 10 additions & 0 deletions 2023/day17/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "day17"
authors = ["mirsella <[email protected]>"]
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
pathfinding = "4.6.0"
28 changes: 28 additions & 0 deletions 2023/day17/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::fs::File;
use std::io::{self, Read};
use std::path::PathBuf;
use std::{env, fs};

fn replace_in_file(file_path: &PathBuf, old: &str, new: &str) -> io::Result<()> {
let mut contents = String::new();
File::open(file_path)?.read_to_string(&mut contents)?;
let new_contents = contents.replace(old, new);
if contents != new_contents {
println!("Updating {}", file_path.display());
fs::write(file_path, new_contents)?;
}
Ok(())
}

fn main() -> io::Result<()> {
let pkg_name = env::var("CARGO_PKG_NAME").unwrap();
replace_in_file(
&"../Cargo.toml".into(),
&format!("# \"{pkg_name}\""),
&format!("\"{pkg_name}\""),
)?;

replace_in_file(&"./Cargo.toml".into(), "\n[workspace]", "")?;

Ok(())
}
94 changes: 94 additions & 0 deletions 2023/day17/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use pathfinding::{directed::dijkstra::dijkstra, matrix::Matrix};

fn pathfind(input: &str, min: usize, max: usize) -> usize {
let grid = Matrix::from_rows(
input
.lines()
.map(|l| l.chars().map(|c| c.to_digit(10).unwrap())),
)
.unwrap();

let result = dijkstra(
&((0, 0), (0, 0), 0),
|&(pos, (direction_x, direction_y), consecutive_count)| {
let mut moves = Vec::new();
let mut add_moves = |direction, consecutive_count| {
if let Some(new_pos) = grid.move_in_direction(pos, direction) {
moves.push(((new_pos, direction, consecutive_count), grid[new_pos]));
};
};
if consecutive_count < max {
add_moves((direction_x, direction_y), consecutive_count + 1);
}
if consecutive_count >= min {
add_moves((-direction_y, -direction_x), 1);
add_moves((direction_y, direction_x), 1);
} else if consecutive_count == 0 {
add_moves((1, 0), 1);
add_moves((0, 1), 1);
}
moves
},
|pos| pos.0 == (grid.rows - 1, grid.columns - 1) && pos.2 >= min,
)
.unwrap();
for (x, row) in grid.iter().enumerate() {
for (y, digit) in row.iter().enumerate() {
if result.0.iter().any(|p| p.0 == (x, y)) {
print!("#");
} else {
print!("{}", digit);
}
}
println!();
}
result.1 as usize
}

fn part1(input: &str) -> usize {
pathfind(input, 1, 3)
}

fn part2(input: &str) -> usize {
pathfind(input, 4, 10)
}

fn main() {
let input = include_str!("../input.txt");
println!("Part 1: {}", part1(input));
println!("Part 2: {}", part2(input));
}

#[cfg(test)]
mod tests {
const INPUT: &str = "2413432311323
3215453535623
3255245654254
3446585845452
4546657867536
1438598798454
4457876987766
3637877979653
4654967986887
4564679986453
1224686865563
2546548887735
4322674655533";
const INPUT2: &str = "111111111111
999999999991
999999999991
999999999991
999999999991";
#[test]
fn part1() {
assert_eq!(super::part1(INPUT), 102);
}
#[test]
fn part2() {
assert_eq!(super::part2(INPUT), 94);
}
#[test]
fn part2_2() {
assert_eq!(super::part2(INPUT2), 71);
}
}

0 comments on commit beb3f01

Please sign in to comment.