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 itertools::Itertools;
|
||||||
|
|
||||||
|
use::std::hash::Hash;
|
||||||
|
|
||||||
use crate::{error::AdventError, input::read_into_vec};
|
use crate::{error::AdventError, input::read_into_vec};
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
#[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> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
self.strength().partial_cmp(&other.strength())
|
self.strength().partial_cmp(&other.strength())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ord for Card {
|
impl Ord for dyn Card {
|
||||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
self.strength().cmp(&other.strength())
|
self.strength().cmp(&other.strength())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Card {
|
impl Card for CardOne {
|
||||||
fn strength(self: &Self) -> u32 {
|
fn strength(self: &Self) -> u32 {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
'2' => 2,
|
'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)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
enum HandType {
|
enum HandType {
|
||||||
None,
|
None,
|
||||||
@ -52,43 +103,127 @@ enum HandType {
|
|||||||
FiveOfAKind,
|
FiveOfAKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
struct Hand {
|
struct HandOne {
|
||||||
cards: [Card;5],
|
|
||||||
hand_type: HandType,
|
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> {
|
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) => {}
|
Some(core::cmp::Ordering::Equal) => {}
|
||||||
ord => return ord,
|
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 {
|
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 {
|
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 {
|
fn new() -> Self {
|
||||||
Hand {
|
Self {
|
||||||
cards: [Card(' '), Card(' '), Card(' '), Card(' '), Card(' ')],
|
cards: [
|
||||||
|
Box::new(CardOne(' ')),
|
||||||
|
Box::new(CardOne(' ')),
|
||||||
|
Box::new(CardOne(' ')),
|
||||||
|
Box::new(CardOne(' ')),
|
||||||
|
Box::new(CardOne(' '))
|
||||||
|
],
|
||||||
hand_type: HandType::None
|
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) -> () {
|
fn determine_type(&mut self) -> () {
|
||||||
let counts = self.cards.iter().counts();
|
let counts = self.cards.iter().counts();
|
||||||
let value_counts = counts.iter().map(|c| { c.1 }).collect_vec();
|
let value_counts = counts.iter().map(|c| { c.1 }).collect_vec();
|
||||||
@ -113,36 +248,41 @@ impl Hand {
|
|||||||
(_, _) => panic!("Hand type match should never fail")
|
(_, _) => 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)]
|
#[derive(Eq)]
|
||||||
struct Line {
|
struct LineOne {
|
||||||
hand: Hand,
|
hand: Box<dyn Hand>,
|
||||||
bid: u32,
|
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 {
|
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> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
match self.hand.partial_cmp(&other.hand) {
|
match self.hand.partial_cmp(&other.hand) {
|
||||||
Some(core::cmp::Ordering::Equal) => {}
|
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 {
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
self.hand.cmp(&other.hand)
|
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;
|
type Err = AdventError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let mut split = s.trim().split_ascii_whitespace();
|
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>()?;
|
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> {
|
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();
|
lines.sort();
|
||||||
Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| {
|
Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| {
|
||||||
acc + (rank as u32 + 1) * hand.bid
|
acc + (rank as u32 + 1) * hand.bid
|
||||||
@ -178,7 +345,7 @@ pub fn one() -> Result<u32, AdventError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn two() -> 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();
|
lines.sort();
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user