Format the code to standards
authorGreg Burri <greg.burri@gmail.com>
Tue, 10 Dec 2024 21:16:09 +0000 (22:16 +0100)
committerGreg Burri <greg.burri@gmail.com>
Tue, 10 Dec 2024 21:16:09 +0000 (22:16 +0100)
20 files changed:
.gitignore
data/put_your_data_files_here.txt [new file with mode: 0644]
src/day01.rs
src/day02.rs
src/day03.rs
src/day04.rs
src/day06.rs
src/day07.rs
src/day08.rs
src/day10.rs
src/day11.rs
src/day12.rs
src/day13.rs
src/day14.rs
src/day15.rs
src/day16.rs
src/day17.rs
src/day18.rs
src/intcode.rs
src/main.rs

index 94bb2fb..4d34c50 100644 (file)
@@ -8,4 +8,5 @@ Cargo.lock
 
 # These are backup files generated by rustfmt
 **/*.rs.bk
-data/day08.png
+
+data/day*
\ No newline at end of file
diff --git a/data/put_your_data_files_here.txt b/data/put_your_data_files_here.txt
new file mode 100644 (file)
index 0000000..52a6950
--- /dev/null
@@ -0,0 +1 @@
+Filename: "dayXX.input"
\ No newline at end of file
index ca1d470..922a685 100644 (file)
@@ -3,7 +3,9 @@ pub fn sum_mass_to_fuel(masses: &[i32]) -> i32 {
 }\r
 \r
 pub fn sum_mass_to_fuel_2(masses: &[i32]) -> i32 {\r
-    masses.iter().fold(0, |sum, mass| sum + mass_to_fuel_2(*mass))\r
+    masses\r
+        .iter()\r
+        .fold(0, |sum, mass| sum + mass_to_fuel_2(*mass))\r
 }\r
 \r
 fn mass_to_fuel(mass: i32) -> i32 {\r
@@ -15,7 +17,9 @@ fn mass_to_fuel_2(mass: i32) -> i32 {
     let mut current_mass = mass;\r
     loop {\r
         let fuel = mass_to_fuel(current_mass);\r
-        if fuel <= 0 { break }\r
+        if fuel <= 0 {\r
+            break;\r
+        }\r
         current_mass = fuel;\r
         sum += fuel;\r
     }\r
@@ -40,4 +44,4 @@ mod tests {
         assert_eq!(mass_to_fuel_2(1969), 966);\r
         assert_eq!(mass_to_fuel_2(100_756), 50346);\r
     }\r
-}
\ No newline at end of file
+}\r
index fd26331..cd361e2 100644 (file)
@@ -8,10 +8,16 @@ fn execute_op_code(code: &mut [i32]) -> i32 {
     let mut cursor = 0;\r
     loop {\r
         match code[cursor] {\r
-            1 => code[code[cursor + 3] as usize] = code[code[cursor + 1] as usize] + code[code[cursor + 2] as usize],\r
-            2 => code[code[cursor + 3] as usize] = code[code[cursor + 1] as usize] * code[code[cursor + 2] as usize],\r
+            1 => {\r
+                code[code[cursor + 3] as usize] =\r
+                    code[code[cursor + 1] as usize] + code[code[cursor + 2] as usize]\r
+            }\r
+            2 => {\r
+                code[code[cursor + 3] as usize] =\r
+                    code[code[cursor + 1] as usize] * code[code[cursor + 2] as usize]\r
+            }\r
             99 => return code[0],\r
-            _ => panic!("Unknown code: {}", code[cursor])\r
+            _ => panic!("Unknown code: {}", code[cursor]),\r
         }\r
         cursor += 4;\r
     }\r
@@ -25,7 +31,7 @@ pub fn find_noun_and_verb(code: &[i32]) -> i32 {
                 code_copy[1] = noun;\r
                 code_copy[2] = verb;\r
                 if execute_op_code(&mut code_copy) == 19_690_720 {\r
-                    return 100 * noun + verb\r
+                    return 100 * noun + verb;\r
                 }\r
             }\r
         }\r
@@ -54,4 +60,4 @@ mod tests {
         execute_op_code(&mut c4);\r
         assert_eq!(c4[0], 30);\r
     }\r
-}
\ No newline at end of file
+}\r
index cb50f8a..f6f16b8 100644 (file)
@@ -1,4 +1,7 @@
-use std::{collections::{HashMap, HashSet}, iter::{Iterator, FromIterator}};\r
+use std::{\r
+    collections::{HashMap, HashSet},\r
+    iter::{FromIterator, Iterator},\r
+};\r
 \r
 pub fn split_movements(movements: &str) -> Vec<&str> {\r
     movements.split(',').collect()\r
@@ -10,10 +13,30 @@ fn positions(wire: &[&str]) -> Vec<(i32, i32)> {
     for mov in wire {\r
         let distance = mov[1..].parse::<i32>().unwrap();\r
         match mov.chars().nth(0).unwrap() {\r
-            'U'      => { for y2 in  y+1 ..= y + distance     { pos.push((x, y2)); } y += distance },\r
-            'D'      => { for y2 in (y - distance .. y).rev() { pos.push((x, y2)); } y -= distance },\r
-            'R'      => { for x2 in  x+1 ..= x + distance     { pos.push((x2, y)); } x += distance },\r
-            'L' | _  => { for x2 in (x - distance .. x).rev() { pos.push((x2, y)); } x -= distance },\r
+            'U' => {\r
+                for y2 in y + 1..=y + distance {\r
+                    pos.push((x, y2));\r
+                }\r
+                y += distance\r
+            }\r
+            'D' => {\r
+                for y2 in (y - distance..y).rev() {\r
+                    pos.push((x, y2));\r
+                }\r
+                y -= distance\r
+            }\r
+            'R' => {\r
+                for x2 in x + 1..=x + distance {\r
+                    pos.push((x2, y));\r
+                }\r
+                x += distance\r
+            }\r
+            'L' | _ => {\r
+                for x2 in (x - distance..x).rev() {\r
+                    pos.push((x2, y));\r
+                }\r
+                x -= distance\r
+            }\r
         }\r
     }\r
     pos\r
@@ -28,18 +51,26 @@ pub fn manhattan_distance_from_cross_to_port(wire1: &[&str], wire2: &[&str]) ->
 \r
 pub fn first_cross_sum_of_lengths(wire1: &[&str], wire2: &[&str]) -> usize {\r
     let positions_wire1 = positions(wire1);\r
-    let positions_wire1_indexed: HashMap<&(i32, i32), usize> = HashMap::from_iter(positions_wire1.iter().enumerate().map(|(i, pos)| (pos, i)).rev());\r
+    let positions_wire1_indexed: HashMap<&(i32, i32), usize> = HashMap::from_iter(\r
+        positions_wire1\r
+            .iter()\r
+            .enumerate()\r
+            .map(|(i, pos)| (pos, i))\r
+            .rev(),\r
+    );\r
 \r
     positions(wire2)\r
-        .iter().enumerate().filter_map(\r
-            |(j, pos2)| {\r
-                if let Some (i) = positions_wire1_indexed.get(pos2) {\r
-                    Some (j + i + 2)\r
-                } else {\r
-                    None\r
-                }\r
+        .iter()\r
+        .enumerate()\r
+        .filter_map(|(j, pos2)| {\r
+            if let Some(i) = positions_wire1_indexed.get(pos2) {\r
+                Some(j + i + 2)\r
+            } else {\r
+                None\r
             }\r
-        ).min().unwrap()\r
+        })\r
+        .min()\r
+        .unwrap()\r
 }\r
 \r
 #[cfg(test)]\r
@@ -99,4 +130,4 @@ mod tests {
             410\r
         );\r
     }\r
-}
\ No newline at end of file
+}\r
index 5f66df4..c575472 100644 (file)
@@ -1,7 +1,11 @@
 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
+    let nums: Vec<i32> = raw\r
+        .trim()\r
+        .split('-')\r
+        .map(|n| n.parse::<i32>().unwrap())\r
+        .collect();\r
     (nums[0], nums[1])\r
 }\r
 \r
@@ -18,37 +22,33 @@ fn get_digits(value: i32) -> Digits {
 }\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
+    nb_passwords(min, max, &|digits: &Digits| {\r
+        for i in 1..digits.len() {\r
+            if digits[i - 1] == digits[i] {\r
+                return true;\r
             }\r
-            false\r
         }\r
-    )\r
+        false\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 d in &digits[1..] {\r
-                if *d == last {\r
-                    n += 1;\r
-                } else {\r
-                    if n == 2 { return true; }\r
-                    n = 1;\r
+    nb_passwords(min, max, &|digits: &Digits| {\r
+        let mut last = digits[0];\r
+        let mut n = 1;\r
+        for d in &digits[1..] {\r
+            if *d == last {\r
+                n += 1;\r
+            } else {\r
+                if n == 2 {\r
+                    return true;\r
                 }\r
-                last = *d;\r
+                n = 1;\r
             }\r
-            n == 2\r
+            last = *d;\r
         }\r
-    )\r
+        n == 2\r
+    })\r
 }\r
 \r
 fn nb_passwords(min: i32, max: i32, valid_password: &dyn Fn(&Digits) -> bool) -> i32 {\r
@@ -57,10 +57,12 @@ fn nb_passwords(min: i32, max: i32, valid_password: &dyn Fn(&Digits) -> bool) ->
     let l = digits.len();\r
 \r
     fn set_range(from: usize, to: usize, value: u8, digits: &mut Digits) {\r
-        for d in &mut digits[from .. to] { *d = value; }\r
+        for d in &mut digits[from..to] {\r
+            *d = value;\r
+        }\r
     }\r
 \r
-    for i in (1 .. l).rev() {\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
@@ -70,21 +72,23 @@ fn nb_passwords(min: i32, max: i32, valid_password: &dyn Fn(&Digits) -> bool) ->
     let mut n = 0;\r
 \r
     loop {\r
-        if valid_password(&digits) { n += 1; }\r
+        if valid_password(&digits) {\r
+            n += 1;\r
+        }\r
 \r
-        for i in 0 .. l {\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
-        for i in (0 .. l).rev() {\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
+                Ordering::Equal => (),\r
             }\r
         }\r
     }\r
-}
\ No newline at end of file
+}\r
index 1ff649d..77ae402 100644 (file)
@@ -16,7 +16,7 @@ fn parents<'a>(orbits: &'a Orbits, planet: &str) -> Vec<&'a str> {
     let mut parents = Vec::<&str>::new();
     let mut current_planet = planet;
 
-    while let Some (parent) = orbits.get(current_planet) {
+    while let Some(parent) = orbits.get(current_planet) {
         parents.insert(0, parent);
         current_planet = parent;
     }
@@ -25,7 +25,9 @@ fn parents<'a>(orbits: &'a Orbits, planet: &str) -> Vec<&'a str> {
 }
 
 pub fn total_direct_and_indirect_orbits(orbits: &Orbits) -> usize {
-    orbits.keys().fold(0, |sum, planet| { sum + parents(orbits, &planet).len() })
+    orbits
+        .keys()
+        .fold(0, |sum, planet| sum + parents(orbits, &planet).len())
 }
 
 pub fn nb_orbital_transfers(orbits: &Orbits, loc1: &str, loc2: &str) -> usize {
@@ -33,7 +35,7 @@ pub fn nb_orbital_transfers(orbits: &Orbits, loc1: &str, loc2: &str) -> usize {
     let parents_loc2 = parents(orbits, loc2);
     for i in 0..cmp::min(parents_loc1.len(), parents_loc2.len()) {
         if parents_loc1[i] != parents_loc2[i] {
-            return parents_loc1.len() + parents_loc2.len() - 2 * i
+            return parents_loc1.len() + parents_loc2.len() - 2 * i;
         }
     }
     0
@@ -45,8 +47,7 @@ mod tests {
 
     #[test]
     fn part1() {
-        let lines: Vec<&str> =
-            "COM)B
+        let lines: Vec<&str> = "COM)B
                 B)C
                 C)D
                 D)E
@@ -56,7 +57,9 @@ mod tests {
                 D)I
                 E)J
                 J)K
-                K)L".lines().collect();
+                K)L"
+        .lines()
+        .collect();
 
         let n = total_direct_and_indirect_orbits(&build_orbits(&lines));
         assert_eq!(n, 42);
@@ -64,8 +67,7 @@ mod tests {
 
     #[test]
     fn part2() {
-        let lines: Vec<&str> =
-            "COM)B
+        let lines: Vec<&str> = "COM)B
                 B)C
                 C)D
                 D)E
@@ -77,9 +79,11 @@ mod tests {
                 J)K
                 K)L
                 K)YOU
-                I)SAN".lines().collect();
+                I)SAN"
+            .lines()
+            .collect();
 
         let n = nb_orbital_transfers(&build_orbits(&lines), "SAN", "YOU");
         assert_eq!(n, 4);
     }
-}
\ No newline at end of file
+}
index 1ab98f7..6d4ecdc 100644 (file)
@@ -1,4 +1,8 @@
-use std::sync::{Arc, Barrier, mpsc::{self, Sender, Receiver}, atomic::{AtomicI64, Ordering}};\r
+use std::sync::{\r
+    atomic::{AtomicI64, Ordering},\r
+    mpsc::{self, Receiver, Sender},\r
+    Arc, Barrier,\r
+};\r
 \r
 use itertools::Itertools;\r
 use threadpool::ThreadPool;\r
@@ -6,17 +10,23 @@ use threadpool::ThreadPool;
 use super::intcode;\r
 \r
 fn last_thruster_signal(code: &[i64], phase_setting: &[i64]) -> i64 {\r
-    phase_setting.iter().fold(0, |last_output, input| intcode::execute_op_code(&code, &[*input, last_output])[0])\r
+    phase_setting.iter().fold(0, |last_output, input| {\r
+        intcode::execute_op_code(&code, &[*input, last_output])[0]\r
+    })\r
 }\r
 \r
 pub fn find_largest_last_thruster_signal(code: &[i64]) -> i64 {\r
-    (0i64 ..= 4i64).permutations(5).map(|phase_setting| last_thruster_signal(&code, &phase_setting)).max().unwrap()\r
+    (0i64..=4i64)\r
+        .permutations(5)\r
+        .map(|phase_setting| last_thruster_signal(&code, &phase_setting))\r
+        .max()\r
+        .unwrap()\r
 }\r
 \r
 struct Stage {\r
     input_channel: mpsc::Receiver<i64>,\r
     output_channel: mpsc::Sender<i64>,\r
-    last_produced_value: i64\r
+    last_produced_value: i64,\r
 }\r
 \r
 impl intcode::IO for Stage {\r
@@ -24,7 +34,7 @@ impl intcode::IO for Stage {
     fn read(&mut self) -> i64 {\r
         match self.input_channel.recv() {\r
             Ok(value) => value,\r
-            Err(_) => 0\r
+            Err(_) => 0,\r
         }\r
     }\r
 \r
@@ -35,23 +45,30 @@ impl intcode::IO for Stage {
     }\r
 }\r
 \r
-fn last_thruster_signal_with_feedback_loop(code: &[i64], phase_setting: &[i64], pool: &ThreadPool) -> i64 {\r
+fn last_thruster_signal_with_feedback_loop(\r
+    code: &[i64],\r
+    phase_setting: &[i64],\r
+    pool: &ThreadPool,\r
+) -> i64 {\r
     let n = phase_setting.len();\r
 \r
     let mut senders = Vec::<Sender<i64>>::new();\r
     let mut receivers = Vec::<Receiver<i64>>::new();\r
 \r
-    for (i, (s, r)) in (0 .. n).map(|i| (i, mpsc::channel::<i64>())) {\r
+    for (i, (s, r)) in (0..n).map(|i| (i, mpsc::channel::<i64>())) {\r
         // Initial values.\r
         s.send(phase_setting[i]).unwrap_or_default();\r
-        if i == 0 { s.send(0).unwrap_or_default(); }\r
+        if i == 0 {\r
+            s.send(0).unwrap_or_default();\r
+        }\r
 \r
         senders.insert(if i == 0 { 0 } else { i - 1 }, s);\r
         receivers.push(r);\r
     }\r
 \r
     // Prepare each pair of received and sender for the each stages.\r
-    let mut channels: Vec<(Receiver<i64>, Sender<i64>)> = receivers.drain(..).zip(senders.drain(..)).collect();\r
+    let mut channels: Vec<(Receiver<i64>, Sender<i64>)> =\r
+        receivers.drain(..).zip(senders.drain(..)).collect();\r
 \r
     let result = Arc::new(AtomicI64::new(0));\r
     let barrier = Arc::new(Barrier::new(2));\r
@@ -61,16 +78,18 @@ fn last_thruster_signal_with_feedback_loop(code: &[i64], phase_setting: &[i64],
         let barrier = barrier.clone();\r
         let result = result.clone();\r
 \r
-        pool.execute(\r
-            move || {\r
-                let mut stage = Stage { input_channel: receiver, output_channel: sender, last_produced_value: 0 };\r
-                intcode::execute_op_code_with_custom_io(&code_copy, &mut stage);\r
-                if i == 4 {\r
-                    result.store(stage.last_produced_value, Ordering::Relaxed);\r
-                    barrier.wait();\r
-                }\r
+        pool.execute(move || {\r
+            let mut stage = Stage {\r
+                input_channel: receiver,\r
+                output_channel: sender,\r
+                last_produced_value: 0,\r
+            };\r
+            intcode::execute_op_code_with_custom_io(&code_copy, &mut stage);\r
+            if i == 4 {\r
+                result.store(stage.last_produced_value, Ordering::Relaxed);\r
+                barrier.wait();\r
             }\r
-        )\r
+        })\r
     }\r
 \r
     barrier.wait();\r
@@ -79,7 +98,11 @@ fn last_thruster_signal_with_feedback_loop(code: &[i64], phase_setting: &[i64],
 \r
 pub fn find_largest_last_thruster_signal_with_feedback_loop(code: &[i64]) -> i64 {\r
     let pool = ThreadPool::new(5);\r
-    (5i64 ..= 9i64).permutations(5).map(|phase_setting| last_thruster_signal_with_feedback_loop(&code, &phase_setting, &pool)).max().unwrap()\r
+    (5i64..=9i64)\r
+        .permutations(5)\r
+        .map(|phase_setting| last_thruster_signal_with_feedback_loop(&code, &phase_setting, &pool))\r
+        .max()\r
+        .unwrap()\r
 }\r
 \r
 #[cfg(test)]\r
@@ -88,38 +111,59 @@ mod tests {
 \r
     #[test]\r
     fn part1_sample_1() {\r
-        let code = vec![3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0];\r
-        let phase_setting = [4,3,2,1,0];\r
+        let code = vec![\r
+            3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0,\r
+        ];\r
+        let phase_setting = [4, 3, 2, 1, 0];\r
         assert_eq!(last_thruster_signal(&code, &phase_setting), 43210);\r
     }\r
 \r
     #[test]\r
     fn part1_sample_2() {\r
-        let code = vec![3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0];\r
-        let phase_setting = [0,1,2,3,4];\r
+        let code = vec![\r
+            3, 23, 3, 24, 1002, 24, 10, 24, 1002, 23, -1, 23, 101, 5, 23, 23, 1, 24, 23, 23, 4, 23,\r
+            99, 0, 0,\r
+        ];\r
+        let phase_setting = [0, 1, 2, 3, 4];\r
         assert_eq!(last_thruster_signal(&code, &phase_setting), 54321);\r
     }\r
 \r
     #[test]\r
     fn part1_sample_3() {\r
-        let code = vec![3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0];\r
-        let phase_setting = [1,0,4,3,2];\r
+        let code = vec![\r
+            3, 31, 3, 32, 1002, 32, 10, 32, 1001, 31, -2, 31, 1007, 31, 0, 33, 1002, 33, 7, 33, 1,\r
+            33, 31, 31, 1, 32, 31, 31, 4, 31, 99, 0, 0, 0,\r
+        ];\r
+        let phase_setting = [1, 0, 4, 3, 2];\r
         assert_eq!(last_thruster_signal(&code, &phase_setting), 65210);\r
     }\r
 \r
     #[test]\r
     fn part2_sample_1() {\r
-        let code = vec![3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5];\r
-        let phase_setting = [9,8,7,6,5];\r
+        let code = vec![\r
+            3, 26, 1001, 26, -4, 26, 3, 27, 1002, 27, 2, 27, 1, 27, 26, 27, 4, 27, 1001, 28, -1,\r
+            28, 1005, 28, 6, 99, 0, 0, 5,\r
+        ];\r
+        let phase_setting = [9, 8, 7, 6, 5];\r
         let pool = ThreadPool::new(5);\r
-        assert_eq!(last_thruster_signal_with_feedback_loop(&code, &phase_setting, &pool), 139_629_729);\r
+        assert_eq!(\r
+            last_thruster_signal_with_feedback_loop(&code, &phase_setting, &pool),\r
+            139_629_729\r
+        );\r
     }\r
 \r
     #[test]\r
     fn part2_sample_2() {\r
-        let code = vec![3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10];\r
-        let phase_setting = [9,7,8,5,6];\r
+        let code = vec![\r
+            3, 52, 1001, 52, -5, 52, 3, 53, 1, 52, 56, 54, 1007, 54, 5, 55, 1005, 55, 26, 1001, 54,\r
+            -5, 54, 1105, 1, 12, 1, 53, 54, 53, 1008, 54, 0, 55, 1001, 55, 1, 55, 2, 53, 55, 53, 4,\r
+            53, 1001, 56, -1, 56, 1005, 56, 6, 99, 0, 0, 0, 0, 10,\r
+        ];\r
+        let phase_setting = [9, 7, 8, 5, 6];\r
         let pool = ThreadPool::new(5);\r
-        assert_eq!(last_thruster_signal_with_feedback_loop(&code, &phase_setting, &pool), 18_216);\r
+        assert_eq!(\r
+            last_thruster_signal_with_feedback_loop(&code, &phase_setting, &pool),\r
+            18_216\r
+        );\r
     }\r
-}
\ No newline at end of file
+}\r
index 50fb119..36f98b8 100644 (file)
@@ -1,20 +1,24 @@
 pub fn read_from_string(raw: &str) -> Vec<u8> {
-    raw.chars().map(|c| c.to_digit(10).unwrap() as u8).collect::<Vec<u8>>()
+    raw.chars()
+        .map(|c| c.to_digit(10).unwrap() as u8)
+        .collect::<Vec<u8>>()
 }
 
 pub fn decode_image(digits: &[u8], width: usize, height: usize) -> Vec<Vec<u8>> {
     let nb_pixel = width * height;
     let nb_layers = digits.len() / nb_pixel;
     let mut layers: Vec<Vec<u8>> = Vec::new();
-    for i in 0 .. nb_layers {
-        let layer: Vec<u8> = Vec::from(&digits[i * nb_pixel .. (i+1) * nb_pixel]);
+    for i in 0..nb_layers {
+        let layer: Vec<u8> = Vec::from(&digits[i * nb_pixel..(i + 1) * nb_pixel]);
         layers.push(layer);
     }
     layers
 }
 
 fn count(layer: &[u8], value: u8) -> u32 {
-    layer.iter().fold(0, |sum, pix| if *pix == value { sum + 1 } else { sum })
+    layer
+        .iter()
+        .fold(0, |sum, pix| if *pix == value { sum + 1 } else { sum })
 }
 
 pub fn layer_with_fewer_0(layers: &[Vec<u8>]) -> &Vec<u8> {
@@ -35,7 +39,7 @@ pub fn merge_layers(layers: &[Vec<u8>]) -> Vec<u8> {
     let mut result: Vec<u8> = Vec::new();
     result.resize(size, 0);
 
-    for i in 0 .. size {
+    for i in 0..size {
         for layer in layers {
             if layer[i] != 2 {
                 result[i] = layer[i];
@@ -70,4 +74,4 @@ mod tests {
         let layer = merge_layers(&layers[..]);
         assert_eq!(layer, vec![0, 1, 1, 0]);
     }
-}
\ No newline at end of file
+}
index 62b989b..799b0a8 100644 (file)
@@ -3,7 +3,7 @@ use std::collections::{HashMap, HashSet};
 pub fn read_map(raw: &str) -> Vec<(i32, i32)> {
     let lines: Vec<&str> = raw.lines().map(|l| l.trim()).collect();
     let mut map = Vec::<(i32, i32)>::new();
-    for x in 0 .. lines[0].len() {
+    for x in 0..lines[0].len() {
         for (y, line) in lines.iter().enumerate() {
             if line.chars().nth(x) == Some('#') {
                 map.push((x as i32, y as i32));
@@ -15,7 +15,8 @@ pub fn read_map(raw: &str) -> Vec<(i32, i32)> {
 
 fn angle(x1: i32, y1: i32, x2: i32, y2: i32) -> i64 {
     // Axis are reverted to match the clockwise laser rotation beginning up.
-    let angle_f64 = (2.0 * std::f64::consts::PI - ((x1 - x2) as f64).atan2((y1 - y2) as f64)) % (2.0 * std::f64::consts::PI);
+    let angle_f64 = (2.0 * std::f64::consts::PI - ((x1 - x2) as f64).atan2((y1 - y2) as f64))
+        % (2.0 * std::f64::consts::PI);
     (angle_f64 * 1_000_000.0) as i64
 }
 
@@ -43,22 +44,29 @@ pub fn find_best_location(map: &[(i32, i32)]) -> (usize, (i32, i32)) {
 
 type PositionsAndDistances = Vec<((i32, i32), i64)>;
 
-pub fn location_nth_vaporized_asteroid(pos: (i32, i32), map: &[(i32, i32)], n: usize) -> (i32, i32) {
+pub fn location_nth_vaporized_asteroid(
+    pos: (i32, i32),
+    map: &[(i32, i32)],
+    n: usize,
+) -> (i32, i32) {
     // Angle -> [(position, distance)].
     let mut asteroids = HashMap::<i64, PositionsAndDistances>::new();
 
     let (x1, y1) = pos;
     for (x2, y2) in map {
-        let angle = angle(x1, y1, *x2 , *y2);
-        let dist = squared_distance(x1, y1, *x2 , *y2);
+        let angle = angle(x1, y1, *x2, *y2);
+        let dist = squared_distance(x1, y1, *x2, *y2);
         match asteroids.get_mut(&angle) {
-            Some (lineup_asteroids) => lineup_asteroids.push(((*x2, *y2), dist)),
-            None => { asteroids.insert(angle, vec![((*x2, *y2), dist)]); }
+            Some(lineup_asteroids) => lineup_asteroids.push(((*x2, *y2), dist)),
+            None => {
+                asteroids.insert(angle, vec![((*x2, *y2), dist)]);
+            }
         }
     }
 
     // Sort everything by angle and by distance.
-    let mut sorted_asteroids: Vec<(&i64, &mut PositionsAndDistances)> = asteroids.iter_mut().collect();
+    let mut sorted_asteroids: Vec<(&i64, &mut PositionsAndDistances)> =
+        asteroids.iter_mut().collect();
     sorted_asteroids.sort_by(|(a1, _), (a2, _)| a1.cmp(a2));
     for (_, lineup_asteroids) in sorted_asteroids.iter_mut() {
         lineup_asteroids.sort_by(|(_, l1), (_, l2)| l1.cmp(l2))
@@ -68,7 +76,9 @@ pub fn location_nth_vaporized_asteroid(pos: (i32, i32), map: &[(i32, i32)], n: u
     loop {
         for (_, lineup_asteroids) in sorted_asteroids.iter_mut() {
             let ((x, y), _) = lineup_asteroids.remove(0);
-            if i == n { return (x, y) }
+            if i == n {
+                return (x, y);
+            }
             i += 1;
         }
     }
@@ -80,8 +90,7 @@ mod tests {
 
     #[test]
     fn part1_sample_1() {
-        let raw_map =
-            ".#..#
+        let raw_map = ".#..#
              .....
              #####
              ....#
@@ -92,8 +101,7 @@ mod tests {
 
     #[test]
     fn part1_sample_2() {
-        let raw_map =
-            "......#.#.
+        let raw_map = "......#.#.
              #..#.#....
              ..#######.
              .#.#.###..
@@ -109,8 +117,7 @@ mod tests {
 
     #[test]
     fn part1_sampl3() {
-        let raw_map =
-            "#.#...#.#.
+        let raw_map = "#.#...#.#.
              .###....#.
              .#....#...
              ##.#.#.#.#
@@ -126,8 +133,7 @@ mod tests {
 
     #[test]
     fn part1_sample_4() {
-        let raw_map =
-            ".#..#..###
+        let raw_map = ".#..#..###
              ####.###.#
              ....###.#.
              ..###.##.#
@@ -143,8 +149,7 @@ mod tests {
 
     #[test]
     fn part1_sample_5() {
-        let raw_map =
-            ".#..##.###...#######
+        let raw_map = ".#..##.###...#######
              ##.############..##.
              .#.######.########.#
              .###.#######.####.#.
@@ -168,11 +173,9 @@ mod tests {
         assert_eq!(find_best_location(&map).0, 210);
     }
 
-
     #[test]
     fn part2_sample_1() {
-        let raw_map =
-            ".#....#####...#..
+        let raw_map = ".#....#####...#..
              ##...##.#####..##
              ##...#...#.#####.
              ..#.....X...###..
@@ -188,8 +191,7 @@ mod tests {
 
     #[test]
     fn part2_sample_2() {
-        let raw_map =
-            ".#..##.###...#######
+        let raw_map = ".#..##.###...#######
              ##.############..##.
              .#.######.########.#
              .###.#######.####.#.
@@ -214,4 +216,4 @@ mod tests {
         let pos_200th = location_nth_vaporized_asteroid(pos, &map, 200);
         assert_eq!(pos_200th, (8, 2));
     }
-}
\ No newline at end of file
+}
index 8847bb1..822e218 100644 (file)
@@ -4,14 +4,14 @@ use super::intcode;
 \r
 enum NextCommand {\r
     Paint,\r
-    Turn\r
+    Turn,\r
 }\r
 \r
 struct Robot {\r
     next_command: NextCommand,\r
     current_pos: (i32, i32),\r
     current_dir: i32, // 0: up, 1: right, 2: down, 3: left.\r
-    panels: HashMap<(i32, i32), i64>\r
+    panels: HashMap<(i32, i32), i64>,\r
 }\r
 \r
 impl Robot {\r
@@ -20,7 +20,7 @@ impl Robot {
             next_command: NextCommand::Paint,\r
             current_pos: (0, 0),\r
             current_dir: 0,\r
-            panels: HashMap::new()\r
+            panels: HashMap::new(),\r
         }\r
     }\r
 }\r
@@ -31,22 +31,25 @@ impl intcode::IO for Robot {
     }\r
 \r
     fn write(&mut self, value: i64) {\r
-        self.next_command =\r
-            match self.next_command {\r
-                NextCommand::Paint => { self.panels.insert(self.current_pos, value); NextCommand::Turn },\r
-                NextCommand::Turn => {\r
-                    self.current_dir = (self.current_dir + if value == 0 /* Turn left. */ { 3 } else /* Turn right. */ { 1 }) % 4;\r
-                    let (x, y) = self.current_pos;\r
-                    self.current_pos =\r
-                        match self.current_dir {\r
-                            0     => (x    , y + 1),\r
-                            1     => (x + 1, y    ),\r
-                            2     => (x    , y - 1),\r
-                            3 | _ => (x - 1, y    )\r
-                        };\r
-                    NextCommand::Paint\r
-                }\r
+        self.next_command = match self.next_command {\r
+            NextCommand::Paint => {\r
+                self.panels.insert(self.current_pos, value);\r
+                NextCommand::Turn\r
             }\r
+            NextCommand::Turn => {\r
+                self.current_dir = (self.current_dir\r
+                    + if value == 0 /* Turn left. */ { 3 } else /* Turn right. */ { 1 })\r
+                    % 4;\r
+                let (x, y) = self.current_pos;\r
+                self.current_pos = match self.current_dir {\r
+                    0 => (x, y + 1),\r
+                    1 => (x + 1, y),\r
+                    2 => (x, y - 1),\r
+                    3 | _ => (x - 1, y),\r
+                };\r
+                NextCommand::Paint\r
+            }\r
+        }\r
     }\r
 }\r
 \r
