[TASK] Solved day 12
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Run-aoc2022-bench-dayX" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
<configuration default="false" name="Run-aoc2022-bench-dayX" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||||
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust --release -- -d 4 -b 1000" />
|
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust --release -- -d 12 -b 100" />
|
||||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||||
<option name="channel" value="DEFAULT" />
|
<option name="channel" value="DEFAULT" />
|
||||||
<option name="requiredFeatures" value="true" />
|
<option name="requiredFeatures" value="true" />
|
||||||
|
|||||||
19
.run/run-day-12.run.xml
Normal file
19
.run/run-day-12.run.xml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="run-day-12" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||||
|
<option name="command" value="run --package advent-of-code-2022-rust --bin advent-of-code-2022-rust -- -d 12" />
|
||||||
|
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||||
|
<option name="channel" value="DEFAULT" />
|
||||||
|
<option name="requiredFeatures" value="true" />
|
||||||
|
<option name="allFeatures" value="false" />
|
||||||
|
<option name="emulateTerminal" value="false" />
|
||||||
|
<option name="withSudo" value="false" />
|
||||||
|
<option name="buildTarget" value="REMOTE" />
|
||||||
|
<option name="backtrace" value="SHORT" />
|
||||||
|
<envs />
|
||||||
|
<option name="isRedirectInput" value="false" />
|
||||||
|
<option name="redirectInputPath" value="" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
41
input/day12.txt
Normal file
41
input/day12.txt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
abccccaaaaaaacccaaaaaaaccccccccccccccccccccccccccccccccccaaaa
|
||||||
|
abcccccaaaaaacccaaaaaaaaaaccccccccccccccccccccccccccccccaaaaa
|
||||||
|
abccaaaaaaaaccaaaaaaaaaaaaaccccccccccccccccccccccccccccaaaaaa
|
||||||
|
abccaaaaaaaaaaaaaaaaaaaaaaacccccccccaaaccccacccccccccccaaacaa
|
||||||
|
abaccaaaaaaaaaaaaaaaaaacacacccccccccaaacccaaaccccccccccccccaa
|
||||||
|
abaccccaaaaaaaaaaaaaaaacccccccccccccaaaaaaaaaccccccccccccccaa
|
||||||
|
abaccccaacccccccccaaaaaacccccccccccccaaaaaaaacccccccccccccccc
|
||||||
|
abcccccaaaacccccccaaaaaaccccccccijjjjjjaaaaaccccccaaccaaccccc
|
||||||
|
abccccccaaaaacccccaaaacccccccciiijjjjjjjjjkkkkkkccaaaaaaccccc
|
||||||
|
abcccccaaaaacccccccccccccccccciiiirrrjjjjjkkkkkkkkaaaaaaccccc
|
||||||
|
abcccccaaaaaccccccccccccccccciiiirrrrrrjjjkkkkkkkkkaaaaaccccc
|
||||||
|
abaaccacaaaaacccccccccccccccciiiqrrrrrrrrrrssssskkkkaaaaacccc
|
||||||
|
abaaaaacaaccccccccccccccccccciiiqqrtuurrrrrsssssskklaaaaacccc
|
||||||
|
abaaaaacccccccccccaaccccccccciiqqqttuuuurrssusssslllaaccccccc
|
||||||
|
abaaaaaccccccccaaaaccccccccciiiqqqttuuuuuuuuuuusslllaaccccccc
|
||||||
|
abaaaaaacccccccaaaaaaccccccciiiqqqttxxxuuuuuuuusslllccccccccc
|
||||||
|
abaaaaaaccccaaccaaaaacccccchhiiqqtttxxxxuyyyyvvsslllccccccccc
|
||||||
|
abaaacacccccaacaaaaaccccccchhhqqqqttxxxxxyyyyvvsslllccccccccc
|
||||||
|
abaaacccccccaaaaaaaacccccchhhqqqqtttxxxxxyyyvvssqlllccccccccc
|
||||||
|
abacccccaaaaaaaaaaccaaacchhhpqqqtttxxxxxyyyyvvqqqlllccccccccc
|
||||||
|
SbaaacaaaaaaaaaaaacaaaaahhhhppttttxxEzzzzyyvvvqqqqlllcccccccc
|
||||||
|
abaaaaaaacaaaaaacccaaaaahhhppptttxxxxxyyyyyyyvvqqqlllcccccccc
|
||||||
|
abaaaaaaccaaaaaaaccaaaaahhhppptttxxxxywyyyyyyvvvqqqmmcccccccc
|
||||||
|
abaaaaaaacaaaaaaacccaaaahhhpppsssxxwwwyyyyyyvvvvqqqmmmccccccc
|
||||||
|
abaaaaaaaaaaaaaaacccaacahhhpppssssssswyyywwvvvvvqqqmmmccccccc
|
||||||
|
abaaaaaaaacacaaaacccccccgggppppsssssswwywwwwvvvqqqqmmmccccccc
|
||||||
|
abcaaacaaaccccaaaccccccccgggppppppssswwwwwrrrrrqqqmmmmccccccc
|
||||||
|
abcaaacccccccccccccccccccgggggpppoosswwwwwrrrrrqqmmmmddcccccc
|
||||||
|
abccaacccccccccccccccccccccgggggoooosswwwrrrnnnmmmmmddddccccc
|
||||||
|
abccccccccccccccccccccccccccgggggooossrrrrrnnnnnmmmddddaccccc
|
||||||
|
abaccccaacccccccccccccccccccccgggfoossrrrrnnnnndddddddaaacccc
|
||||||
|
abaccaaaaaaccccccccccccccccccccgffooorrrrnnnneeddddddaaaacccc
|
||||||
|
abaccaaaaaacccccccccccccccccccccfffooooonnnneeeddddaaaacccccc
|
||||||
|
abacccaaaaaccccccccaaccaaaccccccffffoooonnneeeeccaaaaaacccccc
|
||||||
|
abcccaaaaacccccccccaaccaaaaccccccffffoooneeeeeaccccccaacccccc
|
||||||
|
abaccaaaaaccccccccaaaacaaaaccccccafffffeeeeeaaacccccccccccccc
|
||||||
|
abacccccccccccccccaaaacaaacccccccccffffeeeecccccccccccccccaac
|
||||||
|
abaaaacccccccaaaaaaaaaaaaaacccccccccfffeeeccccccccccccccccaaa
|
||||||
|
abaaaacccccccaaaaaaaaaaaaaaccccccccccccaacccccccccccccccccaaa
|
||||||
|
abaacccccccccaaaaaaaaaaaaaaccccccccccccaacccccccccccccccaaaaa
|
||||||
|
abaaaccccccccccaaaaaaaaccccccccccccccccccccccccccccccccaaaaaa
|
||||||
5
input/day12_example.txt
Normal file
5
input/day12_example.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Sabqponm
|
||||||
|
abcryxxl
|
||||||
|
accszExk
|
||||||
|
acctuvwj
|
||||||
|
abdefghi
|
||||||
113
src/day12.rs
Normal file
113
src/day12.rs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
use crate::day_solver::DaySolver;
|
||||||
|
use crate::util::Grid;
|
||||||
|
|
||||||
|
use super::util;
|
||||||
|
|
||||||
|
pub struct Day12 {
|
||||||
|
map: Grid<u8>,
|
||||||
|
start: (usize, usize),
|
||||||
|
end: (usize, usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Day12 {
|
||||||
|
|
||||||
|
pub fn create() -> Self {
|
||||||
|
// let lines = util::read_file("input/day12_example.txt");
|
||||||
|
let lines = util::read_file("input/day12.txt");
|
||||||
|
|
||||||
|
let map_1d = lines.join("");
|
||||||
|
let width = lines[0].len();
|
||||||
|
let s_idx = map_1d.find("S").unwrap();
|
||||||
|
let e_idx = map_1d.find("E").unwrap();
|
||||||
|
// Put the input into the day struct
|
||||||
|
return Day12 {
|
||||||
|
map: Grid {
|
||||||
|
width,
|
||||||
|
data: map_1d.chars().map(|c| match c {
|
||||||
|
'S' => 0u8,
|
||||||
|
'E' => 'z' as u8 - 'a' as u8,
|
||||||
|
_ => c as u8 - 'a' as u8
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
},
|
||||||
|
start: (s_idx % width, s_idx / width),
|
||||||
|
end: (e_idx % width, e_idx / width)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_reach(&self, from: &u8, to: &u8) -> bool {
|
||||||
|
to < from || to - from <= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_add_path_to_neighbor(&self, cur_pos: usize, target_pos: usize, dists: &mut Vec<usize>, positions_to_check: &mut Vec<usize>, prev_idx: &mut Vec<Option<usize>>) {
|
||||||
|
|
||||||
|
let cur_dist = dists[cur_pos];
|
||||||
|
let cur_height = self.map.data[cur_pos];
|
||||||
|
|
||||||
|
if self.can_reach(&cur_height, &self.map.data[target_pos]) && dists[target_pos] > cur_dist + 1 {
|
||||||
|
dists[target_pos] = cur_dist + 1;
|
||||||
|
positions_to_check.push(target_pos);
|
||||||
|
prev_idx[target_pos] = Some(cur_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_distance_to_end(&self, starting_positions: Vec<usize>) -> usize {
|
||||||
|
|
||||||
|
let mut dists = vec![usize::MAX; self.map.data.len()];
|
||||||
|
let mut prev_idx: Vec<Option<usize>> = vec![None; self.map.data.len()];
|
||||||
|
|
||||||
|
for start_idx in &starting_positions {
|
||||||
|
dists[*start_idx] = 0;
|
||||||
|
}
|
||||||
|
let mut positions_to_check = starting_positions.to_owned();
|
||||||
|
|
||||||
|
while !positions_to_check.is_empty() {
|
||||||
|
positions_to_check.sort_by_key(|p| usize::MAX - dists[*p]);
|
||||||
|
let cur_pos = positions_to_check.pop().unwrap();
|
||||||
|
// Check for each neighbor, if it's accessible, and if moving from here to the neighbor is shorter
|
||||||
|
|
||||||
|
// move up
|
||||||
|
if cur_pos >= self.map.width {
|
||||||
|
let up_pos = cur_pos - self.map.width;
|
||||||
|
self.try_add_path_to_neighbor(cur_pos, up_pos, &mut dists, &mut positions_to_check, &mut prev_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move down
|
||||||
|
if cur_pos + self.map.width < self.map.data.len() {
|
||||||
|
let down_pos = cur_pos +self.map.width;
|
||||||
|
self.try_add_path_to_neighbor(cur_pos, down_pos, &mut dists, &mut positions_to_check, &mut prev_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move left
|
||||||
|
if cur_pos % self.map.width > 0 {
|
||||||
|
let left_pos = cur_pos - 1;
|
||||||
|
self.try_add_path_to_neighbor(cur_pos, left_pos, &mut dists, &mut positions_to_check, &mut prev_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move right
|
||||||
|
if cur_pos % self.map.width < self.map.width - 1 {
|
||||||
|
let right_pos = cur_pos + 1;
|
||||||
|
self.try_add_path_to_neighbor(cur_pos, right_pos, &mut dists, &mut positions_to_check, &mut prev_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("{:?}", dists);
|
||||||
|
|
||||||
|
let end_idx = self.end.0 + self.end.1 * self.map.width;
|
||||||
|
return dists[end_idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DaySolver for Day12 {
|
||||||
|
|
||||||
|
|
||||||
|
fn solve_part1(&mut self) -> String {
|
||||||
|
|
||||||
|
let start_idx = self.start.0 + self.start.1 * self.map.width;
|
||||||
|
self.calculate_distance_to_end(vec![start_idx]).to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve_part2(&mut self) -> String {
|
||||||
|
self.calculate_distance_to_end(self.map.data.iter().enumerate().filter(|(i, x)| x == &&0).map(|(i, _)| i).collect()).to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
57
src/day8.rs
57
src/day8.rs
@@ -1,63 +1,10 @@
|
|||||||
use std::{fmt::{Debug, Display}};
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use crate::day_solver::DaySolver;
|
use crate::day_solver::DaySolver;
|
||||||
|
use crate::util::Grid;
|
||||||
|
|
||||||
use super::util;
|
use super::util;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Grid<T> {
|
|
||||||
width: usize,
|
|
||||||
data: Vec<T>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone + Sized> Grid<T> {
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn set_row(&mut self, x: usize, v: T) {
|
|
||||||
// let range = &mut self.data[x * self.width..(x+1) * self.width];
|
|
||||||
for i in self.width * x..self.width * (x + 1) {
|
|
||||||
self.data[i] = v.to_owned();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn set_col(&mut self, x: usize, v: T) {
|
|
||||||
for y in 0..self.height() {
|
|
||||||
let idx = self.idx(&x, &y);
|
|
||||||
self.data[idx] = v.to_owned();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn idx(&self, x: &usize, y: &usize) -> usize {
|
|
||||||
y * self.width + x
|
|
||||||
}
|
|
||||||
|
|
||||||
fn height(&self) -> usize {
|
|
||||||
self.data.len() / self.width
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get(&self, x: &usize, y: &usize) -> &T {
|
|
||||||
let idx = self.idx(x, y);
|
|
||||||
&self.data[idx]
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl <T: Display + Clone + Sized> Grid<T> {
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn print(&self) {
|
|
||||||
|
|
||||||
for y in 0..self.height() {
|
|
||||||
for x in 0..self.width {
|
|
||||||
print!("{}", self.get(&x, &y))
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Day8 {
|
pub struct Day8 {
|
||||||
grid: Grid<u8>
|
grid: Grid<u8>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use crate::day8::Day8;
|
|||||||
use crate::day9::Day9;
|
use crate::day9::Day9;
|
||||||
use crate::day10::Day10;
|
use crate::day10::Day10;
|
||||||
use crate::day11::Day11;
|
use crate::day11::Day11;
|
||||||
|
use crate::day12::Day12;
|
||||||
use crate::day_solver::DaySolver;
|
use crate::day_solver::DaySolver;
|
||||||
|
|
||||||
mod util;
|
mod util;
|
||||||
@@ -25,8 +26,9 @@ mod day8;
|
|||||||
mod day9;
|
mod day9;
|
||||||
mod day10;
|
mod day10;
|
||||||
mod day11;
|
mod day11;
|
||||||
|
mod day12;
|
||||||
|
|
||||||
const MAX_DAY: u8 = 11;
|
const MAX_DAY: u8 = 12;
|
||||||
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
|
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -101,6 +103,7 @@ fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
|
|||||||
9 => Some(Box::new(Day9::create())),
|
9 => Some(Box::new(Day9::create())),
|
||||||
10 => Some(Box::new(Day10::create())),
|
10 => Some(Box::new(Day10::create())),
|
||||||
11 => Some(Box::new(Day11::create())),
|
11 => Some(Box::new(Day11::create())),
|
||||||
|
12 => Some(Box::new(Day12::create())),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
55
src/util.rs
55
src/util.rs
@@ -1,3 +1,4 @@
|
|||||||
|
use std::fmt::Display;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
pub fn read_file(filename: &str) -> Vec<String> {
|
pub fn read_file(filename: &str) -> Vec<String> {
|
||||||
@@ -10,4 +11,58 @@ pub fn read_file(filename: &str) -> Vec<String> {
|
|||||||
|
|
||||||
res
|
res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Grid<T> {
|
||||||
|
pub(crate) width: usize,
|
||||||
|
pub(crate) data: Vec<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone + Sized> Grid<T> {
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn set_row(&mut self, x: usize, v: T) {
|
||||||
|
// let range = &mut self.data[x * self.width..(x+1) * self.width];
|
||||||
|
for i in self.width * x..self.width * (x + 1) {
|
||||||
|
self.data[i] = v.to_owned();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn set_col(&mut self, x: usize, v: T) {
|
||||||
|
for y in 0..self.height() {
|
||||||
|
let idx = self.idx(&x, &y);
|
||||||
|
self.data[idx] = v.to_owned();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn idx(&self, x: &usize, y: &usize) -> usize {
|
||||||
|
y * self.width + x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn height(&self) -> usize {
|
||||||
|
self.data.len() / self.width
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get(&self, x: &usize, y: &usize) -> &T {
|
||||||
|
let idx = self.idx(x, y);
|
||||||
|
&self.data[idx]
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <T: Display + Clone + Sized> Grid<T> {
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn print(&self) {
|
||||||
|
|
||||||
|
for y in 0..self.height() {
|
||||||
|
for x in 0..self.width {
|
||||||
|
print!("{}", self.get(&x, &y))
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user