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
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:
parent
2fad402c93
commit
ebf3f1d41c
@ -11,7 +11,7 @@ jobs:
|
|||||||
name: Challenge for day
|
name: Challenge for day
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
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
|
runs-on: rust-bookworm
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
|
6
day20/Cargo.toml
Normal file
6
day20/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day20"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
125
day20/src/main.rs
Normal file
125
day20/src/main.rs
Normal 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user