This commit is contained in:
RingOfStorms (Joshua Bell) 2023-12-08 02:59:40 -06:00
parent c67235eb46
commit 3803c544cf
8 changed files with 62 additions and 85 deletions

View file

@ -30,5 +30,6 @@ rayon = "1.8.0"
static_init = "1.0.3"
[features]
part1 = []
part2 = []
default = ["part2"]
default = ["part1"]

View file

@ -1,5 +1,5 @@
use aoc23::prelude::*;
use std::{collections::HashMap, error::Error, fmt::Display, str::FromStr, string::ParseError};
use std::{collections::HashMap, fmt::Display, str::FromStr};
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
enum Cube {

View file

@ -23,7 +23,6 @@ struct Grid {
impl Grid {
fn get_item(&self, row: usize, col: usize) -> Option<&Item> {
// println!("\t\t\tRow:{} Col:{} {:?}", row, col, self.rows.get(row));
match self.rows.get(row) {
Some(row) => row.get(col),
None => None,
@ -36,7 +35,6 @@ impl Grid {
start: usize,
end: usize,
) -> Vec<(&Item, usize, usize)> {
// println!("\tget adj: r{} s{} e{}", row, start, end);
let row_start = if row > 0 { row - 1 } else { 0 };
let col_start = if start > 0 { start - 1 } else { 0 };
let mut items: Vec<(&Item, usize, usize)> = vec![];
@ -44,8 +42,6 @@ impl Grid {
for col_i in col_start..=end + 1 {
if row_i != row || col_i < start || col_i > end {
let item = self.get_item(row_i, col_i);
// println!("\t\trow: {} col: {} item: {:?}", row_i, col_i, item);
if let Some(item) = item {
items.push((item, row_i, col_i));
}

View file

@ -1,10 +1,6 @@
use aoc23::prelude::*;
use itertools::Itertools;
use std::{
collections::{HashMap, VecDeque},
str::FromStr,
time::Instant,
};
use std::{collections::VecDeque, str::FromStr, time::Instant};
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
struct Card {

View file

@ -1,7 +1,6 @@
use aoc23::prelude::*;
use derive_builder::Builder;
use itertools::Itertools;
use rayon::prelude::*;
use std::{cmp::Ordering, str::FromStr, time::Instant};
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
@ -18,51 +17,48 @@ enum Strength {
impl Strength {
#[cfg(feature = "part2")]
fn for_hand(hand: &Hand) -> Self {
let mut possible_counts: Vec<[i32; 14]> = vec![[0; 14]];
// let mut counts = [0; 14]; let mut jokers = 0;
let mut counts = [0; 15];
let mut jokers = 0;
for card in hand.cards.iter() {
if card == &1 {
let mut new_possible_counts: Vec<[i32; 14]> = vec![];
for possible_count in possible_counts.iter() {
for i in 0..14 {
let mut new_counts = possible_count.clone();
new_counts[i] += 1;
new_possible_counts.push(new_counts);
}
}
possible_counts = new_possible_counts;
jokers += 1;
} else {
for counts in possible_counts.iter_mut() {
counts[*card as usize - 2] += 1;
}
counts[*card as usize - 2] += 1;
}
}
possible_counts.iter().map(|counts| {
counts.iter().fold(Strength::HighCard, |strength, &count| {
std::cmp::max(
strength.clone(),
match count {
5 => Strength::FiveOfAKind,
4 => Strength::FourOfAKind,
3 => match strength {
Strength::TwoPair => Strength::FullHouse,
Strength::OnePair => Strength::FullHouse,
_ => Strength::ThreeOfAKind,
},
2 => match strength {
Strength::ThreeOfAKind => Strength::FullHouse,
Strength::OnePair => Strength::TwoPair,
_ => Strength::OnePair,
},
_ => strength,
},
)
})
}).sorted().next().unwrap()
let mut strength = counts
.iter()
.fold(Strength::HighCard, |strength, &count| match count {
5 => Strength::FiveOfAKind,
4 => Strength::FourOfAKind,
3 => match strength {
Strength::TwoPair => Strength::FullHouse,
Strength::OnePair => Strength::FullHouse,
_ => Strength::ThreeOfAKind,
},
2 => match strength {
Strength::ThreeOfAKind => Strength::FullHouse,
Strength::OnePair => Strength::TwoPair,
_ => Strength::OnePair,
},
_ => strength,
});
while jokers > 0 {
strength = match strength {
Strength::HighCard => Strength::OnePair,
Strength::OnePair => Strength::ThreeOfAKind,
Strength::TwoPair => Strength::FullHouse,
Strength::ThreeOfAKind => Strength::FourOfAKind,
Strength::FullHouse => Strength::FourOfAKind,
Strength::FourOfAKind => Strength::FiveOfAKind,
Strength::FiveOfAKind => Strength::FiveOfAKind,
};
jokers -= 1;
}
strength
}
#[cfg(not(feature = "part2"))]
#[cfg(feature = "part1")]
fn for_hand(hand: &Hand) -> Self {
let mut counts = [0; 15];
for card in hand.cards.iter() {
@ -135,19 +131,19 @@ impl FromStr for Hand {
digit
} else {
match c {
#[cfg(not(feature = "part2"))]
#[cfg(feature = "part1")]
'A' => 14,
#[cfg(feature = "part2")]
'A' => 13,
#[cfg(not(feature = "part2"))]
#[cfg(feature = "part1")]
'K' => 13,
#[cfg(feature = "part2")]
'K' => 12,
#[cfg(not(feature = "part2"))]
#[cfg(feature = "part1")]
'Q' => 12,
#[cfg(feature = "part2")]
'Q' => 11,
#[cfg(not(feature = "part2"))]
#[cfg(feature = "part1")]
'J' => 11,
#[cfg(feature = "part2")]
'J' => 1,
@ -168,21 +164,12 @@ fn calculate(input: String) -> Result<usize> {
let answer = input
.lines()
.map(|line| line.parse::<Hand>().unwrap())
.sorted().collect_vec();
// .enumerate()
// .map(|(idx, hand)| hand.bid * (idx + 1))
// .sum();
.sorted()
.enumerate()
.map(|(idx, hand)| hand.bid * (idx + 1))
.sum();
let algo_time = start.elapsed();
// ```
for i in answer {
println!("{:?}: {:?}", i, Strength::for_hand(&i));
}
let answer = 0;
// ```
//
// output
println!("Day 5: {answer}");
println!("Day {DAY}: {answer}");
println!("\t{algo_time:?}");
Ok(answer)
}
@ -211,7 +198,7 @@ QQQJA 483";
#[test]
fn test() -> Result<()> {
#[cfg(not(feature = "part2"))]
#[cfg(feature = "part1")]
assert_eq!(calculate(DATA.to_owned())?, 6440);
#[cfg(feature = "part2")]
assert_eq!(calculate(DATA.to_owned())?, 5905);

View file

@ -2,11 +2,7 @@ use aoc23::prelude::*;
use derive_builder::Builder;
use itertools::Itertools;
use rayon::prelude::*;
use std::{
collections::HashMap,
io::{self, Write},
time::Instant,
};
use std::{collections::HashMap, time::Instant};
extern crate regex;
@ -106,7 +102,7 @@ fn part1(input: String) -> Result<usize> {
let algo_time = start.elapsed();
// output
println!("Day 5, part 1: {answer}");
println!("Day {DAY}, part 1: {answer}");
println!("\tparse: {parsed_time:?}");
println!("\talgo: {algo_time:?}");
Ok(answer)
@ -142,7 +138,7 @@ fn part2(input: String) -> Result<u64> {
let algo_time = start.elapsed();
// output
println!("Day 5, part 2: {answer}");
println!("Day {DAY}, part 2: {answer}");
println!("\tparse: {parsed_time:?}");
println!("\talgo: {algo_time:?}");
Ok(answer)

View file

@ -4,6 +4,8 @@ use itertools::Itertools;
use rayon::prelude::*;
use std::{str::FromStr, time::Instant};
static DAY: u8 = TODO;
#[derive(Debug, Builder, Clone)]
struct Todo {}
@ -22,12 +24,12 @@ fn part1(input: String) -> Result<usize> {
let parsed_time = start.elapsed();
// algo
let start = Instant::now();
let a_start = Instant::now();
let answer = 0;
let algo_time = start.elapsed();
let algo_time = a_start.elapsed();
// output
println!("Day 5, part 1: {answer}");
println!("part 1: {answer}\t[total: {:?}]", start.elapsed());
println!("\tparse: {parsed_time:?}");
println!("\talgo: {algo_time:?}");
Ok(answer)
@ -40,18 +42,17 @@ fn part2(input: String) -> Result<usize> {
let parsed_time = start.elapsed();
// algo
let start = Instant::now();
let a_start = Instant::now();
let answer = 0;
let algo_time = start.elapsed();
let algo_time = a_start.elapsed();
// output
println!("Day 5, part 2: {answer}");
println!("part 2: {answer}\t[total: {:?}]", start.elapsed());
println!("\tparse: {parsed_time:?}");
println!("\talgo: {algo_time:?}");
Ok(answer)
}
// TODO come back and revise for a faster solution
#[tokio::main]
async fn main() -> Result<()> {
println!("Day {DAY}");
@ -62,8 +63,6 @@ async fn main() -> Result<()> {
Ok(())
}
static DAY: u8 = TODO;
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1,3 +1,5 @@
#[cfg(all(feature = "part1", feature = "part2"))]
compile_error!("Part 1 and Part 2 are mutually exclusive and cannot be enabled together");
pub mod utils;
pub mod prelude {