rust(day16): Cleanup and replace BTreeMap with Vec

This commit is contained in:
Sijmen 2020-12-16 13:56:13 +01:00
parent 1271eb0e98
commit a7902f66e3
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48

View file

@ -519,7 +519,6 @@ mod day15 {
} }
mod day16 { mod day16 {
use std::collections::BTreeSet;
use std::fmt; use std::fmt;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -544,6 +543,10 @@ mod day16 {
to: range.next().unwrap().parse().unwrap(), to: range.next().unwrap().parse().unwrap(),
} }
} }
fn contains(&self, i: usize) -> bool {
i >= self.from && i <= self.to
}
} }
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -552,6 +555,13 @@ mod day16 {
ranges: (Range, Range), ranges: (Range, Range),
} }
impl Rule {
fn validate(&self, i: usize) -> bool {
let (a, b) = &self.ranges;
a.contains(i) || b.contains(i)
}
}
pub fn run(print: bool) -> Duration { pub fn run(print: bool) -> Duration {
let input = std::fs::read_to_string("../inputs/16").unwrap(); let input = std::fs::read_to_string("../inputs/16").unwrap();
let instant = Instant::now(); let instant = Instant::now();
@ -597,16 +607,14 @@ mod day16 {
let mut valid_tickets = Vec::new(); let mut valid_tickets = Vec::new();
for ticket in &nearby_tickets { for ticket in &nearby_tickets {
let mut valid = true; let mut valid = true;
for field in ticket { for &field in ticket {
let rule = rules.iter().find(|rule| { let rule = rules.iter().find(|rule| rule.validate(field));
(field >= &rule.ranges.0.from && field <= &rule.ranges.0.to)
|| (field >= &rule.ranges.1.from && field <= &rule.ranges.1.to)
});
if rule.is_none() { if rule.is_none() {
valid = false; valid = false;
part1 += field; part1 += field;
} }
} }
if valid { if valid {
valid_tickets.push(ticket); valid_tickets.push(ticket);
} }
@ -617,7 +625,7 @@ mod day16 {
} }
let mut field_possibilities: Vec<_> = (0..your_ticket.len()) let mut field_possibilities: Vec<_> = (0..your_ticket.len())
.map(|_| (0..rules.len()).collect::<BTreeSet<_>>()) .map(|_| (0..rules.len()).collect::<Vec<_>>())
.collect(); .collect();
for ticket in valid_tickets { for ticket in valid_tickets {
@ -627,7 +635,10 @@ mod day16 {
if !((field >= &rule.ranges.0.from && field <= &rule.ranges.0.to) if !((field >= &rule.ranges.0.from && field <= &rule.ranges.0.to)
|| (field >= &rule.ranges.1.from && field <= &rule.ranges.1.to)) || (field >= &rule.ranges.1.from && field <= &rule.ranges.1.to))
{ {
possibilities.remove(&rule_i); possibilities
.iter()
.position(|i| i == rule_i)
.map(|i| possibilities.remove(i));
} }
} }
} }
@ -641,17 +652,17 @@ mod day16 {
.find(|(_, fp)| fp.len() == 1); .find(|(_, fp)| fp.len() == 1);
let (i, possibility) = match field_possibility { let (i, possibility) = match field_possibility {
Some((i, v)) => (i, *v.iter().next().take().unwrap()), Some((i, v)) => (i, v[0]),
None => break, None => break,
}; };
for fp in field_possibilities.iter_mut() { for fp in field_possibilities.iter_mut() {
fp.remove(&possibility); fp.iter()
.position(|&i| i == possibility)
.map(|i| fp.remove(i));
} }
let rule = &rules[possibility].name; let rule = &rules[possibility].name;
//println!("{} is {}", rule, your_ticket[i]);
if rule.starts_with("departure") { if rule.starts_with("departure") {
part2 *= your_ticket[i]; part2 *= your_ticket[i];
} }
@ -701,7 +712,7 @@ fn main() {
} }
let repetitions = let repetitions =
5000.min((Duration::new(5, 0).as_nanos() / first_run.as_nanos()) as u32); 5000.min((Duration::new(2, 0).as_nanos() / first_run.as_nanos()) as u32);
let mut elapsed = Duration::new(0, 0); let mut elapsed = Duration::new(0, 0);
for _ in 0..repetitions { for _ in 0..repetitions {