Solve day12
This commit is contained in:
parent
afc1255c76
commit
0e87cb94d3
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -156,6 +156,10 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "day12"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"colorous",
|
||||
"termion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day13"
|
||||
|
|
|
@ -8,3 +8,5 @@ build = true
|
|||
app = true
|
||||
|
||||
[dependencies]
|
||||
colorous = "1.0.8"
|
||||
termion = "2.0.1"
|
||||
|
|
41
day12/input
Normal file
41
day12/input
Normal file
|
@ -0,0 +1,41 @@
|
|||
abcccccccccccccccccaaccccccccccccaaaaaaaacccccccccccaaaaaccccaaaaaaccaaaaaaaaaaaaaaaaaccccccccccccccccaaacccccaaaaaaaacccaaaccccccccccccccccccccccccccccccccccccccccccccccccccaaaaa
|
||||
abccccccccccccccccaaacaacccccccccccaaaacccccccccccccaaaaaacccaaaaaaccaaaaaaaaaaaaaaaaaaaacccccccccaaacaaacccccaaaaaaaaaccaaaaccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa
|
||||
abcccccccccccccccccaaaaacccccccccccaaaaaccccccccccccaaaaaaccccaaaacccaaaacccaaaaaaaaaaaaacccccccccaaaaaaaaaacccaaaaaaaaccaaaaccccccccccccccccccccccccccccccccccaaacccccccccccaaaaaa
|
||||
abcccccccccccccccaaaaaacccccccccccaaacaaccaaccccccccaaaaaaccccaaaacccaaaccccaaaaaaaaaaaaaccccccccccaaaaaaaaaccaaaaaacccccaaacccccccccccccccccccccccccccccccccccaaaccccccccccccccaaa
|
||||
abcccccccccccccccaaaaaaaacccccccccaacccacaaacaacccccccaaccccccaccaccccccccaaaaaaaaaaaaccccccccccccccaaaaaaacccaaaaaaacccccccccccccaacccccccccccccccccccccccccccaaaccccccccccccccaaa
|
||||
abcccccccccccccccaacaaaaacccccccccccccccccaaaaacccccccccccccccccccccccccccaaaaaaaaaaaaccccccccccccccaaaaaaccccaaccaaacccccccccccaaaaaaccccccccccccccccccccccccccdccccccccccccccccaa
|
||||
abccaacccccccaaacccaaacaccccccccccaaacccaaaaaaccccccccccccccccccccccccccccaaacccaaaaaacaaaaccccccccaaaaaaaccccccccaaacccccccccccaaaaaacccccccccccccccccllllllcccdddddcccccccccccccc
|
||||
abaaaacccacccaaccccaacccccccccccccaaacccaaaaaaaacccccccccccccccccaaccccccccacccaaaaccccaaaaccccccccaaacaaaccccccccccccccccccccccaaaaaaccccccccccccccccllllllllldddddddddddccaaccccc
|
||||
abaaaaccaaaaaaaacccccccccccccccaaaaaaaacaacaaaaacccccccccccccccccaaacccccccaaacaaccccccaaaacccccccccccccaaccccccccccccccccccccccaaaaaccccccccccccccccclllllllllldddddddddeeaaaccccc
|
||||
abaaaccccaaaaaaaaccccccccaaacccaaaaaaaacccaaacccccccccccccccccaaaaaaaaccccccaaaaacccccccaacccccccccccccccccccccccccccccccccccccccaaaaccccaaaccccccccckllppppplllmmmmmmmdeeeeaaccccc
|
||||
abaaaacccaaaaaaaaacccccaaaaaaccccaaaaaccccaaccccccccccccccccccaaaaaaaaccccccaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccaaaacccccccckklpppppppplmmmmmmmmmeeeeaccccc
|
||||
abaaaacccaaaaaaaaacccccaaaaaacccaaaaaaccccccccaacccccccccccccccaaaaaaccccccaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccaaaacccccccckkkppppppppqmmmmmmmmmmeeeaacccc
|
||||
abaaaaaccaaaaaaaaccccccaaaaaacccaaaaaaccccccacaaaacccccccccccccaaaaaaccccccaaaaaaaaccccccccaaaaccccccccaaacccccccccccccccccccccccccccccccaaacccccccckkkpppuuuppqqqqqqqqmmmeeeeacccc
|
||||
abacccccaaaaaaaccccccccaaaaaccccaccaaaccccccaaaaaacccccacccccccaaaaaaccccccaaaaaacaaaccccccaaaaccccccccaaaacccccccccccccccccccccccccccccccccccccccckkkpppuuuuuuqqqqqqqqqnnneeeccccc
|
||||
abcccccccaccaaaccccccccaaaaacccccccccccccccccaaaacccaaaacccccccaacaaacccccccccaaacaaaaaccccaaaaccccccccaaaaccccccccccccccccccccccccccccccccccccccckkkkpppuuuuuuuqvvvvqqqnnneeeccccc
|
||||
abcccccccccccaaacaaccccccccccccccccccccccccccaaaacccaaaaaacccccccccccccccccccccccaaaaaaccccaaacccccccccaaaccccccccccccccccccccccccccccccccccccccckkkkrrpuuuxxxuvvvvvvvqqnnneeeccccc
|
||||
abcccccccccccccccaacaaaccccccccccccccccccccccaacaacccaaaaacccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccckkkkrrrruuxxxxuvvvvvvvqqnnneeeccccc
|
||||
abcccccccccccccccaaaaacccccccccccccccccccccccccccaccaaaaacccccaaccccccccccccccccccaaaaaccccccccccccccccaaaccccccccccccccaaacccccccccccccccccccckkkkrrrruuuxxxxyyyyyvvvqqnnneecccccc
|
||||
abcccccccccccccaaaaaacccccccccccaacaacccccccccccaaaaaaaaacccacaaaacaaccaaccccccccaaacaaccccccccccaaccccaaaaaacccaacaacccaaacacccccccccccccccccjjkkrrrruuuuuxxxyyyyyvvqrqnneffcccccc
|
||||
abcccccccccccccaaaaaaaacccaaacccaaaaaccccccaacccaaaaaaaaacccaaaaaacaaaaaaccccccccaaacaaacccccccaaaaaacaaaaaaacccaaaaacaaaaaaaaccccccccccccccccjjjrrrtttuuxxxxxyyyyyvvrrnnnfffcccccc
|
||||
SbccccccccccccccccaaaaacccaaaaccaaaaaaccccaaaaaacaaaaaaaaacccaaaacccaaaaaccccccccaaaaaaacccccccaaaaaaaaaaaaaaccaaaaaccaaaaaaaaccccccccccccccccjjjrrrtttxxxEzzzzyyyvvrrrnnnfffcccccc
|
||||
abccccccccccaaaccaaccaacccaaaaccaaaaaacccccaaaaacaaaaaaaaacccaaaaccaaaaaacccccccccaaaaaaccccccccaaaacaaaaaaacccaaaaaaccaaaaaacccccccccccccccccjjjrrrtttxxxxxyyyyyyvvrrrnnnfffcccccc
|
||||
abcccccccccaaaaccaacccccccaaacccaaaaaacccaaaaaaaaaaaaaaaaacccaacacaaaaaaaacccccaaaaaaaacccccccccaaaacccaaaaaaccccaaaacccaaaaacccccccccccccccccjjjrrrtttxxxxxyyyyyyywvrrnnnfffcccccc
|
||||
abcccccccccaaaacccccccccccccccccccaaaccccaaaaaaaaaaaaaaaaaacccccccaaaaaaaacccccaaaaaaaaaccccccccaccacccaaaaaaccccacccccaaaaaacccccccccccccccccjjjrrrrttttxxxyyyyyyywwrrroooffcccccc
|
||||
abccccccccccaaaccccccccccccccccccccccccccaaaaaaaaaccaaaaaaaccccccccccaaccccccccaaaaaaaaaaccccccccccccccaacccccccccccccccaaccccccccccccccccccccjjjjqqqqttttxxyywwwwwwwwrrooofffccccc
|
||||
abcccccccccccccccccccccccccccccccccccccccccaaacacccccaaaaccccccccccccaacccccccccccaaacaaacccccccccccccccccccccccccccccaaacccccccccccccccccccaacjjjjqqqqqttwwwwwwwwwwwrrrooofffccccc
|
||||
abcccccccccccccccccccccccccccccccccccccccccaaccccccccccaacccccccccccccccccccccccccaaacccccccccccccccccccccccccccccccccaaacccccccccccccccccaaaaaajjjjqqqqttwwwwwwsswwrrrrooofffccccc
|
||||
abcccccaaaaccccccccccccccaacaaccccccccccccccccccccccccccccccccccccccccccccccccccccaacccccccccccccccccccccccccccccccaaaaaaaaccaaaacccccccccaaaaaacjjjiqqqtttwwwwsssssrrrrooofffccccc
|
||||
abccccaaaaaccccccccccccccaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaaaaccaaaaacccccccccaaaaacciiiiqqttswwwssssssrrroooogffccccc
|
||||
abccccaaaaaacccccccccccccaaaaaacccaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaccaaaaaaccccccccaaaaacccciiiqqqssssssspppooooooogggaccccc
|
||||
abccccaaaaaaccccccccaacccaaaaaaccccaacccccccccccccccccccccccccccccccccaaaaccccccccccccccccccccccccccccccccccccccccccaaaaaaccaaaaaaccccccccaaaaaccccciiiqqsssssspppppoooooggggaacccc
|
||||
abccccaaaaaccccccaaaaacccaaaaaacaacaaaaaccccccccccccccccccccaacccccccaaaaacccccccccccaaaccccccccccccccccccccccccccccaaaaaacccaaaaacccccccccacccccccciiiqqqpssspppppgggggggggaaacccc
|
||||
abccccccaaacccccccaaaaaccccaaaccaaaaaaaacccccccaacccccccaaccaacccccccaaaaaacccccccccaaaacccccccccccaaaaccccccccccccaaccaaacccaaacccccaaacaaaccccccccciiqqppppppphhhggggggggaaaacccc
|
||||
abccccccccccccccccaaaaaccccccccccaaaaaccccccccaaacaaccccaaaaaacccccccaaaaaaaccccccccaaaacccccccccccaaaacccccccccaaaaaacccccccccccccccaaaaaaaccccccccciiippppppphhhhggggggcaaacccccc
|
||||
abaacccccccccccccaaaaaccccccccccccaaaaaccccccccaaaaacccccaaaaaaacccccaaaaacaaacccccccaaacccccccccccaaaacccccccccaaaaacccccccccccccccccaaaaaacccccccccciiiippphhhhhhcccccccaaacccccc
|
||||
abaacccccccccccccccaaacccccccccccaaacaaccccccaaaaaaccccccaaaaaaacccaaccaaacaaaaccaaaccccccccccccccccaaacccccccccaaaaaaacccccccccccccccaaaaaaaacccccccciiihhhhhhhhaaaccccccccccccccc
|
||||
abaaccccccccccccccccccccccccccccccaacccccccccaaaaaaaacccaaaaaaccaaaaaacccccaaaacaaaaaccccccccccccccccccccccccccaaaaaaaaccccccccccccccaaaaaaaaaccccccccciihhhhhhcaaaacccccccccccccca
|
||||
abaaccccccccccccccccccccccccccccccccaacccccccaacaaaaacccaaaaaaccaaaaacccccccaaaaaaaacccccccccccccccccccccccccccaaaaaaaacccccccccaaacaaaaaaaaaacccccccccccchhhaccccaacccccccccccccca
|
||||
abaaccccccccccccccccccccccccccccccccaaaaaaccccccaaccccccccccaaccaaaaaaacccccaaaaaaaccccccccccccccccccccccccaaaccacaaacccccccccccaaaaaaacaaacaaaaaacccccccccaaacccccccccccccccaaaaaa
|
||||
abccccccccccccccccccccccccccccccccccaaaaaccccccaaccccccccccccccaaaaaaaacaaaaaaaaaaccccccccccccccccccccccccaaaaaaccaaaccccccccccccaaaaaacaaacaaaaaacccccccccaaaccccccccccccccccaaaaa
|
||||
abccccccccccccccccccccccccccccccccaaaaaaaacccccccccccccccccccccaaaaaaaacaaaaaaaaaaaaacccccccccccccccccccccaaaaaacccccccccccccccaaaaaaaaaaaaaaaaaacccccccccccccccccccccccccccccaaaaa
|
5
day12/input.test
Normal file
5
day12/input.test
Normal file
|
@ -0,0 +1,5 @@
|
|||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
|
@ -1,3 +1,213 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use std::{
|
||||
cmp::Reverse,
|
||||
fs::File,
|
||||
io::{BufRead, BufReader, Read},
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
enum SolvePuzzle {
|
||||
First,
|
||||
#[default]
|
||||
Second,
|
||||
Print,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct HeightMap {
|
||||
heights: Vec<u8>,
|
||||
width: usize,
|
||||
height: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, Ord)]
|
||||
struct ScoredPos {
|
||||
height: u8,
|
||||
score: u32,
|
||||
index_on_map: usize,
|
||||
}
|
||||
|
||||
impl HeightMap {
|
||||
pub fn solve_a_star<const STARTING: u8>(&self) -> usize {
|
||||
let mut entries: Vec<_> = self
|
||||
.heights
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, &height)| ScoredPos {
|
||||
height,
|
||||
score: if height == STARTING { 0 } else { u32::MAX },
|
||||
index_on_map: idx,
|
||||
})
|
||||
.collect();
|
||||
let mut open: Vec<usize> = entries
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, entry)| entry.height == STARTING)
|
||||
.map(|(idx, _)| idx)
|
||||
.collect();
|
||||
open.sort_by_cached_key(|&idx| Reverse(entries[idx].score));
|
||||
let mut came_from: Vec<Option<usize>> =
|
||||
::std::iter::repeat(None).take(self.heights.len()).collect();
|
||||
while !open.is_empty() {
|
||||
let current_idx = *open.last().unwrap();
|
||||
if entries[current_idx].height == b'E' {
|
||||
return self.count_path(&came_from, current_idx);
|
||||
}
|
||||
let current_idx = open.pop().unwrap();
|
||||
for neighbor_idx in self.neighbors_of(current_idx) {
|
||||
let tentative_score = &entries[current_idx].score + 1;
|
||||
let neighbor = &mut entries[neighbor_idx];
|
||||
if tentative_score < neighbor.score {
|
||||
came_from[neighbor_idx] = Some(current_idx);
|
||||
neighbor.score = tentative_score;
|
||||
if !open.contains(&neighbor_idx) {
|
||||
open.push(neighbor_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
open.sort_by_cached_key(|&idx| Reverse(entries[idx].score));
|
||||
}
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn neighbors_of(&self, current: usize) -> impl Iterator<Item = usize> + '_ {
|
||||
let (x, y) = self.coords_of(current);
|
||||
let curr_height = self.height_of(current);
|
||||
[
|
||||
(x.saturating_sub(1), y),
|
||||
(x, y.saturating_sub(1)),
|
||||
(x + 1, y),
|
||||
(x, y + 1),
|
||||
]
|
||||
.into_iter()
|
||||
.filter(move |&(x, _)| x < self.width)
|
||||
.filter(|&(_, y)| y < self.height)
|
||||
.filter(move |&(new_x, new_y)| new_x != x || new_y != y)
|
||||
.map(|neigh| self.index_of(&neigh))
|
||||
.filter(move |&idx| self.height_of(idx) <= curr_height + 1)
|
||||
}
|
||||
|
||||
fn coords_of(&self, current: usize) -> (usize, usize) {
|
||||
(current % self.width, current / self.width)
|
||||
}
|
||||
|
||||
fn index_of(&self, (x, y): &(usize, usize)) -> usize {
|
||||
x + y * self.width
|
||||
}
|
||||
|
||||
fn height_of(&self, idx: usize) -> u8 {
|
||||
match self.heights[idx] {
|
||||
b'S' => b'a',
|
||||
b'E' => b'z',
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
fn count_path(&self, came_from: &[Option<usize>], mut current: usize) -> usize {
|
||||
let mut count = 0;
|
||||
while let Some(new) = came_from[current] {
|
||||
count += 1;
|
||||
current = new;
|
||||
}
|
||||
count
|
||||
}
|
||||
|
||||
fn print_fancy(&self) {
|
||||
let sup = (b'z' - b'a' + 1) as usize;
|
||||
for y in 0..self.height {
|
||||
for x in 0..self.width {
|
||||
let idx = self.index_of(&(x, y));
|
||||
let height = self.height_of(idx) - b'a';
|
||||
let char = if self.heights[idx] == b'S' {
|
||||
'S'
|
||||
} else if self.heights[idx] == b'E' {
|
||||
'E'
|
||||
} else {
|
||||
'█'
|
||||
};
|
||||
let color = colorous::RED_YELLOW_GREEN.eval_rational(26 - height as usize, sup);
|
||||
print!(
|
||||
"{}{}{char}",
|
||||
termion::color::Fg(termion::color::Rgb(color.r, color.g, color.b)),
|
||||
termion::color::Bg(termion::color::Rgb(0, 0, 0))
|
||||
);
|
||||
}
|
||||
println!()
|
||||
}
|
||||
println!()
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_puzzle<const STARTING: u8, R: BufRead>(reader: R) -> usize {
|
||||
let map = HeightMap::from(reader);
|
||||
map.solve_a_star::<STARTING>()
|
||||
}
|
||||
|
||||
fn print_puzzle<R: BufRead>(reader: R) -> usize {
|
||||
let map = HeightMap::from(reader);
|
||||
map.print_fancy();
|
||||
0
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = ::std::env::args().skip(1);
|
||||
let file = args.next().unwrap_or_else(|| String::from("./input"));
|
||||
let solve = args
|
||||
.next()
|
||||
.map(|arg| match arg.as_str() {
|
||||
"first" => SolvePuzzle::First,
|
||||
"second" => SolvePuzzle::Second,
|
||||
"print" => SolvePuzzle::Print,
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let file = BufReader::new(File::open(file).expect("Open file"));
|
||||
let solution = match solve {
|
||||
SolvePuzzle::First => solve_puzzle::<b'S', _>(file),
|
||||
SolvePuzzle::Second => solve_puzzle::<b'a', _>(file),
|
||||
SolvePuzzle::Print => print_puzzle(file),
|
||||
};
|
||||
println!("{}", solution);
|
||||
}
|
||||
|
||||
impl<R: Read> From<R> for HeightMap {
|
||||
fn from(reader: R) -> Self {
|
||||
let mut width = None;
|
||||
let heights: Vec<_> = reader
|
||||
.bytes()
|
||||
.map(Result::unwrap)
|
||||
.enumerate()
|
||||
.inspect(|&(idx, byte)| {
|
||||
if width.is_none() && byte == b'\n' {
|
||||
width = Some(idx);
|
||||
}
|
||||
})
|
||||
.map(|(_, byte)| byte)
|
||||
.filter(|&byte| byte != b'\n')
|
||||
.collect();
|
||||
let width = width.unwrap_or(heights.len());
|
||||
let height = heights.len() / width;
|
||||
HeightMap {
|
||||
heights,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ScoredPos {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.height == other.height
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for ScoredPos {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
if self.height < other.height {
|
||||
Some(::std::cmp::Ordering::Less)
|
||||
} else if self.height < other.height {
|
||||
Some(::std::cmp::Ordering::Greater)
|
||||
} else {
|
||||
Some(::std::cmp::Ordering::Equal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue