Day 2: Gift Shop
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
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-
-
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;} -
Setup block content
let nums = i_str.char_indices();let mut curr = String::new();let comp = &i_str[0..check_len]; -
Now we append each character to
curr, and on every ‘n’th character, we comparecurrandcomp, if it is different, we return false, otherwise we clearcurrand continue.for (id, c) in nums {if id % check_len == 0 && id != 0 {if comp != curr {return false;}curr = String::new();}curr.push(c);} -
We also need to check the last block
if comp != curr {return false;} -
We return true, if all blocks are same
true
Our Final checkn function-
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-
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}