From cab8962911ca83adf82b432d9f27e28c28305aa8 Mon Sep 17 00:00:00 2001 From: Malte Tammena Date: Sun, 25 Dec 2022 09:47:27 +0100 Subject: [PATCH] Solve first part of day25 --- Cargo.lock | 63 ++++++++++-------- Cargo.toml | 2 +- day25/Cargo.toml | 10 +++ day25/input | 116 ++++++++++++++++++++++++++++++++ day25/input.test | 13 ++++ day25/src/main.rs | 165 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 340 insertions(+), 29 deletions(-) create mode 100644 day25/Cargo.toml create mode 100644 day25/input create mode 100644 day25/input.test create mode 100644 day25/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index f1371a8..41e2869 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ checksum = "2dbdbb2877d26e0647c6b8125802b2ecf2dc2a28d864dde41e6f9b9a54da08fe" [[package]] name = "async-trait" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3" dependencies = [ "proc-macro2", "quote", @@ -129,9 +129,9 @@ checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" [[package]] name = "cc" -version = "1.0.77" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cfg-if" @@ -141,9 +141,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.0.29" +version = "4.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" +checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39" dependencies = [ "bitflags", "clap_derive", @@ -179,9 +179,9 @@ dependencies = [ [[package]] name = "colorous" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882e392738ed515520f38708166e9efec85ee154f80bf1fc64510e2fc54bf481" +checksum = "2875caafcad10de47ec09ead140f27a276a25b0b2f553cec9b2152194b96bf5d" [[package]] name = "darling" @@ -376,6 +376,13 @@ version = "0.1.0" [[package]] name = "day24" version = "0.1.0" +dependencies = [ + "bitvec", +] + +[[package]] +name = "day25" +version = "0.1.0" [[package]] name = "errno" @@ -539,9 +546,9 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" dependencies = [ "hermit-abi", "io-lifetimes", @@ -586,15 +593,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "linux-raw-sys" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "logos" @@ -687,18 +694,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -799,9 +806,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" [[package]] name = "smallvec" @@ -820,9 +827,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -868,18 +875,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -911,9 +918,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "version_check" diff --git a/Cargo.toml b/Cargo.toml index cb76fbe..2c6baae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = [ "day01", "day01-gen-problem", "day02", "day02-gen-problem", "day03", "day03-gen-problem", "day04", "day05", "day06", "day07", "day08", "day09", "day10", "day11", "day12", "day12-tim", "day13", "day14", "day15", "day16", "day17", "day18", "day19", "day20", "day21", "day22", "day23", "day24", ] +members = [ "day01", "day01-gen-problem", "day02", "day02-gen-problem", "day03", "day03-gen-problem", "day04", "day05", "day06", "day07", "day08", "day09", "day10", "day11", "day12", "day12-tim", "day13", "day14", "day15", "day16", "day17", "day18", "day19", "day20", "day21", "day22", "day23", "day24", "day25", ] [profile.release] #debug = true diff --git a/day25/Cargo.toml b/day25/Cargo.toml new file mode 100644 index 0000000..3b2f2b9 --- /dev/null +++ b/day25/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day25" +version = "0.1.0" +edition = "2021" + +[package.metadata.nix] +build = true +app = true + +[dependencies] diff --git a/day25/input b/day25/input new file mode 100644 index 0000000..4837f2e --- /dev/null +++ b/day25/input @@ -0,0 +1,116 @@ +1-12212=-=--=0221 +1----2-1 +1=2==-1-1=1-02--- +220--0=2-01- +2=02-101-2-0221 +10=-21- +1-02-0-10=0002 +20 +1==0- +22-1201-011= +1- +22=21 +121-=02=1--222 +2=-=2 +1--1=-2-002-=-21 +1=-=1=1-==0=- +1-==01000-1-121 +1=0=1==00=1- +2110-1-21201002-0=1 +1--=11 +2=0-0-2=20020=1=1 +1-0=2-=12020111-1222 +101-=0--=1=00101 +2-=022-0-22=12=-0 +2=-1201-20==-2=20 +1-=21001 +1==2210220 +1=-21--1- +1--==0212-10021-=1 +10- +102011-0=2= +22-100=---0-0 +1-0222--0-220-- +10211 +1-2--=10=-1- +1-20-111 +1-1202=1=021 +2==0==0-0=2 +2=210=01--=011- +21- +1=02-210-0 +11 +1-0-21===0-=1-=2- +10=22012=2-0-12- +112 +21-1-22 +1=0010021=01 +2-0=120 +1=0-0-2-0-= +212=20-- +1-=1--21-= +1-- +2-12---=1202-1 +2=1 +1-0-11=021 +2-0-120- +1-=10102-0-11201121 +1021--- +1=02=0012=-00=211 +10-1=2-0=-1-= +11-1=0==1 +1=-1--12222 +1=00-0 +1--211 +1=10-=2=22--==- +1=0=12--212=--=-1 +10200 +100=22=020210=12=- +2-1=0=221 +1-02-0= +2-1-20 +220=20 +22=202 +1==11=-11 +21=21=10=2=2= +10100=-1===--2--=- +1=-012=1 +210==0=-0-2120 +1002220--00=22 +1-2 +202-=1221-=----1 +202-0201122-2 +10010-02=02-1 +11=02-0--2=-10 +1==2-22--=1=-12=-- +12000 +1===1--=2-2=2----== +10-12= +1=1--=2==12 +1-2=0=12=0 +1=-1 +1=2-=0=020=-00= +1-0-211- +12-=1=01=0=22-2==2 +2=2=0-02-2 +212022 +101=11= +1=00-2==0201==1 +2=-011=212221=212 +2-2 +1=-20-=--101 +1-212=12=0-0==1- +2--2-1-0-11-2 +20- +11-----0- +102--=1011=01 +1--11-- +1-2=1=1==20111 +21200-===20 +1-0=12-0= +2--- +20-2= +1=- +221-== +1-01212==01-1220 +1-01202=10--010001 diff --git a/day25/input.test b/day25/input.test new file mode 100644 index 0000000..237ef0c --- /dev/null +++ b/day25/input.test @@ -0,0 +1,13 @@ +1=-0-2 +12111 +2=0= +21 +2=01 +111 +20012 +112 +1=-1= +1-12 +12 +1= +122 \ No newline at end of file diff --git a/day25/src/main.rs b/day25/src/main.rs new file mode 100644 index 0000000..bb4b22e --- /dev/null +++ b/day25/src/main.rs @@ -0,0 +1,165 @@ +use std::{ + convert::Infallible, + fmt::Display, + fs::File, + io::{BufRead, BufReader}, + ops::Add, + str::FromStr, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +struct Snafu(isize); + +fn solve(reader: R) -> Snafu { + reader + .lines() + .map(Result::unwrap) + .map(|line| line.parse::()) + .map(Result::unwrap) + .sum() +} + +fn main() { + let mut args = ::std::env::args().skip(1); + let file = args.next().unwrap_or_else(|| String::from("./input")); + let file = BufReader::new(File::open(file).expect("Opening file")); + println!("{}", solve(file)) +} + +impl FromStr for Snafu { + type Err = Infallible; + + fn from_str(s: &str) -> Result { + let dec = s + .as_bytes() + .iter() + .rev() + .map(|&byte| match byte { + b'=' => -2_isize, + b'-' => -1, + b'0' => 0, + b'1' => 1, + b'2' => 2, + _ => unreachable!(), + }) + .scan(0_u32, |power, number| { + let base5 = number * 5_isize.pow(*power); + *power += 1; + Some(base5) + }) + .sum(); + Ok(Self(dec)) + } +} + +impl PartialEq for Snafu { + fn eq(&self, other: &isize) -> bool { + self.0.eq(other) + } +} + +impl From for Snafu { + fn from(raw: isize) -> Self { + Snafu(raw) + } +} + +impl Display for Snafu { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut target = self.0; + let mut power = (target.abs() * 2).ilog(5); + loop { + let five_pow = 5_isize.pow(power); + // The digit can be found by checking into which interval the target value falls + // [(x - 0.5) * 5^p, .., (x + 0.5) * 5^p] where x in [-2, .., 2] + let digit = (-2..=2) + .find(|&x| { + // Double everything to get rid of the floats + let from = (2 * x - 1) * five_pow; + let to = (2 * x + 1) * five_pow; + (from..to).contains(&(2 * target)) + }) + .unwrap(); + write!( + f, + "{}", + match digit { + -2 => "=", + -1 => "-", + 0 => "0", + 1 => "1", + 2 => "2", + digit => unreachable!("What, why {digit}"), + } + )?; + target -= digit * five_pow; + if power == 0 { + break Ok(()); + } + power -= 1; + } + } +} + +impl Add for Snafu { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +impl std::iter::Sum for Snafu { + fn sum>(iter: I) -> Self { + iter.fold(Snafu::from(0), |acc, snafu| acc + snafu) + } +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + fn example() { + let reader = Cursor::new(include_str!("../input.test")); + assert_eq!(solve(reader).to_string(), "2=-1=0"); + } + + #[test] + fn snafu_parsing() { + assert_eq!(Snafu::from_str("1=-0-2").unwrap(), 1747); + assert_eq!(Snafu::from_str("12111").unwrap(), 906); + assert_eq!(Snafu::from_str("2=0=").unwrap(), 198); + assert_eq!(Snafu::from_str("21").unwrap(), 11); + assert_eq!(Snafu::from_str("2=01").unwrap(), 201); + assert_eq!(Snafu::from_str("111").unwrap(), 31); + assert_eq!(Snafu::from_str("20012").unwrap(), 1257); + assert_eq!(Snafu::from_str("112").unwrap(), 32); + assert_eq!(Snafu::from_str("1=-1=").unwrap(), 353); + assert_eq!(Snafu::from_str("1-12").unwrap(), 107); + assert_eq!(Snafu::from_str("12").unwrap(), 7); + assert_eq!(Snafu::from_str("1=").unwrap(), 3); + assert_eq!(Snafu::from_str("122").unwrap(), 37); + } + + #[test] + fn snafu_formatting() { + assert_eq!(Snafu::from(1).to_string(), "1"); + assert_eq!(Snafu::from(2).to_string(), "2"); + assert_eq!(Snafu::from(3).to_string(), "1="); + assert_eq!(Snafu::from(4).to_string(), "1-"); + assert_eq!(Snafu::from(5).to_string(), "10"); + assert_eq!(Snafu::from(6).to_string(), "11"); + assert_eq!(Snafu::from(7).to_string(), "12"); + assert_eq!(Snafu::from(8).to_string(), "2="); + assert_eq!(Snafu::from(9).to_string(), "2-"); + assert_eq!(Snafu::from(10).to_string(), "20"); + assert_eq!(Snafu::from(15).to_string(), "1=0"); + assert_eq!(Snafu::from(20).to_string(), "1-0"); + assert_eq!(Snafu::from(2022).to_string(), "1=11-2"); + assert_eq!(Snafu::from(12345).to_string(), "1-0---0"); + assert_eq!(Snafu::from(314159265).to_string(), "1121-1110-1=0"); + } +}