rustfmt 2023
This commit is contained in:
@@ -23,7 +23,10 @@ pub fn part1(input: &str) -> nom::IResult<&str, String> {
|
|||||||
"",
|
"",
|
||||||
values
|
values
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| v.first().expect("always at least one number") * 10 + v.last().expect("always atleast one number"))
|
.map(|v| {
|
||||||
|
v.first().expect("always at least one number") * 10
|
||||||
|
+ v.last().expect("always atleast one number")
|
||||||
|
})
|
||||||
.sum::<u32>()
|
.sum::<u32>()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ pub fn part2(input: &str) -> String {
|
|||||||
println!("{values:?}");
|
println!("{values:?}");
|
||||||
values
|
values
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| v.first().expect("There is always at least one number") * 10 + v.last().expect("there is always at least one number"))
|
.map(|v| {
|
||||||
|
v.first().expect("There is always at least one number") * 10
|
||||||
|
+ v.last().expect("there is always at least one number")
|
||||||
|
})
|
||||||
.sum::<u32>()
|
.sum::<u32>()
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
@@ -42,7 +45,11 @@ fn parse_line(line: &str) -> Vec<u32> {
|
|||||||
} else if reduced_line.starts_with("zero") {
|
} else if reduced_line.starts_with("zero") {
|
||||||
Some(0)
|
Some(0)
|
||||||
} else {
|
} else {
|
||||||
reduced_line.chars().next().expect("there is alwayss a character").to_digit(10)
|
reduced_line
|
||||||
|
.chars()
|
||||||
|
.next()
|
||||||
|
.expect("there is alwayss a character")
|
||||||
|
.to_digit(10)
|
||||||
};
|
};
|
||||||
|
|
||||||
result
|
result
|
||||||
|
|||||||
@@ -11,12 +11,7 @@
|
|||||||
pub fn part1(input: &str) -> String {
|
pub fn part1(input: &str) -> String {
|
||||||
input
|
input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|x| {
|
.map(|x| x.split(',').map(unhash).sum::<usize>().to_string())
|
||||||
x.split(',')
|
|
||||||
.map(unhash)
|
|
||||||
.sum::<usize>()
|
|
||||||
.to_string()
|
|
||||||
})
|
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#![warn(clippy::all, clippy::pedantic)]
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
|
||||||
use std::{
|
use std::collections::{HashMap, VecDeque};
|
||||||
collections::{HashMap, VecDeque},
|
|
||||||
};
|
|
||||||
|
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use pathfinding::prelude::dijkstra;
|
use pathfinding::prelude::dijkstra;
|
||||||
@@ -106,4 +104,3 @@ mod test {
|
|||||||
assert_eq!(result, "102".to_string());
|
assert_eq!(result, "102".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#![warn(clippy::all, clippy::pedantic)]
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
|
||||||
use std::{
|
use std::collections::{HashMap, VecDeque};
|
||||||
collections::{HashMap, VecDeque},
|
|
||||||
};
|
|
||||||
|
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use pathfinding::prelude::dijkstra;
|
use pathfinding::prelude::dijkstra;
|
||||||
@@ -46,7 +44,7 @@ pub fn part2(input: &str) -> String {
|
|||||||
//let b = (next_lasts[3] - next_lasts[2]).signum();
|
//let b = (next_lasts[3] - next_lasts[2]).signum();
|
||||||
//let c = next_lasts[4] - next_lasts[3]).signum();
|
//let c = next_lasts[4] - next_lasts[3]).signum();
|
||||||
|
|
||||||
if a == dir || a *-1 == dir{
|
if a == dir || a * -1 == dir {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
next_lasts.pop_back();
|
next_lasts.pop_back();
|
||||||
@@ -58,14 +56,26 @@ pub fn part2(input: &str) -> String {
|
|||||||
})
|
})
|
||||||
.map(|pos| {
|
.map(|pos| {
|
||||||
let range = pos.0 - pos.1[1];
|
let range = pos.0 - pos.1[1];
|
||||||
let total = if range.x == 0 && range.y > 0 {
|
let total = if range.x == 0 && range.y > 0 {
|
||||||
(0..range.y).map(|y| pos.0 - IVec2::new(0,y)).map(|v| grid.get(&v).unwrap()).sum::<u32>()
|
(0..range.y)
|
||||||
|
.map(|y| pos.0 - IVec2::new(0, y))
|
||||||
|
.map(|v| grid.get(&v).unwrap())
|
||||||
|
.sum::<u32>()
|
||||||
} else if range.x == 0 && range.y < 0 {
|
} else if range.x == 0 && range.y < 0 {
|
||||||
(range.y+1..=0).map(|y| pos.0 - IVec2::new(0,y)).map(|v| grid.get(&v).unwrap()).sum::<u32>()
|
(range.y + 1..=0)
|
||||||
|
.map(|y| pos.0 - IVec2::new(0, y))
|
||||||
|
.map(|v| grid.get(&v).unwrap())
|
||||||
|
.sum::<u32>()
|
||||||
} else if range.y == 0 && range.x > 0 {
|
} else if range.y == 0 && range.x > 0 {
|
||||||
(0..range.x).map(|x| pos.0 - IVec2::new(x,0)).map(|v| grid.get(&v).unwrap()).sum::<u32>()
|
(0..range.x)
|
||||||
|
.map(|x| pos.0 - IVec2::new(x, 0))
|
||||||
|
.map(|v| grid.get(&v).unwrap())
|
||||||
|
.sum::<u32>()
|
||||||
} else {
|
} else {
|
||||||
(range.x+1..=0).map(|x| pos.0 - IVec2::new(x,0)).map(|v| grid.get(&v).unwrap()).sum::<u32>()
|
(range.x + 1..=0)
|
||||||
|
.map(|x| pos.0 - IVec2::new(x, 0))
|
||||||
|
.map(|v| grid.get(&v).unwrap())
|
||||||
|
.sum::<u32>()
|
||||||
};
|
};
|
||||||
(pos, total)
|
(pos, total)
|
||||||
})
|
})
|
||||||
@@ -103,7 +113,8 @@ mod test {
|
|||||||
use rstest::rstest;
|
use rstest::rstest;
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case("2413432311323
|
#[case(
|
||||||
|
"2413432311323
|
||||||
3215453535623
|
3215453535623
|
||||||
3255245654254
|
3255245654254
|
||||||
3446585845452
|
3446585845452
|
||||||
@@ -115,15 +126,19 @@ mod test {
|
|||||||
4564679986453
|
4564679986453
|
||||||
1224686865563
|
1224686865563
|
||||||
2546548887735
|
2546548887735
|
||||||
4322674655533", "94")]
|
4322674655533",
|
||||||
#[case("111111111111
|
"94"
|
||||||
|
)]
|
||||||
|
#[case(
|
||||||
|
"111111111111
|
||||||
999999999991
|
999999999991
|
||||||
999999999991
|
999999999991
|
||||||
999999999991
|
999999999991
|
||||||
999999999991", "71")]
|
999999999991",
|
||||||
|
"71"
|
||||||
|
)]
|
||||||
fn part2_works(#[case] input: &str, #[case] expected: &str) {
|
fn part2_works(#[case] input: &str, #[case] expected: &str) {
|
||||||
let result = part2(input);
|
let result = part2(input);
|
||||||
assert_eq!(result, expected);
|
assert_eq!(result, expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use petgraph::{prelude::*, algo};
|
use petgraph::{algo, prelude::*};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum PointType {
|
enum PointType {
|
||||||
@@ -32,21 +31,44 @@ pub fn part1(input: &str) -> String {
|
|||||||
let maze = parse_input(input);
|
let maze = parse_input(input);
|
||||||
//get the start position (assuming there is only one)
|
//get the start position (assuming there is only one)
|
||||||
let start = *maze.keys().find(|pos| pos.y == 0).unwrap();
|
let start = *maze.keys().find(|pos| pos.y == 0).unwrap();
|
||||||
let end = maze.keys().fold(IVec2::splat(0), | max, current| if max.y.max(current.y) == current.y { *current } else {max});
|
let end = maze.keys().fold(IVec2::splat(0), |max, current| {
|
||||||
let mut maze_graph = DiGraph::<&PointType, u32>::new();
|
if max.y.max(current.y) == current.y {
|
||||||
let node_map = maze.iter().map(|(pos, point_type)| (pos, maze_graph.add_node(point_type)) ).collect::<HashMap<_,_>>();
|
*current
|
||||||
|
} else {
|
||||||
maze.iter().flat_map(|(pos, point_type)| {
|
max
|
||||||
point_type.next_possibles().iter().copied().filter_map(|dir| {
|
}
|
||||||
let next_pos = dir + *pos;
|
|
||||||
node_map.get(&next_pos).is_some().then(|| (node_map[pos], node_map[&next_pos], 1))
|
|
||||||
}).collect::<Vec<_>>()
|
|
||||||
})
|
|
||||||
.for_each(|(a, b, weight)| {
|
|
||||||
maze_graph.add_edge(a,b,weight);
|
|
||||||
});
|
});
|
||||||
|
let mut maze_graph = DiGraph::<&PointType, u32>::new();
|
||||||
|
let node_map = maze
|
||||||
|
.iter()
|
||||||
|
.map(|(pos, point_type)| (pos, maze_graph.add_node(point_type)))
|
||||||
|
.collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
(algo::all_simple_paths::<Vec<_>,_>(&maze_graph, node_map[&start], node_map[&end], 0, None).max_by(|a, b| a.len().cmp(&b.len())).unwrap().len() -1).to_string()
|
maze.iter()
|
||||||
|
.flat_map(|(pos, point_type)| {
|
||||||
|
point_type
|
||||||
|
.next_possibles()
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter_map(|dir| {
|
||||||
|
let next_pos = dir + *pos;
|
||||||
|
node_map
|
||||||
|
.get(&next_pos)
|
||||||
|
.is_some()
|
||||||
|
.then(|| (node_map[pos], node_map[&next_pos], 1))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.for_each(|(a, b, weight)| {
|
||||||
|
maze_graph.add_edge(a, b, weight);
|
||||||
|
});
|
||||||
|
|
||||||
|
(algo::all_simple_paths::<Vec<_>, _>(&maze_graph, node_map[&start], node_map[&end], 0, None)
|
||||||
|
.max_by(|a, b| a.len().cmp(&b.len()))
|
||||||
|
.unwrap()
|
||||||
|
.len()
|
||||||
|
- 1)
|
||||||
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_input(input: &str) -> HashMap<IVec2, PointType> {
|
fn parse_input(input: &str) -> HashMap<IVec2, PointType> {
|
||||||
@@ -103,5 +125,3 @@ mod test {
|
|||||||
assert_eq!(result, "94".to_string());
|
assert_eq!(result, "94".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use petgraph::{prelude::*, algo};
|
use petgraph::{algo, prelude::*};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum PointType {
|
enum PointType {
|
||||||
@@ -28,21 +27,44 @@ pub fn part2(input: &str) -> String {
|
|||||||
let maze = parse_input(input);
|
let maze = parse_input(input);
|
||||||
//get the start position (assuming there is only one)
|
//get the start position (assuming there is only one)
|
||||||
let start = *maze.keys().find(|pos| pos.y == 0).unwrap();
|
let start = *maze.keys().find(|pos| pos.y == 0).unwrap();
|
||||||
let end = maze.keys().fold(IVec2::splat(0), | max, current| if max.y.max(current.y) == current.y { *current } else {max});
|
let end = maze.keys().fold(IVec2::splat(0), |max, current| {
|
||||||
let mut maze_graph = DiGraph::<&PointType, u32>::new();
|
if max.y.max(current.y) == current.y {
|
||||||
let node_map = maze.iter().map(|(pos, point_type)| (pos, maze_graph.add_node(point_type)) ).collect::<HashMap<_,_>>();
|
*current
|
||||||
|
} else {
|
||||||
maze.iter().flat_map(|(pos, point_type)| {
|
max
|
||||||
point_type.next_possibles().iter().copied().filter_map(|dir| {
|
}
|
||||||
let next_pos = dir + *pos;
|
|
||||||
node_map.get(&next_pos).is_some().then(|| (node_map[pos], node_map[&next_pos], 1))
|
|
||||||
}).collect::<Vec<_>>()
|
|
||||||
})
|
|
||||||
.for_each(|(a, b, weight)| {
|
|
||||||
maze_graph.add_edge(a,b,weight);
|
|
||||||
});
|
});
|
||||||
|
let mut maze_graph = DiGraph::<&PointType, u32>::new();
|
||||||
|
let node_map = maze
|
||||||
|
.iter()
|
||||||
|
.map(|(pos, point_type)| (pos, maze_graph.add_node(point_type)))
|
||||||
|
.collect::<HashMap<_, _>>();
|
||||||
|
|
||||||
(algo::all_simple_paths::<Vec<_>,_>(&maze_graph, node_map[&start], node_map[&end], 0, None).max_by(|a, b| a.len().cmp(&b.len())).unwrap().len() -1).to_string()
|
maze.iter()
|
||||||
|
.flat_map(|(pos, point_type)| {
|
||||||
|
point_type
|
||||||
|
.next_possibles()
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter_map(|dir| {
|
||||||
|
let next_pos = dir + *pos;
|
||||||
|
node_map
|
||||||
|
.get(&next_pos)
|
||||||
|
.is_some()
|
||||||
|
.then(|| (node_map[pos], node_map[&next_pos], 1))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.for_each(|(a, b, weight)| {
|
||||||
|
maze_graph.add_edge(a, b, weight);
|
||||||
|
});
|
||||||
|
|
||||||
|
(algo::all_simple_paths::<Vec<_>, _>(&maze_graph, node_map[&start], node_map[&end], 0, None)
|
||||||
|
.max_by(|a, b| a.len().cmp(&b.len()))
|
||||||
|
.unwrap()
|
||||||
|
.len()
|
||||||
|
- 1)
|
||||||
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_input(input: &str) -> HashMap<IVec2, PointType> {
|
fn parse_input(input: &str) -> HashMap<IVec2, PointType> {
|
||||||
@@ -99,5 +121,3 @@ mod test {
|
|||||||
assert_eq!(result, "154".to_string());
|
assert_eq!(result, "154".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ mod test {
|
|||||||
let (input, card) = parse_card(line).expect("card should be parsed");
|
let (input, card) = parse_card(line).expect("card should be parsed");
|
||||||
assert_eq!(input, "");
|
assert_eq!(input, "");
|
||||||
assert_eq!(card.get_score(), expected);
|
assert_eq!(card.get_score(), expected);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const INPUT: &str = "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
|
const INPUT: &str = "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#![warn(clippy::all, clippy::pedantic)]
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use nom::{character::complete, multi::separated_list1, sequence::separated_pair, IResult};
|
use nom::{character::complete, multi::separated_list1, sequence::separated_pair, IResult};
|
||||||
|
use std::fmt;
|
||||||
use std::{
|
use std::{
|
||||||
cmp::{Ord, Ordering, PartialOrd},
|
cmp::{Ord, Ordering, PartialOrd},
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Day1Part2Error;
|
struct Day1Part2Error;
|
||||||
@@ -70,20 +70,20 @@ impl From<&Card> for &u32 {
|
|||||||
}
|
}
|
||||||
impl fmt::Display for Card {
|
impl fmt::Display for Card {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let c = match self {
|
let c = match self {
|
||||||
Card::Joker => 'J',
|
Card::Joker => 'J',
|
||||||
Card::Two => '2',
|
Card::Two => '2',
|
||||||
Card::Three => '3',
|
Card::Three => '3',
|
||||||
Card::Four => '4',
|
Card::Four => '4',
|
||||||
Card::Five => '5',
|
Card::Five => '5',
|
||||||
Card::Six => '6',
|
Card::Six => '6',
|
||||||
Card::Seven => '7',
|
Card::Seven => '7',
|
||||||
Card::Eight => '8',
|
Card::Eight => '8',
|
||||||
Card::Nine => '9',
|
Card::Nine => '9',
|
||||||
Card::Ten => 'T',
|
Card::Ten => 'T',
|
||||||
Card::Queen => 'Q',
|
Card::Queen => 'Q',
|
||||||
Card::King => 'K',
|
Card::King => 'K',
|
||||||
Card::Ace => 'A',
|
Card::Ace => 'A',
|
||||||
};
|
};
|
||||||
write!(f, "{c}")
|
write!(f, "{c}")
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ impl From<&Hand> for HandType {
|
|||||||
.collect::<Vec<_>>()[..]
|
.collect::<Vec<_>>()[..]
|
||||||
{
|
{
|
||||||
[(_, x), ..] if jokers + x == 5 => Self::FiveOfAKind,
|
[(_, x), ..] if jokers + x == 5 => Self::FiveOfAKind,
|
||||||
[] if jokers == 5 => Self::FiveOfAKind,
|
[] if jokers == 5 => Self::FiveOfAKind,
|
||||||
[(_, x), ..] if jokers + x == 4 => Self::FourOfAKind,
|
[(_, x), ..] if jokers + x == 4 => Self::FourOfAKind,
|
||||||
[(_, 3), (_, 2)] => Self::FullHouse,
|
[(_, 3), (_, 2)] => Self::FullHouse,
|
||||||
[(_, 2), (_, 2)] if jokers == 1 => Self::FullHouse,
|
[(_, 2), (_, 2)] if jokers == 1 => Self::FullHouse,
|
||||||
|
|||||||
@@ -59,4 +59,3 @@ mod test {
|
|||||||
assert_eq!(result, "114".to_string());
|
assert_eq!(result, "114".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,4 +61,3 @@ mod test {
|
|||||||
assert_eq!(result, "2".to_string());
|
assert_eq!(result, "2".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user