···11---
22title: "Secret Entrance"
33-published: 2025-12-15
33+published: 2025-12-16
44draft: false
55---
66···10101111We are given line seperated operations that happen on a 100 pin circular dial. The dial starts at 50 and we are to output, how many times the dial stops at 0!
12121313-An example-
1313+We first, as expected, just take in the input and initialise variables to store current dial position and total number of times the dial has stopped at 0.
1414+1515+```rust title="setup"
1616+use std::fs::read_to_string;
1717+fn main() {
1818+ let contents = read_to_string("./input.txt").unwrap();
1919+ let mut curr: i32 = 50;
2020+ let mut tot = 0;
2121+2222+ <<logic_loop>>
2323+2424+ println!("Password: {tot}");
2525+}
2626+```
2727+2828+We go through each line of input, and parse it. Our input is in the form -"L50" where the first character is the direction in which the dial is to be rotated and the rest is the amplitude.
2929+3030+```rust title="logic_loop"
3131+for line in contents.lines() {
3232+ let words: Vec<char> = line.chars().collect();
3333+ let dir = words[0];
3434+ let amp: String = words[1..].iter().collect();
3535+ let amp: i32 = amp.parse().unwrap();
3636+3737+ <<rotate_dial>>
3838+}
3939+```
4040+4141+Now that we have both the dir and the amp, we can modify the dial position.
4242+4343+```rust title="rotate_dial"
4444+if dir == 'L' {
4545+ curr -= amp;
4646+} else {
4747+ curr += amp;
4848+}
4949+5050+<<loopback>>
5151+```
5252+5353+The value of curr could have gone above 99 or below 0, which we need to rectify.
5454+5555+```rust title="loopback"
5656+if curr < 0 {
5757+ curr = 100 + curr;
5858+}
5959+6060+curr = curr % 100;
6161+6262+<<count_zeros>>
6363+```
6464+6565+Now that we have the current position of the dial, we only need to check if it currently points at 0, and increment `tot`, if it does.
6666+6767+```rust title="count_zeros"
6868+if curr == 0 {
6969+ tot += 1;
7070+}
7171+```
7272+7373+We have the final program-
7474+7575+```rust title="Full Program"
7676+use std::fs::read_to_string;
7777+fn main() {
7878+ let contents = read_to_string("./input.txt").unwrap();
7979+ let mut curr: i32 = 50;
8080+ let mut tot = 0;
8181+8282+ for line in contents.lines() {
8383+ let words: Vec<char> = line.chars().collect();
8484+ let dir = words[0];
8585+ let amp: String = words[1..].iter().collect();
8686+ let amp: i32 = amp.parse().unwrap();
8787+8888+ if dir == 'L' {
8989+ curr -= amp;
9090+ } else {
9191+ curr += amp;
9292+ }
9393+9494+ if curr < 0 {
9595+ curr = 100 + curr;
9696+ }
9797+9898+ curr = curr % 100;
9999+100100+ if curr == 0 {
101101+ tot += 1;
102102+ }
103103+ }
104104+105105+ println!("Password: {tot}");
106106+}
107107+```
108108+109109+110110+# Part 2
111111+112112+Another complication has been added to our little problem! Now we not only need to say how many times the dial stopped at 0, but also how many times it crossed it!
113113+114114+We add two new variables that are going to help us! `prev` and `cross`. We are going to keep `tot` and its related logic and add onto it!
115115+116116+```rust
117117+// In setup
118118+let mut prev: i32 = 50;
119119+let mut cross = 0;
120120+```
121121+122122+If the amplitude is >100, that means atleast one full rotation, therefore, atleast oe crossing of 0! We can figure out the number of crossing here using division. We also bring the value of amp to the range [0, 99].
123123+124124+```rust
125125+cross += amp / 100;
126126+let amp = amp % 100;
127127+```
128128+129129+And easy way to detect a crossing is to check if the difference in `curr` and `prev` is opposite to what we expected. For example, let's say dial position is at `5` and we get input `L10`, as the `dir` is `L`, the dial position should decrease, that is, `curr` < `prev`, but as the `amp` was 10, the new dial position becomes `95`. Now, `curr` (95) > `prev` (5). Detecting for this, and similarly `curr` < `prev` for `R`, we can get if there was a crossing on this move! One thing we need to keep in mind is to ignore those where either `curr` or `prev` were 0, as they would have been already counted by `tot`!
130130+131131+:::duck
132132+Also, do remember to set `prev = curr` at the end, you don't want to know how much time I spent debugging this!
133133+:::
134134+135135+```rust
136136+if ((dir == 'L' && prev < curr) || (dir == 'R' && prev > curr)) && curr != 0 && prev != 0 {
137137+ cross += 1;
138138+}
139139+140140+prev = curr;
141141+```
142142+143143+Our final program-
144144+145145+```rust title="main.rs"
146146+use std::fs::read_to_string;
147147+148148+fn main() {
149149+ let contents = read_to_string("./input.txt").unwrap();
150150+151151+ let mut curr: i32 = 50;
152152+ let mut prev: i32 = 50;
153153+ let mut tot = 0;
154154+ let mut cross = 0;
155155+156156+ for line in contents.lines() {
157157+ let words: Vec<char> = line.chars().collect();
158158+ let dir = words[0];
159159+ let amp: String = words[1..].iter().collect();
160160+ let amp: i32 = amp.parse().unwrap();
161161+162162+ cross += amp / 100;
163163+ let amp = amp % 100;
164164+165165+ if dir == 'L' {
166166+ curr -= amp;
167167+ } else {
168168+ curr += amp;
169169+ }
170170+171171+ if curr < 0 {
172172+ curr = 100 + curr;
173173+ }
174174+ curr = curr % 100;
141751515-> L68
1616-> L30
1717-> R48
1818-> L5
1919-> R60
2020-> L55
2121-> L1
2222-> L99
2323-> R14
2424-> L82
176176+ if curr == 0 {
177177+ tot += 1;
178178+ }
179179+ if ((dir == 'L' && prev < curr) || (dir == 'R' && prev > curr)) && curr != 0 && prev != 0 {
180180+ cross += 1;
181181+ }
251822626-- Dial @ 50
2727-- L68 -> 82
2828-- L30 -> 52
2929-- R48 -> **0**!
3030-- L5 -> 95
3131-- R60 -> 55
3232-- L55 -> **0**!
3333-- L1 -> 99
3434-- L99 -> **0**!
3535-- R14 -> 14
3636-- L82 -> 32
3737-3838- So, in total `3` times! `3` is our answer!
183183+ prev = curr;
184184+ }
185185+ println!("Password: {}", cross + tot);
186186+}
187187+```
39188
+143-1
src/content/aoc/2025/01.org
···11#+title: Secret Entrance
22#+OPTIONS: toc:nil
33+#+PROPERTY: header-args:rust :noweb no-export
3445* Part 1
56We are given line seperated operations that happen on a 100 pin circular dial. The dial starts at 50 and we are to output, how many times the dial stops at 0!
6788+99+We first, as expected, just take in the input and initialise variables to store current dial position and total number of times the dial has stopped at 0.
1010+#+name: setup
1111+#+begin_src rust :title "setup"
1212+ use std::fs::read_to_string;
1313+ fn main() {
1414+ let contents = read_to_string("./input.txt").unwrap();
1515+ let mut curr: i32 = 50;
1616+ let mut tot = 0;
1717+1818+ <<logic_loop>>
1919+2020+ println!("Password: {tot}");
2121+ }
2222+#+end_src
2323+2424+We go through each line of input, and parse it. Our input is in the form -"L50" where the first character is the direction in which the dial is to be rotated and the rest is the amplitude.
2525+2626+#+name: logic_loop
2727+#+begin_src rust :title "logic_loop"
2828+ for line in contents.lines() {
2929+ let words: Vec<char> = line.chars().collect();
3030+ let dir = words[0];
3131+ let amp: String = words[1..].iter().collect();
3232+ let amp: i32 = amp.parse().unwrap();
3333+3434+ <<rotate_dial>>
3535+ }
3636+#+end_src
3737+3838+Now that we have both the dir and the amp, we can modify the dial position.
3939+#+name: rotate_dial
4040+#+begin_src rust :title "rotate_dial"
4141+ if dir == 'L' {
4242+ curr -= amp;
4343+ } else {
4444+ curr += amp;
4545+ }
4646+4747+ <<loopback>>
4848+#+end_src
4949+5050+The value of curr could have gone above 99 or below 0, which we need to rectify.
5151+#+name: loopback
5252+#+begin_src rust :title "loopback"
5353+ if curr < 0 {
5454+ curr = 100 + curr;
5555+ }
5656+5757+ curr = curr % 100;
5858+5959+ <<count_zeros>>
6060+#+end_src
6161+6262+Now that we have the current position of the dial, we only need to check if it currently points at 0, and increment =tot=, if it does.
6363+#+name: count_zeros
6464+#+begin_src rust :title "count_zeros"
6565+ if curr == 0 {
6666+ tot += 1;
6767+ }
6868+#+end_src
6969+7070+We have the final program-
7171+7272+#+begin_src rust :noweb yes :title "Full Program"
7373+ <<setup>>
7474+#+end_src
7575+7676+* Part 2
7777+7878+Another complication has been added to our little problem! Now we not only need to say how many times the dial stopped at 0, but also how many times it crossed it!
7979+8080+We add two new variables that are going to help us! =prev= and =cross=. We are going to keep =tot= and its related logic and add onto it!
8181+782#+begin_src rust
8383+ // In setup
8484+ let mut prev: i32 = 50;
8585+ let mut cross = 0;
886#+end_src
9871010-#+RESULTS:
8888+If the amplitude is >100, that means atleast one full rotation, therefore, atleast oe crossing of 0! We can figure out the number of crossing here using division. We also bring the value of amp to the range [0, 99].
8989+#+begin_src rust
9090+ cross += amp / 100;
9191+ let amp = amp % 100;
9292+#+end_src
9393+9494+And easy way to detect a crossing is to check if the difference in =curr= and =prev= is opposite to what we expected. For example, let's say dial position is at =5= and we get input =L10=, as the =dir= is =L=, the dial position should decrease, that is, =curr= < =prev=, but as the =amp= was 10, the new dial position becomes =95=. Now, =curr= (95) > =prev= (5). Detecting for this, and similarly =curr= < =prev= for =R=, we can get if there was a crossing on this move! One thing we need to keep in mind is to ignore those where either =curr= or =prev= were 0, as they would have been already counted by =tot=!
9595+9696+:::duck
9797+Also, do remember to set =prev = curr= at the end, you don't want to know how much time I spent debugging this!
9898+:::
9999+100100+#+begin_src rust
101101+ if ((dir == 'L' && prev < curr) || (dir == 'R' && prev > curr)) && curr != 0 && prev != 0 {
102102+ cross += 1;
103103+ }
104104+105105+ prev = curr;
106106+#+end_src
107107+108108+109109+Our final program-
110110+#+begin_src rust :title "main.rs"
111111+ use std::fs::read_to_string;
112112+113113+ fn main() {
114114+ let contents = read_to_string("./input.txt").unwrap();
115115+116116+ let mut curr: i32 = 50;
117117+ let mut prev: i32 = 50;
118118+ let mut tot = 0;
119119+ let mut cross = 0;
120120+121121+ for line in contents.lines() {
122122+ let words: Vec<char> = line.chars().collect();
123123+ let dir = words[0];
124124+ let amp: String = words[1..].iter().collect();
125125+ let amp: i32 = amp.parse().unwrap();
126126+127127+ cross += amp / 100;
128128+ let amp = amp % 100;
129129+130130+ if dir == 'L' {
131131+ curr -= amp;
132132+ } else {
133133+ curr += amp;
134134+ }
135135+136136+ if curr < 0 {
137137+ curr = 100 + curr;
138138+ }
139139+ curr = curr % 100;
140140+141141+ if curr == 0 {
142142+ tot += 1;
143143+ }
144144+ if ((dir == 'L' && prev < curr) || (dir == 'R' && prev > curr)) && curr != 0 && prev != 0 {
145145+ cross += 1;
146146+ }
147147+148148+ prev = curr;
149149+ }
150150+ println!("Password: {}", cross + tot);
151151+ }
152152+#+end_src