This commit is contained in:
Acvaxoort 2023-12-07 13:59:03 +01:00
parent 9dafa9952f
commit 5a03581041
4 changed files with 1152 additions and 0 deletions

16
day7/Cargo.lock generated Normal file
View File

@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day7"
version = "0.1.0"
dependencies = [
"once_cell",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"

9
day7/Cargo.toml Normal file
View 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]
once_cell = "1.19.0"

1000
day7/input.txt Normal file

File diff suppressed because it is too large Load Diff

127
day7/src/main.rs Normal file
View File

@ -0,0 +1,127 @@
use once_cell::sync::Lazy;
use std::fs::read_to_string;
static CARD_STRENGTH: Lazy<[u8; 128]> = Lazy::new(|| core::array::from_fn(
|i| {
match i as u8 as char {
'2'..='9' => i as u8 - '2' as u8,
'T' => 8 as u8,
'J' => 9 as u8,
'Q' => 10 as u8,
'K' => 11 as u8,
'A' => 12 as u8,
_ => 0 as u8
}
}));
static CARD_STRENGTH_ALT: Lazy<[u8; 128]> = Lazy::new(|| core::array::from_fn(
|i| {
match i as u8 as char {
'J' => 0 as u8,
'2'..='9' => i as u8 - '1' as u8,
'T' => 9 as u8,
'Q' => 10 as u8,
'K' => 11 as u8,
'A' => 12 as u8,
_ => 0 as u8
}
}));
fn get_hand_strength(str: &str) -> i32 {
// Amount of combinations is much smaller than i32, so we can just order them all
let mut iter = str.bytes().map(|c| CARD_STRENGTH[c as usize]);
let hand: [u8; 5] = [iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap()];
// strength of cards from first to last, constructed like a base13 number, used to break ties
let mut cards_strengths: i32 = 0;
let mut occurences: [u8; 13] = [0; 13];
for c in hand {
occurences[c as usize] += 1;
cards_strengths *= 13;
cards_strengths += c as i32;
}
let mut occurences_reduced = occurences.iter().cloned().filter(|&c| c > 0 as u8).collect::<Vec<_>>();
// sorting the numbers of occurences descending, the biggest group is always the most important
occurences_reduced.sort_by(|a, b| b.cmp(a));
let mut combination_strength: i32 = match occurences_reduced[0] {
5 => 6,
4 => 5,
3 => 3,
2 => 1,
_ => 0
};
if occurences_reduced.len() > 1 && occurences_reduced[1] == 2 {
combination_strength += 1;
}
cards_strengths + combination_strength * 371293 // 13^5, max value of cards_strengths + 1
}
fn get_hand_strength_alt(str: &str) -> i32 {
// Amount of combinations is much smaller than i32, so we can just order them all
let mut iter = str.bytes().map(|c| CARD_STRENGTH_ALT[c as usize]);
let hand: [u8; 5] = [iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap()];
// strength of cards from first to last, constructed like a base13 number, used to break ties
let mut cards_strengths: i32 = 0;
let mut occurences: [u8; 13] = [0; 13];
for c in hand {
occurences[c as usize] += 1;
cards_strengths *= 13;
cards_strengths += c as i32;
}
// taking jokers out of the picture, they will be added after getting the sorted groups
let jokers = occurences[0];
occurences[0] = 0;
let mut occurences_reduced = occurences.iter().cloned().filter(|&c| c > 0 as u8).collect::<Vec<_>>();
// sorting the numbers of occurences descending, the biggest group is always the most important
occurences_reduced.sort_by(|a, b| b.cmp(a));
if occurences_reduced.is_empty() {
// if all cards are jokers
occurences_reduced.push(jokers);
} else {
// adding jokers to the biggest group will always get the biggest value increase
occurences_reduced[0] += jokers;
}
let mut combination_strength: i32 = match occurences_reduced[0] {
5 => 6,
4 => 5,
3 => 3,
2 => 1,
_ => 0
};
if occurences_reduced.len() > 1 && occurences_reduced[1] == 2 {
combination_strength += 1;
}
cards_strengths + combination_strength * 371293 // 13^5, max value of cards_strengths + 1
}
fn main() {
let hands = read_to_string("input.txt").unwrap().lines().map(
|str| {
let mut elems = str.split_whitespace();
let hand_text = String::from(elems.next().unwrap());
let bid = elems.next().unwrap().parse::<i32>().unwrap();
(hand_text, bid)
}
).collect::<Vec<_>>();
let mut hands_task1 = hands.iter().map(
|(hand_text, bid)| {
(get_hand_strength(hand_text), *bid)
}
).collect::<Vec<_>>();
hands_task1.sort();
let winnings1 = hands_task1.iter().enumerate().fold(
0, |acc, (order, &(_, bid))| {
acc + (order as i32 + 1) * bid
});
let mut hands_task2 = hands.iter().map(
|(hand_text, bid)| {
(get_hand_strength_alt(hand_text), hand_text, *bid)
}
).collect::<Vec<_>>();
hands_task2.sort();
let winnings2 = hands_task2.iter().enumerate().fold(
0, |acc, (order, &(_, _, bid))| {
acc + (order as i32 + 1) * bid
});
println!("Winnings1: {}", winnings1);
println!("Winnings2: {}", winnings2);
}