70 lines
2.1 KiB
Rust
70 lines
2.1 KiB
Rust
|
#![feature(test)]
|
||
|
extern crate test;
|
||
|
use aoc2023::{boilerplate, common::*};
|
||
|
use itertools::Itertools;
|
||
|
|
||
|
const DAY: usize = 7;
|
||
|
type I = usize;
|
||
|
type Parsed = Vec<([I; 5], I, I)>;
|
||
|
|
||
|
const CARDS: [u8; 13] = [b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'T', b'J', b'Q', b'K', b'A'];
|
||
|
|
||
|
fn parse_input(raw: &str) -> Parsed {
|
||
|
raw.lines()
|
||
|
.map(|l| l.split_once(' ').unwrap())
|
||
|
.map(|(hand, points)| {
|
||
|
(<[_; 5]>::try_from(hand.as_bytes()).unwrap().map(|b| CARDS.iter().position(|&c| c == b).unwrap()), parse_num(points))
|
||
|
})
|
||
|
.map(|(hand, points)| (hand, points, hand.iter().fold(0, |acc, n| (acc << 4) + n)))
|
||
|
.collect()
|
||
|
}
|
||
|
|
||
|
fn part1(hands: &Parsed) -> usize {
|
||
|
let mut rated_hands = hands
|
||
|
.iter()
|
||
|
.cloned()
|
||
|
.map(|(mut hand, points, tiebreak)| {
|
||
|
hand.sort();
|
||
|
let paired = hand
|
||
|
.into_iter()
|
||
|
.map(|c| (c, 1))
|
||
|
.coalesce(|(c1, n1), (c2, n2)| if c1 == c2 { Ok((c1, n1 + n2)) } else { Err(((c1, n1), (c2, n2))) })
|
||
|
.map(|(_, n)| n)
|
||
|
.collect_vec();
|
||
|
let value = match paired.as_slice() {
|
||
|
[_] => (1 << 30) + tiebreak,
|
||
|
[4, 1] | [1, 4] => (1 << 29) + tiebreak,
|
||
|
[3, 2] | [2, 3] => (1 << 28) + tiebreak,
|
||
|
[3, 1, 1] | [1, 3, 1] | [1, 1, 3] => (1 << 27) + tiebreak,
|
||
|
// can only be 2 pair
|
||
|
[_, _, _] => (1 << 26) + tiebreak,
|
||
|
[_, _, _, _] => (1 << 25) + tiebreak,
|
||
|
_ => (1 << 24) + tiebreak,
|
||
|
};
|
||
|
(value, points)
|
||
|
})
|
||
|
.collect_vec();
|
||
|
rated_hands.sort_unstable_by_key(|(v, _)| *v);
|
||
|
rated_hands.into_iter().zip(1..).map(|((_, points), position)| points * position).sum()
|
||
|
}
|
||
|
|
||
|
fn part2(parsed: &Parsed) -> usize {
|
||
|
unimplemented!()
|
||
|
}
|
||
|
|
||
|
boilerplate! {
|
||
|
TEST_INPUT == "\
|
||
|
32T3K 765
|
||
|
T55J5 684
|
||
|
KK677 28
|
||
|
KTJJT 220
|
||
|
QQQJA 483",
|
||
|
tests: {
|
||
|
part1: { TEST_INPUT => 6440 },
|
||
|
part2: { TEST_INPUT => 0 },
|
||
|
},
|
||
|
bench1 == 248812215,
|
||
|
bench2 == 0,
|
||
|
bench_parse: Vec::len => 1000,
|
||
|
}
|