Compare commits
3 Commits
b5bcc8268f
...
1a4c40b8aa
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a4c40b8aa | |||
| fdd43c7953 | |||
| ab88556e4c |
38
src/day05.rs
38
src/day05.rs
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
src/main.rs
11
src/main.rs
@@ -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";
|
||||||
|
|||||||
Reference in New Issue
Block a user