@@ -73,8 +76,8 @@ pub fn panels_to_layer(panels: &HashMap<(i32, i32), i64>) -> (Vec<u8>, usize) {
     let mut layer = Vec::new();\r
     layer.resize(width * height, 0);\r
 \r
-    for x in min_x ..= max_x {\r
-        for y in min_y ..= max_y {\r
+    for x in min_x..=max_x {\r
+        for y in min_y..=max_y {\r
             let pos = (x - min_x) + ((height as i32 - y + min_y - 1) * width as i32); // Y axis is down.\r
             layer[pos as usize] = *panels.get(&(x, y)).unwrap_or(&0) as u8;\r
         }\r
@@ -85,8 +88,8 @@ pub fn panels_to_layer(panels: &HashMap<(i32, i32), i64>) -> (Vec<u8>, usize) {
 \r
 #[cfg(test)]\r
 mod tests {\r
-    use super::*;\r
     use super::intcode::IO;\r
+    use super::*;\r
 \r
     #[test]\r
     fn part1() {\r
@@ -114,4 +117,4 @@ mod tests {
 \r
         assert_eq!(robot.panels.len(), 6);\r
     }\r
-}
\ No newline at end of file
+}\r
index db95447..34aefac 100644 (file)
@@ -4,7 +4,7 @@ use std::{cmp::Ordering, ops::AddAssign};
 pub struct Vector3D {
     x: i32,
     y: i32,
-    z: i32
+    z: i32,
 }
 
 impl AddAssign for Vector3D {
@@ -12,7 +12,7 @@ impl AddAssign for Vector3D {
         *self = Self {
             x: self.x + other.x,
             y: self.y + other.y,
-            z: self.z + other.z
+            z: self.z + other.z,
         };
     }
 }
@@ -20,13 +20,13 @@ impl AddAssign for Vector3D {
 #[derive(Debug, Copy, Clone)]
 pub struct Moon {
     position: Vector3D,
-    velocity: Vector3D
+    velocity: Vector3D,
 }
 
 impl Moon {
     fn total_energy(&self) -> i32 {
-        (self.position.x.abs() + self.position.y.abs() + self.position.z.abs()) *
-        (self.velocity.x.abs() + self.velocity.y.abs() + self.velocity.z.abs())
+        (self.position.x.abs() + self.position.y.abs() + self.position.z.abs())
+            * (self.velocity.x.abs() + self.velocity.y.abs() + self.velocity.z.abs())
     }
 }
 
@@ -35,9 +35,21 @@ fn next_step(moons: &mut Vec<Moon>) {
     let moons_copy = moons.clone();
     for m1 in moons.iter_mut() {
         for m2 in &moons_copy {
-            m1.velocity.x += match m2.position.x.cmp(&m1.position.x) { Ordering::Greater => 1, Ordering::Less => -1, Ordering::Equal => 0 };
-            m1.velocity.y += match m2.position.y.cmp(&m1.position.y) { Ordering::Greater => 1, Ordering::Less => -1, Ordering::Equal => 0 };
-            m1.velocity.z += match m2.position.z.cmp(&m1.position.z) { Ordering::Greater => 1, Ordering::Less => -1, Ordering::Equal => 0 };
+            m1.velocity.x += match m2.position.x.cmp(&m1.position.x) {
+                Ordering::Greater => 1,
+                Ordering::Less => -1,
+                Ordering::Equal => 0,
+            };
+            m1.velocity.y += match m2.position.y.cmp(&m1.position.y) {
+                Ordering::Greater => 1,
+                Ordering::Less => -1,
+                Ordering::Equal => 0,
+            };
+            m1.velocity.z += match m2.position.z.cmp(&m1.position.z) {
+                Ordering::Greater => 1,
+                Ordering::Less => -1,
+                Ordering::Equal => 0,
+            };
         }
     }
 
@@ -48,17 +60,25 @@ fn next_step(moons: &mut Vec<Moon>) {
 }
 
 fn create_moons(moon_positions: &[Vector3D]) -> Vec<Moon> {
-    moon_positions.iter().map(|position| Moon { position: *position, velocity: Vector3D { x: 0, y: 0, z: 0 } }).collect()
+    moon_positions
+        .iter()
+        .map(|position| Moon {
+            position: *position,
+            velocity: Vector3D { x: 0, y: 0, z: 0 },
+        })
+        .collect()
 }
 
 pub fn final_energy(moon_positions: &[Vector3D], steps: u32) -> i32 {
     let mut moons: Vec<Moon> = create_moons(moon_positions);
 
-    for _ in 0 .. steps {
+    for _ in 0..steps {
         next_step(&mut moons);
     }
 
-    moons.iter().fold(0, |energy, moon| energy + moon.total_energy())
+    moons
+        .iter()
+        .fold(0, |energy, moon| energy + moon.total_energy())
 }
 
 pub fn find_same_state(moon_positions: &[Vector3D]) -> i64 {
@@ -73,39 +93,56 @@ pub fn find_same_state(moon_positions: &[Vector3D]) -> i64 {
         next_step(&mut moons);
         i += 1;
 
-        if nb_cycles.x == 0 && initial_state.iter().zip(&moons).all(
-            |(m1, m2)| m1.position.x == m2.position.x && m1.velocity.x == m2.velocity.x
-        ) { nb_cycles.x = i; }
+        if nb_cycles.x == 0
+            && initial_state
+                .iter()
+                .zip(&moons)
+                .all(|(m1, m2)| m1.position.x == m2.position.x && m1.velocity.x == m2.velocity.x)
+        {
+            nb_cycles.x = i;
+        }
 
-        if nb_cycles.y == 0 && initial_state.iter().zip(&moons).all(
-            |(m1, m2)| m1.position.y == m2.position.y && m1.velocity.y == m2.velocity.y
-        ) { nb_cycles.y = i; }
+        if nb_cycles.y == 0
+            && initial_state
+                .iter()
+                .zip(&moons)
+                .all(|(m1, m2)| m1.position.y == m2.position.y && m1.velocity.y == m2.velocity.y)
+        {
+            nb_cycles.y = i;
+        }
 
-        if nb_cycles.z == 0 && initial_state.iter().zip(&moons).all(
-            |(m1, m2)| m1.position.z == m2.position.z && m1.velocity.z == m2.velocity.z
-        ) { nb_cycles.z = i; }
+        if nb_cycles.z == 0
+            && initial_state
+                .iter()
+                .zip(&moons)
+                .all(|(m1, m2)| m1.position.z == m2.position.z && m1.velocity.z == m2.velocity.z)
+        {
+            nb_cycles.z = i;
+        }
 
         if nb_cycles.x != 0 && nb_cycles.y != 0 && nb_cycles.z != 0 {
-            return (nb_cycles.x as i64).lcm(&(nb_cycles.y as i64)).lcm(&(nb_cycles.z as i64))
+            return (nb_cycles.x as i64)
+                .lcm(&(nb_cycles.y as i64))
+                .lcm(&(nb_cycles.z as i64));
         }
     }
 }
 
 pub fn parse_positions(input: &str) -> Vec<Vector3D> {
     use regex::Regex;
-    fn build_pattern(var: &str) -> Regex { Regex::new(&format!(r".*{}\W*?=\W*?(-?.*?\d+).*", var)).unwrap() }
+    fn build_pattern(var: &str) -> Regex {
+        Regex::new(&format!(r".*{}\W*?=\W*?(-?.*?\d+).*", var)).unwrap()
+    }
     let rex = build_pattern("x");
     let rey = build_pattern("y");
     let rez = build_pattern("z");
     input
         .lines()
-        .map(|l|
-            Vector3D {
-                x: rex.captures(l).unwrap()[1].parse().unwrap(),
-                y: rey.captures(l).unwrap()[1].parse().unwrap(),
-                z: rez.captures(l).unwrap()[1].parse().unwrap()
-            }
-        )
+        .map(|l| Vector3D {
+            x: rex.captures(l).unwrap()[1].parse().unwrap(),
+            y: rey.captures(l).unwrap()[1].parse().unwrap(),
+            z: rez.captures(l).unwrap()[1].parse().unwrap(),
+        })
         .collect()
 }
 
@@ -115,8 +152,7 @@ mod tests {
 
     #[test]
     fn part1() {
-        let input =
-            "<x=-1, y=0, z=2>
+        let input = "<x=-1, y=0, z=2>
              <x=2, y=-10, z=-7>
              <x=4, y=-8, z=8>
              <x=3, y=5, z=-1>";
@@ -126,12 +162,11 @@ mod tests {
 
     #[test]
     fn part2() {
-        let input =
-            "<x=-8, y=-10, z=0>
+        let input = "<x=-8, y=-10, z=0>
              <x=5, y=5, z=10>
              <x=2, y=-7, z=3>
              <x=9, y=-8, z=-3>";
         let coordinates = parse_positions(input);
         assert_eq!(find_same_state(&coordinates), 4_686_774_924);
     }
-}
\ No newline at end of file
+}
index 286791b..4823211 100644 (file)
@@ -19,13 +19,20 @@ enum Tile {
 pub fn count_nb_block(code: &[i64]) -> i32 {
     let output = intcode::execute_op_code(code, &[]);
 
-    output.iter().chunks(3).into_iter().map(
-        |tile_with_pos| {
+    output
+        .iter()
+        .chunks(3)
+        .into_iter()
+        .map(|tile_with_pos| {
             let tile_with_pos: Vec<&i64> = tile_with_pos.collect();
             let tile = Tile::try_from(*tile_with_pos[2] as u8).unwrap();
-            if tile == Tile::Block { 1 } else { 0 }
-        }
-    ).sum()
+            if tile == Tile::Block {
+                1
+            } else {
+                0
+            }
+        })
+        .sum()
 }
 
 struct State {
@@ -53,12 +60,11 @@ impl intcode::IO for State {
                 } else if tile == Tile::Paddle {
                     self.paddle_position_x = self.buffer[0];
                 }
-                self.joystick =
-                    match self.paddle_position_x.cmp(&self.ball_position_x) {
-                        Ordering::Greater => -1,
-                        Ordering::Less => 1,
-                        Ordering::Equal => 0
-                    };
+                self.joystick = match self.paddle_position_x.cmp(&self.ball_position_x) {
+                    Ordering::Greater => -1,
+                    Ordering::Less => 1,
+                    Ordering::Equal => 0,
+                };
             }
             self.buffer.clear();
         }
@@ -66,7 +72,13 @@ impl intcode::IO for State {
 }
 
 pub fn final_score(code: &[i64]) -> i64 {
-    let mut state = State { score: 0, joystick: 0, paddle_position_x: 0, ball_position_x: 0, buffer: Vec::new() };
+    let mut state = State {
+        score: 0,
+        joystick: 0,
+        paddle_position_x: 0,
+        ball_position_x: 0,
+        buffer: Vec::new(),
+    };
     intcode::execute_op_code_with_custom_io(&code, &mut state);
     state.score
 }
index 7dfb6e6..e921cbd 100644 (file)
@@ -22,7 +22,10 @@ pub fn parse(input: &str) -> Reactions {
         let reaction: Vec<&str> = line.split("=>").collect();
         let input_chemicals: Vec<Chemical> = reaction[0].split(',').map(parse_chemical).collect();
         let output_chemical = parse_chemical(reaction[1]);
-        result.insert(output_chemical.name, (output_chemical.quantity, input_chemicals));
+        result.insert(
+            output_chemical.name,
+            (output_chemical.quantity, input_chemicals),
+        );
     }
     result
 }
@@ -32,46 +35,77 @@ pub fn ore_needed_per_fuel(reactions: &Reactions) -> i64 {
     ore_needed(reactions, 1, &mut remainders)
 }
 
-fn ore_needed(reactions: &Reactions, fuel_quantity: i64, remainders: &mut HashMap<String, i64>) -> i64 {
-
-    fn needed(reactions: &Reactions, chemicals: &[Chemical], remainders: &mut HashMap<String, i64>) -> i64 {
+fn ore_needed(
+    reactions: &Reactions,
+    fuel_quantity: i64,
+    remainders: &mut HashMap<String, i64>,
+) -> i64 {
+    fn needed(
+        reactions: &Reactions,
+        chemicals: &[Chemical],
+        remainders: &mut HashMap<String, i64>,
+    ) -> i64 {
         chemicals.iter().fold(0, |sum, chemical| {
-            let quantity_needed =
-                match remainders.get(&chemical.name) {
-                    Some(quantity) => {
-                        let remainder = quantity - chemical.quantity;
-                        if remainder < 0  {
-                            remainders.remove(&chemical.name);
-                            remainder.abs()
-                        } else {
-                            remainders.insert(chemical.name.clone(), remainder);
-                            0
-                        }
-                    },
-                    None => chemical.quantity
-                };
-
-            sum +
-                if chemical.name == "ORE" {
-                    quantity_needed
-                } else {
-                    match reactions.get(&chemical.name) {
-                        Some((quantity_produced, chemicals_needed)) => {
-                            let n = (quantity_needed / quantity_produced) + (if quantity_needed % quantity_produced == 0 { 0 } else { 1 });
-                            let rem = n * quantity_produced - quantity_needed;
-                            match remainders.get(&chemical.name) {
-                                Some(&q) => { remainders.insert(chemical.name.clone(), q + rem); },
-                                None => { remainders.insert(chemical.name.clone(), rem); }
+            let quantity_needed = match remainders.get(&chemical.name) {
+                Some(quantity) => {
+                    let remainder = quantity - chemical.quantity;
+                    if remainder < 0 {
+                        remainders.remove(&chemical.name);
+                        remainder.abs()
+                    } else {
+                        remainders.insert(chemical.name.clone(), remainder);
+                        0
+                    }
+                }
+                None => chemical.quantity,
+            };
+
+            sum + if chemical.name == "ORE" {
+                quantity_needed
+            } else {
+                match reactions.get(&chemical.name) {
+                    Some((quantity_produced, chemicals_needed)) => {
+                        let n = (quantity_needed / quantity_produced)
+                            + (if quantity_needed % quantity_produced == 0 {
+                                0
+                            } else {
+                                1
+                            });
+                        let rem = n * quantity_produced - quantity_needed;
+                        match remainders.get(&chemical.name) {
+                            Some(&q) => {
+                                remainders.insert(chemical.name.clone(), q + rem);
+                            }
+                            None => {
+                                remainders.insert(chemical.name.clone(), rem);
                             }
-                            needed(reactions, &chemicals_needed.iter().map(|c| Chemical { quantity: n * c.quantity, name: c.name.clone() }).collect::<Vec<Chemical>>(), remainders)
-                        },
-                        None => panic!("Unable to find reaction to create {}", chemical.name)
+                        }
+                        needed(
+                            reactions,
+                            &chemicals_needed
+                                .iter()
+                                .map(|c| Chemical {
+                                    quantity: n * c.quantity,
+                                    name: c.name.clone(),
+                                })
+                                .collect::<Vec<Chemical>>(),
+                            remainders,
+                        )
                     }
+                    None => panic!("Unable to find reaction to create {}", chemical.name),
                 }
+            }
         })
     }
 
-    needed(reactions, &[Chemical { quantity: fuel_quantity, name: String::from("FUEL") }], remainders)
+    needed(
+        reactions,
+        &[Chemical {
+            quantity: fuel_quantity,
+            name: String::from("FUEL"),
+        }],
+        remainders,
+    )
 }
 
 pub fn fuel_produced(reactions: &Reactions, ore: i64, ore_per_fuel: i64) -> i64 {
@@ -84,7 +118,7 @@ pub fn fuel_produced(reactions: &Reactions, ore: i64, ore_per_fuel: i64) -> i64
         ore_available -= ore_needed(reactions, fuel, &mut remainders);
 
         if ore_available <= 0 {
-            return fuel_produced
+            return fuel_produced;
         }
 
         fuel_produced += fuel;
@@ -97,8 +131,7 @@ mod tests {
 
     #[test]
     fn part1_sample_1() {
-        let input =
-            "10 ORE => 10 A
+        let input = "10 ORE => 10 A
              1 ORE => 1 B
              7 A, 1 B => 1 C
              7 A, 1 C => 1 D
@@ -110,8 +143,7 @@ mod tests {
 
     #[test]
     fn part1_sample_2() {
-        let input =
-            "9 ORE => 2 A
+        let input = "9 ORE => 2 A
              8 ORE => 3 B
              7 ORE => 5 C
              3 A, 4 B => 1 AB
@@ -124,8 +156,7 @@ mod tests {
 
     #[test]
     fn part1_sample_3() {
-        let input =
-            "157 ORE => 5 NZVS
+        let input = "157 ORE => 5 NZVS
              165 ORE => 6 DCFZ
              44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL
              12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ
@@ -140,8 +171,7 @@ mod tests {
 
     #[test]
     fn part1_sample_4() {
-        let input =
-            "2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
+        let input = "2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
              17 NVRVD, 3 JNWZP => 8 VPVL
              53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL
              22 VJHF, 37 MNCFX => 5 FWMGM
@@ -159,8 +189,7 @@ mod tests {
 
     #[test]
     fn part1_sample_5() {
-        let input =
-            "171 ORE => 8 CNZTR
+        let input = "171 ORE => 8 CNZTR
              7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL
              114 ORE => 4 BHXH
              14 VRPVC => 6 BMBT
@@ -183,8 +212,7 @@ mod tests {
 
     #[test]
     fn part2_sample_1() {
-        let input =
-            "157 ORE => 5 NZVS
+        let input = "157 ORE => 5 NZVS
              165 ORE => 6 DCFZ
              44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL
              12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ
@@ -195,13 +223,15 @@ mod tests {
              3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT";
         let reactions = parse(input);
         let ore_per_fuel = ore_needed_per_fuel(&reactions);
-        assert_eq!(fuel_produced(&reactions, 1_000_000_000_000, ore_per_fuel), 82_892_753);
+        assert_eq!(
+            fuel_produced(&reactions, 1_000_000_000_000, ore_per_fuel),
+            82_892_753
+        );
     }
 
     #[test]
     fn part2_sample_2() {
-        let input =
-            "2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
+        let input = "2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
              17 NVRVD, 3 JNWZP => 8 VPVL
              53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL
              22 VJHF, 37 MNCFX => 5 FWMGM
@@ -215,13 +245,15 @@ mod tests {
              176 ORE => 6 VJHF";
         let reactions = parse(input);
         let ore_per_fuel = ore_needed_per_fuel(&reactions);
-        assert_eq!(fuel_produced(&reactions, 1_000_000_000_000, ore_per_fuel), 5_586_022);
+        assert_eq!(
+            fuel_produced(&reactions, 1_000_000_000_000, ore_per_fuel),
+            5_586_022
+        );
     }
 
     #[test]
     fn part2_sample_3() {
-        let input =
-            "171 ORE => 8 CNZTR
+        let input = "171 ORE => 8 CNZTR
              7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL
              114 ORE => 4 BHXH
              14 VRPVC => 6 BMBT
@@ -240,6 +272,9 @@ mod tests {
              5 BHXH, 4 VRPVC => 5 LTCX";
         let reactions = parse(input);
         let ore_per_fuel = ore_needed_per_fuel(&reactions);
-        assert_eq!(fuel_produced(&reactions, 1_000_000_000_000, ore_per_fuel), 460_664);
+        assert_eq!(
+            fuel_produced(&reactions, 1_000_000_000_000, ore_per_fuel),
+            460_664
+        );
     }
-}
\ No newline at end of file
+}
index 2af8e3c..b2791e6 100644 (file)
@@ -1,4 +1,7 @@
-use std::{collections::{HashMap, HashSet}, iter::FromIterator};\r
+use std::{\r
+    collections::{HashMap, HashSet},\r
+    iter::FromIterator,\r
+};\r
 \r
 use super::intcode;\r
 \r
@@ -26,21 +29,28 @@ impl DroidTrackingSystem {
             current_path: vec![(0, 0)],\r
             oxygen_location: (0, 0),\r
             steps_to_oxygen: 0,\r
-            all_locations_explored: false\r
+            all_locations_explored: false,\r
         }\r
     }\r
 \r
-    fn current_position(&self) -> (i32, i32) { *self.current_path.last().unwrap() }\r
+    fn current_position(&self) -> (i32, i32) {\r
+        *self.current_path.last().unwrap()\r
+    }\r
 \r
     fn positions_around(&self) -> Vec<(i64, (i32, i32))> {\r
         let (x, y) = self.current_position();\r
-        vec![(1, (x, y + 1)), (2, (x, y - 1)), (3, (x - 1, y)), (4, (x + 1, y))]\r
+        vec![\r
+            (1, (x, y + 1)),\r
+            (2, (x, y - 1)),\r
+            (3, (x - 1, y)),\r
+            (4, (x + 1, y)),\r
+        ]\r
     }\r
 \r
     fn get_state(&self, position: (i32, i32)) -> LocationState {\r
         match self.board.get(&position) {\r
             Some(state) => *state,\r
-            None => LocationState::Unknown\r
+            None => LocationState::Unknown,\r
         }\r
     }\r
 \r
@@ -53,7 +63,7 @@ impl DroidTrackingSystem {
         for (mov, pos) in self.positions_around() {\r
             if self.get_state(pos) == LocationState::Unknown {\r
                 self.current_path.push(pos);\r
-                return mov\r
+                return mov;\r
             }\r
         }\r
 \r
@@ -61,7 +71,7 @@ impl DroidTrackingSystem {
             if self.get_state(pos) == LocationState::Visited {\r
                 self.set_state(self.current_position(), LocationState::DeadEnd);\r
                 self.current_path.pop();\r
-                return mov\r
+                return mov;\r
             }\r
         }\r
 \r
@@ -69,7 +79,9 @@ impl DroidTrackingSystem {
         1\r
     }\r
 \r
-    // 0: droid hit a wall, 1: droid moved one step, 2: droid moved one step and has found the oxygen system.\r
+    // 0: droid hit a wall\r
+    // 1: droid moved one step\r
+    // 2: droid moved one step and has found the oxygen system.\r
     fn reply_from_droid(&mut self, status: i64) {\r
         if status == 0 {\r
             self.set_state(self.current_position(), LocationState::Wall);\r
@@ -77,7 +89,8 @@ impl DroidTrackingSystem {
         } else if status == 1 || status == 2 {\r
             self.set_state(self.current_position(), LocationState::Visited);\r
 \r
-            // We need to explore all positions even if we find the oxygen to compute the time (see 'time_to_flood_the_area') in part 2.\r
+            // We need to explore all positions even if we find the oxygen to compute the time\r
+            // (see 'time_to_flood_the_area') in part 2.\r
             if status == 2 {\r
                 self.steps_to_oxygen = self.current_path.len() as i32 - 1;\r
                 self.oxygen_location = self.current_position();\r
@@ -130,4 +143,4 @@ pub fn time_to_flood_the_area(dts: &DroidTrackingSystem) -> i32 {
     }\r
 \r
     max_length - 1\r
-}
\ No newline at end of file
+}\r
index 931ff5b..b6b7f6a 100644 (file)
@@ -1,34 +1,46 @@
 use std::iter::FromIterator;\r
 \r
 pub fn parse(input: &str) -> Vec<i32> {\r
-    input.chars().map(|c| c.to_digit(10).unwrap() as i32).collect()\r
+    input\r
+        .chars()\r
+        .map(|c| c.to_digit(10).unwrap() as i32)\r
+        .collect()\r
 }\r
 \r
-pub fn fft(signal: &[i32], pattern: &[i32], nb_phases: i32, offset: usize, length: usize, nb_signal_repeated: usize) -> Vec<i32> {\r
-\r
+pub fn fft(\r
+    signal: &[i32],\r
+    pattern: &[i32],\r
+    nb_phases: i32,\r
+    offset: usize,\r
+    length: usize,\r
+    nb_signal_repeated: usize,\r
+) -> Vec<i32> {\r
     let l = signal.len();\r
     let pattern_l = pattern.len();\r
 \r
     let mut output = Vec::from_iter(signal.iter().cycle().take(l * nb_signal_repeated).copied());\r
 \r
-    for _ in 0 .. nb_phases {\r
+    for _ in 0..nb_phases {\r
         let cloned_output = output.clone();\r
-        for i in 0 .. output.len() {\r
-            output[i] =\r
-                cloned_output.iter().enumerate().fold(\r
-                    0,\r
-                    |sum, (j, value)| {\r
-                        sum + value * pattern[(j + 1) / (i + 1) % pattern_l]\r
-                    }\r
-                ).abs() % 10;\r
+        for i in 0..output.len() {\r
+            output[i] = cloned_output\r
+                .iter()\r
+                .enumerate()\r
+                .fold(0, |sum, (j, value)| {\r
+                    sum + value * pattern[(j + 1) / (i + 1) % pattern_l]\r
+                })\r
+                .abs()\r
+                % 10;\r
         }\r
     }\r
 \r
-    Vec::from(&output[offset .. offset + length])\r
+    Vec::from(&output[offset..offset + length])\r
 }\r
 \r
 pub fn digits_as_string(signal: &[i32]) -> String {\r
-    signal.iter().fold(String::new(), |result, digit| result + &digit.to_string())\r
+    signal\r
+        .iter()\r
+        .fold(String::new(), |result, digit| result + &digit.to_string())\r
 }\r
 \r
 // Part 2 is from 'https://github.com/mkeeter/advent-of-code/blob/master/2019/16/src/main.rs'.\r
@@ -102,4 +114,4 @@ mod tests {
         let output = fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1);\r
         assert_eq!(digits_as_string(&output), "52432133");\r
     }\r
-}
\ No newline at end of file
+}\r
index c3c3917..bdad2bb 100644 (file)
@@ -5,7 +5,12 @@ use itertools::Itertools;
 use super::intcode;\r
 \r
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]\r
-enum Direction { Up, Left, Down, Right }\r
+enum Direction {\r
+    Up,\r
+    Left,\r
+    Down,\r
+    Right,\r
+}\r
 \r
 impl TryFrom<char> for Direction {\r
     type Error = ();\r
@@ -16,16 +21,22 @@ impl TryFrom<char> for Direction {
             '<' => Ok(Direction::Left),\r
             'v' => Ok(Direction::Down),\r
             '>' => Ok(Direction::Right),\r
-             _  => Err(())\r
+            _ => Err(()),\r
         }\r
     }\r
 }\r
 \r
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]\r
-enum Movement { Left, Right }\r
+enum Movement {\r
+    Left,\r
+    Right,\r
+}\r
 \r
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]\r
-struct MovementCommand { mov: Movement, steps: u32 }\r
+struct MovementCommand {\r
+    mov: Movement,\r
+    steps: u32,\r
+}\r
 \r
 struct RobotTrackingSystem {\r
     board: Vec<Vec<char>>,\r
@@ -57,7 +68,7 @@ impl RobotTrackingSystem {
                 current_x = 0;\r
             } else {\r
                 let c = (*c as u8) as char;\r
-                if let Ok(dir) =  Direction::try_from(c) {\r
+                if let Ok(dir) = Direction::try_from(c) {\r
                     rts.start_position = (current_x, rts.board.len() as i32);\r
                     rts.start_dir = dir\r
                 }\r
@@ -89,7 +100,12 @@ impl RobotTrackingSystem {
         let mut steps = 0;\r
 \r
         'main: loop {\r
-            let positions = [(Direction::Up, (x, y - 1)), (Direction::Left, (x - 1, y)), (Direction::Right, (x + 1, y)), (Direction::Down, (x, y + 1))];\r
+            let positions = [\r
+                (Direction::Up, (x, y - 1)),\r
+                (Direction::Left, (x - 1, y)),\r
+                (Direction::Right, (x + 1, y)),\r
+                (Direction::Down, (x, y + 1)),\r
+            ];\r
 \r
             let next_position = positions.iter().find(|(d, _)| *d == dir).unwrap().1;\r
 \r
@@ -105,19 +121,26 @@ impl RobotTrackingSystem {
             }\r
 \r
             if steps != 0 {\r
-                self.dir_commands.push(MovementCommand { mov: last_mov, steps });\r
+                self.dir_commands.push(MovementCommand {\r
+                    mov: last_mov,\r
+                    steps,\r
+                });\r
                 steps = 0;\r
             }\r
 \r
             for (d, p) in &positions {\r
                 if self.get(p.0, p.1) == Some('#') && !visited_locations.contains(p) {\r
-\r
-                    last_mov =\r
-                        match (dir, *d) {\r
-                            (Direction::Up, Direction::Right) | (Direction::Right, Direction::Down) | (Direction::Down, Direction::Left) | (Direction::Left, Direction::Up) => Movement::Right,\r
-                            (Direction::Up, Direction::Left) | (Direction::Left, Direction::Down) | (Direction::Down, Direction::Right) | (Direction::Right, Direction::Up) => Movement::Left,\r
-                            _ => panic!("Unable to find a movement from {:?} to {:?}", dir, *d)\r
-                        };\r
+                    last_mov = match (dir, *d) {\r
+                        (Direction::Up, Direction::Right)\r
+                        | (Direction::Right, Direction::Down)\r
+                        | (Direction::Down, Direction::Left)\r
+                        | (Direction::Left, Direction::Up) => Movement::Right,\r
+                        (Direction::Up, Direction::Left)\r
+                        | (Direction::Left, Direction::Down)\r
+                        | (Direction::Down, Direction::Right)\r
+                        | (Direction::Right, Direction::Up) => Movement::Left,\r
+                        _ => panic!("Unable to find a movement from {:?} to {:?}", dir, *d),\r
+                    };\r
 \r
                     visited_locations.insert(*p);\r
                     steps += 1;\r
@@ -134,17 +157,18 @@ impl RobotTrackingSystem {
 }\r
 \r
 struct CommandSequences {\r
-    commands: Vec<(usize, Range<usize>)> // Each range is associated with a sequence number (first tuple value).\r
+    // Each range is associated with a sequence number (first tuple value).\r
+    commands: Vec<(usize, Range<usize>)>,\r
 }\r
 \r
-fn is_overlapping<T : PartialOrd>(r1: &Range<T>, r2: &Range<T>) -> bool {\r
+fn is_overlapping<T: PartialOrd>(r1: &Range<T>, r2: &Range<T>) -> bool {\r
     r1.start < r2.start && r1.end > r2.start || r2.start < r1.start && r2.end > r1.start\r
 }\r
 \r
 impl CommandSequences {\r
     fn new() -> Self {\r
         CommandSequences {\r
-            commands: Vec::new()\r
+            commands: Vec::new(),\r
         }\r
     }\r
 \r
@@ -153,20 +177,29 @@ impl CommandSequences {
         let len_min = 3;\r
         let len_max = 6;\r
 \r
-        for l1 in len_min ..= len_max {\r
-            for l2 in len_min ..= len_max {\r
-                for l3 in len_min ..= len_max {\r
+        for l1 in len_min..=len_max {\r
+            for l2 in len_min..=len_max {\r
+                for l3 in len_min..=len_max {\r
                     self.commands.clear();\r
                     let mut position: usize = 0;\r
-                    for seq_num in 0 .. 3 {\r
-                        let l = match seq_num { 0 => l1, 1 => l2, _ => l3 };\r
-                        let range = position .. position + l;\r
+                    for seq_num in 0..3 {\r
+                        let l = match seq_num {\r
+                            0 => l1,\r
+                            1 => l2,\r
+                            _ => l3,\r
+                        };\r
+                        let range = position..position + l;\r
                         self.commands.push((seq_num, range.clone()));\r
                         // Try to find the sequence elsewhere in 'movements'.\r
                         let mut position2 = position + l;\r
                         while position2 <= movements.len() - l {\r
-                            let range2 = position2 .. position2 + l;\r
-                            if !self.commands.iter().any(|(_, r)| is_overlapping(&r, &range2)) && movements.get(range.clone()) == movements.get(range2.clone()) {\r
+                            let range2 = position2..position2 + l;\r
+                            if !self\r
+                                .commands\r
+                                .iter()\r
+                                .any(|(_, r)| is_overlapping(&r, &range2))\r
+                                && movements.get(range.clone()) == movements.get(range2.clone())\r
+                            {\r
                                 self.commands.push((seq_num, range2));\r
                                 position2 += l;\r
                             } else {\r
@@ -181,19 +214,31 @@ impl CommandSequences {
                     }\r
 \r
                     // Check if all movements are included into a sequence.\r
-                    if self.commands.iter().fold(0, |sum, (_, range)| sum + range.len()) == movements.len() {\r
+                    if self\r
+                        .commands\r
+                        .iter()\r
+                        .fold(0, |sum, (_, range)| sum + range.len())\r
+                        == movements.len()\r
+                    {\r
                         return;\r
                     }\r
                 }\r
-\r
             }\r
         }\r
     }\r
 }\r
 \r
-struct Part1 { output: Vec<i64>, }\r
+struct Part1 {\r
+    output: Vec<i64>,\r
+}\r
 \r
-impl Part1 { fn new() -> Self { Part1 { output: Vec::<i64>::new() } }}\r
+impl Part1 {\r
+    fn new() -> Self {\r
+        Part1 {\r
+            output: Vec::<i64>::new(),\r
+        }\r
+    }\r
+}\r
 \r
 struct Part2 {\r
     output: Vec<i64>,\r
@@ -204,11 +249,24 @@ struct Part2 {
     dust_collected: i64,\r
 }\r
 \r
-impl Part2 { fn new() -> Self { Part2 { output: Vec::<i64>::new(), rts: None, commands_sequences: CommandSequences::new(), input: Vec::new(), input_position: 0, dust_collected: 0 } } }\r
+impl Part2 {\r
+    fn new() -> Self {\r
+        Part2 {\r
+            output: Vec::<i64>::new(),\r
+            rts: None,\r
+            commands_sequences: CommandSequences::new(),\r
+            input: Vec::new(),\r
+            input_position: 0,\r
+            dust_collected: 0,\r
+        }\r
+    }\r
+}\r
 \r
 impl intcode::IO for Part1 {\r
     // Read instructions\r
-    fn read(&mut self) -> i64 { 0 }\r
+    fn read(&mut self) -> i64 {\r
+        0\r
+    }\r
 \r
     // Send to the output channel.\r
     fn write(&mut self, value: i64) {\r
@@ -221,22 +279,50 @@ impl intcode::IO for Part2 {
     fn read(&mut self) -> i64 {\r
         if self.rts.is_none() {\r
             self.rts = Some(RobotTrackingSystem::from(&self.output));\r
-            self.commands_sequences.find_sequences(&self.rts.as_ref().unwrap().dir_commands);\r
+            self.commands_sequences\r
+                .find_sequences(&self.rts.as_ref().unwrap().dir_commands);\r
 \r
             // 1: add the movements sequences: "A,B,C,A\n" // Max: 10 sequence calls.\r
-            for (i, (seq_num, _)) in self.commands_sequences.commands.iter().sorted_by(|(_, r1), (_, r2)| r1.start.cmp(&r2.start)).enumerate() {\r
-                if i > 0 { self.input.push(44); }\r
+            for (i, (seq_num, _)) in self\r
+                .commands_sequences\r
+                .commands\r
+                .iter()\r
+                .sorted_by(|(_, r1), (_, r2)| r1.start.cmp(&r2.start))\r
+                .enumerate()\r
+            {\r
+                if i > 0 {\r
+                    self.input.push(44);\r
+                }\r
                 self.input.push(*seq_num as i64 + 65);\r
             }\r
             self.input.push(10);\r
 \r
             // 2: Add the sequence A, B and C: "R,8,L,2,R,1\n", Max: ~6 movements.\r
-            for seq_num in 0 .. 3 {\r
-                let (_, sequence) = self.commands_sequences.commands.iter().find(|(s, _)| *s == seq_num).unwrap();\r
-                for (i, movement_command) in self.rts.as_ref().unwrap().dir_commands.get(sequence.clone()).unwrap().iter().enumerate() {\r
-\r
-                    if i > 0 { self.input.push(44); }\r
-                    if movement_command.mov == Movement::Left { self.input.push(76); } else { self.input.push(82); }\r
+            for seq_num in 0..3 {\r
+                let (_, sequence) = self\r
+                    .commands_sequences\r
+                    .commands\r
+                    .iter()\r
+                    .find(|(s, _)| *s == seq_num)\r
+                    .unwrap();\r
+                for (i, movement_command) in self\r
+                    .rts\r
+                    .as_ref()\r
+                    .unwrap()\r
+                    .dir_commands\r
+                    .get(sequence.clone())\r
+                    .unwrap()\r
+                    .iter()\r
+                    .enumerate()\r
+                {\r
+                    if i > 0 {\r
+                        self.input.push(44);\r
+                    }\r
+                    if movement_command.mov == Movement::Left {\r
+                        self.input.push(76);\r
+                    } else {\r
+                        self.input.push(82);\r
+                    }\r
                     self.input.push(44);\r
                     for c in movement_command.steps.to_string().as_bytes() {\r
                         self.input.push(*c as i64);\r
@@ -268,11 +354,13 @@ pub fn scaffold_intersections(code: &[i64]) -> i32 {
     let mut part1 = Part1::new();\r
     intcode::execute_op_code_with_custom_io(code, &mut part1);\r
     let rts = RobotTrackingSystem::from(&part1.output);\r
-    rts.crossings.iter().fold(0, |sum, crossing| sum + crossing.0 * crossing.1)\r
+    rts.crossings\r
+        .iter()\r
+        .fold(0, |sum, crossing| sum + crossing.0 * crossing.1)\r
 }\r
 \r
 pub fn collected_dust(code: &[i64]) -> i64 {\r
     let mut part2 = Part2::new();\r
     intcode::execute_op_code_with_custom_io(code, &mut part2);\r
     part2.dust_collected\r
-}
\ No newline at end of file
+}\r
index 027f403..3bd7819 100644 (file)
@@ -18,7 +18,12 @@ impl Vault {
         let mut entrance = (0, 0);
         for (row, line) in input.lines().enumerate() {
             tunnels.push(line.trim().chars().collect::<Vec<char>>());
-            if let Some((col, _)) = tunnels.last().unwrap().iter().find_position(|c| c == &&START_SYMBOL) {
+            if let Some((col, _)) = tunnels
+                .last()
+                .unwrap()
+                .iter()
+                .find_position(|c| c == &&START_SYMBOL)
+            {
                 entrance = (row as i32, col as i32);
             }
         }
@@ -38,40 +43,50 @@ mod v1 {
     }
 
     struct NodeIterator {
-        current: Option<Rc<Node>>
+        current: Option<Rc<Node>>,
     }
 
     impl NodeIterator {
-        fn from(node: Rc<Node>) -> NodeIterator { NodeIterator { current: Some(node) } }
+        fn from(node: Rc<Node>) -> NodeIterator {
+            NodeIterator {
+                current: Some(node),
+            }
+        }
     }
 
     impl Iterator for NodeIterator {
         type Item = Rc<Node>;
         fn next(&mut self) -> Option<Rc<Node>> {
             let next = self.current.as_ref().map(|n| Rc::clone(n));
-            self.current =
-                match self.current.as_ref() {
-                    Some(n) => n.parent.as_ref().map(|n| Rc::clone(n)),
-                    None => None
-                };
+            self.current = match self.current.as_ref() {
+                Some(n) => n.parent.as_ref().map(|n| Rc::clone(n)),
+                None => None,
+            };
             next
         }
     }
 
     impl Node {
         fn new(parent: Option<Rc<Node>>, length_to_parent: u32, key: char) -> Self {
-            Node { parent, length_to_parent, key }
+            Node {
+                parent,
+                length_to_parent,
+                key,
+            }
         }
     }
 
-
     fn iter(node: Rc<Node>) -> NodeIterator {
         NodeIterator::from(node)
     }
 
-    fn nb_of_keys(node: Rc<Node>) -> u32 { iter(node).count() as u32 - 1 }
+    fn nb_of_keys(node: Rc<Node>) -> u32 {
+        iter(node).count() as u32 - 1
+    }
 
-    fn length(node: Rc<Node>) -> u32 { iter(node).fold(0, |sum, node| sum + node.length_to_parent) }
+    fn length(node: Rc<Node>) -> u32 {
+        iter(node).fold(0, |sum, node| sum + node.length_to_parent)
+    }
 
     fn can_open(node: Rc<Node>, door: char) -> bool {
         let key_needed = door.to_ascii_lowercase();
@@ -84,7 +99,7 @@ mod v1 {
 
     #[allow(dead_code)]
     pub fn nb_steps_to_collect_all_key(vault: &Vault) -> u32 {
-        fn find_keys(from : (i32, i32), parent: Rc<Node>, vault: &Vault) -> Vec<Rc<Node>> {
+        fn find_keys(from: (i32, i32), parent: Rc<Node>, vault: &Vault) -> Vec<Rc<Node>> {
             let mut to_visit = vec![(from, 1)];
             let mut visited_positions: HashSet<(i32, i32)> = HashSet::new();
             let mut reachable_keys = Vec::<Rc<Node>>::new();
@@ -95,30 +110,46 @@ mod v1 {
             }
 
             while let Some((pos, steps)) = to_visit.pop() {
-
-                if cfg!(debug_assertions) { println!("Pos to visit: {:?}", pos); }
+                if cfg!(debug_assertions) {
+                    println!("Pos to visit: {:?}", pos);
+                }
 
                 visited_positions.insert(pos);
 
                 for pos_d in &[(-1, 0), (0, 1), (1, 0), (0, -1)] {
                     let adjacent = (pos.0 + pos_d.0, pos.1 + pos_d.1);
 
-                    if cfg!(debug_assertions) { println!("Adjacent: {:?}", adjacent); }
+                    if cfg!(debug_assertions) {
+                        println!("Adjacent: {:?}", adjacent);
+                    }
 
                     if !visited_positions.contains(&adjacent) {
                         match vault.tunnels[adjacent.0 as usize][adjacent.1 as usize] {
                             // Simple floor or a door or a owned key.
-                            c if c == FLOOR_SYMBOL || c == START_SYMBOL || c.is_ascii_uppercase() && can_open(Rc::clone(&parent), c) || c.is_ascii_lowercase() && has_key(Rc::clone(&parent), c) => {
-                                if cfg!(debug_assertions) { println!("-> To visit"); }
+                            c if c == FLOOR_SYMBOL
+                                || c == START_SYMBOL
+                                || c.is_ascii_uppercase() && can_open(Rc::clone(&parent), c)
+                                || c.is_ascii_lowercase() && has_key(Rc::clone(&parent), c) =>
+                            {
+                                if cfg!(debug_assertions) {
+                                    println!("-> To visit");
+                                }
                                 to_visit.push((adjacent, steps + 1));
-                            },
-                            c if c.is_ascii_lowercase() => { // A non-owned key.
-                                if cfg!(debug_assertions) { println!("-> A new key! {:?}", c); }
+                            }
+                            c if c.is_ascii_lowercase() => {
+                                // A non-owned key.
+                                if cfg!(debug_assertions) {
+                                    println!("-> A new key! {:?}", c);
+                                }
                                 visited_positions.insert(adjacent);
                                 let node = Rc::new(Node::new(Some(Rc::clone(&parent)), steps, c));
                                 reachable_keys.append(&mut find_keys(adjacent, node, vault));
-                            },
-                            _ => if cfg!(debug_assertions) { println!("-> WALL") },
+                            }
+                            _ => {
+                                if cfg!(debug_assertions) {
+                                    println!("-> WALL")
+                                }
+                            }
                         }
                     }
                 }
@@ -134,7 +165,13 @@ mod v1 {
         let root = Rc::new(Node::new(None, 0, START_SYMBOL));
         let nodes = find_keys(vault.entrance, root, vault);
 
-        nodes.iter().map(|n| (length(Rc::clone(n)), nb_of_keys(Rc::clone(n)))).sorted_by(|(l1, n1), (l2, n2)| n1.cmp(&n2).then(l1.cmp(&l2))).next().unwrap().0
+        nodes
+            .iter()
+            .map(|n| (length(Rc::clone(n)), nb_of_keys(Rc::clone(n))))
+            .sorted_by(|(l1, n1), (l2, n2)| n1.cmp(&n2).then(l1.cmp(&l2)))
+            .next()
+            .unwrap()
+            .0
     }
 }
 
@@ -145,19 +182,34 @@ mod v2 {
     struct Path {
         to_visit: Vec<(i32, i32)>,
         visited: HashSet<(i32, i32)>,
-        keys: Vec<char>
+        keys: Vec<char>,
     }
 
     impl Path {
         pub fn new(initial_position: (i32, i32)) -> Self {
-            Path { to_visit: vec![initial_position], visited: HashSet::new(), keys: Vec::new() }
+            Path {
+                to_visit: vec![initial_position],
+                visited: HashSet::new(),
+                keys: Vec::new(),
+            }
         }
     }
 
     pub fn nb_steps_to_collect_all_key(vault: &Vault) -> u32 {
-        let nb_of_keys: usize = vault.tunnels.iter().map(|line| line.iter().fold(0, |acc, c| if c.is_ascii_lowercase() { acc + 1 } else { acc })).sum();
-
-        if cfg!(debug_assertions) { println!("nb_of_keys = {}", nb_of_keys); }
+        let nb_of_keys: usize = vault
+            .tunnels
+            .iter()
+            .map(|line| {
+                line.iter().fold(
+                    0,
+                    |acc, c| if c.is_ascii_lowercase() { acc + 1 } else { acc },
+                )
+            })
+            .sum();
+
+        if cfg!(debug_assertions) {
+            println!("nb_of_keys = {}", nb_of_keys);
+        }
 
         let mut paths = vec![Path::new(vault.entrance)];
 
@@ -166,9 +218,11 @@ mod v2 {
             step += 1;
             let mut new_paths: Vec<Path> = Vec::new();
 
-            if cfg!(debug_assertions) { println!("----------------------------\n{:?}", paths); }
+            if cfg!(debug_assertions) {
+                println!("----------------------------\n{:?}", paths);
+            }
 
-            for i in (0 .. paths.len()).rev() {
+            for i in (0..paths.len()).rev() {
                 let path = &mut paths[i];
 
                 let to_visit = path.to_visit.clone();
@@ -185,18 +239,26 @@ mod v2 {
                             let c = vault.tunnels[adjacent.0 as usize][adjacent.1 as usize];
 
                             if c == WALL_SYMBOL {
-                            }
-                            else if c.is_ascii_lowercase() && !path.keys.contains(&c) {
+                            } else if c.is_ascii_lowercase() && !path.keys.contains(&c) {
                                 if path.keys.len() + 1 == nb_of_keys {
                                     return step;
                                 }
 
-                                let mut new_path = Path { to_visit: vec![adjacent], visited: HashSet::new(), keys: path.keys.clone() };
+                                let mut new_path = Path {
+                                    to_visit: vec![adjacent],
+                                    visited: HashSet::new(),
+                                    keys: path.keys.clone(),
+                                };
                                 new_path.keys.push(c);
                                 new_paths.push(new_path);
                             }
                             // Simple floor or a door or a owned key.
-                            else if c == FLOOR_SYMBOL || c == START_SYMBOL || c.is_ascii_lowercase() || c.is_ascii_uppercase() && path.keys.contains(&c.to_ascii_lowercase()) {
+                            else if c == FLOOR_SYMBOL
+                                || c == START_SYMBOL
+                                || c.is_ascii_lowercase()
+                                || c.is_ascii_uppercase()
+                                    && path.keys.contains(&c.to_ascii_lowercase())
+                            {
                                 path.to_visit.push(adjacent);
                             }
                         }
@@ -223,18 +285,21 @@ mod tests {
 
     #[test]
     fn part1_sample1() {
-        let input =
-            "#########
-             #b.A.@.a#
-             #########";
+        let input = "#########
+#b.A.@.a#
+#########";
 
         let vault = Vault::parse(input);
         dbg!(&vault);
 
-        if cfg!(debug_assertions) { println!("===== Version 1 =====") }
+        if cfg!(debug_assertions) {
+            println!("===== Version 1 =====")
+        }
         let steps_v1 = v1::nb_steps_to_collect_all_key(&vault);
 
-        if cfg!(debug_assertions) { println!("===== Version 2 =====") }
+        if cfg!(debug_assertions) {
+            println!("===== Version 2 =====")
+        }
         let steps_v2 = v2::nb_steps_to_collect_all_key(&vault);
 
         assert_eq!(steps_v1, steps_v2);
@@ -244,12 +309,11 @@ mod tests {
 
     #[test]
     fn part1_sample2() {
-        let input =
-            "########################
-             #f.D.E.e.C.b.A.@.a.B.c.#
-             ######################.#
-             #d.....................#
-             ########################";
+        let input = "########################
+#f.D.E.e.C.b.A.@.a.B.c.#
+######################.#
+#d.....................#
+########################";
 
         let vault = Vault::parse(input);
 
@@ -263,12 +327,11 @@ mod tests {
 
     #[test]
     fn part1_sample3() {
-        let input =
-            "########################
-             #...............b.C.D.f#
-             #.######################
-             #.....@.a.B.c.d.A.e.F.g#
-             ########################";
+        let input = "########################
+#...............b.C.D.f#
+#.######################
+#.....@.a.B.c.d.A.e.F.g#
+########################";
 
         let vault = Vault::parse(input);
 
@@ -282,16 +345,15 @@ mod tests {
 
     #[test]
     fn part1_sample4() {
-        let input =
-            "#################
-             #i.G..c...e..H.p#
-             ########.########
-             #j.A..b...f..D.o#
-             ########@########
-             #k.E..a...g..B.n#
-             ########.########
-             #l.F..d...h..C.m#
-             #################";
+        let input = "#################
+#i.G..c...e..H.p#
+########.########
+#j.A..b...f..D.o#
+########@########
+#k.E..a...g..B.n#
+########.########
+#l.F..d...h..C.m#
+#################";
 
         let vault = Vault::parse(input);
 
@@ -305,12 +367,11 @@ mod tests {
 
     #[test]
     fn part1_sample4b() {
-        let input =
-            "#################
-             #j.A..b...a..D.o#
-             ########@########
-             #k.E..e...d..B.n#
-             #################";
+        let input = "#################
+#j.A..b...a..D.o#
+########@########
+#k.E..e...d..B.n#
+#################";
 
         let vault = Vault::parse(input);
 
@@ -324,13 +385,12 @@ mod tests {
 
     #[test]
     fn part1_sample5() {
-        let input =
-            "########################
-             #@..............ac.GI.b#
-             ###d#e#f################
-             ###A#B#C################
-             ###g#h#i################
-             ########################";
+        let input = "########################
+#@..............ac.GI.b#
+###d#e#f################
+###A#B#C################
+###g#h#i################
+########################";
 
         let vault = Vault::parse(input);
 
@@ -341,4 +401,4 @@ mod tests {
 
         println!("Steps: {}", steps_v1);
     }
-}
\ No newline at end of file
+}
index fee58ca..e446932 100644 (file)
@@ -2,26 +2,28 @@
 enum Mode {\r
     Position,\r
     Immediate,\r
-    Relative\r
+    Relative,\r
 }\r
 \r
 pub trait IO {\r
     fn read(&mut self) -> i64;\r
     fn write(&mut self, value: i64);\r
-    fn halt(&self) -> bool { false }\r
-    fn finished(&mut self) { }\r
+    fn halt(&self) -> bool {\r
+        false\r
+    }\r
+    fn finished(&mut self) {}\r
 }\r
 \r
 struct Buffer {\r
     output: Vec<i64>,\r
-    input: Vec<i64>\r
+    input: Vec<i64>,\r
 }\r
 \r
 impl Buffer {\r
     fn from(input: &[i64]) -> Self {\r
         Buffer {\r
             output: Vec::new(),\r
-            input: Vec::from(input)\r
+            input: Vec::from(input),\r
         }\r
     }\r
 }\r
@@ -38,7 +40,7 @@ impl IO for Buffer {
 \r
 // 'true' -> immediate mode, 'false' -> position mode.\r
 fn read_op_and_modes(mut code: i64) -> (i64, [Mode; 3]) {\r
-    let mut modes: [Mode; 3] = [ Mode::Position, Mode::Position, Mode::Position ];\r
+    let mut modes: [Mode; 3] = [Mode::Position, Mode::Position, Mode::Position];\r
 \r
     for i in (2..=4).rev() {\r
         let power = 10i64.pow(i);\r
@@ -66,22 +68,35 @@ pub fn execute_op_code_with_custom_io(code: &[i64], io: &mut dyn IO) {
     let mut relative_base = 0;\r
 \r
     fn read(position: usize, code: &[i64], mode: Mode, relative_base: i64) -> i64 {\r
-        if position >= code.len() { return 0 }\r
+        if position >= code.len() {\r
+            return 0;\r
+        }\r
 \r
         match mode {\r
-            Mode::Position => if code[position] as usize >= code.len() { 0 } else { code[code[position] as usize] },\r
+            Mode::Position => {\r
+                if code[position] as usize >= code.len() {\r
+                    0\r
+                } else {\r
+                    code[code[position] as usize]\r
+                }\r
+            }\r
             Mode::Immediate => code[position],\r
-            Mode::Relative => if (code[position] + relative_base) as usize >= code.len() { 0 } else { code[(code[position] + relative_base) as usize] }\r
+            Mode::Relative => {\r
+                if (code[position] + relative_base) as usize >= code.len() {\r
+                    0\r
+                } else {\r
+                    code[(code[position] + relative_base) as usize]\r
+                }\r
+            }\r
         }\r
     }\r
 \r
     fn write(position: usize, value: i64, code: &mut Vec<i64>, mode: Mode, relative_base: i64) {\r
-        let ref_position =\r
-            match mode {\r
-                Mode::Position => code[position] as usize,\r
-                Mode::Immediate => panic!("Can't write un immediate mode"),\r
-                Mode::Relative => (code[position] + relative_base) as usize\r
-            };\r
+        let ref_position = match mode {\r
+            Mode::Position => code[position] as usize,\r
+            Mode::Immediate => panic!("Can't write un immediate mode"),\r
+            Mode::Relative => (code[position] + relative_base) as usize,\r
+        };\r
 \r
         if ref_position >= code.len() {\r
             code.resize(ref_position + 1, 0);\r
@@ -90,7 +105,13 @@ pub fn execute_op_code_with_custom_io(code: &[i64], io: &mut dyn IO) {
         code[ref_position] = value;\r
     }\r
 \r
-    fn jump_if(cond: bool, cursor: usize, code: &[i64], modes: [Mode; 3], relative_base: i64) -> usize {\r
+    fn jump_if(\r
+        cond: bool,\r
+        cursor: usize,\r
+        code: &[i64],\r
+        modes: [Mode; 3],\r
+        relative_base: i64,\r
+    ) -> usize {\r
         let value = read(cursor + 1, &code, modes[0], relative_base);\r
         if cond == (value != 0) {\r
             read(cursor + 2, &code, modes[1], relative_base) as usize\r
@@ -100,22 +121,38 @@ pub fn execute_op_code_with_custom_io(code: &[i64], io: &mut dyn IO) {
     }\r
 \r
     loop {\r
-        if io.halt() { break; }\r
+        if io.halt() {\r
+            break;\r
+        }\r
 \r
         let (op, modes) = read_op_and_modes(code[cursor]);\r
 \r
         match op {\r
             // Sum.\r
             1 => {\r
-                write(cursor + 3, read(cursor + 1, &code, modes[0], relative_base) + read(cursor + 2, &code, modes[1], relative_base), &mut code, modes[2], relative_base);\r
+                write(\r
+                    cursor + 3,\r
+                    read(cursor + 1, &code, modes[0], relative_base)\r
+                        + read(cursor + 2, &code, modes[1], relative_base),\r
+                    &mut code,\r
+                    modes[2],\r
+                    relative_base,\r
+                );\r
                 cursor += 4;\r
-            },\r
+            }\r
 \r
             // Multiply.\r
             2 => {\r
-                write(cursor + 3, read(cursor + 1, &code, modes[0], relative_base) * read(cursor + 2, &code, modes[1], relative_base), &mut code, modes[2], relative_base);\r
+                write(\r
+                    cursor + 3,\r
+                    read(cursor + 1, &code, modes[0], relative_base)\r
+                        * read(cursor + 2, &code, modes[1], relative_base),\r
+                    &mut code,\r
+                    modes[2],\r
+                    relative_base,\r
+                );\r
                 cursor += 4;\r
-            },\r
+            }\r
 \r
             // Input.\r
             3 => {\r
@@ -137,15 +174,39 @@ pub fn execute_op_code_with_custom_io(code: &[i64], io: &mut dyn IO) {
 \r
             // Less than.\r
             7 => {\r
-                write(cursor + 3, if read(cursor + 1, &code, modes[0], relative_base) < read(cursor + 2, &code, modes[1], relative_base) { 1 } else { 0 }, &mut code, modes[2], relative_base);\r
+                write(\r
+                    cursor + 3,\r
+                    if read(cursor + 1, &code, modes[0], relative_base)\r
+                        < read(cursor + 2, &code, modes[1], relative_base)\r
+                    {\r
+                        1\r
+                    } else {\r
+                        0\r
+                    },\r
+                    &mut code,\r
+                    modes[2],\r
+                    relative_base,\r
+                );\r
                 cursor += 4;\r
-            },\r
+            }\r
 \r
             // Equals.\r
             8 => {\r
-                write(cursor + 3, if read(cursor + 1, &code, modes[0], relative_base) == read(cursor + 2, &code, modes[1], relative_base) { 1 } else { 0 }, &mut code, modes[2], relative_base);\r
+                write(\r
+                    cursor + 3,\r
+                    if read(cursor + 1, &code, modes[0], relative_base)\r
+                        == read(cursor + 2, &code, modes[1], relative_base)\r
+                    {\r
+                        1\r
+                    } else {\r
+                        0\r
+                    },\r
+                    &mut code,\r
+                    modes[2],\r
+                    relative_base,\r
+                );\r
                 cursor += 4;\r
-            },\r
+            }\r
 \r
             // Change relative base.\r
             9 => {\r
@@ -155,7 +216,7 @@ pub fn execute_op_code_with_custom_io(code: &[i64], io: &mut dyn IO) {
 \r
             99 => break,\r
 \r
-            _ => panic!("Unknown code: {}", code[cursor])\r
+            _ => panic!("Unknown code: {}", code[cursor]),\r
         }\r
     }\r
 \r
@@ -168,7 +229,11 @@ mod tests_day05 {
 \r
     #[test]\r
     fn part2() {\r
-        let c = [3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31,1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104,999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99];\r
+        let c = [\r
+            3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, 1106, 0, 36, 98, 0,\r
+            0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104, 999, 1105, 1, 46, 1101, 1000, 1, 20, 4,\r
+            20, 1105, 1, 46, 98, 99,\r
+        ];\r
 \r
         let r1 = execute_op_code(&c, &[7]);\r
         assert_eq!(r1[0], 999);\r
@@ -187,22 +252,24 @@ mod tests_day09 {
 \r
     #[test]\r
     fn copy_of_itself() {\r
-        let c = [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99];\r
+        let c = [\r
+            109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99,\r
+        ];\r
         let r = execute_op_code(&c, &Vec::new());\r
         assert_eq!(r, c);\r
     }\r
 \r
     #[test]\r
     fn output_big_number() {\r
-        let c = [1102,34_915_192,34_915_192,7,4,7,99,0];\r
+        let c = [1102, 34_915_192, 34_915_192, 7, 4, 7, 99, 0];\r
         let r = execute_op_code(&c, &Vec::new());\r
         assert_eq!(r[0], 1_219_070_632_396_864);\r
     }\r
 \r
     #[test]\r
     fn input_big_number() {\r
-        let c = [104,1_125_899_906_842_624,99];\r
+        let c = [104, 1_125_899_906_842_624, 99];\r
         let r = execute_op_code(&c, &Vec::new());\r
         assert_eq!(r[0], 1_125_899_906_842_624);\r
     }\r
-}
\ No newline at end of file
+}\r
index ef4a7a7..e23f773 100644 (file)
@@ -3,7 +3,6 @@ use std::fs;
 use std::time::Instant;
 
 mod common;
-mod intcode;
 mod day01;
 mod day02;
 mod day03;
@@ -20,15 +19,24 @@ mod day15;
 mod day16;
 mod day17;
 mod day18;
+mod intcode;
 
 fn day01() -> String {
     let masses = common::read_list_of_numbers("data/day01.input", "\n");
-    format!("part1: {}, part2: {}", day01::sum_mass_to_fuel(&masses), day01::sum_mass_to_fuel_2(&masses))
+    format!(
+        "part1: {}, part2: {}",
+        day01::sum_mass_to_fuel(&masses),
+        day01::sum_mass_to_fuel_2(&masses)
+    )
 }
 
 fn day02() -> String {
     let code = common::read_list_of_numbers("data/day02.input", ",");
-    format!("part1: {}, part2: {}", day02::execute_op_code_with_state_fixed(&mut Vec::from(&code[..])), day02::find_noun_and_verb(&code))
+    format!(
+        "part1: {}, part2: {}",
+        day02::execute_op_code_with_state_fixed(&mut Vec::from(&code[..])),
+        day02::find_noun_and_verb(&code)
+    )
 }
 
 fn day03() -> String {
@@ -36,33 +44,55 @@ fn day03() -> String {
     let movements: Vec<&str> = file_content.lines().collect();
     format!(
         "part1: {}, part2: {}",
-        day03::manhattan_distance_from_cross_to_port(&day03::split_movements(&movements[0]), &day03::split_movements(&movements[1])),
-        day03::first_cross_sum_of_lengths(&day03::split_movements(&movements[0]), &day03::split_movements(&movements[1]))
+        day03::manhattan_distance_from_cross_to_port(
+            &day03::split_movements(&movements[0]),
+            &day03::split_movements(&movements[1])
+        ),
+        day03::first_cross_sum_of_lengths(
+            &day03::split_movements(&movements[0]),
+            &day03::split_movements(&movements[1])
+        )
     )
 }
 
 fn day04() -> String {
     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))
+    format!(
+        "part1: {:?}, part2: {}",
+        day04::nb_passwords_part1(min, max),
+        day04::nb_passwords_part2(min, max)
+    )
 }
 
 fn day05() -> String {
     let code = common::read_list_of_numbers("data/day05.input", ",");
-    format!("part1: {:?}, part2: {:?}", intcode::execute_op_code(&code, &[1]), intcode::execute_op_code(&code, &[5]))
+    format!(
+        "part1: {:?}, part2: {:?}",
+        intcode::execute_op_code(&code, &[1]),
+        intcode::execute_op_code(&code, &[5])
+    )
 }
 
 fn day06() -> String {
     let file_content = fs::read_to_string("data/day06.input").unwrap();
     let lines: Vec<&str> = file_content.lines().collect();
     let orbits = day06::build_orbits(&lines);
-    format!("part1: {}, part2: {}", day06::total_direct_and_indirect_orbits(&orbits), day06::nb_orbital_transfers(&orbits, "SAN", "YOU"))
+    format!(
+        "part1: {}, part2: {}",
+        day06::total_direct_and_indirect_orbits(&orbits),
+        day06::nb_orbital_transfers(&orbits, "SAN", "YOU")
+    )
 }
 
 fn day07() -> String {
     let code = common::read_list_of_numbers("data/day07.input", ",");
 
-    format!("part1: {}, part2: {}", day07::find_largest_last_thruster_signal(&code), day07::find_largest_last_thruster_signal_with_feedback_loop(&code))
+    format!(
+        "part1: {}, part2: {}",
+        day07::find_largest_last_thruster_signal(&code),
+        day07::find_largest_last_thruster_signal_with_feedback_loop(&code)
+    )
 }
 
 fn day08() -> String {
@@ -74,13 +104,21 @@ fn day08() -> String {
     let layer = day08::layer_with_fewer_0(&layers[..]);
     let merged = day08::merge_layers(&layers[..]);
 
-    format!("part1: {}, part2:\n{}", day08::one_digits_times_two_digits(layer), common::layer_to_printable_string(&merged, 25))
+    format!(
+        "part1: {}, part2:\n{}",
+        day08::one_digits_times_two_digits(layer),
+        common::layer_to_printable_string(&merged, 25)
+    )
 }
 
 fn day09() -> String {
     let code = common::read_list_of_numbers::<&str, i64>("data/day09.input", ",");
 
-    format!("part1: {:?}, part2: {:?}", intcode::execute_op_code(&code, &[1]), intcode::execute_op_code(&code, &[2]))
+    format!(
+        "part1: {:?}, part2: {:?}",
+        intcode::execute_op_code(&code, &[1]),
+        intcode::execute_op_code(&code, &[2])
+    )
 }
 
 fn day10() -> String {
@@ -95,32 +133,52 @@ fn day11() -> String {
     let panels = day11::run_robot(&code, 1);
     let (layer, width) = day11::panels_to_layer(&panels);
 
-    format!("part1: {:?}, part2:\n{}", day11::run_robot(&code, 0).len(), common::layer_to_printable_string(&layer, width))
+    format!(
+        "part1: {:?}, part2:\n{}",
+        day11::run_robot(&code, 0).len(),
+        common::layer_to_printable_string(&layer, width)
+    )
 }
 
 fn day12() -> String {
     let coordinates = day12::parse_positions(&fs::read_to_string("data/day12.input").unwrap());
-    format!("part1: {}, part2: {}", day12::final_energy(&coordinates, 1000), day12::find_same_state(&coordinates))
+    format!(
+        "part1: {}, part2: {}",
+        day12::final_energy(&coordinates, 1000),
+        day12::find_same_state(&coordinates)
+    )
 }
 
 fn day13() -> String {
     let code = common::read_list_of_numbers::<&str, i64>("data/day13.input", ",");
     let mut modified_code = Vec::from(&code[..]);
     modified_code[0] = 2;
-    format!("part1: {}, part2: {}", day13::count_nb_block(&code), day13::final_score(&modified_code))
+    format!(
+        "part1: {}, part2: {}",
+        day13::count_nb_block(&code),
+        day13::final_score(&modified_code)
+    )
 }
 
 fn day14() -> String {
     let reactions = day14::parse(&fs::read_to_string("data/day14.input").unwrap());
 
     let ore_per_fuel = day14::ore_needed_per_fuel(&reactions);
-    format!("part1: {}, part2: {}", ore_per_fuel, day14::fuel_produced(&reactions, 1_000_000_000_000, ore_per_fuel))
+    format!(
+        "part1: {}, part2: {}",
+        ore_per_fuel,
+        day14::fuel_produced(&reactions, 1_000_000_000_000, ore_per_fuel)
+    )
 }
 
 fn day15() -> String {
     let code = common::read_list_of_numbers("data/day15.input", ",");
     let (n, dts) = day15::nb_of_movement_to_reach_oxygen(&code);
-    format!("part1: {}, part2: {}", n, day15::time_to_flood_the_area(&dts))
+    format!(
+        "part1: {}, part2: {}",
+        n,
+        day15::time_to_flood_the_area(&dts)
+    )
 }
 
 fn day16() -> String {
@@ -128,7 +186,11 @@ fn day16() -> String {
     let signal = day16::parse(&signal_raw);
     let output_part_1 = day16::fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1);
     // let output_part_2 = day16::part2(&signal);
-    format!("part1: {}, part2: {}", day16::digits_as_string(&output_part_1), /*day16::digits_as_string(&output_part_2)*/ "<skipped: take too long ~ 1 min>")
+    format!(
+        "part1: {}, part2: {}",
+        day16::digits_as_string(&output_part_1),
+        /*day16::digits_as_string(&output_part_2)*/ "<skipped: take too long ~ 1 min>"
+    )
 }
 
 fn day17() -> String {
@@ -159,51 +221,40 @@ fn format_micros(t: u128) -> String {
 
 fn do_day(days: &[fn() -> String], day: usize) {
     let now = Instant::now();
-    println!("Result of day {:02}: {} (time: {})", day, days[day - 1](), format_micros(now.elapsed().as_micros()));
+    println!(
+        "Result of day {:02}: {} (time: {})",
+        day,
+        days[day - 1](),
+        format_micros(now.elapsed().as_micros())
+    );
 }
 
 fn main() {
     println!("https://adventofcode.com/2019");
 
-    let days: Vec<fn() -> String> = vec!(
-        day01,
-        day02,
-        day03,
-        day04,
-        day05,
-        day06,
-        day07,
-        day08,
-        day09,
-        day10,
-        day11,
-        day12,
-        day13,
-        day14,
-        day15,
-        day16,
-        day17,
-        day18,
-    );
+    let days: Vec<fn() -> String> = vec![
+        day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
+        day14, day15, day16, day17, day18,
+    ];
 
     let args: Vec<String> = env::args().skip(1).collect();
 
     // No argument -> execute all day problems.
     if args.is_empty() {
         let now = Instant::now();
-        for i in 1 ..= days.len() {
+        for i in 1..=days.len() {
             do_day(&days, i)
         }
-        println!("Time to execute all days: {}", format_micros(now.elapsed().as_micros()));
+        println!(
+            "Time to execute all days: {}",
+            format_micros(now.elapsed().as_micros())
+        );
     } else {
         for arg in args {
             match arg.parse::<usize>() {
-                Ok(day) if day >= 1 && day <= days.len() =>
-                    do_day(&days, day),
-                Ok(day) =>
-                    println!("Unknown day: {}", day),
-                Err(error) =>
-                    println!("Unable to parse day number: \"{}\", error: {}", arg, error)
+                Ok(day) if day >= 1 && day <= days.len() => do_day(&days, day),
+                Ok(day) => println!("Unknown day: {}", day),
+                Err(error) => println!("Unable to parse day number: \"{}\", error: {}", arg, error),
             }
         }
     }