diff --git a/day3/Cargo.lock b/day3/Cargo.lock new file mode 100644 index 0000000..bdc4aa0 --- /dev/null +++ b/day3/Cargo.lock @@ -0,0 +1,181 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", +] + +[[package]] +name = "day3" +version = "0.1.0" +dependencies = [ + "color-eyre", + "lazy_static", + "linebuffer", + "smallmap", +] + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "linebuffer" +version = "0.1.0" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "miniz_oxide" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +dependencies = [ + "adler", +] + +[[package]] +name = "object" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "smallmap" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2df0ae8eb5af9e6e00be6ba531cc6860ba93d5226d6d1d4f80ead510a5d6296e" +dependencies = [ + "rustc_version", +] diff --git a/day3/Cargo.toml b/day3/Cargo.toml new file mode 100644 index 0000000..f25aa98 --- /dev/null +++ b/day3/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "day3" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[profile.release] +opt-level = 3 +lto = "fat" +codegen-units = 1 +strip = true + +[profile.prof] +inherits="release" +strip = false + + +[dependencies] +color-eyre = { version = "0.6.2", default-features = false } +lazy_static = "1.4.0" +linebuffer = { path = "/home/avril/work/linebuffer" } +smallmap = "1.4.0" diff --git a/day3/src/ext.rs b/day3/src/ext.rs new file mode 100644 index 0000000..4f1dede --- /dev/null +++ b/day3/src/ext.rs @@ -0,0 +1,32 @@ +//! Extensions +use super::*; +use std::{ + iter::{self, Fuse,} +}; +pub trait TaekTwoExt: Iterator +{ + fn take_two(self) -> TakeTwo; +} + +#[derive(Debug, Clone)] +pub struct TakeTwo(I); + +impl + ?Sized> Iterator for TakeTwo +{ + type Item = (T, Option); + #[inline] + fn next(&mut self) -> Option + { + let first = self.0.next()?; + Some((first, self.0.next())) + } +} + +impl TaekTwoExt for I +where I: Iterator + Sized +{ + #[inline] + fn take_two(self) -> TakeTwo { + TakeTwo(self) + } +} diff --git a/day3/src/main.rs b/day3/src/main.rs new file mode 100644 index 0000000..7aec75a --- /dev/null +++ b/day3/src/main.rs @@ -0,0 +1,117 @@ + +#[macro_use] extern crate lazy_static; + +use smallmap::{ + Map, + smallmap, +}; +use std::{ + collections::BTreeSet, +}; +use linebuffer::{ + buf::forward, + TryFromBuf, + FromBuf, + ParsedLines, +}; + +use color_eyre::{ + eyre::{ + self, eyre, + WrapErr as _, + }, + Help as _, SectionExt as _, +}; + +mod ext; +pub use ext::*; + +fn init() -> eyre::Result<()> +{ + color_eyre::install() +} + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +struct Sack { + split_by: usize, + containers: Vec>, + full: BTreeSet, +} + +impl Sack +{ + /// Compute the intersection of each `N` part of the container + pub fn intersection(&self) -> impl Iterator + '_ + { + self.containers.iter().take_two().flat_map(|(a, b)| b.map(move |b| (a, b))) + .map(|(a, b)| a.intersection(b)).flatten().copied() + } +} + +#[inline] +fn read_input_from(input: R) -> ParsedLines> +{ + ParsedLines::new(input) +} + +fn read_input() -> eyre::Result>> +{ + let reader = std::fs::OpenOptions::new() + .read(true) + .open("input") + .wrap_err("Failed to open input file for reading")?; + Ok(read_input_from(reader)) +} + +#[derive(Debug)] +pub struct SackParseError{ + expected_div: usize, + size: usize, +} + +impl std::str::FromStr for Sack +{ + type Err = SackParseError; + fn from_str(s: &str) -> Result { + let (first, second) = s.split_at(s.len()/2); + Ok(Self { + split_by: 2, + containers: vec![ + first.chars().collect(), + second.chars().collect(), + ], + full: s.chars().collect(), + }) + } +} + +#[inline] +fn prop_swivle<'a>(sigh: impl IntoIterator+ 'a) -> impl Iterator + 'a +{ + lazy_static! { + static ref PMAP: Map = ('a'..='z').enumerate().map(|(i, n)| (i+1, n)) + .chain (('A'..='Z').enumerate().map(|(i, n)| (i + 27, n))) + .map(|(i, n)| (n, i)) + .collect(); + } + sigh.into_iter().map(|ref ch| PMAP.get(ch)).flat_map(std::convert::identity).copied() +} + +fn main() -> eyre::Result<()> { + init().wrap_err("Panic hook failed to install")?; + + let mut input = read_input()?; + + let mut psum = 0; + + while let Some(sack) = input.try_next() + { + let sack = sack.expect("Failed to parse input line"); + psum += prop_swivle(sack.intersection()) + .sum::(); + // TODO: part2: find sack.full's intersection through *all other* lines, up to two where the intersection is exactly 1 between all three. This is boring, I give up. + } + println!("{psum}"); + + Ok(()) +}