minor improvements
This commit is contained in:
parent
4e64b9786d
commit
bcefb1b68f
18 changed files with 111 additions and 124 deletions
|
|
@ -3,6 +3,7 @@ pub mod direction;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
pub mod helper;
|
pub mod helper;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
|
pub mod name;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod pos;
|
pub mod pos;
|
||||||
pub mod turn;
|
pub mod turn;
|
||||||
|
|
|
||||||
30
src/common/name.rs
Normal file
30
src/common/name.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
use std::{fmt::Display, ops::Deref, rc::Rc};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
pub struct Name(Rc<str>);
|
||||||
|
|
||||||
|
impl Name {
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Name {
|
||||||
|
type Target = str;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Name {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
Self(Rc::from(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Name {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.0.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::split_lines;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
|
||||||
|
|
||||||
pub struct Day;
|
pub struct Day;
|
||||||
const DAY_NUMBER: usize = 1;
|
const DAY_NUMBER: usize = 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::split_lines;
|
||||||
|
use std::{cmp::Ordering, str::FromStr};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 2;
|
const DAY_NUMBER: usize = 2;
|
||||||
|
|
@ -60,9 +58,7 @@ impl Rps {
|
||||||
Err(RPSError::IllegalLine(line.to_owned()))?
|
Err(RPSError::IllegalLine(line.to_owned()))?
|
||||||
};
|
};
|
||||||
|
|
||||||
let first = Rps::try_from(first)?;
|
Ok((first.parse()?, second.parse()?))
|
||||||
let second = Rps::try_from(second)?;
|
|
||||||
Ok((first, second))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn value(&self) -> i64 {
|
pub fn value(&self) -> i64 {
|
||||||
|
|
@ -98,10 +94,10 @@ impl PartialOrd for Rps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&str> for Rps {
|
impl FromStr for Rps {
|
||||||
type Error = RPSError;
|
type Err = RPSError;
|
||||||
|
|
||||||
fn try_from(value: &str) -> std::result::Result<Self, Self::Error> {
|
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||||
match value {
|
match value {
|
||||||
"A" | "X" => Ok(Rps::Rock),
|
"A" | "X" => Ok(Rps::Rock),
|
||||||
"B" | "Y" => Ok(Rps::Paper),
|
"B" | "Y" => Ok(Rps::Paper),
|
||||||
|
|
@ -110,6 +106,7 @@ impl TryFrom<&str> for Rps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||||
enum Strategy {
|
enum Strategy {
|
||||||
Loose,
|
Loose,
|
||||||
|
|
@ -124,9 +121,7 @@ impl Strategy {
|
||||||
Err(RPSError::IllegalLine(line.to_owned()))?
|
Err(RPSError::IllegalLine(line.to_owned()))?
|
||||||
};
|
};
|
||||||
|
|
||||||
let first = Rps::try_from(first)?;
|
Ok((first.parse()?, second.parse()?))
|
||||||
let second = Strategy::try_from(second)?;
|
|
||||||
Ok((first, second))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fullfill(&self, other: &Rps) -> Rps {
|
pub fn fullfill(&self, other: &Rps) -> Rps {
|
||||||
|
|
@ -139,10 +134,10 @@ impl Strategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&str> for Strategy {
|
impl FromStr for Strategy {
|
||||||
type Error = RPSError;
|
type Err = RPSError;
|
||||||
|
|
||||||
fn try_from(value: &str) -> std::result::Result<Self, Self::Error> {
|
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||||
match value {
|
match value {
|
||||||
"X" => Ok(Strategy::Loose),
|
"X" => Ok(Strategy::Loose),
|
||||||
"Y" => Ok(Strategy::Draw),
|
"Y" => Ok(Strategy::Draw),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::split_lines;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::split_lines;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::split_lines;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::{file::split_lines, name::Name};
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
num::ParseIntError,
|
num::ParseIntError,
|
||||||
rc::{Rc, Weak},
|
rc::{Rc, Weak},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 7;
|
const DAY_NUMBER: usize = 7;
|
||||||
|
|
@ -75,7 +73,7 @@ enum DirectoryError {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Node {
|
struct Node {
|
||||||
parent: Option<Weak<RefCell<Node>>>,
|
parent: Option<Weak<RefCell<Node>>>,
|
||||||
name: String,
|
name: Name,
|
||||||
sub_dirs: Vec<Rc<RefCell<Node>>>,
|
sub_dirs: Vec<Rc<RefCell<Node>>>,
|
||||||
file_size: i64,
|
file_size: i64,
|
||||||
size: Cell<Option<i64>>,
|
size: Cell<Option<i64>>,
|
||||||
|
|
@ -85,7 +83,7 @@ impl Node {
|
||||||
fn root() -> Node {
|
fn root() -> Node {
|
||||||
Node {
|
Node {
|
||||||
parent: None,
|
parent: None,
|
||||||
name: "/".to_owned(),
|
name: "/".into(),
|
||||||
sub_dirs: vec![],
|
sub_dirs: vec![],
|
||||||
file_size: 0,
|
file_size: 0,
|
||||||
size: Cell::new(None),
|
size: Cell::new(None),
|
||||||
|
|
@ -96,7 +94,7 @@ impl Node {
|
||||||
self.sub_dirs.push(subdir);
|
self.sub_dirs.push(subdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_file(&mut self, _name: &str, size: i64) {
|
fn add_file<N: Into<Name>>(&mut self, _name: N, size: i64) {
|
||||||
self.file_size += size;
|
self.file_size += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,10 +139,10 @@ impl Directory {
|
||||||
self.node.borrow().file_size
|
self.node.borrow().file_size
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_subdir(&mut self, name: &str) {
|
pub fn add_subdir<N: Into<Name>>(&mut self, name: N) {
|
||||||
let subdir = Rc::new(RefCell::new(Node {
|
let subdir = Rc::new(RefCell::new(Node {
|
||||||
parent: Some(Rc::downgrade(&self.node)),
|
parent: Some(Rc::downgrade(&self.node)),
|
||||||
name: name.to_owned(),
|
name: name.into(),
|
||||||
sub_dirs: vec![],
|
sub_dirs: vec![],
|
||||||
file_size: 0,
|
file_size: 0,
|
||||||
size: Cell::new(None),
|
size: Cell::new(None),
|
||||||
|
|
@ -152,7 +150,7 @@ impl Directory {
|
||||||
self.node.borrow_mut().add_subdir(subdir);
|
self.node.borrow_mut().add_subdir(subdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_file(&mut self, name: &str, size: i64) {
|
pub fn add_file<N: Into<Name>>(&mut self, name: N, size: i64) {
|
||||||
self.node.borrow_mut().add_file(name, size)
|
self.node.borrow_mut().add_file(name, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,8 +163,9 @@ impl Directory {
|
||||||
.map(|node| Directory { node })
|
.map(|node| Directory { node })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_subdir(&self, name: &str) -> Option<Directory> {
|
pub fn get_subdir<N: Into<Name>>(&self, name: N) -> Option<Directory> {
|
||||||
let node = self.node.borrow();
|
let node = self.node.borrow();
|
||||||
|
let name = name.into();
|
||||||
let sub_node = node.sub_dirs.iter().find(|node| node.borrow().name == name);
|
let sub_node = node.sub_dirs.iter().find(|node| node.borrow().name == name);
|
||||||
sub_node.map(|node| Directory::create(node.clone()))
|
sub_node.map(|node| Directory::create(node.clone()))
|
||||||
}
|
}
|
||||||
|
|
@ -187,7 +186,7 @@ impl Directory {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let Some(next) = current.get_subdir(dir) else {
|
let Some(next) = current.get_subdir(dir) else {
|
||||||
return Err(DirectoryError::NoSuchDirectory(dir.to_owned()))
|
return Err(DirectoryError::NoSuchDirectory(dir.to_owned()));
|
||||||
};
|
};
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::split_lines;
|
||||||
use itertools::{iproduct, FoldWhile, Itertools};
|
use itertools::{iproduct, FoldWhile, Itertools};
|
||||||
|
use std::str::FromStr;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 8;
|
const DAY_NUMBER: usize = 8;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
use std::{num::ParseIntError, slice::Iter};
|
use crate::common::file::split_lines;
|
||||||
|
use itertools::Itertools;
|
||||||
|
use std::{num::ParseIntError, slice::Iter, str::FromStr};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 10;
|
const DAY_NUMBER: usize = 10;
|
||||||
|
|
@ -14,17 +14,13 @@ impl DayTrait for Day {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part1(&self, lines: &str) -> anyhow::Result<ResultType> {
|
fn part1(&self, lines: &str) -> anyhow::Result<ResultType> {
|
||||||
let instructions = split_lines(lines)
|
let instructions: Vec<_> = split_lines(lines).map(|line| line.parse()).try_collect()?;
|
||||||
.map(|line| Instruction::parse(line))
|
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
|
||||||
let result = CpuCycles::signal_strength(&instructions, &[20, 60, 100, 140, 180, 220]);
|
let result = CpuCycles::signal_strength(&instructions, &[20, 60, 100, 140, 180, 220]);
|
||||||
Ok(ResultType::Integer(result as i64))
|
Ok(ResultType::Integer(result as i64))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(&self, lines: &str) -> anyhow::Result<ResultType> {
|
fn part2(&self, lines: &str) -> anyhow::Result<ResultType> {
|
||||||
let instructions = split_lines(lines)
|
let instructions: Vec<_> = split_lines(lines).map(|line| line.parse()).try_collect()?;
|
||||||
.map(|line| Instruction::parse(line))
|
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
|
||||||
let result = CpuCycles::draw(&instructions);
|
let result = CpuCycles::draw(&instructions);
|
||||||
Ok(ResultType::Lines(result))
|
Ok(ResultType::Lines(result))
|
||||||
}
|
}
|
||||||
|
|
@ -39,18 +35,18 @@ enum CpuError {
|
||||||
InvalidInteger(#[from] ParseIntError),
|
InvalidInteger(#[from] ParseIntError),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Instruction {
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
Add(i32),
|
struct Instruction(Option<i32>);
|
||||||
Noop,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Instruction {
|
impl FromStr for Instruction {
|
||||||
pub fn parse(line: &str) -> Result<Self, CpuError> {
|
type Err = CpuError;
|
||||||
|
|
||||||
|
fn from_str(line: &str) -> Result<Self, Self::Err> {
|
||||||
if line == "noop" {
|
if line == "noop" {
|
||||||
Ok(Instruction::Noop)
|
Ok(Instruction(None))
|
||||||
} else if line.starts_with("addx") {
|
} else if line.starts_with("addx") {
|
||||||
let value = line[5..].parse()?;
|
let value = line[5..].parse()?;
|
||||||
Ok(Instruction::Add(value))
|
Ok(Instruction(Some(value)))
|
||||||
} else {
|
} else {
|
||||||
Err(CpuError::UnknownInstruction(line.to_owned()))
|
Err(CpuError::UnknownInstruction(line.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
@ -114,10 +110,7 @@ impl<'a> Iterator for CpuCycles<'a> {
|
||||||
self.current = None;
|
self.current = None;
|
||||||
Some(start_register)
|
Some(start_register)
|
||||||
} else if let Some(instruction) = self.instructions.next() {
|
} else if let Some(instruction) = self.instructions.next() {
|
||||||
match instruction {
|
self.current = instruction.0;
|
||||||
Instruction::Add(value) => self.current = Some(*value),
|
|
||||||
Instruction::Noop => {}
|
|
||||||
}
|
|
||||||
Some(self.register)
|
Some(self.register)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -134,7 +127,11 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() -> Result<()> {
|
fn test_simple() -> Result<()> {
|
||||||
let instructions = vec![Instruction::Noop, Instruction::Add(3), Instruction::Add(-5)];
|
let instructions = vec![
|
||||||
|
Instruction(None),
|
||||||
|
Instruction(Some(3)),
|
||||||
|
Instruction(Some(-5)),
|
||||||
|
];
|
||||||
let expected = vec![1, 1, 1, 4, 4];
|
let expected = vec![1, 1, 1, 4, 4];
|
||||||
let result = CpuCycles::create(&instructions).collect::<Vec<_>>();
|
let result = CpuCycles::create(&instructions).collect::<Vec<_>>();
|
||||||
assert_eq!(result, expected);
|
assert_eq!(result, expected);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
|
use super::template::{DayTrait, ResultType};
|
||||||
use crate::common::parser::{
|
use crate::common::parser::{
|
||||||
empty_lines, eol_terminated, extract_result, ignore, trim0, trim_left1, true_false,
|
empty_lines, eol_terminated, extract_result, ignore, trim0, trim_left1, true_false,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::tag,
|
bytes::complete::tag,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
use std::collections::{BinaryHeap, HashSet};
|
|
||||||
|
|
||||||
use crate::common::{file::split_lines, pos::Pos};
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::{file::split_lines, pos::Pos};
|
||||||
|
use std::collections::{BinaryHeap, HashSet};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 12;
|
const DAY_NUMBER: usize = 12;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::split_lines;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 13;
|
const DAY_NUMBER: usize = 13;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::{file::split_lines, pos::Pos};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::{collections::HashSet, num::ParseIntError};
|
use std::{collections::HashSet, num::ParseIntError};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::common::{file::split_lines, pos::Pos};
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 14;
|
const DAY_NUMBER: usize = 14;
|
||||||
|
|
||||||
pub struct Day;
|
pub struct Day;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
use crate::common::parser::{eol_terminated, extract_result, ignore, trim0, trim1, trim_left1};
|
use crate::common::{
|
||||||
|
name::Name,
|
||||||
|
parser::{eol_terminated, extract_result, ignore, trim0, trim1, trim_left1},
|
||||||
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
|
|
@ -95,6 +98,7 @@ impl Mul<Flow> for Time {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
struct Flow(i64);
|
struct Flow(i64);
|
||||||
|
|
||||||
impl Deref for Flow {
|
impl Deref for Flow {
|
||||||
type Target = i64;
|
type Target = i64;
|
||||||
|
|
||||||
|
|
@ -208,7 +212,7 @@ impl<'a> TryFrom<&'a str> for RawValve<'a> {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Valve {
|
struct Valve {
|
||||||
id: String,
|
id: Name,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
flow: Flow,
|
flow: Flow,
|
||||||
distances: Vec<Time>,
|
distances: Vec<Time>,
|
||||||
|
|
@ -245,7 +249,7 @@ impl Valve {
|
||||||
distances.sort_unstable_by_key(|(id, _)| *id);
|
distances.sort_unstable_by_key(|(id, _)| *id);
|
||||||
|
|
||||||
Ok(Valve {
|
Ok(Valve {
|
||||||
id: valve.id.to_owned(),
|
id: valve.id.into(),
|
||||||
idx,
|
idx,
|
||||||
flow: valve.flow,
|
flow: valve.flow,
|
||||||
distances: distances
|
distances: distances
|
||||||
|
|
@ -257,7 +261,7 @@ impl Valve {
|
||||||
|
|
||||||
fn zero_flow(valve: &RawValve, idx: Index) -> Valve {
|
fn zero_flow(valve: &RawValve, idx: Index) -> Valve {
|
||||||
Valve {
|
Valve {
|
||||||
id: valve.id.to_owned(),
|
id: valve.id.into(),
|
||||||
idx,
|
idx,
|
||||||
flow: valve.flow,
|
flow: valve.flow,
|
||||||
distances: vec![],
|
distances: vec![],
|
||||||
|
|
@ -309,11 +313,12 @@ impl ValveSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn get_valve_by_id(&self, id: &str) -> Result<&Valve, ValveError> {
|
fn get_valve_by_id<N: Into<Name>>(&self, id: N) -> Result<&Valve, ValveError> {
|
||||||
|
let id = id.into();
|
||||||
self.valves
|
self.valves
|
||||||
.iter()
|
.iter()
|
||||||
.find(|valve| valve.id == id)
|
.find(|valve| valve.id == id)
|
||||||
.ok_or(ValveError::ValveNotFound(id.to_owned()))
|
.ok_or(ValveError::ValveNotFound(id.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_valve(&self, idx: Index) -> &Valve {
|
fn get_valve(&self, idx: Index) -> &Valve {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
use std::{cell::Cell, marker::PhantomData, ops::Index};
|
|
||||||
|
|
||||||
use crate::common::file::{read_string, split_lines};
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::{read_string, split_lines};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use std::{cell::Cell, marker::PhantomData, ops::Index};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 17;
|
const DAY_NUMBER: usize = 17;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
|
use super::template::{DayTrait, ResultType};
|
||||||
|
use crate::common::file::split_lines;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::{collections::HashSet, num::ParseIntError};
|
use std::{collections::HashSet, num::ParseIntError};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::common::file::split_lines;
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 18;
|
const DAY_NUMBER: usize = 18;
|
||||||
|
|
||||||
pub struct Day;
|
pub struct Day;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use std::{collections::HashMap, ops::Deref, rc::Rc, str::FromStr};
|
|
||||||
|
|
||||||
use super::template::{DayTrait, ResultType};
|
use super::template::{DayTrait, ResultType};
|
||||||
use crate::common::parser::{extract_result, ignore, trim0};
|
use crate::common::{
|
||||||
|
name::Name,
|
||||||
|
parser::{extract_result, ignore, trim0},
|
||||||
|
};
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
character::complete::{alpha1, char, i64, multispace0, one_of},
|
character::complete::{alpha1, char, i64, multispace0, one_of},
|
||||||
|
|
@ -10,6 +11,7 @@ use nom::{
|
||||||
sequence::{terminated, tuple},
|
sequence::{terminated, tuple},
|
||||||
Err, IResult, Parser,
|
Err, IResult, Parser,
|
||||||
};
|
};
|
||||||
|
use std::{collections::HashMap, str::FromStr};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const DAY_NUMBER: usize = 21;
|
const DAY_NUMBER: usize = 21;
|
||||||
|
|
@ -34,29 +36,6 @@ impl DayTrait for Day {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
|
||||||
struct Name(Rc<str>);
|
|
||||||
|
|
||||||
impl Name {
|
|
||||||
fn as_str(&self) -> &str {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Name {
|
|
||||||
type Target = str;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for Name {
|
|
||||||
fn from(value: &str) -> Self {
|
|
||||||
Self(Rc::from(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
enum MonkeyError {
|
enum MonkeyError {
|
||||||
#[error("Not a valid description: {0}")]
|
#[error("Not a valid description: {0}")]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue