Day 2: Gift Shop

Year: 2025
Table of Contents

We are given comma-separated ranges of numbers that we have to check, we sum all the numbers which are n repeating blocks, for example, 123123 has n = 2, and block = 123, similarly, 111, has n = 3, and block = 1! Part 1 has n = 2, and Part 2 can have any value as n! So we can just directly solve Part 2 (although I did solve Part 1 as a standalone problem first). Let’s get started…

Boilerplate

use std::fs;
fn main() {
let input = fs::read_to_string("./input.txt").unwrap();
let ranges = input.split(",");
let mut sum = 0;
for range in ranges {
let mut nums = range.split("-");
let start: u64 = nums.next().unwrap().trim().parse().unwrap();
let end: u64 = nums.next().unwrap().trim().parse().unwrap();
for i in start..=end {
let i_str = i.to_string();
if check(i_str) {
sum += i;
}
}
}
println!("Sum: {sum}");
}

We parse the input, and send the number (as a string) to check function for the actual logic.

check

check
fn check(i_str: String) -> bool {
for check_len in 1..i_str.len() {
if check_n(&i_str, check_len) {
return true;
}
}
return false;
}

We start with n=1 and go up to the length of the string checking if it has ‘n’ repeating blocks!

checkn

checkn actually performs the logic-

  1. It is obviously not going to be ‘n’ repeating blocks if the length of the string is not even divisible by n!

    if i_str.len() % check_len != 0 {
    return false;
    }
  2. Setup block content

    let nums = i_str.char_indices();
    let mut curr = String::new();
    let comp = &i_str[0..check_len];
  3. Now we append each character to curr, and on every ‘n’th character, we compare curr and comp, if it is different, we return false, otherwise we clear curr and continue.

    for (id, c) in nums {
    if id % check_len == 0 && id != 0 {
    if comp != curr {
    return false;
    }
    curr = String::new();
    }
    curr.push(c);
    }
  4. We also need to check the last block

    if comp != curr {
    return false;
    }
  5. We return true, if all blocks are same

    true

Our Final checkn function-

check_n
fn check_n(i_str: &str, check_len: usize) -> bool {
if i_str.len() % check_len != 0 {
return false;
}
let nums = i_str.char_indices();
let mut curr = String::new();
let comp = &i_str[0..check_len];
for (id, c) in nums {
if id % check_len == 0 && id != 0 {
if comp != curr {
return false;
}
curr = String::new();
}
curr.push(c);
}
if comp != curr {
return false;
}
true
}

Which gives us our final program-

main.rs
use std::fs;
fn main() {
let input = fs::read_to_string("./input.txt").unwrap();
let ranges = input.split(",");
let mut sum = 0;
for range in ranges {
let mut nums = range.split("-");
let start: u64 = nums.next().unwrap().trim().parse().unwrap();
let end: u64 = nums.next().unwrap().trim().parse().unwrap();
for i in start..=end {
let i_str = i.to_string();
if check(i_str) {
sum += i;
}
}
}
println!("Sum: {sum}");
}
fn check(i_str: String) -> bool {
for check_len in 1..i_str.len() {
if check_n(&i_str, check_len) {
return true;
}
}
return false;
}
fn check_n(i_str: &str, check_len: usize) -> bool {
if i_str.len() % check_len != 0 {
return false;
}
let nums = i_str.char_indices();
let mut curr = String::new();
let comp = &i_str[0..check_len];
for (id, c) in nums {
if id % check_len == 0 && id != 0 {
if comp != curr {
return false;
}
curr = String::new();
}
curr.push(c);
}
if comp != curr {
return false;
}
true
}