1
0

Compare commits

..

3 Commits

Author SHA1 Message Date
1a4c40b8aa improve day 5 speed 2024-12-05 18:50:18 +01:00
fdd43c7953 clippy 2024-12-05 18:43:20 +01:00
ab88556e4c make day 5 faster 2024-12-05 18:40:12 +01:00
2 changed files with 25 additions and 24 deletions

View File

@@ -1,4 +1,6 @@
use itertools::Itertools; use itertools::Itertools;
use std::collections::HashSet;
use std::str::FromStr;
use std::{cmp::Ordering, fs::read_to_string}; use std::{cmp::Ordering, fs::read_to_string};
pub fn day_main() { pub fn day_main() {
@@ -8,21 +10,21 @@ pub fn day_main() {
println!(" part2: {}", part2(input)); println!(" part2: {}", part2(input));
} }
type RiddleResult = usize; type R = usize;
fn part1(input: &str) -> RiddleResult { fn part1(input: &str) -> R {
let (rules, books) = parse(input); let (rules, books) = parse(input);
books books
.iter() .iter()
.filter(|book| valid_book(book, &rules)) .filter(|book| valid_book(book, &rules))
.map(|book| book[book.len() / 2].parse::<RiddleResult>().unwrap()) .map(|book| book[book.len() / 2])
.sum() .sum()
} }
fn valid_book(book: &[&str], rules: &[(&str, &str)]) -> bool { fn valid_book(book: &[R], rules: &HashSet<(R, R)>) -> bool {
for (i, a) in book.iter().enumerate() { for (i, a) in book.iter().enumerate() {
for b in book.iter().skip(i + 1) { for b in book.iter().skip(i + 1) {
if rules.contains(&(b, a)) { if rules.contains(&(*b, *a)) {
return false; return false;
} }
} }
@@ -30,36 +32,37 @@ fn valid_book(book: &[&str], rules: &[(&str, &str)]) -> bool {
true true
} }
fn parse(input: &str) -> (Vec<(&str, &str)>, Vec<Vec<&str>>) { fn parse(input: &str) -> (HashSet<(R, R)>, Vec<Vec<R>>) {
let (a, b) = input.split_once("\n\n").unwrap(); let (a, b) = input.split_once("\n\n").unwrap();
let rules = a let rules = a
.lines() .lines()
.map(|line| line.split_once("|").unwrap()) .map(|line| line.split_once("|").unwrap())
.collect_vec(); .map(|(a, b)| (R::from_str(a).unwrap(), R::from_str(b).unwrap()))
.collect();
let books = b let books = b
.lines() .lines()
.map(|line| line.split(",").collect_vec()) .map(|line| line.split(",").flat_map(R::from_str).collect_vec())
.collect_vec(); .collect_vec();
(rules, books) (rules, books)
} }
fn part2(input: &str) -> RiddleResult { fn part2(input: &str) -> R {
let (rules, books) = parse(input); let (rules, books) = parse(input);
books books
.iter() .iter()
.filter(|book| !valid_book(book, &rules)) .filter(|book| !valid_book(book, &rules))
.map(|book| fix(book, &rules)) .map(|book| fix(book, &rules))
.map(|book| book[book.len() / 2].parse::<RiddleResult>().unwrap()) .map(|book| book[book.len() / 2])
.sum() .sum()
} }
fn fix<'a>(book: &'a [&str], rules: &[(&str, &str)]) -> Vec<&'a str> { fn fix(book: &[R], rules: &HashSet<(R, R)>) -> Vec<R> {
let mut b = book.iter().copied().collect_vec(); let mut b = book.iter().copied().collect_vec();
b.sort_unstable_by(|a, b| { b.sort_unstable_by(|a, b| {
if rules.contains(&(a, b)) { if rules.contains(&(*a, *b)) {
Ordering::Less Ordering::Less
} else if rules.contains(&(b, a)) { } else if rules.contains(&(*b, *a)) {
Ordering::Greater Ordering::Greater
} else { } else {
Ordering::Equal Ordering::Equal
@@ -70,9 +73,8 @@ fn fix<'a>(book: &'a [&str], rules: &[(&str, &str)]) -> Vec<&'a str> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::day05::valid_book; use super::{part1, part2, valid_book};
use std::collections::HashSet;
use super::{part1, part2};
const TEST_INPUT: &str = r"47|53 const TEST_INPUT: &str = r"47|53
97|13 97|13
@@ -106,8 +108,8 @@ mod test {
#[test] #[test]
fn test1() { fn test1() {
assert!(valid_book(&vec!["97", "5", "13"], &vec![("97", "13")])); assert!(valid_book(&vec![97, 5, 13], &HashSet::from([(97, 13)])));
assert!(!valid_book(&vec!["13", "5", "97"], &vec![("97", "13")])); assert!(!valid_book(&vec![13, 5, 97], &HashSet::from([(97, 13)])));
assert_eq!(part1(TEST_INPUT), 143); assert_eq!(part1(TEST_INPUT), 143);
} }

View File

@@ -39,10 +39,9 @@ fn run(d: u8, f: &fn()) {
let start = Instant::now(); let start = Instant::now();
f(); f();
let duration = start.elapsed(); let duration = start.elapsed();
println!( println!("{COLOR}{ITALIC}Took {duration:?}{RESET_FORMATTING}");
"{color}{italic}Took {duration:?}{reset_formatting}",
color = "\x1b[38;5;247m",
italic = "\x1b[3m",
reset_formatting = "\x1b[0m"
);
} }
const COLOR: &str = "\x1b[38;5;247m";
const ITALIC: &str = "\x1b[3m";
const RESET_FORMATTING: &str = "\x1b[0m";