Implemented Day 7 part 1.
This commit is contained in:
parent
63ce6b5cf2
commit
a19e839fe0
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -17,9 +17,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.7.11"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d"
|
||||
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
@ -6,4 +6,4 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
itertools = "0.7.4"
|
||||
itertools = "0.12.0"
|
||||
|
1000
resources/input7.txt
Normal file
1000
resources/input7.txt
Normal file
File diff suppressed because it is too large
Load Diff
184
src/days/day7.rs
Normal file
184
src/days/day7.rs
Normal 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)
|
||||
}
|
@ -4,3 +4,4 @@ pub mod day3;
|
||||
pub mod day4;
|
||||
pub mod day5;
|
||||
pub mod day6;
|
||||
pub mod day7;
|
@ -17,6 +17,7 @@ fn main() -> Result<(), 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>),
|
||||
(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 {
|
||||
|
Loading…
Reference in New Issue
Block a user