Day7 part1
This commit is contained in:
parent
6489efa279
commit
d0a7ddea55
16
day7/Cargo.lock
generated
Normal file
16
day7/Cargo.lock
generated
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day7"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
]
|
9
day7/Cargo.toml
Normal file
9
day7/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "day7"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.75"
|
1000
day7/input
Normal file
1000
day7/input
Normal file
File diff suppressed because it is too large
Load Diff
132
day7/src/main.rs
Normal file
132
day7/src/main.rs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
use std::{fmt::Display, io::stdin, str::FromStr};
|
||||||
|
use anyhow::{anyhow, Result, Error};
|
||||||
|
|
||||||
|
#[derive(Debug,Clone,Copy,Eq,PartialEq)]
|
||||||
|
struct Card(char);
|
||||||
|
|
||||||
|
#[derive(Debug,Clone,Copy,Eq,PartialEq)]
|
||||||
|
struct Hand([Card; 5]);
|
||||||
|
|
||||||
|
#[derive(Debug,Clone,Copy,Eq,PartialEq,Ord,PartialOrd)]
|
||||||
|
enum Suit {
|
||||||
|
HighCard,
|
||||||
|
OnePair,
|
||||||
|
TwoPairs,
|
||||||
|
Three,
|
||||||
|
Full,
|
||||||
|
Four,
|
||||||
|
Five,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Card {
|
||||||
|
|
||||||
|
fn new(c: char) -> Result<Self> {
|
||||||
|
match c {
|
||||||
|
'A'|'K'|'Q'|'J'|'T'|'2'..='9' => Ok(Self(c)),
|
||||||
|
_ => Err(anyhow!("invalid card {c:?}"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value(self) -> usize {
|
||||||
|
match self.0 {
|
||||||
|
'A' => 14,
|
||||||
|
'K' => 13,
|
||||||
|
'Q' => 12,
|
||||||
|
'J' => 11,
|
||||||
|
'T' => 10,
|
||||||
|
'2'..='9' => char::to_digit(self.0, 10).unwrap() as usize,
|
||||||
|
_ => panic!("invalid card"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Card {
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
self.value().cmp(&other.value())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Card {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
Some(self.0.cmp(&other.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Card {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.0.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hand {
|
||||||
|
fn suit(&self) -> Suit {
|
||||||
|
let mut cache = [0; 16];
|
||||||
|
let mut counts = [0; 5];
|
||||||
|
for v in self.0 {
|
||||||
|
cache[v.value()] += 1;
|
||||||
|
}
|
||||||
|
for c in cache {
|
||||||
|
if c > 0 { counts[c-1] += 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
match counts {
|
||||||
|
[_,_,_,_,1] => Suit::Five,
|
||||||
|
[_,_,_,1,_] => Suit::Four,
|
||||||
|
[_,1,1,_,_] => Suit::Full,
|
||||||
|
[_,_,1,_,_] => Suit::Three,
|
||||||
|
[_,2,_,_,_] => Suit::TwoPairs,
|
||||||
|
[_,1,_,_,_] => Suit::OnePair,
|
||||||
|
_ => Suit::HighCard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Hand {
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
self.suit().cmp(&other.suit())
|
||||||
|
.then_with(|| self.0.cmp(&other.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Hand {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
Some(self.cmp(&other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Hand {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
if s.len() != 5 { return Err(anyhow!("Invalid hand {s}")) }
|
||||||
|
let c = s.chars().map(Card::new)
|
||||||
|
.collect::<Result<Vec<_>>>()?;
|
||||||
|
|
||||||
|
Ok(Self([c[0], c[1], c[2], c[3], c[4]]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
|
||||||
|
let mut data: Vec<(Hand, usize)> = stdin()
|
||||||
|
.lines()
|
||||||
|
.map(|l| -> Result<(Hand,usize)> {
|
||||||
|
let l = l?;
|
||||||
|
let (hand, bet) = l.split_once(' ')
|
||||||
|
.ok_or_else(|| anyhow!("bad line {l:?}"))?;
|
||||||
|
Ok((hand.parse()?, bet.parse()?))
|
||||||
|
})
|
||||||
|
.collect::<Result<_>>()?;
|
||||||
|
|
||||||
|
data.sort_by(|a,b| a.0.cmp(&b.0));
|
||||||
|
|
||||||
|
let total: usize = data.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(rank, (_,bid))| bid*(rank+1) )
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
println!("Part 1: total winnings {total}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user