]> aoc.elinar.fr Git - aoc_2023/commitdiff
Day15 - part 2
authoralex <null>
Fri, 15 Dec 2023 09:14:25 +0000 (10:14 +0100)
committeralex <null>
Fri, 15 Dec 2023 22:25:43 +0000 (23:25 +0100)
src/day15.rs

index 28f26ae257db66451af957a0e84305f113733b2d..8d84672566fdaab8692ebbe3da7728d60b915f85 100644 (file)
@@ -2,6 +2,8 @@ use std::io::Read;
 use std::error::Error;
 use std::fs::File;
 
+use std::collections::HashMap;
+
 pub fn run(input_file: &str) -> Result<(), Box<dyn Error>> {
     let mut f = File::open(input_file)?;
     let mut input = String::new();
@@ -16,6 +18,15 @@ pub fn run(input_file: &str) -> Result<(), Box<dyn Error>> {
     Ok(())
 }
 
+fn aoc_hash(s: &str) -> u32 {
+    let mut r: u32 = 0;
+    s.as_bytes().iter()
+        .for_each(|&b| {
+            r = ((r + b as u32) * 17 ) % 256;
+        });
+    r
+}
+
 fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
     println!("Running day15 - part 1");
 
@@ -28,12 +39,7 @@ fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
             match h.is_empty() {
                 true => None,
                 false => {
-                    let mut r: u32 = 0;
-                    h.as_bytes().iter()
-                        .for_each(|&b| {
-                            r = ((r + b as u32) * 17 ) % 256;
-                        });
-                    Some(r)
+                    Some(aoc_hash(h))
                 },
             }
         })
@@ -44,7 +50,73 @@ fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
 
 fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
     println!("Running day15 - part 2");
-    let res = 0;
+
+    // map sur nom de la lentille
+    // la valeur contient le slot de la lentille et sa focale
+    let mut boxes: Vec<HashMap<String, (usize, u32)>> = Vec::new();
+    (0..256).for_each(|_| { boxes.push(HashMap::new()); });
+
+    let s = match input.ends_with('\n') {
+        false => input,
+        true  => &input[..input.len() - 1],
+    };
+    s.split(',')
+        .filter(|h| !h.is_empty())
+        .for_each(|h| {
+            let (label, n_lens) = h.split_once(['-', '=']).unwrap();
+            let box_n: usize = aoc_hash(label) as usize;
+            match n_lens {
+                "" => {
+                    // supprimer les lentilles
+                    let value = boxes[box_n].remove(label);
+                    // déplacer les slots des lentilles restantes
+                    if value.is_some() {
+                        let removed_slot = value.unwrap().0;
+                        let b = &mut boxes[box_n];
+                        b.iter_mut()
+                            .for_each(|value| { // label => (slot, focal)
+                                if value.1.0 > removed_slot {
+                                    value.1.0 -= 1;
+                                }
+                            });
+                    }
+                },
+                _ => {
+                    match boxes[box_n].get_mut(label) {
+                        Some(value) => { // (slot, label)
+                            // remplacer les lentilles
+                            value.1 = n_lens.parse().unwrap();
+                        },
+                        None => {
+                            // ajouter les lentilles
+                            let slot = boxes[box_n].values()
+                                .map(|(i,_)| i)
+                                .max();
+                            let slot = match slot {
+                                Some(s) => s + 1,
+                                None => 0,
+                            };
+                            boxes[box_n].insert(
+                                label.to_string(),
+                                (slot, n_lens.parse().unwrap())
+                            );
+                        },
+                    }
+                },
+            }
+        });
+
+    let res = boxes.iter().enumerate()
+        .map(|(i, b)| {
+            b.iter()
+                .map(|(_, (slot, focal))| {
+                    //println!("{} = i: {} slot: {} focal: {}", label, i + 1, slot + 1, focal);
+                    // focusing power
+                    (i as u32 + 1) * (*slot as u32 + 1) * focal
+                })
+                .sum::<u32>()
+        })
+        .sum();
     Ok(res)
 }
 
@@ -63,6 +135,6 @@ mod tests {
     #[test]
     fn day15_part2() {
         let res = run_part2(TEXT_INPUT);
-        assert_eq!(0, res.unwrap());
+        assert_eq!(145, res.unwrap());
     }
 }