2018: day03: part2

This commit is contained in:
Antoine Martin 2019-11-15 17:25:40 +01:00
parent 64d8e7b779
commit 2274074cdd
2 changed files with 65 additions and 10 deletions

View file

@ -1,4 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet;
use std::fmt; use std::fmt;
use super::Result; use super::Result;
@ -7,6 +8,7 @@ const INPUT: &str = include_str!("../input/day03.txt");
pub fn run() -> Result<()> { pub fn run() -> Result<()> {
println!("part 1: {}", part1(INPUT)?); println!("part 1: {}", part1(INPUT)?);
println!("part 2: {}", part2(INPUT)?);
Ok(()) Ok(())
} }
@ -109,21 +111,63 @@ fn part1(input: &str) -> Result<u64> {
Ok(res) Ok(res)
} }
fn part2(input: &str) -> Result<usize> {
let mut map: HashMap<(usize, usize), Vec<usize>> = HashMap::default();
let mut set = HashSet::new();
for line in input.lines() {
let claim = parse(line).ok_or(ParseError::new(line))?;
set.insert(claim.id);
for i in 0..claim.width {
for j in 0..claim.height {
let x = claim.x + i;
let y = claim.y + j;
// add tissue patch at coordinates (x, y)
let entry = map.entry((x, y)).or_default();
entry.push(claim.id);
// if overlap, remove claims from possible solutions
if entry.len() > 1 {
for id in entry {
set.remove(id);
}
}
}
}
}
assert!(!set.is_empty());
Ok(set.into_iter().next().unwrap())
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
#[test] const PROVIDED: &str = "#1 @ 1,3: 4x4
fn part1_provided() {
let input = "#1 @ 1,3: 4x4
#2 @ 3,1: 4x4 #2 @ 3,1: 4x4
#3 @ 5,5: 2x2 #3 @ 5,5: 2x2
"; ";
assert_eq!(part1(input).unwrap(), 4);
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 4);
} }
#[test] #[test]
fn part1_real() { fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 114946); assert_eq!(part1(INPUT).unwrap(), 114946);
} }
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 3);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 877);
}
} }

View file

@ -2,18 +2,29 @@ use std::env;
use aoc2018::day01; use aoc2018::day01;
use aoc2018::day02; use aoc2018::day02;
use aoc2018::day03;
use aoc2018::Result; use aoc2018::Result;
fn main() -> Result<()> { fn main() -> Result<()> {
let days = [day01::run, day02::run]; let days: &[fn() -> Result<()>] = &[day01::run, day02::run, day03::run];
let mut args = env::args(); let mut args = env::args();
args.next(); args.next();
let day = args match args.next() {
.next() Some(arg) => {
.expect("Please provide a day to launch") let day: usize = arg.parse().expect("Please provide a day number");
.parse::<usize>()?; days[day - 1]().expect("error running day specified");
}
days[day - 1]() None => {
for (i, day) in days.iter().enumerate() {
println!("day{}: ", i);
day().expect(&format!("error running day {}", i));
println!();
}
}
}
Ok(())
} }