summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcos <cos>2019-12-04 14:32:58 +0100
committercos <cos>2019-12-04 14:32:58 +0100
commitd0ac44d6d968e6eb385a631745b63a5824908046 (patch)
treeffe0616512298a77ccaa87e9996057aa3bc2d7fb
parent80bfbefdb77a5153561ae4c1cb61d6d4e2b662c6 (diff)
downloadadventofcode-d0ac44d6d968e6eb385a631745b63a5824908046.zip
Add day04, 2019
-rw-r--r--2019/rust/Cargo.toml1
-rw-r--r--2019/rust/day04/Cargo.toml8
-rw-r--r--2019/rust/day04/src/main.rs73
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);
+}