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.
This commit is contained in:
2018-12-03 14:20:34 +01:00
parent 38db4487e3
commit 3d68f20097
3 changed files with 24 additions and 29 deletions

View File

@@ -7,3 +7,4 @@ authors = ["Bert Peters <bert@bertptrs.nl>"]
clap = "2.32"
regex = "1.1.0"
chrono = "0.4.6"
itertools = "0.7.11"

View File

@@ -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<usize> {
fn xrange(&self) -> Range<usize> {
self.x..(self.x + self.width)
}
pub fn yrange(&self) -> Range<usize> {
fn yrange(&self) -> Range<usize> {
self.y..(self.y + self.height)
}
pub fn range(&self) -> impl Iterator<Item=(usize, usize)> {
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<usize>> = HashMap::new();
let mut overlaps: Vec<HashSet<usize>> = 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)
}
}

View File

@@ -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;