Implemented Day 7 part 1.

This commit is contained in:
Dennis Brentjes 2023-12-08 11:04:03 +01:00
parent 63ce6b5cf2
commit a19e839fe0
6 changed files with 1190 additions and 4 deletions

4
Cargo.lock generated
View File

@ -17,9 +17,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.7.11" version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
dependencies = [ dependencies = [
"either", "either",
] ]

View File

@ -6,4 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
itertools = "0.7.4" itertools = "0.12.0"

1000
resources/input7.txt Normal file

File diff suppressed because it is too large Load Diff

184
src/days/day7.rs Normal file
View File

@ -0,0 +1,184 @@
use std::{path::Path, str::FromStr};
use itertools::Itertools;
use crate::{error::AdventError, input::read_into_vec};
#[derive(Debug, Eq, PartialEq, Hash)]
struct Card(char);
impl PartialOrd for Card {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.strength().partial_cmp(&other.strength())
}
}
impl Ord for Card {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.strength().cmp(&other.strength())
}
}
impl Card {
fn strength(self: &Self) -> u32 {
match self.0 {
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'T' => 10,
'J' => 11,
'Q' => 12,
'K' => 13,
'A' => 14,
_ => panic!("Invalid card found")
}
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
enum HandType {
None,
HighCard,
OnePair,
TwoPair,
ThreeOfAKind,
FullHouse,
FourOfAKind,
FiveOfAKind,
}
#[derive(Debug, Eq)]
struct Hand {
cards: [Card;5],
hand_type: HandType,
}
impl PartialOrd for Hand {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match self.hand_type.partial_cmp(&other.hand_type) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
self.cards.partial_cmp(&other.cards)
}
}
impl Ord for Hand {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.hand_type.cmp(&other.hand_type)
}
}
impl PartialEq for Hand {
fn eq(&self, other: &Self) -> bool {
self.hand_type == other.hand_type
}
}
impl Hand {
fn new() -> Self {
Hand {
cards: [Card(' '), Card(' '), Card(' '), Card(' '), Card(' ')],
hand_type: HandType::None
}
}
fn determine_type(&mut self) -> () {
let counts = self.cards.iter().counts();
let value_counts = counts.iter().map(|c| { c.1 }).collect_vec();
self.hand_type = match (counts.len(), value_counts) {
(5, _) => HandType::HighCard,
(4, _) => HandType::OnePair,
(3, c) => {
if c.contains(&&3) {
HandType::ThreeOfAKind
} else {
HandType::TwoPair
}
}
(2, c) => {
if c.contains(&&4) {
HandType::FourOfAKind
} else {
HandType::FullHouse
}
}
(1, _) => HandType::FiveOfAKind,
(_, _) => panic!("Hand type match should never fail")
};
}
}
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)
}
}
#[derive(Debug, Eq)]
struct Line {
hand: Hand,
bid: u32,
}
impl PartialEq for Line {
fn eq(&self, other: &Self) -> bool {
self.hand == other.hand
}
}
impl PartialOrd for Line {
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 Line {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.hand.cmp(&other.hand)
}
}
impl FromStr for Line {
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 bid = split.nth(0).ok_or(AdventError("no score found".into()))?.parse::<u32>()?;
Ok(Line { hand, bid })
}
}
pub fn one() -> Result<u32, AdventError> {
let mut lines = read_into_vec::<Line>(Path::new("resources/input7.txt".into()))?;
lines.sort();
Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| {
acc + (rank as u32 + 1) * hand.bid
}))
}
pub fn two() -> Result<u32, AdventError> {
let mut lines = read_into_vec::<Line>(Path::new("resources/input7.txt".into()))?;
lines.sort();
Ok(0)
}

View File

@ -4,3 +4,4 @@ pub mod day3;
pub mod day4; pub mod day4;
pub mod day5; pub mod day5;
pub mod day6; pub mod day6;
pub mod day7;

View File

@ -17,6 +17,7 @@ fn main() -> Result<(), AdventError> {
(day4::one as fn() -> Result<u32, AdventError>, day4::two as fn() -> Result<u32, AdventError>), (day4::one as fn() -> Result<u32, AdventError>, day4::two as fn() -> Result<u32, AdventError>),
(day5::one as fn() -> Result<u32, AdventError>, day5::two as fn() -> Result<u32, AdventError>), (day5::one as fn() -> Result<u32, AdventError>, day5::two as fn() -> Result<u32, AdventError>),
(day6::one as fn() -> Result<u32, AdventError>, day6::two as fn() -> Result<u32, AdventError>), (day6::one as fn() -> Result<u32, AdventError>, day6::two as fn() -> Result<u32, AdventError>),
(day7::one as fn() -> Result<u32, AdventError>, day7::two as fn() -> Result<u32, AdventError>),
]; ];
if env::args().len() == 1 { if env::args().len() == 1 {