Attempt at day7 part 2
This commit is contained in:
parent
a19e839fe0
commit
cacc884cf1
249
src/days/day7.rs
249
src/days/day7.rs
@ -2,24 +2,52 @@ use std::{path::Path, str::FromStr};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use::std::hash::Hash;
|
||||
|
||||
use crate::{error::AdventError, input::read_into_vec};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
struct Card(char);
|
||||
struct CardOne(char);
|
||||
|
||||
impl PartialOrd for Card {
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
enum CardTwo {
|
||||
Card(char),
|
||||
Joker,
|
||||
}
|
||||
|
||||
trait Card {
|
||||
fn strength(self: &Self) -> u32;
|
||||
}
|
||||
|
||||
impl Hash for dyn Card {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.strength().hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for dyn Card {
|
||||
|
||||
}
|
||||
|
||||
impl PartialEq for dyn Card {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.strength().eq(&other.strength())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for dyn Card {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
self.strength().partial_cmp(&other.strength())
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Card {
|
||||
impl Ord for dyn Card {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.strength().cmp(&other.strength())
|
||||
}
|
||||
}
|
||||
|
||||
impl Card {
|
||||
impl Card for CardOne {
|
||||
fn strength(self: &Self) -> u32 {
|
||||
match self.0 {
|
||||
'2' => 2,
|
||||
@ -40,6 +68,29 @@ impl Card {
|
||||
}
|
||||
}
|
||||
|
||||
impl Card for CardTwo {
|
||||
fn strength(self: &Self) -> u32 {
|
||||
match self {
|
||||
Self::Card(c) => match c {
|
||||
'2' => 2,
|
||||
'3' => 3,
|
||||
'4' => 4,
|
||||
'5' => 5,
|
||||
'6' => 6,
|
||||
'7' => 7,
|
||||
'8' => 8,
|
||||
'9' => 9,
|
||||
'T' => 10,
|
||||
'Q' => 12,
|
||||
'K' => 13,
|
||||
'A' => 14,
|
||||
_ => panic!("Invalid card found")
|
||||
},
|
||||
Self::Joker => 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum HandType {
|
||||
None,
|
||||
@ -52,43 +103,127 @@ enum HandType {
|
||||
FiveOfAKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
struct Hand {
|
||||
cards: [Card;5],
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct HandOne {
|
||||
hand_type: HandType,
|
||||
cards: [Box<dyn Card>;5],
|
||||
|
||||
}
|
||||
|
||||
impl PartialOrd for Hand {
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct HandTwo {
|
||||
hand_type: HandType,
|
||||
cards: [Box<dyn Card>;5]
|
||||
}
|
||||
|
||||
impl HandTwo {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
cards: [
|
||||
Box::new(CardTwo::Card(' ')),
|
||||
Box::new(CardTwo::Card(' ')),
|
||||
Box::new(CardTwo::Card(' ')),
|
||||
Box::new(CardTwo::Card(' ')),
|
||||
Box::new(CardTwo::Card(' '))
|
||||
],
|
||||
hand_type: HandType::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hand for HandTwo {
|
||||
fn determine_type(&mut self) -> () {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_hand_type(&self) -> &HandType {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_cards(&self) -> &[Box<dyn Card>;5] {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
trait Hand {
|
||||
fn determine_type(&mut self) -> ();
|
||||
|
||||
fn get_hand_type(&self) -> &HandType;
|
||||
fn get_cards(&self) -> &[Box<dyn Card>;5];
|
||||
}
|
||||
|
||||
impl PartialOrd for dyn Hand {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
match self.hand_type.partial_cmp(&other.hand_type) {
|
||||
match self.get_hand_type().partial_cmp(&other.get_hand_type()) {
|
||||
Some(core::cmp::Ordering::Equal) => {}
|
||||
ord => return ord,
|
||||
}
|
||||
|
||||
self.cards.partial_cmp(&other.cards)
|
||||
self.get_cards().partial_cmp(&other.get_cards())
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Hand {
|
||||
impl Eq for dyn Hand {
|
||||
|
||||
}
|
||||
|
||||
impl Ord for dyn Hand {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.hand_type.cmp(&other.hand_type)
|
||||
self.get_hand_type().cmp(&other.get_hand_type())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Hand {
|
||||
impl PartialEq for dyn Hand {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.hand_type == other.hand_type
|
||||
self.get_hand_type() == other.get_hand_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl Hand {
|
||||
impl HandOne {
|
||||
fn new() -> Self {
|
||||
Hand {
|
||||
cards: [Card(' '), Card(' '), Card(' '), Card(' '), Card(' ')],
|
||||
Self {
|
||||
cards: [
|
||||
Box::new(CardOne(' ')),
|
||||
Box::new(CardOne(' ')),
|
||||
Box::new(CardOne(' ')),
|
||||
Box::new(CardOne(' ')),
|
||||
Box::new(CardOne(' '))
|
||||
],
|
||||
hand_type: HandType::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for HandOne {
|
||||
type Err = AdventError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut hand = HandOne::new();
|
||||
for i in 0..s.len() {
|
||||
hand.cards[i] = Box::new(CardOne(s.chars().nth(i).ok_or(AdventError("Couldn't convert into Card".into()))?));
|
||||
}
|
||||
hand.determine_type();
|
||||
Ok(hand)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for HandTwo {
|
||||
type Err = AdventError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut hand = HandTwo::new();
|
||||
for i in 0..s.len() {
|
||||
hand.cards[i] = Box::new(match s.chars().nth(i).ok_or(AdventError("Couldn't convert into Card".into()))? {
|
||||
'J' => CardTwo::Joker,
|
||||
c => CardTwo::Card(c),
|
||||
});
|
||||
};
|
||||
hand.determine_type();
|
||||
Ok(hand)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hand for HandOne {
|
||||
fn determine_type(&mut self) -> () {
|
||||
let counts = self.cards.iter().counts();
|
||||
let value_counts = counts.iter().map(|c| { c.1 }).collect_vec();
|
||||
@ -113,36 +248,41 @@ impl Hand {
|
||||
(_, _) => panic!("Hand type match should never fail")
|
||||
};
|
||||
}
|
||||
|
||||
fn get_hand_type(&self) -> &HandType {
|
||||
&self.hand_type
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl FromStr for Hand {
|
||||
type Err = AdventError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut hand: Hand = Hand::new();
|
||||
for i in 0..s.len() {
|
||||
hand.cards[i] = Card(s.chars().nth(i).ok_or(AdventError("Couldn't convert into Card".into()))?);
|
||||
hand.determine_type();
|
||||
}
|
||||
Ok(hand)
|
||||
fn get_cards(&self) -> &[Box<dyn Card>;5] {
|
||||
&self.cards
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
struct Line {
|
||||
hand: Hand,
|
||||
#[derive(Eq)]
|
||||
struct LineOne {
|
||||
hand: Box<dyn Hand>,
|
||||
bid: u32,
|
||||
}
|
||||
|
||||
impl PartialEq for Line {
|
||||
#[derive(Eq)]
|
||||
struct LineTwo {
|
||||
hand: Box<dyn Hand>,
|
||||
bid: u32,
|
||||
}
|
||||
|
||||
impl PartialEq for LineOne {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.hand == other.hand
|
||||
self.hand.as_ref() == other.hand.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Line {
|
||||
impl PartialEq for LineTwo {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.hand.as_ref() == other.hand.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for LineOne {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
match self.hand.partial_cmp(&other.hand) {
|
||||
Some(core::cmp::Ordering::Equal) => {}
|
||||
@ -152,25 +292,52 @@ impl PartialOrd for Line {
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Line {
|
||||
impl PartialOrd for LineTwo {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
match self.hand.partial_cmp(&other.hand) {
|
||||
Some(core::cmp::Ordering::Equal) => {}
|
||||
ord => return ord,
|
||||
}
|
||||
self.bid.partial_cmp(&other.bid)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for LineOne {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.hand.cmp(&other.hand)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Line {
|
||||
impl Ord for LineTwo {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.hand.cmp(&other.hand)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for LineOne {
|
||||
type Err = AdventError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut split = s.trim().split_ascii_whitespace();
|
||||
let hand = Hand::from_str(split.nth(0).ok_or(AdventError("no hand found".into()))?)?;
|
||||
let hand = Box::new(HandOne::from_str(split.nth(0).ok_or(AdventError("no hand found".into()))?)?);
|
||||
let bid = split.nth(0).ok_or(AdventError("no score found".into()))?.parse::<u32>()?;
|
||||
Ok(Line { hand, bid })
|
||||
Ok(Self { hand, bid })
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for LineTwo {
|
||||
type Err = AdventError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut split = s.trim().split_ascii_whitespace();
|
||||
let hand = Box::new(HandTwo::from_str(split.nth(0).ok_or(AdventError("no hand found".into()))?)?);
|
||||
let bid = split.nth(0).ok_or(AdventError("no score found".into()))?.parse::<u32>()?;
|
||||
Ok(Self { hand, bid })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn one() -> Result<u32, AdventError> {
|
||||
let mut lines = read_into_vec::<Line>(Path::new("resources/input7.txt".into()))?;
|
||||
let mut lines = read_into_vec::<LineOne>(Path::new("resources/input7.txt".into()))?;
|
||||
lines.sort();
|
||||
Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| {
|
||||
acc + (rank as u32 + 1) * hand.bid
|
||||
@ -178,7 +345,7 @@ pub fn one() -> Result<u32, AdventError> {
|
||||
}
|
||||
|
||||
pub fn two() -> Result<u32, AdventError> {
|
||||
let mut lines = read_into_vec::<Line>(Path::new("resources/input7.txt".into()))?;
|
||||
let mut lines = read_into_vec::<LineTwo>(Path::new("resources/input7.txt".into()))?;
|
||||
lines.sort();
|
||||
Ok(0)
|
||||
}
|
Loading…
Reference in New Issue
Block a user