Skip to main content
added 669 characters in body
Source Link
Boiethios
  • 600
  • 2
  • 11

If you want to do the two days in one like in your code:

fn offset_sum(s: &str, day1: bool) -> u32 {

    fn get_sum(s: &str, offset: usize) -> u32 {
        s.chars()
         .zip(s.chars().cycle().skip(offset))
         .filter(|&(a, b)| a == b)
         .filter_map(|(a, _)| a.to_digit(10))
         .sum()
    }
    
    let offset = if day1 { 1 } else { s.len() / 2 };
    get_sum(s, offset)
}

fn main() {
    let input = include_str!("input.txt");

    println!("day 1: {}", offset_sum(input, true));
    println!("day 2: {}", offset_sum(input, false));
}

If you want to do the two days in one like in your code:

fn offset_sum(s: &str, day1: bool) -> u32 {

    fn get_sum(s: &str, offset: usize) -> u32 {
        s.chars()
         .zip(s.chars().cycle().skip(offset))
         .filter(|&(a, b)| a == b)
         .filter_map(|(a, _)| a.to_digit(10))
         .sum()
    }
    
    let offset = if day1 { 1 } else { s.len() / 2 };
    get_sum(s, offset)
}

fn main() {
    let input = include_str!("input.txt");

    println!("day 1: {}", offset_sum(input, true));
    println!("day 2: {}", offset_sum(input, false));
}
Source Link
Boiethios
  • 600
  • 2
  • 11

If you only need to read one line from a file that will not change at runtime, you can use include_str!

As already said, the whole program can be simplified a lot using a functional programming style on iterators:

fn result(s: &str) -> u32 {
    s.chars()
     .zip(s.chars().cycle().skip(1))
     .filter(|&(a, b)| a == b)
     .filter_map(|(a, _)| a.to_digit(10))
     .sum()
}

fn main() {
    // is everything ok?
    assert_eq!(result("1122"), 3);
    assert_eq!(result("1111"), 4);
    assert_eq!(result("1234"), 0);
    assert_eq!(result("91212129"), 9);
    
    // get your answer:
    println!("{}", result(include_str!("input.txt")));
}

Explanations:

s.chars().cycle().skip(1) gives you a shifted string. cycle makes the iterator cycle infinitely, skip(1) remove the first (replace it with cycle(s.len() / 2) for the second part.

You the zip the two iterators: one on the string, one on the shifted string.

Then you keep the pairs with same numbers: filter(|&(a, b)| a == b)

Then you convert each char to u32 and you discard the failed conversions.

Then you make the sum of all the numbers.