More day 17 optimizations
This commit is contained in:
parent
36ffc1cf00
commit
66bc3c6d42
@ -1,7 +1,6 @@
|
|||||||
#![feature(core_intrinsics)]
|
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
use std::{intrinsics::unlikely, ops::RangeInclusive};
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
type TargetArea = (RangeInclusive<isize>, RangeInclusive<isize>);
|
type TargetArea = (RangeInclusive<isize>, RangeInclusive<isize>);
|
||||||
type Probe = ((isize, isize), (isize, isize));
|
type Probe = ((isize, isize), (isize, isize));
|
||||||
@ -29,27 +28,25 @@ fn step(((xvel, yvel), (x, y)): &Probe) -> Probe {
|
|||||||
((xvel - xvel.signum(), yvel - 1), (x + xvel, y + yvel))
|
((xvel - xvel.signum(), yvel - 1), (x + xvel, y + yvel))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_input() -> TargetArea {
|
fn get_target() -> TargetArea {
|
||||||
(34..=67, -215..=-186)
|
(34..=67, -215..=-186)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part1(hits: &[((isize, isize), isize)]) -> isize {
|
fn part1(hits: &[isize]) -> isize {
|
||||||
*hits.iter().map(|(_, y)| y).max().unwrap()
|
(1..=*hits.iter().max().unwrap()).sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_hits(target: &TargetArea) -> Vec<((isize, isize), isize)> {
|
fn find_hits(target: &TargetArea) -> Vec<isize> {
|
||||||
|
// Doing y in the outer loop and x in the inner would allow us to call last() instead of max()
|
||||||
|
// in part1, however, for reasons unknown to me, that makes this function 20% slower.
|
||||||
(1..=*target.0.end())
|
(1..=*target.0.end())
|
||||||
.flat_map(move |x| (*target.1.start()..250).map(move |y| (x, y)))
|
.flat_map(move |x| (*target.1.start()..250).map(move |y| (x, y)))
|
||||||
.filter_map(|start| {
|
.filter_map(|(startx, starty)| {
|
||||||
let mut probe = (start, (0, 0));
|
let mut probe = ((startx, starty), (0, 0));
|
||||||
let mut y_high = 0;
|
|
||||||
loop {
|
loop {
|
||||||
probe = step(&probe);
|
probe = step(&probe);
|
||||||
if unlikely(probe.0 .1 == 0) {
|
|
||||||
y_high = probe.1 .1;
|
|
||||||
}
|
|
||||||
match calc_status(&probe, target) {
|
match calc_status(&probe, target) {
|
||||||
ProbeStatus::Hit => return Some((start, y_high)),
|
ProbeStatus::Hit => return Some(starty),
|
||||||
ProbeStatus::Miss => continue,
|
ProbeStatus::Miss => continue,
|
||||||
ProbeStatus::NoLongerReachable => return None,
|
ProbeStatus::NoLongerReachable => return None,
|
||||||
}
|
}
|
||||||
@ -59,8 +56,7 @@ fn find_hits(target: &TargetArea) -> Vec<((isize, isize), isize)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let target = parse_input();
|
let hits = find_hits(&get_target());
|
||||||
let hits = find_hits(&target);
|
|
||||||
println!("Part 1: {}", part1(&hits));
|
println!("Part 1: {}", part1(&hits));
|
||||||
println!("Part 2: {}", hits.len());
|
println!("Part 2: {}", hits.len());
|
||||||
}
|
}
|
||||||
@ -86,14 +82,14 @@ mod tests {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_find_hits(b: &mut test::Bencher) {
|
fn bench_find_hits(b: &mut test::Bencher) {
|
||||||
let input = parse_input();
|
let input = get_target();
|
||||||
b.iter(|| assert_eq!(find_hits(&input).len(), 2040))
|
b.iter(|| assert_eq!(find_hits(test::black_box(&input)).len(), 2040))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_part1(b: &mut test::Bencher) {
|
fn bench_part1(b: &mut test::Bencher) {
|
||||||
let input = parse_input();
|
let input = get_target();
|
||||||
let hits = find_hits(&input);
|
let hits = find_hits(&input);
|
||||||
b.iter(|| assert_eq!(part1(&hits), 23005))
|
b.iter(|| assert_eq!(part1(test::black_box(&hits)), 23005))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user