From 6921d46db3ccec4f3311685097d8c1e220a87886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Thu, 10 Dec 2020 23:41:34 +0000 Subject: [PATCH] Complete day 10 --- day-10/.gitignore | 1 + day-10/Cargo.lock | 78 ++++++++++++++++ day-10/Cargo.toml | 10 ++ day-10/input | 95 +++++++++++++++++++ day-10/src/main.rs | 225 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 409 insertions(+) create mode 100644 day-10/.gitignore create mode 100644 day-10/Cargo.lock create mode 100644 day-10/Cargo.toml create mode 100644 day-10/input create mode 100644 day-10/src/main.rs diff --git a/day-10/.gitignore b/day-10/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/day-10/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/day-10/Cargo.lock b/day-10/Cargo.lock new file mode 100644 index 0000000..a47b207 --- /dev/null +++ b/day-10/Cargo.lock @@ -0,0 +1,78 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "day-10" +version = "0.1.0" +dependencies = [ + "indoc", +] + +[[package]] +name = "indoc" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47741a8bc60fb26eb8d6e0238bbb26d8575ff623fdc97b1a2c00c050b9684ed8" +dependencies = [ + "indoc-impl", + "proc-macro-hack", +] + +[[package]] +name = "indoc-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce046d161f000fffde5f432a0d034d0341dc152643b2598ed5bfce44c4f3a8f0" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", + "unindent", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "unindent" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" diff --git a/day-10/Cargo.toml b/day-10/Cargo.toml new file mode 100644 index 0000000..14614ac --- /dev/null +++ b/day-10/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day-10" +version = "0.1.0" +authors = ["Tristan Daniƫl Maat "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +indoc = "0.3" diff --git a/day-10/input b/day-10/input new file mode 100644 index 0000000..f7374a0 --- /dev/null +++ b/day-10/input @@ -0,0 +1,95 @@ +76 +12 +97 +28 +132 +107 +145 +121 +84 +34 +115 +127 +22 +23 +11 +135 +113 +82 +140 +119 +69 +77 +83 +36 +13 +37 +92 +133 +122 +99 +147 +112 +42 +62 +65 +40 +123 +139 +33 +129 +149 +68 +41 +16 +48 +109 +5 +27 +142 +81 +90 +9 +78 +103 +26 +100 +141 +59 +55 +120 +126 +1 +35 +2 +20 +114 +58 +54 +10 +51 +116 +93 +6 +134 +108 +47 +70 +91 +138 +63 +19 +64 +148 +106 +21 +98 +43 +30 +146 +46 +128 +73 +94 +87 +29 diff --git a/day-10/src/main.rs b/day-10/src/main.rs new file mode 100644 index 0000000..3f7fd30 --- /dev/null +++ b/day-10/src/main.rs @@ -0,0 +1,225 @@ +use std::convert::TryInto; +use std::fs; + +fn main() -> Result<(), Box> { + let input = fs::read_to_string("input")?; + let jolts = parse_jolts(&input)?; + + // Part 1 + let result = chain_all(&jolts); + println!("{}", result.0 * result.1); + + // Part 2 + let result = count_possible_chains(&jolts)?; + println!("{}", result); + + Ok(()) +} + +fn count_possible_chains(jolts: &Vec) -> Result { + let mut jolts = jolts.to_vec(); + jolts.push(0); + jolts.sort(); + jolts.push(jolts.last().expect("Need some jolts") + 3); + + let window_lengths: Vec = jolts + .windows(2) + .scan(0, |length, window| { + if let [previous, current, _empty @ ..] = window { + if *current - *previous < 3 { + *length += 1; + Some(None) + } else { + let full_length = *length; + *length = 0; + Some(Some(full_length)) + } + } else { + unreachable!("Window size is 2"); + } + }) + .filter_map(|option| option) + .collect(); + + fn permutations(length: u32) -> u64 { + if length == 0 { + 1 + } else { + 2u64.pow(length - 1) - if length > 3 { 2u64.pow(length - 4) } else { 0 } + } + } + + window_lengths + .iter() + .map(|length| Ok(permutations((*length).try_into()?))) + .product() +} + +fn chain_all(jolts: &Vec) -> (usize, usize) { + let mut jolts = jolts.to_vec(); + jolts.push(0); + jolts.sort(); + jolts.push(jolts.last().expect("Need some jolts") + 3); + + let jolt_jumps: Vec = jolts + .windows(2) + .map(|window| { + if let [first, second, _empty @ ..] = window { + second - first + } else { + unreachable!("Window size is 2"); + } + }) + .collect(); + + let jump_1s = jolt_jumps.iter().filter(|e| **e == 1).count(); + let jump_3s = jolt_jumps.iter().filter(|e| **e == 3).count(); + + (jump_1s, jump_3s) +} + +fn parse_jolts(input: &str) -> Result, std::num::ParseIntError> { + input.lines().map(|line| line.parse()).collect() +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + #[test] + fn test_simple() -> Result<(), Box> { + let input = indoc!( + "16 + 10 + 15 + 5 + 1 + 11 + 7 + 19 + 6 + 12 + 4 + " + ); + + let jolts = parse_jolts(input)?; + let result = chain_all(&jolts); + + assert_eq!(result.0 * result.1, 7 * 5); + Ok(()) + } + + #[test] + fn test_simple2() -> Result<(), Box> { + let input = indoc!( + "28 + 33 + 18 + 42 + 31 + 14 + 46 + 20 + 48 + 47 + 24 + 23 + 49 + 45 + 19 + 38 + 39 + 11 + 1 + 32 + 25 + 35 + 8 + 17 + 7 + 9 + 4 + 2 + 34 + 10 + 3 + " + ); + + let jolts = parse_jolts(input)?; + let result = chain_all(&jolts); + + assert_eq!(result.0 * result.1, 22 * 10); + Ok(()) + } + + #[test] + fn test_simple3() -> Result<(), Box> { + let input = indoc!( + "16 + 10 + 15 + 5 + 1 + 11 + 7 + 19 + 6 + 12 + 4 + " + ); + + let jolts = parse_jolts(input)?; + let result = count_possible_chains(&jolts)?; + assert_eq!(result, 8); + + Ok(()) + } + + #[test] + fn test_simple4() -> Result<(), Box> { + let input = indoc!( + "28 + 33 + 18 + 42 + 31 + 14 + 46 + 20 + 48 + 47 + 24 + 23 + 49 + 45 + 19 + 38 + 39 + 11 + 1 + 32 + 25 + 35 + 8 + 17 + 7 + 9 + 4 + 2 + 34 + 10 + 3 + " + ); + + let jolts = parse_jolts(input)?; + let result = count_possible_chains(&jolts)?; + + assert_eq!(result, 19208); + Ok(()) + } +}