feat: added day 20 part 1 and 2
All checks were successful
Build and run challenges / Challenge for day (1) (push) Successful in 3s
Build and run challenges / Challenge for day (10) (push) Successful in 3s
Build and run challenges / Challenge for day (11) (push) Successful in 3s
Build and run challenges / Challenge for day (12) (push) Successful in 3s
Build and run challenges / Challenge for day (13) (push) Successful in 3s
Build and run challenges / Challenge for day (14) (push) Successful in 3s
Build and run challenges / Challenge for day (15) (push) Successful in 3s
Build and run challenges / Challenge for day (16) (push) Successful in 3s
Build and run challenges / Challenge for day (17) (push) Successful in 3s
Build and run challenges / Challenge for day (18) (push) Successful in 3s
Build and run challenges / Challenge for day (19) (push) Successful in 3s
Build and run challenges / Challenge for day (2) (push) Successful in 3s
Build and run challenges / Challenge for day (20) (push) Successful in 3s
Build and run challenges / Challenge for day (4) (push) Successful in 5s
Build and run challenges / Challenge for day (5) (push) Successful in 5s
Build and run challenges / Challenge for day (6) (push) Successful in 5s
Build and run challenges / Challenge for day (3) (push) Successful in 11s
Build and run challenges / Challenge for day (8) (push) Successful in 3s
Build and run challenges / Challenge for day (9) (push) Successful in 3s
Build and run challenges / Challenge for day (7) (push) Successful in 4s

Signed-off-by: Louis Vallat <contact@louis-vallat.dev>
This commit is contained in:
Louis Vallat 2025-01-01 16:42:44 +01:00
parent 2fad402c93
commit ebf3f1d41c
Signed by: louis
SSH Key Fingerprint: SHA256:usb9EA8eIADT+Bt0Ne8ZkISCbgPSOYkVgS2iZqdZj8s
3 changed files with 132 additions and 1 deletions

View File

@ -11,7 +11,7 @@ jobs:
name: Challenge for day
strategy:
matrix:
day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
runs-on: rust-bookworm
steps:
- name: Check out repository code

6
day20/Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "day20"
version = "0.1.0"
edition = "2021"
[dependencies]

125
day20/src/main.rs Normal file
View File

@ -0,0 +1,125 @@
use std::collections::HashSet;
use std::{env, fs};
fn read_input(path: &str) -> String {
fs::read_to_string(path).expect("Cannot read file.")
}
fn parse_input(input: &str) -> (Vec<Vec<i32>>, (usize, usize), (usize, usize)) {
let mut map = Vec::new();
let (mut start, mut end) = ((0, 0), (0, 0));
for (row, line) in input.lines().filter(|s| !s.is_empty()).enumerate() {
map.push(Vec::new());
for (col, char) in line.chars().enumerate() {
match char {
'#' => map[row].push(-1),
'.' => map[row].push(0),
'E' => {
map[row].push(0);
end = (row, col);
}
'S' => {
map[row].push(0);
start = (row, col);
}
_ => unreachable!(),
}
}
}
(map, start, end)
}
fn get_if_in_map(
map: &Vec<Vec<i32>>,
row: usize,
offset_r: i32,
col: usize,
offset_c: i32,
) -> Option<(usize, usize)> {
let (row, col) = (row as i32 + offset_r, col as i32 + offset_c);
if !(0..map.len() as i32).contains(&row) || !(0..map[row as usize].len() as i32).contains(&col)
{
None
} else {
Some((row as usize, col as usize))
}
}
fn race_without_cheating(
map: &mut Vec<Vec<i32>>,
start: &(usize, usize),
end: &(usize, usize),
) -> HashSet<(usize, usize)> {
let mut positions = HashSet::new();
positions.insert(*start);
let mut position = *start;
let mut cost = 0;
while position != *end {
for dir in [(0, 1), (-1, 0), (1, 0), (0, -1)] {
if let Some((row, col)) = get_if_in_map(map, position.0, dir.0, position.1, dir.1) {
if map[row][col] == 0 && (row, col) != *start {
(position, cost) = ((row, col), cost + 1);
map[row][col] = cost;
positions.insert(position);
break;
}
}
}
}
positions
}
fn get_cheating_shortcuts(
map: &Vec<Vec<i32>>,
path: &HashSet<(usize, usize)>,
radius: i32,
) -> usize {
let mut savings = 0;
for &position in path {
let source = map[position.0][position.1];
for i in -radius..=radius {
for j in -radius..=radius {
let distance = i.abs() + j.abs();
if distance > radius {
continue;
}
if let Some((row, col)) = get_if_in_map(map, position.0, i, position.1, j) {
let destination = map[row][col];
if source >= destination || destination == -1 {
continue;
}
let saving = destination - source - distance;
if distance <= radius && saving >= 100 {
savings += 1;
}
}
}
}
}
savings
}
fn main() {
let args: Vec<String> = env::args().collect();
for arg in args.iter().skip(1) {
let input = read_input(&arg);
let (mut map, start, end) = parse_input(&input);
let race = race_without_cheating(&mut map, &start, &end);
println!("[{}]", &arg);
println!(
"\t[Part 1] => Answer is '{}'.",
get_cheating_shortcuts(&map, &race, 2)
);
println!(
"\t[Part 2] => Answer is '{}'.",
get_cheating_shortcuts(&map, &race, 20)
);
}
}