From 3d68f20097054fa8a7fb82ce9e4340720a986a3b Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Mon, 3 Dec 2018 14:20:34 +0100 Subject: [PATCH] Slightly more efficient and compact code. This version loops the input twice, first to build the claims, and then to check whether they have been claimed more than once. --- 2018/Cargo.toml | 1 + 2018/src/day03.rs | 51 ++++++++++++++++++++--------------------------- 2018/src/main.rs | 1 + 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/2018/Cargo.toml b/2018/Cargo.toml index 1a83267..42d2855 100644 --- a/2018/Cargo.toml +++ b/2018/Cargo.toml @@ -7,3 +7,4 @@ authors = ["Bert Peters "] clap = "2.32" regex = "1.1.0" chrono = "0.4.6" +itertools = "0.7.11" diff --git a/2018/src/day03.rs b/2018/src/day03.rs index 2d71aea..eb469cb 100644 --- a/2018/src/day03.rs +++ b/2018/src/day03.rs @@ -1,5 +1,4 @@ use std::collections::HashMap; -use std::collections::HashSet; use std::io; use std::io::BufRead; use std::ops::Range; @@ -17,13 +16,17 @@ struct Claim { impl Claim { - pub fn xrange(&self) -> Range { + fn xrange(&self) -> Range { self.x..(self.x + self.width) } - pub fn yrange(&self) -> Range { + fn yrange(&self) -> Range { self.y..(self.y + self.height) } + + pub fn range(&self) -> impl Iterator { + iproduct!(self.xrange(), self.yrange()) + } } #[derive(Default)] @@ -56,21 +59,24 @@ impl Day03 { self.claims.push(claim); } } + + fn get_claims(&self) -> HashMap<(usize, usize), i32> { + let mut claims = HashMap::new(); + for claim in &self.claims { + for coordinate in claim.range() { + *claims.entry(coordinate).or_insert(0) += 1; + } + } + + claims + } } impl common::Solution for Day03 { fn part1(&mut self, input: &mut io::Read) -> String { self.read_claims(input); - let mut claim_map = HashMap::new(); - - for claim in &self.claims { - for x in claim.xrange() { - for y in claim.yrange() { - *claim_map.entry((x, y)).or_insert(0) += 1; - } - } - } + let claim_map = self.get_claims(); let multi_claim = claim_map.values() .filter(|&&x| x > 1) @@ -81,25 +87,12 @@ impl common::Solution for Day03 { fn part2(&mut self, input: &mut io::Read) -> String { self.read_claims(input); - let mut claim_map: HashMap<(usize, usize), Vec> = HashMap::new(); - let mut overlaps: Vec> = Vec::new(); - overlaps.resize(self.claims.len(), HashSet::new()); + let claims = self.get_claims(); - for (idx, claim) in self.claims.iter().enumerate() { - for x in claim.xrange() { - for y in claim.yrange() { - let entry = claim_map.entry((x, y)).or_insert(Vec::new()); - for claim in entry.iter() { - overlaps[*claim].insert(idx); - overlaps[idx].insert(*claim); - } + let uncontested = self.claims.iter() + .position(|x| x.range().all(|x| *claims.get(&x).unwrap() == 1)) + .unwrap(); - &entry.push(idx); - } - } - } - - let uncontested = overlaps.iter().position(|x| x.is_empty()).unwrap(); format!("{}", uncontested + 1) } } diff --git a/2018/src/main.rs b/2018/src/main.rs index 7bf5547..adba627 100644 --- a/2018/src/main.rs +++ b/2018/src/main.rs @@ -1,6 +1,7 @@ extern crate clap; extern crate chrono; extern crate regex; +#[macro_use] extern crate itertools; use clap::{Arg, App}; use std::fs; use std::io;