diff --git a/aoc2018/src/day03.rs b/aoc2018/src/day03.rs index 7944213..0d7ac04 100644 --- a/aoc2018/src/day03.rs +++ b/aoc2018/src/day03.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::collections::HashSet; use std::fmt; use super::Result; @@ -7,6 +8,7 @@ const INPUT: &str = include_str!("../input/day03.txt"); pub fn run() -> Result<()> { println!("part 1: {}", part1(INPUT)?); + println!("part 2: {}", part2(INPUT)?); Ok(()) } @@ -109,21 +111,63 @@ fn part1(input: &str) -> Result { Ok(res) } +fn part2(input: &str) -> Result { + let mut map: HashMap<(usize, usize), Vec> = 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)] mod tests { use super::*; - #[test] - fn part1_provided() { - let input = "#1 @ 1,3: 4x4 + const PROVIDED: &str = "#1 @ 1,3: 4x4 #2 @ 3,1: 4x4 #3 @ 5,5: 2x2 "; - assert_eq!(part1(input).unwrap(), 4); + + #[test] + fn part1_provided() { + assert_eq!(part1(PROVIDED).unwrap(), 4); } #[test] fn part1_real() { 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); + } } diff --git a/aoc2018/src/main.rs b/aoc2018/src/main.rs index 2ca3d8d..cc96e70 100644 --- a/aoc2018/src/main.rs +++ b/aoc2018/src/main.rs @@ -2,18 +2,29 @@ use std::env; use aoc2018::day01; use aoc2018::day02; +use aoc2018::day03; + use aoc2018::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(); args.next(); - let day = args - .next() - .expect("Please provide a day to launch") - .parse::()?; + match args.next() { + Some(arg) => { + let day: usize = arg.parse().expect("Please provide a day number"); + days[day - 1]().expect("error running day specified"); + } + None => { + for (i, day) in days.iter().enumerate() { + println!("day{}: ", i); + day().expect(&format!("error running day {}", i)); + println!(); + } + } + } - days[day - 1]() + Ok(()) }