From bbbde2836de909328ac422dbe8f81fc351142e55 Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Tue, 10 Dec 2019 18:36:53 +0100 Subject: [PATCH] 2019: day10: part 1 --- aoc2019/benches/bench.rs | 2 + aoc2019/input/day10.txt | 20 +++++ aoc2019/src/day10.rs | 174 +++++++++++++++++++++++++++++++++++++++ aoc2019/src/lib.rs | 1 + aoc2019/src/main.rs | 2 + 5 files changed, 199 insertions(+) create mode 100644 aoc2019/input/day10.txt create mode 100644 aoc2019/src/day10.rs diff --git a/aoc2019/benches/bench.rs b/aoc2019/benches/bench.rs index 6a37c10..9720d7f 100644 --- a/aoc2019/benches/bench.rs +++ b/aoc2019/benches/bench.rs @@ -9,6 +9,7 @@ use aoc2019::day06; use aoc2019::day07; use aoc2019::day08; use aoc2019::day09; +use aoc2019::day10; fn aoc2019_all(c: &mut Criterion) { c.bench_function("day01", |b| b.iter(|| day01::run().unwrap())); @@ -20,6 +21,7 @@ fn aoc2019_all(c: &mut Criterion) { c.bench_function("day07", |b| b.iter(|| day07::run().unwrap())); c.bench_function("day08", |b| b.iter(|| day08::run().unwrap())); c.bench_function("day09", |b| b.iter(|| day09::run().unwrap())); + c.bench_function("day10", |b| b.iter(|| day10::run().unwrap())); } criterion_group! { diff --git a/aoc2019/input/day10.txt b/aoc2019/input/day10.txt new file mode 100644 index 0000000..716efc4 --- /dev/null +++ b/aoc2019/input/day10.txt @@ -0,0 +1,20 @@ +.###.###.###.#####.# +#####.##.###..###..# +.#...####.###.###### +######.###.####.#### +#####..###..######## +#.##.###########.#.# +##.###.######..#.#.# +.#.##.###.#.####.### +##..#.#.##.######### +###.#######.###..##. +###.###.##.##..####. +.##.####.##########. +#######.##.###.##### +#####.##..####.##### +##.#.#####.##.#.#..# +###########.#######. +#.##..#####.#####..# +#####..#####.###.### +####.#.############. +####.#.#.##########. diff --git a/aoc2019/src/day10.rs b/aoc2019/src/day10.rs new file mode 100644 index 0000000..464cae0 --- /dev/null +++ b/aoc2019/src/day10.rs @@ -0,0 +1,174 @@ +use std::collections::HashSet; +use std::fmt::Write; + +use aoc::err; +use aoc::Result; + +const INPUT: &str = include_str!("../input/day10.txt"); + +pub fn run() -> Result { + let mut res = String::with_capacity(128); + + writeln!(res, "part 1: {}", part1(INPUT)?)?; + + Ok(res) +} + +#[derive(Debug, PartialEq, Eq, Hash)] +struct Position { + x: i64, + y: i64, +} + +#[derive(Debug, PartialEq)] +struct Asteroid { + pos: Position, +} + +fn gcd(a: i64, b: i64) -> i64 { + if b == 0 { + a + } else { + gcd(b, a % b) + } +} + +fn part1(input: &str) -> Result { + let mut asteroids = Vec::new(); + for (i, line) in input.lines().enumerate() { + for (j, c) in line.chars().enumerate() { + if c == '#' { + asteroids.push(Asteroid { + pos: Position { + x: j as i64, + y: i as i64, + }, + }) + } + } + } + + let mut best = None; + for a in asteroids.iter() { + let mut set = HashSet::new(); + + for b in asteroids.iter() { + if a == b { + continue; + } + + let direction = Position { + x: b.pos.x - a.pos.x, + y: b.pos.y - a.pos.y, + }; + + let mut div = gcd(direction.x, direction.y); + if div < 0 { + div *= -1; + } + + set.insert(Position { + x: direction.x / div, + y: direction.y / div, + }); + } + + best = match best { + None => Some(set), + Some(old) => { + if set.len() > old.len() { + Some(set) + } else { + Some(old) + } + } + }; + } + + let best = best.ok_or_else(|| err!("zero asteroid provided"))?; + Ok(best.len()) +} + +#[cfg(test)] +mod tests { + use super::*; + + const PROVIDED1: &str = ".#..# +..... +##### +....# +...## +"; + + const PROVIDED2: &str = "......#.#. +#..#.#.... +..#######. +.#.#.###.. +.#..#..... +..#....#.# +#..#....#. +.##.#..### +##...#..#. +.#....#### +"; + + const PROVIDED3: &str = "#.#...#.#. +.###....#. +.#....#... +##.#.#.#.# +....#.#.#. +.##..###.# +..#...##.. +..##....## +......#... +.####.###. +"; + + const PROVIDED4: &str = ".#..#..### +####.###.# +....###.#. +..###.##.# +##.##.#.#. +....###..# +..#.#..#.# +#..#.#.### +.##...##.# +.....#.#.. +"; + + const PROVIDED5: &str = ".#..##.###...####### +##.############..##. +.#.######.########.# +.###.#######.####.#. +#####.##.#.##.###.## +..#####..#.######### +#################### +#.####....###.#.#.## +##.################# +#####.##.###..####.. +..######..##.####### +####.##.####...##..# +.#####..#.######.### +##...#.##########... +#.##########.####### +.####.#.###.###.#.## +....##.##.###..##### +.#.#.###########.### +#.#.#.#####.####.### +###.##.####.##.#..## +"; + + #[test] + fn part1_provided() { + assert_eq!(part1(PROVIDED1).unwrap(), 8); + assert_eq!(part1(PROVIDED2).unwrap(), 33); + assert_eq!(part1(PROVIDED3).unwrap(), 35); + assert_eq!(part1(PROVIDED4).unwrap(), 41); + assert_eq!(part1(PROVIDED5).unwrap(), 210); + } + + #[test] + fn part1_real() { + assert_eq!(part1(INPUT).unwrap(), 214); + } +} diff --git a/aoc2019/src/lib.rs b/aoc2019/src/lib.rs index 5344116..f2d798f 100644 --- a/aoc2019/src/lib.rs +++ b/aoc2019/src/lib.rs @@ -9,3 +9,4 @@ pub mod day06; pub mod day07; pub mod day08; pub mod day09; +pub mod day10; diff --git a/aoc2019/src/main.rs b/aoc2019/src/main.rs index d7de35b..56693e4 100644 --- a/aoc2019/src/main.rs +++ b/aoc2019/src/main.rs @@ -10,6 +10,7 @@ use aoc2019::day06; use aoc2019::day07; use aoc2019::day08; use aoc2019::day09; +use aoc2019::day10; fn main() -> Result<()> { let days: &[DayFunc] = &[ @@ -22,6 +23,7 @@ fn main() -> Result<()> { day07::run, day08::run, day09::run, + day10::run, ]; aoc::run(days)