at main 2.5 kB view raw
1#![allow(dead_code)] 2use anyhow::Context; 3const INPUT: &str = include_str!("input/2/actual.txt"); 4const IS_PART_2: bool = true; 5 6pub fn main() -> anyhow::Result<()> { 7 let ranges = parse(INPUT).context("parsing input")?; 8 9 let mut sum: u128 = 0; 10 11 for range in &ranges { 12 let range_sum = range 13 .sum_of_invalid_ids() 14 .context("summing invalid IDs for range")?; 15 sum += range_sum; 16 } 17 18 println!("TOTAL SUM OF INVALID NUMBERS IS {}", sum); 19 20 Ok(()) 21} 22 23struct Range(u128, u128); 24 25impl Range { 26 pub fn sum_of_invalid_ids(&self) -> anyhow::Result<u128> { 27 let mut sum: u128 = 0; 28 for n in self.0..=self.1 { 29 if (if IS_PART_2 { 30 is_invalid_pt_2(n) 31 } else { 32 is_invalid(n) 33 }) 34 .context("checking invalidity")? 35 { 36 // println!("{} is invalid", n); 37 sum += n 38 } else { 39 // println!("{} is valid", n); 40 } 41 } 42 Ok(sum) 43 } 44} 45 46fn parse(input: &str) -> anyhow::Result<Vec<Range>> { 47 let input = input.trim(); 48 let mut ranges = Vec::new(); 49 input 50 .split(',') 51 .try_for_each(|raw_range| -> anyhow::Result<()> { 52 let split_raw = raw_range.split('-').collect::<Vec<&str>>(); 53 let first = split_raw 54 .get(0) 55 .context("getting first")? 56 .parse::<u128>() 57 .context("parsing first")?; 58 let second = split_raw 59 .get(1) 60 .context("getting second")? 61 .parse::<u128>() 62 .context("parsing second")?; 63 ranges.push(Range(first, second)); 64 Ok(()) 65 }) 66 .context("running loop")?; 67 Ok(ranges) 68} 69 70fn is_invalid_pt_2(num: u128) -> anyhow::Result<bool> { 71 let as_string = num.to_string(); 72 let length = as_string.len(); 73 74 for i in 1..=length / 2 { 75 if length % i != 0 { 76 continue; 77 } 78 79 let pattern = &as_string[0..i]; 80 let repetitions = length / i; 81 82 if pattern.repeat(repetitions) == as_string { 83 return Ok(true); 84 } 85 } 86 87 Ok(false) 88} 89 90fn is_invalid(num: u128) -> anyhow::Result<bool> { 91 let as_string = num.to_string(); 92 let middle = as_string.len() / 2; 93 94 let split = as_string.split_at(middle); 95 96 let (left, right) = (split.0.to_string(), split.1.to_string()); 97 98 Ok(left == right) 99}