mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-14 09:35:01 +01:00
d7p1
This commit is contained in:
parent
5a4ca1c2a1
commit
45d6814aa8
7 changed files with 1198 additions and 0 deletions
15
2023/day07/Cargo.toml
Normal file
15
2023/day07/Cargo.toml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "day07"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nom.workspace = true
|
||||
helper.workspace = true
|
||||
divan.workspace = true
|
||||
|
||||
[[bench]]
|
||||
name = "benches"
|
||||
harness = false
|
||||
3
2023/day07/benches/benches.rs
Normal file
3
2023/day07/benches/benches.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
day07::bench();
|
||||
}
|
||||
1000
2023/day07/input.txt
Normal file
1000
2023/day07/input.txt
Normal file
File diff suppressed because it is too large
Load diff
5
2023/day07/input_small.txt
Normal file
5
2023/day07/input_small.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483
|
||||
163
2023/day07/src/lib.rs
Normal file
163
2023/day07/src/lib.rs
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
use std::cmp::{self, Ordering};
|
||||
|
||||
use helper::{Day, IteratorExt, Variants};
|
||||
|
||||
pub fn main() {
|
||||
helper::main::<Day07>(include_str!("../input.txt"));
|
||||
}
|
||||
|
||||
struct Day07;
|
||||
|
||||
helper::define_variants! {
|
||||
day => crate::Day07;
|
||||
part1 {
|
||||
basic => crate::part1;
|
||||
}
|
||||
part2 {
|
||||
basic => crate::part2;
|
||||
}
|
||||
}
|
||||
|
||||
impl Day for Day07 {
|
||||
fn part1() -> Variants {
|
||||
part1_variants!(construct_variants)
|
||||
}
|
||||
|
||||
fn part2() -> Variants {
|
||||
part2_variants!(construct_variants)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum HandType {
|
||||
FiveSame = 0,
|
||||
FourSame,
|
||||
FullHouse,
|
||||
ThreeSame,
|
||||
TwoPair,
|
||||
OnePair,
|
||||
HighCard,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Hand {
|
||||
values: [u8; 5],
|
||||
hand_type: HandType,
|
||||
bid: u64,
|
||||
}
|
||||
|
||||
impl HandType {
|
||||
fn of(hand: [u8; 5]) -> Self {
|
||||
let mut map: [Option<(u8, u8)>; 5] = [None; 5];
|
||||
|
||||
for card in hand {
|
||||
if let Some(existing) = map.iter_mut().find(|c| c.is_some_and(|c| c.0 == card)) {
|
||||
existing.as_mut().unwrap().1 += 1;
|
||||
} else {
|
||||
let idx = map.iter().position(|c| c.is_none()).unwrap();
|
||||
map[idx] = Some((card, 1));
|
||||
}
|
||||
}
|
||||
map.sort_by_key(|c| cmp::Reverse(c.map(|c| c.1)));
|
||||
|
||||
let map = map.map(|c| c.map_or(0, |c| c.1));
|
||||
if map[0] == 5 {
|
||||
Self::FiveSame
|
||||
} else if map[0] == 4 {
|
||||
Self::FourSame
|
||||
} else if map[0] == 3 && map[1] == 2 {
|
||||
Self::FullHouse
|
||||
} else if map[0] == 3 {
|
||||
Self::ThreeSame
|
||||
} else if map[0] == 2 && map[1] == 2 {
|
||||
Self::TwoPair
|
||||
} else if map[0] == 2 {
|
||||
Self::OnePair
|
||||
} else {
|
||||
Self::HighCard
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::HandType;
|
||||
|
||||
#[test]
|
||||
fn hand_type() {
|
||||
assert_eq!(HandType::of(*b"32T3K"), HandType::OnePair);
|
||||
assert_eq!(HandType::of(*b"K6KK6"), HandType::FullHouse);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(input: &str) -> Vec<Hand> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let mut parts = line.split_ascii_whitespace();
|
||||
let cards = parts.next().unwrap();
|
||||
let bid = parts.next().unwrap().parse().unwrap();
|
||||
|
||||
let values = cards.bytes().collect_array::<5>().unwrap();
|
||||
let hand_type = HandType::of(values);
|
||||
|
||||
Hand {
|
||||
values,
|
||||
hand_type,
|
||||
bid,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> u64 {
|
||||
let mut hands = parse(input);
|
||||
|
||||
// Worst hand first, best hand last.
|
||||
hands.sort_by(|a, b| {
|
||||
let mk_compare = |v| match v {
|
||||
b'A' => b'Z',
|
||||
b'K' => b'Y',
|
||||
b'T' => b'I',
|
||||
other => other,
|
||||
};
|
||||
|
||||
let types = a.hand_type.cmp(&b.hand_type);
|
||||
if types != Ordering::Equal {
|
||||
return types.reverse();
|
||||
}
|
||||
for (a, b) in std::iter::zip(a.values, b.values) {
|
||||
if a == b {
|
||||
continue;
|
||||
}
|
||||
let a = mk_compare(a);
|
||||
let b = mk_compare(b);
|
||||
|
||||
return a.cmp(&b);
|
||||
}
|
||||
Ordering::Equal
|
||||
});
|
||||
|
||||
hands
|
||||
.iter()
|
||||
.zip(1_u64..)
|
||||
.map(|(hand, i)| hand.bid * i)
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn part2(_input: &str) -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
helper::tests! {
|
||||
day07 Day07;
|
||||
part1 {
|
||||
small => 6440;
|
||||
default => 248453531;
|
||||
}
|
||||
part2 {
|
||||
small => 0;
|
||||
default => 0;
|
||||
}
|
||||
}
|
||||
helper::benchmarks! {}
|
||||
3
2023/day07/src/main.rs
Normal file
3
2023/day07/src/main.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
day07::main();
|
||||
}
|
||||
9
Cargo.lock
generated
9
Cargo.lock
generated
|
|
@ -179,6 +179,15 @@ dependencies = [
|
|||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day07"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"divan",
|
||||
"helper",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "divan"
|
||||
version = "0.1.4"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue