58 lines
1.3 KiB
Rust
58 lines
1.3 KiB
Rust
#![feature(test)]
|
|
#![allow(clippy::ptr_arg)]
|
|
extern crate test;
|
|
use std::collections::HashMap;
|
|
use aoc2020::common::*;
|
|
|
|
type Parsed = Vec<usize>;
|
|
|
|
fn read_input() -> String {
|
|
String::from("15,12,0,14,3,1")
|
|
}
|
|
|
|
#[inline]
|
|
fn parse_input(raw: &str) -> Parsed {
|
|
parse_nums(raw)
|
|
}
|
|
|
|
#[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
|
|
}
|
|
|
|
// only here so the test/bench macro works
|
|
#[allow(unused)]
|
|
#[inline]
|
|
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);
|
|
bench!(part1(2020) == 249);
|
|
// bench!(part2(30000000) == 41687);
|
|
bench_input!(len == 6);
|
|
}
|