day10: part1

master
Avril 4 years ago
parent 643eece253
commit 569a3bd2ae
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -0,0 +1,15 @@
[package]
name = "day10"
version = "0.1.0"
authors = ["Avril <flanchan@cumallover.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
test=[]
[dependencies]
ad-hoc-iter = "0.2.2"
cfg-if = "1.0.0"
smallmap = "1.2.1"

@ -0,0 +1,144 @@
#![allow(dead_code)]
#[macro_use] extern crate ad_hoc_iter;
#[macro_use] extern crate cfg_if;
use std::{
io,
io::BufReader,
fs::OpenOptions,
num::NonZeroU8,
ops,
iter,
};
use smallmap::Map;
mod input;
const INPUT: &str = "input";
type Adaptors = Map<NonZeroU8, ()>;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
struct Diffs([usize; 3]);
impl ops::Add for Diffs
{
type Output = Self;
fn add(self, other: Self) -> Self::Output{
Self([
self.0[0] + other.0[0],
self.0[1] + other.0[1],
self.0[2] + other.0[2],
])
}
}
impl ops::AddAssign for Diffs
{
fn add_assign(&mut self, rhs: Self) {
self.0[0] += rhs.0[0];
self.0[1] += rhs.0[1];
self.0[2] += rhs.0[2];
}
}
impl Diffs
{
pub fn jd1(&self) -> usize
{
self.0[0]
}
pub fn jd2(&self) -> usize
{
self.0[1]
}
pub fn jd3(&self) -> usize
{
self.0[2]
}
}
fn parse_input(file: &str) -> Result<impl Iterator<Item = input::Int>, io::Error>
{
let file = OpenOptions::new().read(true).open(file)?;
Ok(input::read_input(BufReader::new(file)))
}
fn find_smallest(map: &Adaptors, finding: impl Into<u8>) -> (Option<u8>, Diffs)
{
#![allow(unused_assignments)]
let finding = finding.into();
let mut diffs = Diffs::default();
let mut set=false;
macro_rules! find {
($l:literal) => {
{
let shim = finding + $l;
debug_assert!(shim > 0);
//eprintln!("Looking up {}", shim);
match map.get(&unsafe {
NonZeroU8::new_unchecked(shim)
}).map(|_| shim) {
Some(yes) if !set => {
set = true;
diffs.0[($l-1)] += 1;
Some(yes)
},
x => x
}
}
}
};
(iter![
find!(1),
find!(2),
find!(3)
].filter_map(std::convert::identity)
.min(), diffs)
}
#[inline(always)] fn conv_input(input: impl Iterator<Item=input::Int>) -> impl Iterator<Item = (NonZeroU8, ())>
{
input.filter_map(NonZeroU8::new).zip(iter::repeat(()))
}
#[inline(always)] fn get_input() -> impl Iterator<Item=input::Int>
{
cfg_if!{
if #[cfg(feature="test")] {
input::test_input()
} else {
parse_input(INPUT).unwrap()
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>>
{
let all_jolts = {
let mut map: Adaptors = conv_input(get_input()).collect();
unsafe {
map.insert(NonZeroU8::new_unchecked(map.iter().map(|&(x, _)| x).max().unwrap().get() + 3), ());
}
map
};
debug_assert_eq!(all_jolts.num_pages(), 1); // Assert we have space efficiency.
let mut current = 0;
#[allow(unused_variables)]
let mut sum=0;
let mut whole_diffs = Diffs::default();
loop {
if let (Some(next), diffs) = find_smallest(&all_jolts, current) {
current = next;
sum+=1;
whole_diffs += diffs;
} else {
break;
}
}
println!("{}", whole_diffs.jd1() * whole_diffs.jd3());
Ok(())
}
Loading…
Cancel
Save