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" static_init = "1.0.3"
[features] [features]
part1 = []
part2 = [] part2 = []
default = ["part2"] default = ["part1"]

View file

@ -1,5 +1,5 @@
use aoc23::prelude::*; 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)] #[derive(Debug, Eq, PartialEq, Clone, Hash)]
enum Cube { enum Cube {

View file

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

View file

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

View file

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

View file

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

View file

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