-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path07.rs
111 lines (95 loc) · 2.32 KB
/
07.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#![feature(test)]
use counter::Counter;
use itertools::Itertools;
type Input = Vec<Hand>;
#[derive(Debug)]
struct Hand {
cards: [Card; 5],
bid: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Card(u8);
impl Card {
fn from_byte(b: u8) -> Self {
Self(match b {
b'2'..=b'9' => b - b'0',
b'T' => 10,
b'J' => 11,
b'Q' => 12,
b'K' => 13,
b'A' => 14,
_ => panic!(),
})
}
fn is_joker(&self) -> bool {
self.0 == 11
}
fn remap_joker(self) -> Self {
if self.is_joker() {
Self(0)
} else {
self
}
}
}
impl Hand {
fn sort_key<const JOKERS: bool>(&self) -> impl Ord + std::fmt::Debug {
let cnt = self
.cards
.into_iter()
.filter(|card| !JOKERS || !card.is_joker())
.collect::<Counter<_>>()
.into_map()
.into_values()
.sorted_unstable()
.collect_vec();
let ty = match &cnt[..] {
[] | [_] => 6,
[1, _] => 5,
[2, _] => 4,
[1, 1, _] => 3,
[1, 2, _] => 2,
[1, 1, 1, _] => 1,
_ => 0,
};
let cards = if JOKERS {
self.cards.map(Card::remap_joker)
} else {
self.cards
};
(ty, cards)
}
}
fn setup(input: &str) -> Input {
input
.lines()
.map(|line| {
let mut line = line.split_whitespace();
let cards = line
.next()
.unwrap()
.bytes()
.map(Card::from_byte)
.collect_vec()
.try_into()
.unwrap();
let bid = line.next().unwrap().parse().unwrap();
Hand { cards, bid }
})
.collect()
}
fn solve<O: Ord>(input: &Input, sort_key: fn(&Hand) -> O) -> u64 {
input
.iter()
.sorted_by_cached_key(|&hand| sort_key(hand))
.enumerate()
.map(|(i, hand)| (i as u64 + 1) * hand.bid)
.sum()
}
fn part1(input: &Input) -> u64 {
solve(input, Hand::sort_key::<false>)
}
fn part2(input: &Input) -> u64 {
solve(input, Hand::sort_key::<true>)
}
aoc::main!(2023, 7, ex: 1);