github.com/mnlphlp/aoc22@v0.0.0-20230330151331-c1dc4bff1b9b/aoc22_rust/src/day03.rs (about)

     1  use crate::types::Task;
     2  
     3  fn find_duplicate(r: &[u8]) -> u8 {
     4      let mut seen: u64 = 0;
     5      let len = r.len();
     6      let (comp1, comp2) = r.split_at(r.len() / 2);
     7      for i in 0..len / 2 {
     8          // set bit for character in rucksack 1
     9          seen |= 1u64 << (comp1[i] - 65);
    10      }
    11      for i in 0..len / 2 {
    12          // check if character in rucksack 2 is already set
    13          if (seen & (1u64 << (comp2[i] - 65))) > 0 {
    14              return comp2[i];
    15          }
    16      }
    17      println!("No duplicate found in data:\n  {comp1:?}\n  {comp2:?}");
    18      return 0;
    19  }
    20  
    21  fn get_priority(duplicate: u8) -> i32 {
    22      if duplicate >= b'a' && duplicate <= b'z' {
    23          return duplicate as i32 - b'a' as i32 + 1;
    24      } else {
    25          return duplicate as i32 - b'A' as i32 + 27;
    26      }
    27  }
    28  
    29  fn find_badges(rucksacks: Vec<&str>) -> Vec<u8> {
    30      let mut badges = vec![0; rucksacks.len() / 3];
    31      // loop over groups
    32      for i in (0..rucksacks.len()).step_by(3) {
    33          let mut seen = vec![0; 3];
    34          // create set of seen items for each rucksack in one group
    35          for j in 0..3 {
    36              for c in rucksacks[i + j].as_bytes() {
    37                  seen[j] |= 1u64 << (c - 65)
    38              }
    39          }
    40          // search bit (character) set in all 3 rucksacks
    41          for r in 0..64 {
    42              if ((1u64 << r) & seen[0] & seen[1] & seen[2]) > 0 {
    43                  badges[i / 3] = r + 65;
    44                  break;
    45              }
    46          }
    47      }
    48      return badges;
    49  }
    50  
    51  pub fn solve(input: &str, test: bool, task: Task) -> (String, String) {
    52      let rucksacks: Vec<&str> = input.lines().collect();
    53      if test {
    54          println!("Rucksacks: {rucksacks:?}");
    55      }
    56      let (mut res1, mut res2) = ("".into(), "".into());
    57      if !matches!(task, Task::Two) {
    58          let sum: i32 = rucksacks
    59              .iter()
    60              .map(|r| find_duplicate(r.as_bytes()))
    61              .map(|d| get_priority(d))
    62              .sum();
    63          res1 = sum.to_string();
    64      }
    65      if !matches!(task, Task::One) {
    66          let badges = find_badges(rucksacks);
    67          let badge_sum: i32 = badges.iter().map(|b| get_priority(*b)).sum();
    68          if test {
    69              for b in badges {
    70                  println!("Badge: {}", String::from_utf8(vec![b]).unwrap());
    71              }
    72          }
    73          res2 = badge_sum.to_string();
    74      }
    75      return (res1, res2);
    76  }