···11+---
22+title: "Gift Shop"
33+published: 2025-12-18
44+draft: false
55+---
66+77+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…
88+99+1010+# Boilerplate
1111+1212+```rust
1313+use std::fs;
1414+1515+fn main() {
1616+ let input = fs::read_to_string("./input.txt").unwrap();
1717+ let ranges = input.split(",");
1818+ let mut sum = 0;
1919+ for range in ranges {
2020+ let mut nums = range.split("-");
2121+2222+ let start: u64 = nums.next().unwrap().trim().parse().unwrap();
2323+ let end: u64 = nums.next().unwrap().trim().parse().unwrap();
2424+2525+ for i in start..=end {
2626+ let i_str = i.to_string();
2727+2828+ if check(i_str) {
2929+ sum += i;
3030+ }
3131+ }
3232+ }
3333+ println!("Sum: {sum}");
3434+}
3535+```
3636+3737+We parse the input, and send the number (as a string) to `check` function for the actual logic.
3838+3939+4040+# check
4141+4242+```rust title="check"
4343+fn check(i_str: String) -> bool {
4444+ for check_len in 1..i_str.len() {
4545+ if check_n(&i_str, check_len) {
4646+ return true;
4747+ }
4848+ }
4949+ return false;
5050+}
5151+```
5252+5353+We start with n=1 and go up to the length of the string checking if it has 'n' repeating blocks!
5454+5555+5656+# check<sub>n</sub>
5757+5858+check<sub>n</sub> actually performs the logic-
5959+6060+1. It is obviously not going to be 'n' repeating blocks if the length of the string is not even divisible by n!
6161+6262+ ```rust
6363+ if i_str.len() % check_len != 0 {
6464+ return false;
6565+ }
6666+ ```
6767+6868+2. Setup block content
6969+7070+ ```rust
7171+ let nums = i_str.char_indices();
7272+7373+ let mut curr = String::new();
7474+ let comp = &i_str[0..check_len];
7575+ ```
7676+7777+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.
7878+7979+ ```rust
8080+ for (id, c) in nums {
8181+ if id % check_len == 0 && id != 0 {
8282+ if comp != curr {
8383+ return false;
8484+ }
8585+ curr = String::new();
8686+ }
8787+ curr.push(c);
8888+ }
8989+ ```
9090+9191+4. We also need to check the last block
9292+9393+ ```rust
9494+ if comp != curr {
9595+ return false;
9696+ }
9797+ ```
9898+9999+5. We return true, if all blocks are same
100100+101101+ ```rust
102102+ true
103103+ ```
104104+105105+Our Final check<sub>n</sub> function-
106106+107107+```rust title="check_n"
108108+fn check_n(i_str: &str, check_len: usize) -> bool {
109109+ if i_str.len() % check_len != 0 {
110110+ return false;
111111+ }
112112+ let nums = i_str.char_indices();
113113+114114+ let mut curr = String::new();
115115+ let comp = &i_str[0..check_len];
116116+ for (id, c) in nums {
117117+ if id % check_len == 0 && id != 0 {
118118+ if comp != curr {
119119+ return false;
120120+ }
121121+ curr = String::new();
122122+ }
123123+ curr.push(c);
124124+ }
125125+ if comp != curr {
126126+ return false;
127127+ }
128128+ true
129129+}
130130+```
131131+132132+Which gives us our final program-
133133+134134+```rust title="main.rs"
135135+use std::fs;
136136+137137+fn main() {
138138+ let input = fs::read_to_string("./input.txt").unwrap();
139139+ let ranges = input.split(",");
140140+ let mut sum = 0;
141141+ for range in ranges {
142142+ let mut nums = range.split("-");
143143+144144+ let start: u64 = nums.next().unwrap().trim().parse().unwrap();
145145+ let end: u64 = nums.next().unwrap().trim().parse().unwrap();
146146+147147+ for i in start..=end {
148148+ let i_str = i.to_string();
149149+150150+ if check(i_str) {
151151+ sum += i;
152152+ }
153153+ }
154154+ }
155155+ println!("Sum: {sum}");
156156+}
157157+fn check(i_str: String) -> bool {
158158+ for check_len in 1..i_str.len() {
159159+ if check_n(&i_str, check_len) {
160160+ return true;
161161+ }
162162+ }
163163+ return false;
164164+}
165165+fn check_n(i_str: &str, check_len: usize) -> bool {
166166+ if i_str.len() % check_len != 0 {
167167+ return false;
168168+ }
169169+ let nums = i_str.char_indices();
170170+171171+ let mut curr = String::new();
172172+ let comp = &i_str[0..check_len];
173173+ for (id, c) in nums {
174174+ if id % check_len == 0 && id != 0 {
175175+ if comp != curr {
176176+ return false;
177177+ }
178178+ curr = String::new();
179179+ }
180180+ curr.push(c);
181181+ }
182182+ if comp != curr {
183183+ return false;
184184+ }
185185+ true
186186+}
187187+```
188188+
+120
src/content/aoc/2025/02.org
···11+#+title: Gift Shop
22+#+OPTIONS: toc:nil
33+#+PROPERTY: header-args:rust :noweb no-export
44+55+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...
66+77+88+** Boilerplate
99+#+name: boiler
1010+#+begin_src rust
1111+ use std::fs;
1212+1313+ fn main() {
1414+ let input = fs::read_to_string("./input.txt").unwrap();
1515+ let ranges = input.split(",");
1616+ let mut sum = 0;
1717+ for range in ranges {
1818+ let mut nums = range.split("-");
1919+2020+ let start: u64 = nums.next().unwrap().trim().parse().unwrap();
2121+ let end: u64 = nums.next().unwrap().trim().parse().unwrap();
2222+2323+ for i in start..=end {
2424+ let i_str = i.to_string();
2525+2626+ if check(i_str) {
2727+ sum += i;
2828+ }
2929+ }
3030+ }
3131+ println!("Sum: {sum}");
3232+ }
3333+#+end_src
3434+3535+We parse the input, and send the number (as a string) to =check= function for the actual logic.
3636+3737+** check
3838+#+name: check
3939+#+begin_src rust :title "check"
4040+ fn check(i_str: String) -> bool {
4141+ for check_len in 1..i_str.len() {
4242+ if check_n(&i_str, check_len) {
4343+ return true;
4444+ }
4545+ }
4646+ return false;
4747+ }
4848+#+end_src
4949+We start with n=1 and go up to the length of the string checking if it has 'n' repeating blocks!
5050+5151+** check_n
5252+check_n actually performs the logic-
5353+5454+ 1. It is obviously not going to be 'n' repeating blocks if the length of the string is not even divisible by n!
5555+ #+name: cn_1
5656+ #+begin_src rust
5757+ if i_str.len() % check_len != 0 {
5858+ return false;
5959+ }
6060+ #+end_src
6161+6262+ 2. Setup block content
6363+ #+name: cn_2
6464+ #+begin_src rust
6565+ let nums = i_str.char_indices();
6666+6767+ let mut curr = String::new();
6868+ let comp = &i_str[0..check_len];
6969+ #+end_src
7070+7171+ 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.
7272+ #+name: cn_3
7373+ #+begin_src rust
7474+ for (id, c) in nums {
7575+ if id % check_len == 0 && id != 0 {
7676+ if comp != curr {
7777+ return false;
7878+ }
7979+ curr = String::new();
8080+ }
8181+ curr.push(c);
8282+ }
8383+ #+end_src
8484+8585+ 4. We also need to check the last block
8686+ #+name: cn_4
8787+ #+begin_src rust
8888+ if comp != curr {
8989+ return false;
9090+ }
9191+ #+end_src
9292+9393+ 5. We return true, if all blocks are same
9494+ #+name: cn_5
9595+ #+begin_src rust
9696+ true
9797+ #+end_src
9898+9999+Our Final check_n function-
100100+101101+#+name: check_n
102102+#+begin_src rust :title "check_n" :noweb yes
103103+ fn check_n(i_str: &str, check_len: usize) -> bool {
104104+ <<cn_1>>
105105+ <<cn_2>>
106106+ <<cn_3>>
107107+ <<cn_4>>
108108+ <<cn_5>>
109109+ }
110110+#+end_src
111111+112112+113113+114114+115115+Which gives us our final program-
116116+#+begin_src rust :title "main.rs" :noweb yes
117117+ <<boiler>>
118118+ <<check>>
119119+ <<check_n>>
120120+#+end_src