Day 4 part 1&2
authorGreg Burri <greg.burri@gmail.com>
Wed, 1 Jan 2020 19:18:28 +0000 (20:18 +0100)
committerGreg Burri <greg.burri@gmail.com>
Wed, 1 Jan 2020 19:18:28 +0000 (20:18 +0100)
src/common.rs
src/day04.rs
src/day17.rs
src/day18.rs [new file with mode: 0644]
src/main.rs

index b3db167..f22fbfd 100644 (file)
@@ -9,7 +9,7 @@ where
     T::Err: std::fmt::Debug\r
 \r
 {\r
-    fs::read_to_string(file).unwrap().split(sep).map(|line| line.parse::<T>().unwrap()).collect()\r
+    fs::read_to_string(file).unwrap().split(sep).map(|line| line.trim().parse::<T>().unwrap()).collect()\r
 }\r
 \r
 pub fn layer_to_printable_string(layer: &[u8], width: usize) -> String {\r
index 8a5064f..42fb047 100644 (file)
@@ -1,16 +1,90 @@
+use std::cmp::Ordering;\r
 \r
+pub fn parse_range(raw: &str) -> (i32, i32) {\r
+    let nums: Vec<i32> = raw.trim().split('-').map(|n| n.parse::<i32>().unwrap()).collect();\r
+    (nums[0], nums[1])\r
+}\r
+\r
+type Digits = Vec<u8>;\r
+\r
+fn get_digits(value: i32) -> Digits {\r
+    let mut digits = Vec::<u8>::new();\r
+    let mut value = value;\r
+    while value > 0 {\r
+        digits.push((value % 10) as u8);\r
+        value /= 10;\r
+    }\r
+    digits\r
+}\r
 \r
-fn find_password(min: i32) {\r
-    ;\r
+pub fn nb_passwords_part1(min: i32, max: i32) -> i32 {\r
+    nb_passwords(\r
+        min,\r
+        max,\r
+        &|digits: &Digits| {\r
+            for i in 1 .. digits.len() {\r
+                if digits[i - 1] == digits[i] { return true; }\r
+            }\r
+            false\r
+        }\r
+    )\r
 }\r
 \r
+pub fn nb_passwords_part2(min: i32, max: i32) -> i32 {\r
+    nb_passwords(\r
+        min,\r
+        max,\r
+        &|digits: &Digits| {\r
+            let mut last = digits[0];\r
+            let mut n = 1;\r
+            for i in 1 .. digits.len() {\r
+                if digits[i] == last {\r
+                    n += 1;\r
+                } else {\r
+                    if n == 2 { return true; }\r
+                    n = 1;\r
+                }\r
+                last = digits[i];\r
+            }\r
+            n == 2\r
+        }\r
+    )\r
+}\r
+\r
+fn nb_passwords(min: i32, max: i32, valid_password: &dyn Fn(&Digits) -> bool) -> i32 {\r
+    let mut digits = get_digits(min);\r
+    let digits_max = get_digits(max);\r
+    let l = digits.len();\r
+\r
+    fn set_range(from: usize, to: usize, value: u8, digits: &mut Digits) {\r
+        for i in from .. to { digits[i] = value; }\r
+    };\r
+\r
+    for i in (1 .. l).rev() {\r
+        if digits[i - 1] < digits[i] {\r
+            set_range(0, i, digits[i], &mut digits);\r
+            break;\r
+        }\r
+    }\r
+\r
+    let mut n = 0;\r
 \r
+    loop {\r
+        if valid_password(&digits) { n += 1; }\r
 \r
-#[cfg(test)]\r
-mod tests {\r
-    use super::*;\r
+        for i in 0 .. l {\r
+            if i == l - 1 || digits[i + 1] <= digits[i] && digits[i] != 9 {\r
+                set_range(0, i + 1, digits[i] + 1, &mut digits);\r
+                break;\r
+            }\r
+        }\r
 \r
-    #[test]\r
-    fn part1() {\r
+        for i in (0 .. l).rev() {\r
+            match digits[i].cmp(&digits_max[i]) {\r
+                Ordering::Greater => return n,\r
+                Ordering::Less => break,\r
+                Ordering::Equal => ()\r
+            }\r
+        }\r
     }\r
 }
\ No newline at end of file
index f120506..52d5988 100644 (file)
@@ -139,7 +139,7 @@ impl RobotTrackingSystem {
 }\r
 \r
 impl intcode::IO for RobotTrackingSystem {\r
-    // May block.\r
+    // Read instructions \r
     fn read(&mut self) -> i64 {\r
         self.build_board_from_output();\r
         42 // TODO: part2.\r
diff --git a/src/day18.rs b/src/day18.rs
new file mode 100644 (file)
index 0000000..ff90b85
--- /dev/null
@@ -0,0 +1,19 @@
+
+pub fn parse(input: &str) {
+
+}
+
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn part1_sample1() {
+        let input =
+            "#########
+             #b.A.@.a#
+             #########";
+
+    }
+}
\ No newline at end of file
index c66dfc9..71eec79 100644 (file)
@@ -7,6 +7,7 @@ mod intcode;
 mod day01;
 mod day02;
 mod day03;
+mod day04;
 mod day06;
 mod day07;
 mod day08;
@@ -18,6 +19,7 @@ mod day14;
 mod day15;
 mod day16;
 mod day17;
+mod day18;
 
 fn day01() -> String {
     let masses = common::read_list_of_numbers("data/day01.input", "\n");
@@ -40,7 +42,9 @@ fn day03() -> String {
 }
 
 fn day04() -> String {
-    format!("")
+    let raw = fs::read_to_string("data/day04.input").unwrap();
+    let (min, max) = day04::parse_range(&raw);
+    format!("part1: {:?}, part2: {}", day04::nb_passwords_part1(min, max), day04::nb_passwords_part2(min, max))
 }
 
 fn day05() -> String {
@@ -136,6 +140,10 @@ fn day17() -> String {
 
 }
 
+fn day18() -> String {
+    format!("part1: {}, part2: {}", "", "")
+}
+
 fn format_micros(t: u128) -> String {
     if t < 10_000 {
         format!("{} μs", t)
@@ -172,6 +180,7 @@ fn main() {
         day15,
         day16,
         day17,
+        day18,
     );
 
     let args: Vec<String> = env::args().skip(1).collect();