Missed several updates. Working on 8 pt 2
This commit is contained in:
171
day_07/src/lib.rs
Normal file
171
day_07/src/lib.rs
Normal file
@@ -0,0 +1,171 @@
|
||||
use nom::{
|
||||
bytes::complete::take,
|
||||
character::complete::{
|
||||
self, space1,
|
||||
},
|
||||
sequence::preceded,
|
||||
IResult,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
// 393J3 50208020002 836
|
||||
// 3TJAJ 50209001200 837
|
||||
|
||||
fn is_five_of_a_kind(card: &str, match_numbers: Vec<usize>) -> bool {
|
||||
if match_numbers.iter().any(|x| {x==&5}) {
|
||||
true
|
||||
} else if match_numbers.iter().any(|x| {x==&4}) && card.matches("J").count() == 1 {
|
||||
true
|
||||
} else if match_numbers.iter().any(|x| {x==&3}) && card.matches("J").count() == 2 {
|
||||
true
|
||||
} else if match_numbers.iter().any(|x| {x==&2}) && card.matches("J").count() == 3 {
|
||||
true
|
||||
} else if match_numbers.iter().any(|x| {x==&1}) && card.matches("J").count() == 4 {
|
||||
true
|
||||
} else if card.matches("J").count() == 5 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_four_of_a_kind(card: &str, match_numbers: Vec<usize>) -> bool {
|
||||
if match_numbers.iter().any(|x| {x==&4}) {
|
||||
true
|
||||
} else if match_numbers.iter().any(|x| {x==&3}) && card.matches("J").count() == 1 {
|
||||
true
|
||||
} else if match_numbers.iter().any(|x| {x==&2}) && card.matches("J").count() == 2 {
|
||||
true
|
||||
} else if card.matches("J").count() == 3 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_full_house(card: &str, match_numbers: Vec<usize>) -> bool {
|
||||
if match_numbers.iter().filter(|x| x > &&0).count() == 2 && match_numbers.iter().sum::<usize>() == 5 {
|
||||
true
|
||||
} else if match_numbers.iter().filter(|x| x == &&2).count() == 2 && card.matches("J").count() == 1 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_three_of_a_kind(card: &str, match_numbers: Vec<usize>) -> bool {
|
||||
if match_numbers.iter().any(|x| {x==&3}) {
|
||||
true
|
||||
} else if match_numbers.iter().any(|x| {x==&2}) && card.matches("J").count() == 1 {
|
||||
true
|
||||
} else if card.matches("J").count() == 2 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_two_pair(_card: &str, match_numbers: Vec<usize>) -> bool {
|
||||
if match_numbers.iter().filter(|x| x == &&2).count() == 2 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_pair(card: &str, match_numbers: Vec<usize>) -> bool {
|
||||
if match_numbers.iter().any(|x| {x==&2}) {
|
||||
true
|
||||
} else if card.matches("J").count() == 1 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn score_card_pt2(card: &str) -> u64 {
|
||||
let values = HashMap::from(
|
||||
[('2', 1),('3', 2),('4', 3),('5', 4),('6', 5),('7', 6),('8', 7),('9', 8),('T', 9),('J', 0),('Q', 10),('K', 11),('A', 12)]
|
||||
);
|
||||
let values_without_joker = HashMap::from(
|
||||
[('2', 1),('3', 2),('4', 3),('5', 4),('6', 5),('7', 6),('8', 7),('9', 8),('T', 9),('Q', 10),('K', 11),('A', 12)]
|
||||
);
|
||||
let sub_score = card.chars().enumerate().fold(0, |acc, (i, character)| {
|
||||
acc + values.get(&character).unwrap() * 10_u64.pow(8 - 2*i as u32)
|
||||
});
|
||||
let match_numbers = values_without_joker.keys().map(|value| { card.matches(*value).count() }).collect::<Vec<usize>>();
|
||||
|
||||
if is_five_of_a_kind(card, match_numbers.clone()) {
|
||||
6 * 10_u64.pow(10) + sub_score
|
||||
} else if is_four_of_a_kind(card, match_numbers.clone()) {
|
||||
5 * 10_u64.pow(10) + sub_score
|
||||
} else if is_full_house(card, match_numbers.clone()) {
|
||||
4 * 10_u64.pow(10) + sub_score
|
||||
} else if is_three_of_a_kind(card, match_numbers.clone()) {
|
||||
3 * 10_u64.pow(10) + sub_score
|
||||
} else if is_two_pair(card, match_numbers.clone()) {
|
||||
2 * 10_u64.pow(10) + sub_score
|
||||
} else if is_pair(card, match_numbers.clone()) {
|
||||
1 * 10_u64.pow(10) + sub_score
|
||||
} else {
|
||||
sub_score
|
||||
}
|
||||
}
|
||||
|
||||
fn score_card(card: &str) -> u64 {
|
||||
let values = HashMap::from(
|
||||
[('2', 0),('3', 1),('4', 2),('5', 3),('6', 4),('7', 5),('8', 6),('9', 7),('T', 8),('J', 9),('Q', 10),('K', 11),('A', 12)]
|
||||
);
|
||||
let sub_score = card.chars().enumerate().fold(0, |acc, (i, character)| {
|
||||
acc + values.get(&character).unwrap() * 10_u64.pow(8 - 2*i as u32)
|
||||
});
|
||||
let match_numbers = values.keys().map(|value| { card.matches(*value).count() });
|
||||
if match_numbers.clone().any(|x| {x==5}) {
|
||||
6 * 10_u64.pow(10) + sub_score
|
||||
} else if match_numbers.clone().any(|x| {x==4}) {
|
||||
5 * 10_u64.pow(10) + sub_score
|
||||
} else if match_numbers.clone().filter(|x| x > &0).count() == 2 && match_numbers.clone().sum::<usize>() == 5 {
|
||||
4 * 10_u64.pow(10) + sub_score
|
||||
} else if match_numbers.clone().any(|x| {x==3}) {
|
||||
3 * 10_u64.pow(10) + sub_score
|
||||
} else if match_numbers.clone().filter(|x| x > &0).count() == 3 {
|
||||
2 * 10_u64.pow(10) + sub_score
|
||||
} else if match_numbers.clone().any(|x| {x==2}) {
|
||||
1 * 10_u64.pow(10) + sub_score
|
||||
} else {
|
||||
sub_score
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_card(input: &str) -> IResult<&str, (&str, u64)> {
|
||||
let (input, card) = take(5 as usize)(input)?;
|
||||
let (input, bid) = preceded(space1, complete::u64)(input)?;
|
||||
Ok((input, (card, bid)))
|
||||
}
|
||||
|
||||
pub fn part1(input: &str) -> String {
|
||||
let mut scored_hands = input.lines().map(|line| {
|
||||
let (_, (card, bid)) = parse_card(line).unwrap();
|
||||
let score = score_card(card);
|
||||
(card, score, bid)
|
||||
}).collect::<Vec<_>>();
|
||||
scored_hands.sort_by_key(|x| {x.1});
|
||||
scored_hands.into_iter().enumerate().map(|(i, (_, _, bid))| { (i as u64 + 1) * bid }).sum::<u64>().to_string()
|
||||
}
|
||||
|
||||
pub fn part2(input: &str) -> String {
|
||||
let mut scored_hands = input.lines().map(|line| {
|
||||
let (_, (card, bid)) = parse_card(line).unwrap();
|
||||
let score = score_card_pt2(card);
|
||||
(card, score, bid)
|
||||
}).collect::<Vec<_>>();
|
||||
scored_hands.sort_by_key(|x| {x.1});
|
||||
scored_hands.iter().enumerate().for_each(|(i, (card, score, _))| {println!("{} {} {}", card, score, i);});
|
||||
scored_hands.into_iter().enumerate().map(|(i, (_, _, bid))| { (i as u64 + 1) * bid }).sum::<u64>().to_string()
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::part1;
|
||||
pub use super::part2;
|
||||
}
|
||||
|
||||
33
day_07/src/main.rs
Normal file
33
day_07/src/main.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use day_07::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("../input.txt");
|
||||
println!("{}", part1(input));
|
||||
println!("{}", part2(input));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let test_input = "32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483";
|
||||
assert_eq!(part1(test_input), "6440".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let test_input = "32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483";
|
||||
assert_eq!(part2(test_input), "5905".to_string());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user