day12 finished
This commit is contained in:
parent
6509fc79ea
commit
0b388cbd13
4 changed files with 343 additions and 1 deletions
5
data/day12/example01.txt
Normal file
5
data/day12/example01.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
Sabqponm
|
||||||
|
abcryxxl
|
||||||
|
accszExk
|
||||||
|
acctuvwj
|
||||||
|
abdefghi
|
||||||
41
data/day12/input.txt
Normal file
41
data/day12/input.txt
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
abcccaaaaaaccccccccaaaaaccccccaaaaaaccccccaaaaaaaacccaaaaaaaccaaaacccccccccccccccccccccccccaaaaaacccccccccccccccccccccccccccccaaaaaa
|
||||||
|
abcccaaaaaacccccccaaaaaaccccaaaaaaaacccccccaaaaaaaaaaaaaaaaccaaaaacccccccccccccccccccccccccaaaaaacccccccccccccccccccccccccccccaaaaaa
|
||||||
|
abccccaaaaacaaaccaaaaaaaacccaaaaaaaaacccccccaaaaaaaaaaaaaaaacaaaaaacccccccccaaacccccccccccaaaaaaaaccccccccccaaccccccccccccccccaaaaaa
|
||||||
|
abccccaaaaccaaaaaaaaaaaaacccaaaaaaaaaacccccaaaaaaaaaaaaaaaaaaacaaaacccccccccaaaacccccccccaaaaaaaaaacccccccccaaaccccccccccccccccccaaa
|
||||||
|
abcccccccccaaaaaacccaacccccccccaaacaaaccccccaacccccccaaaaaaaaacaacccccccccccaaaacccccccccaaaaaaaaaacccccccccaaaccacaaccccccccccccaaa
|
||||||
|
abcccccccccaaaaaacccaacccccccccaaacccccccccccccccccccaaaacaaaacccccccaacaaccaaaccccccccccaccaaaaacacccccccccaaaacaaaaccccccccccccaac
|
||||||
|
abccccccccccaaaaacccccccccccccccacccaaaacccccccccccccaaaacccccccccccccaaaacccccccccccaacccccaaaaccccccccjjjjaaaaaaaaaccccccccccccccc
|
||||||
|
abccccccccccaaaacccccccccccccccccccaaaaacccccccccccccaaaccccccccccccccaaaaacccccccccaaaaaacccaaccccccccjjjjjjkkaaaacccccccccaacccccc
|
||||||
|
abcccccaaccccccccccccccccccccccccccaaaaaacccccccccccccaacccccccccccccaaaaaaccccccccccaaaaaccccccccccccjjjjjjjkkkkaacccccaacaaacccccc
|
||||||
|
abccaaaacccccccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccaaaacaccccccccaaaaaaaccccaacccccjjjjoooookkkkkkkklllaaaaaaacccc
|
||||||
|
abccaaaaaacccccccccccccccccccccccccaaaaacccccccccccccccccccccccccccccccaaccccccccccaaaaaaaaccaaaaccccjjjoooooookkkkkkkllllaaaaaacccc
|
||||||
|
abcccaaaaacccccccccccccccccccccccccccaaaccccccccaaaacccccccccccccccccccccccccccccccaaaaaaaaccaaaaccccjjooooooooppkkppplllllaccaacccc
|
||||||
|
abccaaaaaccccccccccccaccccccccccccccccccccccccccaaaacccccccccccccccccccccccccccccccccaaacacccaaaacccijjooouuuuoppppppppplllccccccccc
|
||||||
|
abcccccaacccccccccccaaaaaaaaccccccccccccccccccccaaaaccccaaccccccccaaacccccccccccccaacaaccccccccccccciijoouuuuuuppppppppplllcccaccccc
|
||||||
|
abcccccccccccccccccccaaaaaaccccccccccccccccccccccaaccccaaaacccccccaaaaccccccccccaaaaaaccccccccccccciiiiootuuuuuupuuuvvpppllccccccccc
|
||||||
|
abcccccccccccccccccccaaaaaaccaaaaacccccccccccccccccccccaaaacccccccaaaaccccccccccaaaaaaccccccccccccciiinnotuuxxxuuuuvvvpppllccccccccc
|
||||||
|
abccccccccccccccacccaaaaaaaacaaaaaaacccccccccccccccccccaaaacccccccaaacccccaaaaccaaaaaccccaaccccccciiiinnnttxxxxuuyyyvvqqqllccccccccc
|
||||||
|
abcccccccccccaaaaccaaaaaaaaaaaaaaaaaaccaacccccccccccccccccccccccccccccccccaaaacccaaaaaccaaacccccciiinnnnnttxxxxxyyyyvvqqqllccccccccc
|
||||||
|
abaaaacccccccaaaaaaaaaaaaaaaaaaaaaaaaaaaacccccccccccccccccccccccccccccccccaaaacccaaaaaacaaaccccciiinnnnttttxxxxxyyyyvvqqmmmccccccccc
|
||||||
|
abaaaaccccccccaaaaacccaaaaacaaaaaacaaaaaaccccccccccccccccaaccccccccccccccccaacccccccaaaaaaaaaaciiinnnnttttxxxxxyyyyvvqqqmmmccccccccc
|
||||||
|
SbaaaacccccccaaaaaccccaaaaaccaaaaaaaaaaaccccccccccccccccaaacaacccccccccccccccccccccccaaaaaaaaachhhnnntttxxxEzzzzyyvvvqqqmmmccccccccc
|
||||||
|
abaaaacccccccaacaacccccaaaaaaaacaaaaaaaaaccccccccccccccccaaaaaccccccccccccccccccccccccaaaaaaacchhhnnntttxxxxxyyyyyyvvvqqmmmdddcccccc
|
||||||
|
abaaaacccccccccccccccccccaaaaaacaaaaaaaaaacccccccccccccaaaaaaccccccccaaaccccccccccccccaaaaaaccchhhnnntttxxxxywyyyyyyvvvqqmmmdddccccc
|
||||||
|
abaacccccccccccccccccccaaaaaaacccccaaaaaaacccccccccccccaaaaaaaacccccaaaacccccccccccccaaaaaaacaahhhmmmttttxxwwyyyyyyyvvvqqmmmdddccccc
|
||||||
|
abcccccccccccccccccccccaaaaaaacaaccaaacccccccccccccccccaacaaaaacccccaaaacccccccccccccaaacaaaaaahhhmmmmtsssswwyywwwwvvvvqqqmmdddccccc
|
||||||
|
abcccccccccccccccaaaccccaaaaaaaaaacaaccaaccccccccccccccccaaacaccccccaaaacccccccccccccccccaaaaacahhhmmmmmsssswwywwwwwvvrrqqmmdddccccc
|
||||||
|
abcccccccccccccaaaaaaccccaaaaaaaaaccaaaacccccccccccccccccaacccccccccccccccccccccccaaaccccaaaaaaahhhhhmmmmssswwwwwrrrrrrrrmmmmddccccc
|
||||||
|
abcccccccccccccaaaaaaccccaaaaaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccaaaaaacccccaaaaachhhhhmmmmsswwwwrrrrrrrrrkkmdddccccc
|
||||||
|
abccccccccccccccaaaaaccccccaaaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccaaaaaaccccaaaaacccchhggmmmssswwrrrrrkkkkkkkkdddacccc
|
||||||
|
abccaaaacccccccaaaaacccccccccaaaaaacaaaaacccccccccccccccccccccccccccccccccccccccaaaaaaccccaacaaaccccggggmmsssssrrlkkkkkkkkkdddaccccc
|
||||||
|
abccaaaacccccccaaaaacccccccccaaaaaaccccaacccccccccccccccccccccccccccccccccccccccaaaaaccccccccaaccccccgggmllssssrllkkkkkkkeeeddaccccc
|
||||||
|
abccaaaacccccccaaacccccccccccaaaaaacccccccccccccccccccaacccccccccccccccccccccccaaaaaacccccccccccccccccggllllssslllkkeeeeeeeeeaaacccc
|
||||||
|
abcccaaccccccccaaacaaaccccccaaaaaaaaaaacccccccccccccaaaaaacccccccccccccccccccccaaacaaacccccaacccccccccggglllllllllfeeeeeeeeaaaaacccc
|
||||||
|
abccccccccccaaaaaaaaaaccccccccccccaccaaaccacccccccccaaaaaaccccaaccaacccaaccccccaaaaaaacccccaaccccccccccggglllllllfffeeecccaaaaaacccc
|
||||||
|
abccccccccccaaaaaaaaacccccccccccccccaaaaaaaccccccccccaaaaaccccaaaaaacccaaaaaaccaaaaaacccaaaaaaaacccccccggggllllfffffccccccaacccccccc
|
||||||
|
abcccccccccccaaaaaaacccccccccccccccccaaaaaaccaacccccaaaaaccccccaaaaacccaaaaaacaaaaaaacccaaaaaaaaccccccccgggffffffffccccccccccccccccc
|
||||||
|
abccccccccccccaaaaaaacccccccccccccaaaaaaaaacaaaaccccaaaaacaaaaaaaaaacaaaaaaacaaaaaaaaaccccaaaacccccccccccggffffffacccccccccccccccaaa
|
||||||
|
abccccccccccccaaaaaaacaaccccccccccaaaaaaaaacaaaacccccaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaacccaaaaacccccccccccaffffaaaaccccccccccccccaaa
|
||||||
|
abccccccccccccaaacaaaaaacccccccccccaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaacccaaacaaaccaaaaaacccccccccccccccccaaaccccccccccccccaaa
|
||||||
|
abccccccccccccaaccaaaaaccccccccccccccaaaaaaaccccaaaaaaaaaaaaccccaacccccaaaaaacccaaaccccccaaccaacccccccccccccccccaaacccccccccccaaaaaa
|
||||||
|
abcccccccccccccccaaaaaaaaccccccccccccaacccacccccccaaaaaaaaaaccccaacccccaaccccccccaccccccccccccccccccccccccccccccccccccccccccccaaaaaa
|
||||||
294
src/days/day12/mod.rs
Normal file
294
src/days/day12/mod.rs
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
use std::collections::{BinaryHeap, HashSet};
|
||||||
|
|
||||||
|
use crate::common::pos::Pos;
|
||||||
|
|
||||||
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
const DAY_NUMBER: usize = 12;
|
||||||
|
|
||||||
|
pub struct Day;
|
||||||
|
|
||||||
|
impl DayTrait for Day {
|
||||||
|
fn get_day_number(&self) -> usize {
|
||||||
|
DAY_NUMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(&self, lines: &[String]) -> anyhow::Result<ResultType> {
|
||||||
|
let valley = Valley::parse(lines)?;
|
||||||
|
Ok(ResultType::Integer(valley.walk()? as i64))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(&self, lines: &[String]) -> anyhow::Result<ResultType> {
|
||||||
|
let valley = Valley::parse(lines)?;
|
||||||
|
Ok(ResultType::Integer(valley.walk_short()? as i64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
enum ValleyError {
|
||||||
|
#[error("Not a legal terrain char: {0}")]
|
||||||
|
NotALegalCharacter(char),
|
||||||
|
#[error("Valley needs to be rectangle")]
|
||||||
|
NotAReactangleValley,
|
||||||
|
#[error("Valley map conatins no data")]
|
||||||
|
EmptyValley,
|
||||||
|
#[error("Could not find start point")]
|
||||||
|
NoStartFound,
|
||||||
|
#[error("Could not find exit point")]
|
||||||
|
NoExitFound,
|
||||||
|
#[error("No path found")]
|
||||||
|
NoPathFound,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
struct Path {
|
||||||
|
length: usize,
|
||||||
|
height: char,
|
||||||
|
pos: Pos<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Path {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
match other.length.partial_cmp(&self.length) {
|
||||||
|
Some(core::cmp::Ordering::Equal) => {}
|
||||||
|
ord => return ord,
|
||||||
|
}
|
||||||
|
match other.height.partial_cmp(&self.height) {
|
||||||
|
Some(core::cmp::Ordering::Equal) => {}
|
||||||
|
ord => return ord,
|
||||||
|
}
|
||||||
|
match self.pos.x().partial_cmp(&other.pos.x()) {
|
||||||
|
Some(core::cmp::Ordering::Equal) => {}
|
||||||
|
ord => return ord,
|
||||||
|
}
|
||||||
|
self.pos.y().partial_cmp(&other.pos.y())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Path {
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
other
|
||||||
|
.length
|
||||||
|
.cmp(&self.length)
|
||||||
|
.then_with(|| other.height.cmp(&self.height))
|
||||||
|
.then_with(|| self.pos.x().cmp(&other.pos.x()))
|
||||||
|
.then_with(|| self.pos.y().cmp(&other.pos.y()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Path {
|
||||||
|
pub fn new(length: usize, height: char, pos: Pos<usize>) -> Self {
|
||||||
|
Path {
|
||||||
|
length,
|
||||||
|
height,
|
||||||
|
pos,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_path<'a>(&'a self, valley: &'a Valley) -> Neighbors<'a> {
|
||||||
|
Neighbors::new(self, valley)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Neighbors<'a> {
|
||||||
|
path: &'a Path,
|
||||||
|
valley: &'a Valley,
|
||||||
|
state: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Neighbors<'a> {
|
||||||
|
pub fn new(path: &'a Path, valley: &'a Valley) -> Self {
|
||||||
|
Neighbors {
|
||||||
|
path,
|
||||||
|
state: 0,
|
||||||
|
valley,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_pos(&mut self) -> Option<Pos<usize>> {
|
||||||
|
while self.state < 4 {
|
||||||
|
self.state += 1;
|
||||||
|
match self.state {
|
||||||
|
1 => {
|
||||||
|
if self.path.pos.x() < self.valley.width() - 1 {
|
||||||
|
return Some(Pos::new(self.path.pos.x() + 1, self.path.pos.y()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
if self.path.pos.y() > 0 {
|
||||||
|
return Some(Pos::new(self.path.pos.x(), self.path.pos.y() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
if self.path.pos.x() > 0 {
|
||||||
|
return Some(Pos::new(self.path.pos.x() - 1, self.path.pos.y()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
if self.path.pos.y() < self.valley.height() - 1 {
|
||||||
|
return Some(Pos::new(self.path.pos.x(), self.path.pos.y() + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for Neighbors<'_> {
|
||||||
|
type Item = Path;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
while let Some(pos) = self.next_pos() {
|
||||||
|
let height = self.valley.get_height(pos);
|
||||||
|
if height as u32 + 1 >= self.path.height as u32 {
|
||||||
|
return Some(Path::new(self.path.length + 1, height, pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Valley {
|
||||||
|
map: Vec<Vec<char>>,
|
||||||
|
start: Pos<usize>,
|
||||||
|
exit: Pos<usize>,
|
||||||
|
width: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Valley {
|
||||||
|
pub fn parse(lines: &[String]) -> Result<Valley, ValleyError> {
|
||||||
|
let mut map = Vec::new();
|
||||||
|
let mut start = None;
|
||||||
|
let mut exit = None;
|
||||||
|
let mut valley_width = None;
|
||||||
|
for (y, row) in lines.iter().enumerate() {
|
||||||
|
let mut height_row = Vec::new();
|
||||||
|
for (x, height_char) in row.chars().enumerate() {
|
||||||
|
match height_char {
|
||||||
|
'S' => {
|
||||||
|
start = Some(Pos::new(x, y));
|
||||||
|
height_row.push('a')
|
||||||
|
}
|
||||||
|
'E' => {
|
||||||
|
exit = Some(Pos::new(x, y));
|
||||||
|
height_row.push('z')
|
||||||
|
}
|
||||||
|
'a'..='z' => height_row.push(height_char),
|
||||||
|
_ => return Err(ValleyError::NotALegalCharacter(height_char)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(width) = valley_width {
|
||||||
|
if width != height_row.len() {
|
||||||
|
return Err(ValleyError::NotAReactangleValley);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valley_width = Some(height_row.len());
|
||||||
|
}
|
||||||
|
map.push(height_row);
|
||||||
|
}
|
||||||
|
let Some(width) = valley_width else {
|
||||||
|
return Err(ValleyError::EmptyValley);
|
||||||
|
};
|
||||||
|
let Some(start) = start else {
|
||||||
|
return Err(ValleyError::NoStartFound);
|
||||||
|
};
|
||||||
|
let Some(exit) = exit else {
|
||||||
|
return Err(ValleyError::NoExitFound);
|
||||||
|
};
|
||||||
|
Ok(Valley {
|
||||||
|
map,
|
||||||
|
start,
|
||||||
|
exit,
|
||||||
|
width,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_height(&self, pos: Pos<usize>) -> char {
|
||||||
|
self.map[pos.y()][pos.x()]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_walk<F>(&self, check: F) -> Result<usize, ValleyError>
|
||||||
|
where
|
||||||
|
F: Fn(Pos<usize>) -> bool,
|
||||||
|
{
|
||||||
|
let mut shortest = HashSet::with_capacity(self.width * self.map.len());
|
||||||
|
let mut queue = BinaryHeap::new();
|
||||||
|
queue.push(Path::new(0, 'z', self.exit));
|
||||||
|
while let Some(current) = queue.pop() {
|
||||||
|
if check(current.pos) {
|
||||||
|
return Ok(current.length);
|
||||||
|
}
|
||||||
|
if shortest.contains(¤t.pos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
shortest.insert(current.pos);
|
||||||
|
for next in current.next_path(self) {
|
||||||
|
queue.push(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(ValleyError::NoPathFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk(&self) -> Result<usize, ValleyError> {
|
||||||
|
self.do_walk(|pos| pos == self.start)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn walk_short(&self) -> Result<usize, ValleyError> {
|
||||||
|
self.do_walk(|pos| self.get_height(pos) == 'a')
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn width(&self) -> usize {
|
||||||
|
self.width
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn height(&self) -> usize {
|
||||||
|
self.map.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use crate::common::file::read_lines;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse() -> Result<()> {
|
||||||
|
let day = Day {};
|
||||||
|
let lines = read_lines(day.get_day_number(), "example01.txt")?;
|
||||||
|
let valley = Valley::parse(&lines)?;
|
||||||
|
assert_eq!(valley.width, 8);
|
||||||
|
assert_eq!(valley.start, Pos::new(0, 0));
|
||||||
|
assert_eq!(valley.exit, Pos::new(5, 2));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part1() -> Result<()> {
|
||||||
|
let day = Day {};
|
||||||
|
let lines = read_lines(day.get_day_number(), "example01.txt")?;
|
||||||
|
let expected = ResultType::Integer(31);
|
||||||
|
let result = day.part1(&lines)?;
|
||||||
|
assert_eq!(result, expected);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part2() -> Result<()> {
|
||||||
|
let day = Day {};
|
||||||
|
let lines = read_lines(day.get_day_number(), "example01.txt")?;
|
||||||
|
let expected = ResultType::Integer(29);
|
||||||
|
let result = day.part2(&lines)?;
|
||||||
|
assert_eq!(result, expected);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ mod day08;
|
||||||
mod day09;
|
mod day09;
|
||||||
mod day10;
|
mod day10;
|
||||||
mod day11;
|
mod day11;
|
||||||
|
mod day12;
|
||||||
mod template;
|
mod template;
|
||||||
|
|
||||||
pub use template::DayTrait;
|
pub use template::DayTrait;
|
||||||
|
|
@ -18,7 +19,7 @@ pub mod day_provider {
|
||||||
use super::*;
|
use super::*;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const MAX_DAY: usize = 11;
|
const MAX_DAY: usize = 12;
|
||||||
|
|
||||||
pub fn get_day(day_num: usize) -> Result<Box<dyn DayTrait>, ProviderError> {
|
pub fn get_day(day_num: usize) -> Result<Box<dyn DayTrait>, ProviderError> {
|
||||||
match day_num {
|
match day_num {
|
||||||
|
|
@ -33,6 +34,7 @@ pub mod day_provider {
|
||||||
9 => Ok(Box::new(day09::Day)),
|
9 => Ok(Box::new(day09::Day)),
|
||||||
10 => Ok(Box::new(day10::Day)),
|
10 => Ok(Box::new(day10::Day)),
|
||||||
11 => Ok(Box::new(day11::Day)),
|
11 => Ok(Box::new(day11::Day)),
|
||||||
|
12 => Ok(Box::new(day12::Day)),
|
||||||
_ => Err(ProviderError::InvalidNumber(day_num)),
|
_ => Err(ProviderError::InvalidNumber(day_num)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue