2018: day03: part2
This commit is contained in:
parent
64d8e7b779
commit
2274074cdd
|
@ -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<u64> {
|
|||
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)]
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<usize>()?;
|
||||
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(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue