make day 5 faster
This commit is contained in:
30
src/day05.rs
30
src/day05.rs
@@ -1,4 +1,5 @@
|
||||
use itertools::Itertools;
|
||||
use std::str::FromStr;
|
||||
use std::{cmp::Ordering, fs::read_to_string};
|
||||
|
||||
pub fn day_main() {
|
||||
@@ -8,21 +9,21 @@ pub fn day_main() {
|
||||
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);
|
||||
books
|
||||
.iter()
|
||||
.filter(|book| valid_book(book, &rules))
|
||||
.map(|book| book[book.len() / 2].parse::<RiddleResult>().unwrap())
|
||||
.map(|book| book[book.len() / 2])
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn valid_book(book: &[&str], rules: &[(&str, &str)]) -> bool {
|
||||
fn valid_book(book: &[R], rules: &[(R, R)]) -> bool {
|
||||
for (i, a) in book.iter().enumerate() {
|
||||
for b in book.iter().skip(i + 1) {
|
||||
if rules.contains(&(b, a)) {
|
||||
if rules.contains(&(*b, *a)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -30,36 +31,37 @@ fn valid_book(book: &[&str], rules: &[(&str, &str)]) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse(input: &str) -> (Vec<(&str, &str)>, Vec<Vec<&str>>) {
|
||||
fn parse(input: &str) -> (Vec<(R, R)>, Vec<Vec<R>>) {
|
||||
let (a, b) = input.split_once("\n\n").unwrap();
|
||||
let rules = a
|
||||
.lines()
|
||||
.map(|line| line.split_once("|").unwrap())
|
||||
.map(|(a, b)| (R::from_str(a).unwrap(), R::from_str(b).unwrap()))
|
||||
.collect_vec();
|
||||
let books = b
|
||||
.lines()
|
||||
.map(|line| line.split(",").collect_vec())
|
||||
.map(|line| line.split(",").flat_map(R::from_str).collect_vec())
|
||||
.collect_vec();
|
||||
|
||||
(rules, books)
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> RiddleResult {
|
||||
fn part2(input: &str) -> R {
|
||||
let (rules, books) = parse(input);
|
||||
books
|
||||
.iter()
|
||||
.filter(|book| !valid_book(book, &rules))
|
||||
.map(|book| fix(book, &rules))
|
||||
.map(|book| book[book.len() / 2].parse::<RiddleResult>().unwrap())
|
||||
.map(|book| book[book.len() / 2])
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn fix<'a>(book: &'a [&str], rules: &[(&str, &str)]) -> Vec<&'a str> {
|
||||
fn fix(book: &[R], rules: &[(R, R)]) -> Vec<R> {
|
||||
let mut b = book.iter().copied().collect_vec();
|
||||
b.sort_unstable_by(|a, b| {
|
||||
if rules.contains(&(a, b)) {
|
||||
if rules.contains(&(*a, *b)) {
|
||||
Ordering::Less
|
||||
} else if rules.contains(&(b, a)) {
|
||||
} else if rules.contains(&(*b, *a)) {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
Ordering::Equal
|
||||
@@ -106,8 +108,8 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test1() {
|
||||
assert!(valid_book(&vec!["97", "5", "13"], &vec![("97", "13")]));
|
||||
assert!(!valid_book(&vec!["13", "5", "97"], &vec![("97", "13")]));
|
||||
assert!(valid_book(&vec![97, 5, 13], &vec![(97, 13)]));
|
||||
assert!(!valid_book(&vec![13, 5, 97], &vec![(97, 13)]));
|
||||
assert_eq!(part1(TEST_INPUT), 143);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user