Compare commits
2 Commits
51f16fa7ad
...
c726b9090f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c726b9090f | ||
|
|
7b51854bb2 |
81
input/day18.txt
Normal file
81
input/day18.txt
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#################################################################################
|
||||||
|
#.#...#.....#...............#.....#v....#.........#p....#...#...................#
|
||||||
|
#.#.#.#.#.#.#M#############.#.###.#####.#####.###.#.###.#.#.#################.#.#
|
||||||
|
#..n#...#.#...#.#...........#...#.......#.....#.....#.#...#...#.......#...#...#.#
|
||||||
|
#########.#####.#.###########.#.#######.#.###########.#######.#C#####.#.#.#.###.#
|
||||||
|
#.........#.#.....#.........#.#.#.......#...........#...........#...#.#.#...#...#
|
||||||
|
#.#########.#.#########.#####.#W###.###############.###.#########.###.#.#####.###
|
||||||
|
#.Y...#...#...#.......#z......#...#.#...#...#.....#..d#.#.#..x..#...#.#.#...#.#.#
|
||||||
|
#####.#.#.#.###.#.###.#####.#####.#.#.#.#.#.#.###.###.#.#.#.###.#.#.#.#.#.#.#.#.#
|
||||||
|
#.....#.#...#...#.#.#.....#...#...#.#.#.#.#...#.......#...#.#...#.#.....#.#...#.#
|
||||||
|
#.#######.#######.#.#####.#####.#####.#.#.#############.###.#.###.#########.###.#
|
||||||
|
#...#...#.#...#...#.#...#.....#...B...#.#.....#...#.....#...#.#.....#....t#.....#
|
||||||
|
#.#.#.#.#.#.#.#.###.#.#.#####.#.#######.#.###.#.#.###.###.###.#.#####.###.#####N#
|
||||||
|
#.#...#.#...#.#.#.....#...#...#.#...#...#...#.#.#...#.#...#...#...#...#.#...#.#.#
|
||||||
|
#.#####.#####.#.#########.#.###.#.#.#.#.###.#.#.###.###.###.#######.###.###.#.#.#
|
||||||
|
#.#...#.#.......#...#.....#...#...#.#.#.#.#.#...#.#.....#...#.....#.#...#...#.#.#
|
||||||
|
#.#.###.#########.#.#.###.###.#####.#.#.#.#.#####.#######.###.###.#.#.###.###.#.#
|
||||||
|
#.#...#.#...#.....#.#...#...#.#...#.#.#.#.#.#.....#.....#...#.#.#...#...#.#...#.#
|
||||||
|
#.###.#.#.#.#.#####.#.#.#####.#.###.#.###.#.#.###.###.#.###.#.#.#####.#.#J#E###.#
|
||||||
|
#.....#.#.#...#...#.#.#.....#.#.....#...#.#.#.#.......#.#...#.#...#...#...#.....#
|
||||||
|
#######.#.#####.###.#######.#.#########.#.#.#.#########.#.###.#.#.#.#########.###
|
||||||
|
#.......#.#.....#.I.#.....#.............#...#...#.....#.#...#.#.#.#.........#...#
|
||||||
|
#.#######.###.###.#.#####.#.###########.#.###.#.###.###.###.#####.#########.###.#
|
||||||
|
#.......#...#.#...#.....#.#.#.......#...#.#...#.#...#.....#.........#.....#.#...#
|
||||||
|
#.#####.###.#.#.#######.#.###.#####.#.###.#####.#.###.#######.#####.#.###.#.###.#
|
||||||
|
#.#...#...#.#.#.......#.#.....#.#...#...#.#...#.#...#u#.....#...#...#.#.#.#...#.#
|
||||||
|
#.###.#.###.#.#######.#.#######.#.#####.#.#.#.#.#.#.#.#.#.#.###.#####.#.#.###.#.#
|
||||||
|
#...#.#...#.....#.....#.#.....#...#...#.#...#.#.#.#...#.#.#...#.#.....#.#.#...#.#
|
||||||
|
###.#.###.#####.#.#####.#.#.#.#.###.#.#.#####.#.#.#####.#.#.###.#.#####.#.#.###.#
|
||||||
|
#...#...#.......#.#.....#.#.#.#.....#.#.#.....#.#.#.....#.#.#...#.....#.#.#.#..k#
|
||||||
|
#.###.###########.#.#######.#.#######.#.#.#####.###.#####.###.#.#####.#.#.#.#.###
|
||||||
|
#...#...........#.#.....#...#.......#.#.#...#.........#...#...#.#.....#.#...#.#.#
|
||||||
|
###.#.###.###.###.#####.#.#.#######.#.#.###.#.#########.#.#.###.#.#####.#####.#.#
|
||||||
|
#.#.#...#...#.#...#...#.#.#.#.....#.#.#.#.#.#...#.......#.#.#...#...#.....#...#.#
|
||||||
|
#.#.###.###.#.#.###.#.#.#.###.###.###.###.#.#####.#######.#.#.#####.#.#.#.#.###.#
|
||||||
|
#.#.#.....#.#.#.....#g#...#...#.#...#...#.#.......#...#...#.#...#.#.#.#.#.#.....#
|
||||||
|
#.#.#######.#.#######.###.#.###.###.###.#.#########.###.###.###.#.#.#.#.#######.#
|
||||||
|
#...#.....#.#.#.....#.#...#.......#.#...#.....#.......#.#.#...#...#.#.#.......#.#
|
||||||
|
#.###.###.#.#.#.###.#.###########.#.#.###.###.#.#####.#.#.###.#####.#.#######.#.#
|
||||||
|
#.....#.....#...#...#.A...........#.........#.......#.R.....#.......#.......#...#
|
||||||
|
#######################################.@.#######################################
|
||||||
|
#.....#.........#...........#......r#...........#.#...#.............#.......#...#
|
||||||
|
###.###.#.#######.#.#######.#.#####.###.#.#.###.#.#.#.#.#######.###.#.#####.###.#
|
||||||
|
#...#...#.........#...#...#.#.....#.....#.#...#...#.#...#...#...#.#.#.....#.....#
|
||||||
|
#.###.###############.#.###.#.###.#####.#.###.#####.#######.#.###.#.#####.#######
|
||||||
|
#.....#.......#.#.....#...#.#.#...#.....#.#.#.#.....#.......#.#...#.....#.......#
|
||||||
|
#.#######.###.#.#.#######.#.###.#.#######.#.#.#.#########.###.#.#######G#.#####.#
|
||||||
|
#.....#...#.#...#.#.......#...#.#.#.....#...#.#.#.....#..a#...#.#.....#.#i....#.#
|
||||||
|
#####.#.###.###.#.###.#.#####.#.###.###.#####.#.###.#.#.#.#.###.#.###.#.#######.#
|
||||||
|
#...#.#.#.....#.#...#.#.#.....#.....#...#...#.......#...#.#.#.....#.#.........#.#
|
||||||
|
#.#.#.#.#.#####.###.#.###.###########.###.#.#.#############.#.#####.#########.#.#
|
||||||
|
#.#.#.#.#.......#...#.....#.....#...#...#.#.#.#.............#.......#...#.....O.#
|
||||||
|
#.#.#.#.#########.#######.#.###.#.#.###.#.#.###.###########.#########.#.#######.#
|
||||||
|
#.#.#e#.........#.#.....#...#...#.#.....#.#.#...#...........#.......#.#.....#...#
|
||||||
|
###.#.#########.#.#.###.#####P###.#######.#.#.#########.#####.#####.#.#####.#.###
|
||||||
|
#...#.......#...#...#.#.#...#...#...#...#.#...#.......#.#w....#f..#...#...#.#...#
|
||||||
|
#.#.#######.#.#######.#.#.#####.#.#.#.#.#.#.###.#####.###.###.#.#.#####.#.#.#####
|
||||||
|
#.#.#...#...#.........#.#...#...#.#...#.#.#.#.......#.#...#...#.#...#...#.#.#...#
|
||||||
|
#.#.#.###.#######.###.#.#.#.#.###.#####.#.###.#######.#.#######.###.#.###.#.#.#.#
|
||||||
|
#.#...#...#.....#...#.#.#.#...#..o..#...#...#...#...#.#...#...F.#...#...#.#...#.#
|
||||||
|
#.#####.###.###.###.###.#####.#####.#.#.#.#.#.###.#.#.###.#.#####L###.#.#.#####.#
|
||||||
|
#.......#...#.#.#...#.#.....#.....#.#.#.#.#...#...#.#.#...#...#...#...#.#.....#.#
|
||||||
|
#K#######.#.#.#.#.###.#####.#####X###.#.#######.###.#.#.#######.#####.#.#######.#
|
||||||
|
#....j..#.#.#.....#...#.....#...#...#.#.#.......#...#.#.....#...#.S.#.#.........#
|
||||||
|
#######.###.#####.#.###.#####.#.###.#.###.#######.###.#####.#.###.#.#.###########
|
||||||
|
#.....#...#.....#.#...#.......#...#.#...#.....#.#.#.......#.#l....#.#.#...#.....#
|
||||||
|
#T#.#####.#####.#####.#.#########.#.###.#.###.#.#.#####.#.#.#######.#.#.###.###.#
|
||||||
|
#.#.....#.#.....#.....#.#.......#.#.#...#c#.#.#.....#...#.#...Z.#...#.#.....#...#
|
||||||
|
#.###.###.#.#.###.#####.#.#####.#.#.#.#.#.#.#.#####.#.#######.###.###.#.#####.#.#
|
||||||
|
#...#...#...#.#...#...#...#...#.#.#.#.#.#...#.....#...#.....#.#s..#...#.#.#...#.#
|
||||||
|
###.###.#.#####.###.###.###.#.###.#.#.###.#######.###.#.#.###.#.###.###Q#.#.#####
|
||||||
|
#.#.#.#.#.#...#...#...#.#...#.....#.#...#.#.....#.#...#.#.#...#.V.#.#...#.#.....#
|
||||||
|
#.#.#.#.#.#.#.###.#.#.#.#.#########.###.#.#.###.#.#####.#.#.#####.#.#.###.#####.#
|
||||||
|
#...#.#...#.#...#.#.#.#.#...#...#...#...#.#...#y..#...#.#.#.......#.#.#.......#.#
|
||||||
|
#.###.#####.###.#.###.#.###.#.###.###.#.#####.#####.#.#.#.#########.#.#.#.#####.#
|
||||||
|
#.#.....#...#.#...#...#.#...#.#.D.#.U.#.#.....#...#.#.#.#.......#...#..b#.#.....#
|
||||||
|
#.#####.#.###.#####.###.#.###.#.###.###.#.#####.#.#.#.#.#######.#.#######.#.###.#
|
||||||
|
#.H...#.#...#...........#.#...#.#.....#.#m......#...#...#.......#.#...#...#.#...#
|
||||||
|
#####.#.###.#############.#.#.#.#####.#.#.###############.#######.#.#.#####.#.###
|
||||||
|
#..q......#...............#.#.........#.#...............#...........#.......#..h#
|
||||||
|
#################################################################################
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
mod tasks;
|
mod tasks;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tasks::day15::run();
|
tasks::day18::run();
|
||||||
}
|
}
|
||||||
|
|||||||
301
src/tasks/day18.rs
Normal file
301
src/tasks/day18.rs
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
use itertools::Itertools;
|
||||||
|
use std::cmp::{Ord, Ordering, PartialOrd};
|
||||||
|
use std::collections::BinaryHeap;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn run() {
|
||||||
|
let input: Map = Map(std::fs::read_to_string("input/day18.txt")
|
||||||
|
.unwrap()
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.chars().collect_vec())
|
||||||
|
.collect_vec());
|
||||||
|
|
||||||
|
let t1 = task(input.clone());
|
||||||
|
println!("Task 1: best bound to get all keys is {}", t1);
|
||||||
|
let t2 = task(input.clone().split_robot());
|
||||||
|
println!("Task 2: best bound to get all keys is {}", t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn task(map: Map) -> usize {
|
||||||
|
let mut all_keys = map
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.flatten()
|
||||||
|
.filter(|c| c.is_alphabetic() && c.is_lowercase())
|
||||||
|
.collect_vec();
|
||||||
|
all_keys.sort();
|
||||||
|
let all_keys: String = all_keys.into_iter().collect();
|
||||||
|
let map = Rc::from(map);
|
||||||
|
|
||||||
|
let mut visited: HashSet<StateSummary> = HashSet::new();
|
||||||
|
let mut open: BinaryHeap<State> = BinaryHeap::new();
|
||||||
|
let mut best_found_for_all = std::usize::MAX;
|
||||||
|
|
||||||
|
open.push(State::new(map.clone()));
|
||||||
|
while let Some(state) = open.pop() {
|
||||||
|
let summary = StateSummary::from(&state);
|
||||||
|
if visited.contains(&summary) || best_found_for_all <= state.steps_taken {
|
||||||
|
// there could come no better solution
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if summary.1 == all_keys {
|
||||||
|
if state.steps_taken < best_found_for_all {
|
||||||
|
best_found_for_all = state.steps_taken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state
|
||||||
|
.get_available_options()
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|s| open.push(s));
|
||||||
|
|
||||||
|
visited.insert(summary);
|
||||||
|
}
|
||||||
|
|
||||||
|
best_found_for_all
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Hash, Debug)]
|
||||||
|
struct StateSummary(Vec<Pos>, String);
|
||||||
|
impl StateSummary {
|
||||||
|
fn from(state: &State) -> Self {
|
||||||
|
let mut s = state.opened.iter().collect_vec();
|
||||||
|
s.sort();
|
||||||
|
Self(
|
||||||
|
state.currents.clone(),
|
||||||
|
s.into_iter()
|
||||||
|
.map(|c| {
|
||||||
|
let mut x = *c;
|
||||||
|
x.make_ascii_lowercase();
|
||||||
|
x
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
struct StateSummaryDist(Pos, HashSet<char>, usize);
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
|
struct Map(Vec<Vec<char>>);
|
||||||
|
|
||||||
|
impl Map {
|
||||||
|
fn coordinate_of(&self, symbol: char) -> Vec<Pos> {
|
||||||
|
self.0
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.fold(Vec::new(), |vec, (y, line)| {
|
||||||
|
line.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_x, c)| **c == symbol)
|
||||||
|
.fold(vec, |mut vec, (x, _c)| {
|
||||||
|
vec.push(Pos(x, y));
|
||||||
|
vec
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return: (char: found key, usize1: index of moved robot,
|
||||||
|
* usize2: distance that robot moved, Pos: new position of robot[index]),
|
||||||
|
* usize3: number of empty points on path to last_door_opened
|
||||||
|
*/
|
||||||
|
fn reachable_keys(
|
||||||
|
&self,
|
||||||
|
start_points: Vec<Pos>,
|
||||||
|
open_doors: &HashSet<char>,
|
||||||
|
last_door_opened: Option<char>,
|
||||||
|
) -> Vec<(char, usize, usize, Pos, usize)> {
|
||||||
|
let all_keys = 'a'..='z';
|
||||||
|
|
||||||
|
let bfs = |start: Pos, open_doors: &HashSet<char>| {
|
||||||
|
// key, distance, new_pos, number of steps of distance until last_open door is met
|
||||||
|
let mut result: Vec<(char, usize, Pos, usize)> = vec![];
|
||||||
|
let mut open: VecDeque<(Pos, usize, usize)> = VecDeque::new(); //position, distance form start, distance until last door opened is met
|
||||||
|
open.push_back((start, 0, 0));
|
||||||
|
let mut visited: HashSet<Pos> = HashSet::new();
|
||||||
|
while let Some((current, walked, ldod)) = open.pop_front() {
|
||||||
|
if visited.contains(¤t) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let field = self.0[current.1][current.0];
|
||||||
|
let field_is_key = all_keys.contains(&field);
|
||||||
|
// if can move over current type: push neighbors to open
|
||||||
|
if field == '.' || field == '@' || open_doors.contains(&field) || field_is_key {
|
||||||
|
let mut ldod = 0;
|
||||||
|
if let Some(ldo) = last_door_opened {
|
||||||
|
if ldo == field {
|
||||||
|
ldod = walked;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
current
|
||||||
|
.neighbors()
|
||||||
|
.iter()
|
||||||
|
.for_each(|n| open.push_back((*n, walked + 1, ldod)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it is a key: push it to result
|
||||||
|
if field_is_key {
|
||||||
|
result.push((field, walked, current, ldod));
|
||||||
|
}
|
||||||
|
|
||||||
|
// anyways: push to visited
|
||||||
|
visited.insert(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
};
|
||||||
|
|
||||||
|
start_points
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(robot_i, robot_pos)| {
|
||||||
|
bfs(*robot_pos, open_doors)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(key, dist, final_pos, ldod)| (key, robot_i, dist, final_pos, ldod))
|
||||||
|
.collect_vec()
|
||||||
|
})
|
||||||
|
.collect_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split_robot(mut self) -> Self {
|
||||||
|
let Pos(x, y) = self.coordinate_of('@')[0];
|
||||||
|
self.0[x][y] = '#';
|
||||||
|
self.0[x - 1][y - 1] = '@';
|
||||||
|
self.0[x - 1][y] = '#';
|
||||||
|
self.0[x - 1][y + 1] = '@';
|
||||||
|
self.0[x + 1][y] = '#';
|
||||||
|
self.0[x + 1][y + 1] = '@';
|
||||||
|
self.0[x][y - 1] = '#';
|
||||||
|
self.0[x + 1][y - 1] = '@';
|
||||||
|
self.0[x][y + 1] = '#';
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
|
struct Pos(usize, usize);
|
||||||
|
|
||||||
|
impl Pos {
|
||||||
|
fn neighbors(&self) -> [Pos; 4] {
|
||||||
|
[
|
||||||
|
Pos(self.0 - 1, self.1),
|
||||||
|
Pos(self.0 + 1, self.1),
|
||||||
|
Pos(self.0, self.1 - 1),
|
||||||
|
Pos(self.0, self.1 + 1),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
struct State {
|
||||||
|
currents: Vec<Pos>,
|
||||||
|
underrun: Vec<usize>, // the number of steps a robot is behind the leading robots steps
|
||||||
|
opened: HashSet<char>, // capital letter
|
||||||
|
map: Rc<Map>,
|
||||||
|
steps_taken: usize,
|
||||||
|
last_door_opened: Option<char>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
fn new(map: Rc<Map>) -> Self {
|
||||||
|
let currents = map.coordinate_of('@');
|
||||||
|
let no_robots = currents.len();
|
||||||
|
Self {
|
||||||
|
currents: currents,
|
||||||
|
underrun: std::iter::repeat(0).take(no_robots).collect_vec(),
|
||||||
|
opened: HashSet::new(),
|
||||||
|
map: map,
|
||||||
|
steps_taken: 0,
|
||||||
|
last_door_opened: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_available_options(&self) -> Vec<State> {
|
||||||
|
// find all keys that are not yet collected + their distance + position
|
||||||
|
let next_keys = self
|
||||||
|
.map
|
||||||
|
.reachable_keys(self.currents.clone(), &self.opened, self.last_door_opened)
|
||||||
|
.into_iter()
|
||||||
|
.filter(|(key, _, _, _, _)| {
|
||||||
|
let mut c = *key;
|
||||||
|
c.make_ascii_uppercase();
|
||||||
|
!self.opened.contains(&c)
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
// create new state with one open door added + steps increased + current position updated
|
||||||
|
next_keys
|
||||||
|
.into_iter()
|
||||||
|
.map(|(key, robot_i, distance, current, ldod)| {
|
||||||
|
self.advance(key, robot_i, distance, current, ldod)
|
||||||
|
})
|
||||||
|
.collect_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn advance(
|
||||||
|
&self,
|
||||||
|
key_added: char,
|
||||||
|
robot_index: usize,
|
||||||
|
additional_steps: usize,
|
||||||
|
new_pos: Pos,
|
||||||
|
ldod: usize,
|
||||||
|
) -> Self {
|
||||||
|
let mut open_doors = self.opened.clone();
|
||||||
|
let mut door = key_added;
|
||||||
|
door.make_ascii_uppercase();
|
||||||
|
open_doors.insert(door);
|
||||||
|
let mut positions = self.currents.clone();
|
||||||
|
positions[robot_index] = new_pos;
|
||||||
|
let underrun = self
|
||||||
|
.underrun
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, u)| {
|
||||||
|
if i != robot_index {
|
||||||
|
*u + additional_steps
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let usable_underrun = if self.underrun[robot_index] >= ldod {
|
||||||
|
ldod
|
||||||
|
} else {
|
||||||
|
self.underrun[robot_index]
|
||||||
|
};
|
||||||
|
let steps_diff = additional_steps - usable_underrun;
|
||||||
|
Self {
|
||||||
|
currents: positions,
|
||||||
|
underrun: underrun,
|
||||||
|
opened: open_doors,
|
||||||
|
map: self.map.clone(),
|
||||||
|
steps_taken: self.steps_taken + steps_diff as usize,
|
||||||
|
last_door_opened: Some(key_added),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The priority queue depends on `Ord`.
|
||||||
|
// Explicitly implement the trait so the queue becomes a min-heap
|
||||||
|
// instead of a max-heap.
|
||||||
|
impl Ord for State {
|
||||||
|
fn cmp(&self, other: &State) -> Ordering {
|
||||||
|
// Notice that the we flip the ordering on costs.
|
||||||
|
// In case of a tie we compare positions - this step is necessary
|
||||||
|
// to make implementations of `PartialEq` and `Ord` consistent.
|
||||||
|
other.steps_taken.cmp(&self.steps_taken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// `PartialOrd` needs to be implemented as well.
|
||||||
|
impl PartialOrd for State {
|
||||||
|
fn partial_cmp(&self, other: &State) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,4 +13,5 @@ pub mod day13;
|
|||||||
pub mod day14;
|
pub mod day14;
|
||||||
pub mod day15;
|
pub mod day15;
|
||||||
pub mod day16;
|
pub mod day16;
|
||||||
|
pub mod day18;
|
||||||
pub mod day21;
|
pub mod day21;
|
||||||
|
|||||||
Reference in New Issue
Block a user