advent-of-code/2020/src/bin/day15.rs

58 lines
1.3 KiB
Rust
Raw Normal View History

2020-12-15 10:21:03 +01:00
#![feature(test)]
#![allow(clippy::ptr_arg)]
2020-12-15 10:21:03 +01:00
extern crate test;
use std::collections::HashMap;
2020-12-16 16:12:41 +01:00
use aoc2020::common::*;
2020-12-15 10:21:03 +01:00
type Parsed = Vec<usize>;
fn read_input() -> String {
String::from("15,12,0,14,3,1")
}
2020-12-16 16:12:41 +01:00
#[inline]
2020-12-15 10:21:03 +01:00
fn parse_input(raw: &str) -> Parsed {
2020-12-16 16:12:41 +01:00
parse_nums(raw)
2020-12-15 10:21:03 +01:00
}
2020-12-15 10:57:59 +01:00
#[rustfmt::skip]
fn part1(initial: &Parsed, limit: usize) -> usize {
(initial.len()..limit - 1).fold(
(initial.iter().enumerate().map(|(i, n)| (*n, i)).collect::<HashMap<_, _>>(), 0),
|(mut prev, curr), i| {
let next = prev.get(&curr).map(|p| i - p).unwrap_or(0);
prev.insert(curr, i);
(prev, next)
},
).1
2020-12-15 10:21:03 +01:00
}
// only here so the test/bench macro works
2020-12-17 14:51:05 +01:00
#[allow(unused)]
2020-12-15 10:32:11 +01:00
#[inline]
2020-12-15 10:21:03 +01:00
fn part2(parsed: &Parsed, limit: usize) -> usize {
part1(parsed, limit)
}
fn main() {
let input = parse_input(&read_input());
println!("Part 1: {}", part1(&input, 2020));
println!("Part 2: {}", part1(&input, 30000000));
}
#[cfg(test)]
mod tests {
use super::*;
use aoc2020::*;
use paste::paste;
use test::black_box;
const TEST_INPUT: &str = "0,3,6";
test!(part1(2020) == 436);
test!(part2(30000000) == 175594);
2020-12-15 10:32:11 +01:00
bench!(part1(2020) == 249);
// bench!(part2(30000000) == 41687);
2020-12-15 10:21:03 +01:00
bench_input!(len == 6);
}