diff options
author | cos <cos> | 2019-12-04 14:32:58 +0100 |
---|---|---|
committer | cos <cos> | 2019-12-04 14:32:58 +0100 |
commit | d0ac44d6d968e6eb385a631745b63a5824908046 (patch) | |
tree | ffe0616512298a77ccaa87e9996057aa3bc2d7fb | |
parent | 80bfbefdb77a5153561ae4c1cb61d6d4e2b662c6 (diff) | |
download | adventofcode-d0ac44d6d968e6eb385a631745b63a5824908046.zip |
Add day04, 2019
-rw-r--r-- | 2019/rust/Cargo.toml | 1 | ||||
-rw-r--r-- | 2019/rust/day04/Cargo.toml | 8 | ||||
-rw-r--r-- | 2019/rust/day04/src/main.rs | 73 |
3 files changed, 82 insertions, 0 deletions
diff --git a/2019/rust/Cargo.toml b/2019/rust/Cargo.toml index b5a41d5..caf0fc3 100644 --- a/2019/rust/Cargo.toml +++ b/2019/rust/Cargo.toml @@ -3,4 +3,5 @@ members = [ "day01", "day02", "day03", + "day04", ] diff --git a/2019/rust/day04/Cargo.toml b/2019/rust/day04/Cargo.toml new file mode 100644 index 0000000..63acdbe --- /dev/null +++ b/2019/rust/day04/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day04" +version = "0.1.0" +authors = ["cos <cos>"] +edition = "2018" + +[dependencies] +itertools = "*" diff --git a/2019/rust/day04/src/main.rs b/2019/rust/day04/src/main.rs new file mode 100644 index 0000000..c4cadef --- /dev/null +++ b/2019/rust/day04/src/main.rs @@ -0,0 +1,73 @@ +use itertools::Itertools; +use std::env; + +fn is_increasing(n:u32) -> bool { + for (l, r) in (0..5).rev().map(|e| n/10u32.pow(e)%10) + .zip((1..6).rev().map(|e| n/10u32.pow(e)%10)) + { + if l < r { return false; } + } + + true +} + +fn has_repeated(n:u32) -> bool { + for (l, r) in (0..5).rev().map(|e| n/10u32.pow(e)%10) + .zip((1..6).rev().map(|e| n/10u32.pow(e)%10)) + { + if l == r { return true; } + } + + false +} +fn has_double(n:u32) -> bool { + #[derive(Debug, PartialEq)] + enum State { NoMatch, Matching, TooLong, Verified }; + let mut state = State::NoMatch; + + for (l, r) in (0..5).rev().map(|e| n/10u32.pow(e)%10) + .zip((1..6).rev().map(|e| n/10u32.pow(e)%10)) + { + state = match state { + State::NoMatch => if l == r { State::Matching } else { State::NoMatch }, + State::Matching => if l == r { State::TooLong } else { State::Verified }, + State::TooLong => if l == r { State::TooLong } else { State::NoMatch }, + State::Verified => State::Verified, + }; + if state == State::Verified { break; } + } + + state == State::Verified || state == State::Matching +} + +fn first_puzzle(input:String) -> usize { + let ( start, end ) = input.split("-") + .map(|s| s.parse::<u32>().unwrap()) + .next_tuple().unwrap(); + + (start..=end) + .filter(|n| is_increasing(*n)) + .filter(|n| has_repeated(*n)) + .count() +} + +fn second_puzzle(input:String) -> usize { + let ( start, end ) = input.split("-") + .map(|s| s.parse::<u32>().unwrap()) + .next_tuple().unwrap(); + + (start..=end) + .filter(|n| is_increasing(*n)) + .filter(|n| has_double(*n)) + .count() +} + +fn main() { + let input = env::args().nth(1).expect("Please provide a valid range as first argument."); + + let first = first_puzzle(input.clone()); + println!("Solution to first part: {}.", first); + + let second = second_puzzle(input); + println!("Solution to second part: {}.", second); +} |