some clippy warnings
This commit is contained in:
@@ -44,7 +44,7 @@ fn parse_input(input: &str) -> IResult<&str, Vec<(u64, u64)>> {
|
|||||||
input,
|
input,
|
||||||
time.iter()
|
time.iter()
|
||||||
.interleave(distance.iter())
|
.interleave(distance.iter())
|
||||||
.map(|x| *x)
|
.copied()
|
||||||
.tuples()
|
.tuples()
|
||||||
.collect(),
|
.collect(),
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ fn parse_input(input: &str) -> IResult<&str, (u64, u64)> {
|
|||||||
)(input)?;
|
)(input)?;
|
||||||
let distance = distance
|
let distance = distance
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| x.to_string())
|
.map(ToString::to_string)
|
||||||
.join("")
|
.join("")
|
||||||
.parse::<u64>()
|
.parse::<u64>()
|
||||||
.expect("is a number");
|
.expect("is a number");
|
||||||
let time = time
|
let time = time
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| x.to_string())
|
.map(ToString::to_string)
|
||||||
.join("")
|
.join("")
|
||||||
.parse::<u64>()
|
.parse::<u64>()
|
||||||
.expect("is a number");
|
.expect("is a number");
|
||||||
|
|||||||
@@ -70,13 +70,13 @@ impl From<&Card> for &u32 {
|
|||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
enum HandType {
|
enum HandType {
|
||||||
FiveOfAKind,
|
|
||||||
FourOfAKind,
|
|
||||||
FullHouse,
|
|
||||||
ThreeOfAKind,
|
|
||||||
TwoPair,
|
|
||||||
OnePair,
|
|
||||||
HighCard,
|
HighCard,
|
||||||
|
OnePair,
|
||||||
|
TwoPair,
|
||||||
|
ThreeOfAKind,
|
||||||
|
FullHouse,
|
||||||
|
FourOfAKind,
|
||||||
|
FiveOfAKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Hand> for HandType {
|
impl From<&Hand> for HandType {
|
||||||
@@ -105,16 +105,21 @@ impl From<&Hand> for HandType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Ord)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
struct Hand {
|
struct Hand {
|
||||||
pub cards: [Card; 5],
|
pub cards: [Card; 5],
|
||||||
pub bet: u32,
|
pub bet: u32,
|
||||||
}
|
}
|
||||||
impl PartialOrd for Hand {
|
impl PartialOrd for Hand {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Ord for Hand {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
let a = HandType::from(self);
|
let a = HandType::from(self);
|
||||||
let b = HandType::from(other);
|
let b = HandType::from(other);
|
||||||
let c = b.cmp(&a);
|
let c = a.cmp(&b);
|
||||||
match c {
|
match c {
|
||||||
Ordering::Equal => self
|
Ordering::Equal => self
|
||||||
.cards
|
.cards
|
||||||
@@ -122,23 +127,22 @@ impl PartialOrd for Hand {
|
|||||||
.interleave(other.cards.iter())
|
.interleave(other.cards.iter())
|
||||||
.tuples::<(_, _)>()
|
.tuples::<(_, _)>()
|
||||||
.find_map(|(a, b)| {
|
.find_map(|(a, b)| {
|
||||||
if b.cmp(a).is_ne() {
|
match a.cmp(b) {
|
||||||
Some(a.cmp(b))
|
Ordering::Equal => None,
|
||||||
} else {
|
x => Some(x)
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}),
|
}).unwrap_or(Ordering::Equal),
|
||||||
x => Some(x),
|
x => x,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn part1(_input: &str) -> String {
|
pub fn part1(input: &str) -> String {
|
||||||
let (_, mut hands) = parse_input(_input).expect("always valid input");
|
let (_, mut hands) = parse_input(input).expect("always valid input");
|
||||||
hands.sort();
|
hands.sort();
|
||||||
|
|
||||||
dbg!(hands)
|
hands
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, hand)| (i + 1) * hand.bet as usize)
|
.map(|(i, hand)| (i + 1) * hand.bet as usize)
|
||||||
@@ -178,4 +182,3 @@ QQQJA 483";
|
|||||||
assert_eq!(result, "6440".to_string());
|
assert_eq!(result, "6440".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,196 @@
|
|||||||
#![warn(clippy::all, clippy::pedantic)]
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
use itertools::Itertools;
|
||||||
|
use nom::{character::complete, multi::separated_list1, sequence::separated_pair, IResult};
|
||||||
|
use std::{
|
||||||
|
cmp::{Ord, Ordering, PartialOrd},
|
||||||
|
collections::BTreeMap,
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Day1Part2Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Ord, Eq, PartialEq, PartialOrd)]
|
||||||
|
enum Card {
|
||||||
|
Joker = 1,
|
||||||
|
Two,
|
||||||
|
Three,
|
||||||
|
Four,
|
||||||
|
Five,
|
||||||
|
Six,
|
||||||
|
Seven,
|
||||||
|
Eight,
|
||||||
|
Nine,
|
||||||
|
Ten,
|
||||||
|
Queen,
|
||||||
|
King,
|
||||||
|
Ace,
|
||||||
|
}
|
||||||
|
impl FromStr for Card {
|
||||||
|
type Err = Day1Part2Error;
|
||||||
|
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||||
|
match input {
|
||||||
|
"2" => Ok(Self::Two),
|
||||||
|
"3" => Ok(Self::Three),
|
||||||
|
"4" => Ok(Self::Four),
|
||||||
|
"5" => Ok(Self::Five),
|
||||||
|
"6" => Ok(Self::Six),
|
||||||
|
"7" => Ok(Self::Seven),
|
||||||
|
"8" => Ok(Self::Eight),
|
||||||
|
"9" => Ok(Self::Nine),
|
||||||
|
"T" => Ok(Self::Ten),
|
||||||
|
"J" => Ok(Self::Joker),
|
||||||
|
"Q" => Ok(Self::Queen),
|
||||||
|
"K" => Ok(Self::King),
|
||||||
|
"A" => Ok(Self::Ace),
|
||||||
|
_ => Err(Day1Part2Error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Card> for &u32 {
|
||||||
|
fn from(value: &Card) -> Self {
|
||||||
|
match value {
|
||||||
|
Card::Two => &2,
|
||||||
|
Card::Three => &3,
|
||||||
|
Card::Four => &4,
|
||||||
|
Card::Five => &5,
|
||||||
|
Card::Six => &6,
|
||||||
|
Card::Seven => &7,
|
||||||
|
Card::Eight => &8,
|
||||||
|
Card::Nine => &9,
|
||||||
|
Card::Ten => &10,
|
||||||
|
Card::Joker => &1,
|
||||||
|
Card::Queen => &12,
|
||||||
|
Card::King => &13,
|
||||||
|
Card::Ace => &14,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
|
enum HandType {
|
||||||
|
HighCard,
|
||||||
|
OnePair,
|
||||||
|
TwoPair,
|
||||||
|
ThreeOfAKind,
|
||||||
|
FullHouse,
|
||||||
|
FourOfAKind,
|
||||||
|
FiveOfAKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Hand> for HandType {
|
||||||
|
fn from(value: &Hand) -> Self {
|
||||||
|
let mut map = value.cards.iter().fold(BTreeMap::new(), |mut acc, card| {
|
||||||
|
if let Some(c) = acc.get_mut(card) {
|
||||||
|
*c += 1;
|
||||||
|
} else {
|
||||||
|
acc.insert(card, 1);
|
||||||
|
}
|
||||||
|
acc
|
||||||
|
});
|
||||||
|
let jokers = map.remove(&Card::Joker).unwrap_or(0);
|
||||||
|
match map
|
||||||
|
.iter()
|
||||||
|
.sorted_by(|a, b| b.1.cmp(a.1))
|
||||||
|
.collect::<Vec<_>>()[..]
|
||||||
|
{
|
||||||
|
[(_, x),..] if jokers + x == 5 => Self::FiveOfAKind,
|
||||||
|
[(_, x), ..] if jokers + x == 4 => Self::FourOfAKind,
|
||||||
|
[(_, 3), (_, 2)] => Self::FullHouse,
|
||||||
|
[(_, 2), (_, 2)] if jokers == 1 => Self::FullHouse,
|
||||||
|
[(_, x), ..] if jokers + x == 3 => Self::ThreeOfAKind,
|
||||||
|
[(_, 2), (_, 2), ..] => Self::TwoPair,
|
||||||
|
[(_, x), ..] if jokers + x == 2 => Self::OnePair,
|
||||||
|
_ => Self::HighCard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
struct Hand {
|
||||||
|
pub cards: [Card; 5],
|
||||||
|
pub bet: u32,
|
||||||
|
}
|
||||||
|
impl PartialOrd for Hand {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Ord for Hand {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
let a = HandType::from(self);
|
||||||
|
let b = HandType::from(other);
|
||||||
|
let c = a.cmp(&b);
|
||||||
|
match c {
|
||||||
|
Ordering::Equal => self
|
||||||
|
.cards
|
||||||
|
.iter()
|
||||||
|
.interleave(other.cards.iter())
|
||||||
|
.tuples::<(_, _)>()
|
||||||
|
.find_map(|(a, b)| {
|
||||||
|
match a.cmp(b) {
|
||||||
|
Ordering::Equal => None,
|
||||||
|
x => Some(x)
|
||||||
|
}
|
||||||
|
}).unwrap_or(Ordering::Equal),
|
||||||
|
x => x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn part2 (_input: &str) -> String {
|
pub fn part2(input: &str) -> String {
|
||||||
"Not Finished".to_string()
|
let (_, mut hands) = parse_input(input).expect("always valid input");
|
||||||
|
hands.sort();
|
||||||
|
|
||||||
|
hands
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, hand)| (i + 1) * hand.bet as usize)
|
||||||
|
.sum::<usize>()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_hand(input: &str) -> IResult<&str, Hand> {
|
||||||
|
let (input, (cards, bet)) =
|
||||||
|
separated_pair(complete::alphanumeric1, complete::space1, complete::u32)(input)?;
|
||||||
|
let cards = cards
|
||||||
|
.chars()
|
||||||
|
.filter_map(|c| c.to_string().parse().ok())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.try_into()
|
||||||
|
.expect("should work");
|
||||||
|
Ok((input, Hand { cards, bet }))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(input: &str) -> IResult<&str, Vec<Hand>> {
|
||||||
|
separated_list1(complete::line_ending, parse_hand)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const INPUT: &str = "";
|
#[test]
|
||||||
|
fn qtest() {
|
||||||
|
let a_str = "JKKK2 9";
|
||||||
|
let b_str = "QQQQ2 8";
|
||||||
|
let (_, a_hand) = parse_hand(a_str).expect("shoould parse a");
|
||||||
|
let (_, b_hand) = parse_hand(b_str).expect("should parse b");
|
||||||
|
let c = a_hand.cmp(&b_hand);
|
||||||
|
assert_eq!(c, Ordering::Less);
|
||||||
|
}
|
||||||
|
|
||||||
|
const INPUT: &str = "32T3K 765
|
||||||
|
T55J5 684
|
||||||
|
KK677 28
|
||||||
|
KTJJT 220
|
||||||
|
QQQJA 483";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part2_works() {
|
fn part2_works() {
|
||||||
let result = part2(INPUT);
|
let result = part2(INPUT);
|
||||||
assert_eq!(result, "Not Finished".to_string());
|
assert_eq!(result, "5905".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user