parent
fcfb68ea33
commit
6ae2840f80
|
@ -2,8 +2,6 @@
|
|||
#![feature(test)]
|
||||
extern crate test;
|
||||
use aoc2021::common::*;
|
||||
use fnv::{FnvHashMap, FnvHasher};
|
||||
use std::hash::BuildHasherDefault;
|
||||
|
||||
const DAY: usize = 5;
|
||||
type Coordinate = (i16, i16); // twice as fast as using i64s ¯\_(ツ)_/¯
|
||||
|
@ -17,21 +15,16 @@ fn parse_input(raw: &str) -> Parsed {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn solve<F: FnMut(&(Coordinate, Coordinate)) -> Vec<Coordinate>>(parsed: &Parsed, capacity: usize, f: F) -> usize {
|
||||
parsed
|
||||
.iter()
|
||||
.flat_map(f)
|
||||
.fold(FnvHashMap::with_capacity_and_hasher(capacity, BuildHasherDefault::<FnvHasher>::default()), |mut map, c| {
|
||||
*map.entry(c).or_insert(0) += 1;
|
||||
map
|
||||
})
|
||||
.values()
|
||||
.filter(|&&n| n > 1)
|
||||
.count()
|
||||
fn solve<F: FnMut(&(Coordinate, Coordinate)) -> Vec<Coordinate>>(parsed: &Parsed, f: F) -> usize {
|
||||
let max_x = *parsed.iter().flat_map(|((x1, _), (x2, _))| [x1, x2]).max().unwrap() + 2;
|
||||
let max_y = *parsed.iter().flat_map(|((_, y1), (_, y2))| [y1, y2]).max().unwrap() + 2;
|
||||
let mut counts = vec![vec![0; max_x as _]; max_y as _];
|
||||
parsed.iter().flat_map(f).for_each(|(x, y)| counts[x as usize][y as usize] += 1);
|
||||
counts.into_iter().flatten().filter(|n| n > &1).count()
|
||||
}
|
||||
|
||||
fn part1(parsed: &Parsed) -> usize {
|
||||
solve(parsed, parsed.len() * 200, |&cs| match cs {
|
||||
solve(parsed, |&cs| match cs {
|
||||
((x1, y1), (x2, y2)) if x1 == x2 => (y1.min(y2)..=y1.max(y2)).map(|y| (x1, y)).collect(),
|
||||
((x1, y1), (x2, y2)) if y1 == y2 => (x1.min(x2)..=x1.max(x2)).map(|x| (x, y1)).collect(),
|
||||
_ => vec![],
|
||||
|
@ -40,7 +33,7 @@ fn part1(parsed: &Parsed) -> usize {
|
|||
|
||||
fn part2(parsed: &Parsed) -> usize {
|
||||
let offset = |x1, x2| (x1 < x2) as i16 - (x1 > x2) as i16;
|
||||
solve(parsed, parsed.len() * 400, |&((mut x1, mut y1), (x2, y2))| {
|
||||
solve(parsed, |&((mut x1, mut y1), (x2, y2))| {
|
||||
let mut coords = Vec::with_capacity(x1.abs_diff(x2).max(y1.abs_diff(y2)) as usize + 1);
|
||||
let x_offset = offset(x1, x2);
|
||||
let y_offset = offset(y1, y2);
|
||||
|
|
Loading…
Reference in New Issue
Block a user