[TASK] Solved day 12
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<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="channel" value="DEFAULT" />
|
||||
<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::util::Grid;
|
||||
|
||||
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)]
|
||||
pub struct Day8 {
|
||||
grid: Grid<u8>
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::day8::Day8;
|
||||
use crate::day9::Day9;
|
||||
use crate::day10::Day10;
|
||||
use crate::day11::Day11;
|
||||
use crate::day12::Day12;
|
||||
use crate::day_solver::DaySolver;
|
||||
|
||||
mod util;
|
||||
@@ -25,8 +26,9 @@ mod day8;
|
||||
mod day9;
|
||||
mod day10;
|
||||
mod day11;
|
||||
mod day12;
|
||||
|
||||
const MAX_DAY: u8 = 11;
|
||||
const MAX_DAY: u8 = 12;
|
||||
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
|
||||
|
||||
fn main() {
|
||||
@@ -101,6 +103,7 @@ fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
|
||||
9 => Some(Box::new(Day9::create())),
|
||||
10 => Some(Box::new(Day10::create())),
|
||||
11 => Some(Box::new(Day11::create())),
|
||||
12 => Some(Box::new(Day12::create())),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
55
src/util.rs
55
src/util.rs
@@ -1,3 +1,4 @@
|
||||
use std::fmt::Display;
|
||||
use std::fs;
|
||||
|
||||
pub fn read_file(filename: &str) -> Vec<String> {
|
||||
@@ -10,4 +11,58 @@ pub fn read_file(filename: &str) -> Vec<String> {
|
||||
|
||||
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