From 7f4e6293f2a3c25eb93f01791d3f1ef699f474f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Thu, 17 Dec 2020 20:15:39 +0000 Subject: [PATCH] WIP: day-16: Implement part 2 --- day-16/Cargo.lock | 16 +++++++ day-16/Cargo.toml | 1 + day-16/src/main.rs | 110 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/day-16/Cargo.lock b/day-16/Cargo.lock index e48194d..3249f91 100644 --- a/day-16/Cargo.lock +++ b/day-16/Cargo.lock @@ -14,10 +14,17 @@ name = "day-16" version = "0.1.0" dependencies = [ "indoc", + "itertools", "lazy_static", "regex", ] +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "indoc" version = "0.3.6" @@ -41,6 +48,15 @@ dependencies = [ "unindent", ] +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + [[package]] name = "lazy_static" version = "1.4.0" diff --git a/day-16/Cargo.toml b/day-16/Cargo.toml index 9599ebe..6f7db8e 100644 --- a/day-16/Cargo.toml +++ b/day-16/Cargo.toml @@ -8,5 +8,6 @@ edition = "2018" [dependencies] indoc = "0.3" +itertools = "0.9" lazy_static = "1.4" regex = "1.4" diff --git a/day-16/src/main.rs b/day-16/src/main.rs index 9d9fd7a..4dacdd8 100644 --- a/day-16/src/main.rs +++ b/day-16/src/main.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::fs; use std::ops::RangeInclusive; +use itertools::Itertools; use lazy_static::lazy_static; use regex::Regex; @@ -10,13 +11,29 @@ type Ticket = Vec; fn main() -> Result<(), Box> { let input = fs::read_to_string("input")?; - let (rules, _, tickets) = parse_tickets(&input)?; + let (rules, own_ticket, tickets) = parse_tickets(&input)?; // Part 1 let invalid = get_invalid_values(&rules, &tickets); - println!("{}", invalid.iter().sum::()); + // Part 2 + let valid = get_valid_tickets(&rules, &tickets); + let order = get_value_order(&rules, &valid); + + let result: u32 = order + .iter() + .zip(own_ticket) + .filter_map(|(name, value)| { + if name.starts_with("departure") { + Some(value) + } else { + None + } + }) + .product(); + println!("{}", result); + Ok(()) } @@ -84,6 +101,68 @@ fn get_invalid_values(rules: &Rules, tickets: &Vec) -> Vec { .collect() } +fn get_valid_tickets(rules: &Rules, tickets: &Vec) -> Vec { + tickets + .iter() + .filter(|ticket| { + ticket.iter().all(|value| { + rules + .values() + .any(|(rule1, rule2)| rule1.contains(value) || rule2.contains(value)) + }) + }) + .cloned() + .collect() +} + +fn get_value_order(rules: &Rules, tickets: &Vec) -> Vec { + let rules: Vec<(String, (RangeInclusive, RangeInclusive))> = rules + .iter() + .map(|tup| (tup.0.clone(), (tup.1 .0, tup.1 .1))) + .collect(); + rules.sort_by(|name, (_, (rule1, rule2))| rule1.count() + rule2.count()); + + let mut next_ticket = 0; + let mut order: Vec = rules.keys().cloned().collect(); + let order_fits = |order: &Vec, ticket: &Ticket| { + order.iter().zip(ticket).all(|(name, value)| { + let (rule1, rule2) = rules.get(name).expect("Must be there"); + rule1.contains(value) || rule2.contains(value) + }) + }; + + loop { + if order_fits(&order, &tickets[next_ticket]) {} + } + + // rules + // .iter() + // .permutations(rules.len()) + // .filter_map(|rules| { + // if tickets.iter().all(|ticket| { + // rules + // .iter() + // .zip(ticket) + // .all(|((_, (rule1, rule2)), value)| { + // rule1.contains(value) | rule2.contains(value) + // }) + // }) { + // Some( + // rules + // .iter() + // .map(|rule| rule.0.clone()) + // .collect::>(), + // ) + // } else { + // None + // } + // }) + // .next() + // .expect("Must have a valid solution") + + unimplemented!() +} + #[cfg(test)] mod tests { use super::*; @@ -115,4 +194,31 @@ mod tests { Ok(()) } + + #[test] + fn test_simple2() -> Result<(), Box> { + let input = indoc!( + " + class: 0-1 or 4-19 + row: 0-5 or 8-19 + seat: 0-13 or 16-19 + + your ticket: + 11,12,13 + + nearby tickets: + 3,9,18 + 15,1,5 + 5,14,9 + " + ); + + let (rules, _, tickets) = parse_tickets(input)?; + let valid = get_valid_tickets(&rules, &tickets); + let order = get_value_order(&rules, &valid); + + assert_eq!(order, vec!["row", "class", "seat"]); + + Ok(()) + } }