Skip to content

Commit 79ecca0

Browse files
committed
2025 01.2
I feel like doing these first thing in the morning is a wonderful exercise in making me feel like a dumbass.
1 parent 7d8ca04 commit 79ecca0

File tree

1 file changed

+140
-27
lines changed

1 file changed

+140
-27
lines changed

src/aoc/y2025/day01.rs

Lines changed: 140 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
use std::fmt::Display;
1111
use std::str::FromStr;
1212

13+
use num::Integer;
14+
1315
use crate::AoCError;
1416

1517
#[derive(Debug)]
1618
enum Instruction {
17-
Left(i16),
18-
Right(i16),
19+
Left(u16),
20+
Right(u16),
1921
}
2022

2123
impl FromStr for Instruction {
@@ -38,18 +40,11 @@ impl FromStr for Instruction {
3840

3941
impl Display for Instruction {
4042
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41-
write!(
42-
f,
43-
"Rotate {} {} clicks",
44-
match self {
45-
Self::Left(_) => "left",
46-
Self::Right(_) => "right",
47-
},
48-
match self {
49-
Self::Left(i) => i,
50-
Self::Right(i) => i,
51-
}
52-
)
43+
let (dir, amt) = match self {
44+
Self::Left(i) => ("L", i),
45+
Self::Right(i) => ("R", i),
46+
};
47+
write!(f, "{}{}", dir, amt)
5348
}
5449
}
5550

@@ -69,27 +64,48 @@ impl Display for Dial {
6964
}
7065

7166
impl Dial {
72-
fn rotate(&mut self, instruction: Instruction) {
67+
fn rotate(&mut self, instruction: Instruction) -> u32 {
68+
let mut ret = 0;
69+
7370
match instruction {
7471
Instruction::Left(count) => {
72+
let (full_rotations, count) = count.div_mod_floor(&100);
73+
ret += full_rotations as u32;
7574
let count: i64 = count.into();
75+
let prezero = self.0 == 0;
7676
self.0 -= count;
77+
if self.0 < 0 {
78+
self.0 += 100;
79+
if !prezero {
80+
ret += 1;
81+
}
82+
} else if count > 0 && self.0 == 0 {
83+
ret += 1;
84+
}
7785
}
7886
Instruction::Right(count) => {
87+
let (full_rotations, count) = count.div_mod_floor(&100);
88+
ret += full_rotations as u32;
7989
let count: i64 = count.into();
8090
self.0 += count;
91+
if self.0 > 99 {
92+
self.0 -= 100;
93+
ret += 1;
94+
} else if count > 0 && self.0 == 0 {
95+
ret += 1;
96+
}
8197
}
8298
}
83-
self.clampinate();
84-
}
85-
86-
fn clampinate(&mut self) {
87-
while self.0 < 0 {
88-
self.0 += 100;
89-
}
90-
while self.0 > 99 {
91-
self.0 -= 100;
99+
if ret > 0 {
100+
log::debug!(
101+
"The dial is rotated {instruction} to point at {}; {ret} passes of 0",
102+
self.0
103+
);
104+
} else {
105+
log::debug!("The dial is rotated {instruction} to point at {}", self.0);
92106
}
107+
108+
ret
93109
}
94110
}
95111

@@ -98,8 +114,6 @@ pub fn part_1(data: crate::DataIn) -> crate::AoCResult<String> {
98114
let mut dial: Dial = Default::default();
99115
for line in data {
100116
let instruction = line.parse()?;
101-
log::debug!("{dial}");
102-
log::debug!("-> {instruction}");
103117
dial.rotate(instruction);
104118
if dial.0 == 0 {
105119
ret += 1;
@@ -109,12 +123,111 @@ pub fn part_1(data: crate::DataIn) -> crate::AoCResult<String> {
109123
Ok(ret.to_string())
110124
}
111125

126+
pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
127+
let mut ret = 0;
128+
let mut dial: Dial = Default::default();
129+
for line in data {
130+
let instruction = line.parse()?;
131+
ret += dial.rotate(instruction);
132+
}
133+
log::info!("{dial}");
134+
Ok(ret.to_string())
135+
}
136+
112137
inventory::submit!(crate::AoCDay {
113138
year: "2025",
114139
day: "1",
115140
part_1: crate::AoCPart {
116141
main: part_1,
117142
example: part_1
118143
},
119-
part_2: None
144+
part_2: Some(crate::AoCPart {
145+
main: part_2,
146+
example: part_2
147+
})
120148
});
149+
150+
#[cfg(test)]
151+
mod test {
152+
use super::{Dial, Instruction};
153+
154+
#[test]
155+
fn test_safe_zero() {
156+
let mut dial = Dial(50);
157+
let instruction = Instruction::Left(50);
158+
159+
let ret = dial.rotate(instruction);
160+
assert_eq!(dial.0, 0);
161+
assert_eq!(ret, 1);
162+
}
163+
164+
#[test]
165+
fn test_right_zero() {
166+
let mut dial = Dial(50);
167+
let instruction = Instruction::Right(50);
168+
169+
let ret = dial.rotate(instruction);
170+
assert_eq!(dial.0, 0);
171+
assert_eq!(ret, 1);
172+
}
173+
174+
#[test]
175+
fn test_left_multi_rot() {
176+
let mut dial = Dial(50);
177+
let instruction = Instruction::Left(150);
178+
179+
let ret = dial.rotate(instruction);
180+
assert_eq!(dial.0, 0);
181+
assert_eq!(ret, 2);
182+
}
183+
184+
#[test]
185+
fn test_right_multi_rot() {
186+
let mut dial = Dial(50);
187+
let instruction = Instruction::Right(150);
188+
189+
let ret = dial.rotate(instruction);
190+
assert_eq!(dial.0, 0);
191+
assert_eq!(ret, 2);
192+
}
193+
194+
#[test]
195+
fn test_zero_full_left() {
196+
let mut dial = Dial(0);
197+
let instruction = Instruction::Left(100);
198+
199+
let ret = dial.rotate(instruction);
200+
assert_eq!(dial.0, 0);
201+
assert_eq!(ret, 1);
202+
}
203+
204+
#[test]
205+
fn test_zero_full_right() {
206+
let mut dial = Dial(0);
207+
let instruction = Instruction::Right(100);
208+
209+
let ret = dial.rotate(instruction);
210+
assert_eq!(dial.0, 0);
211+
assert_eq!(ret, 1);
212+
}
213+
214+
#[test]
215+
fn test_one_click_left() {
216+
let mut dial = Dial(0);
217+
let instruction = Instruction::Left(1);
218+
219+
let ret = dial.rotate(instruction);
220+
assert_eq!(dial.0, 99);
221+
assert_eq!(ret, 0);
222+
}
223+
224+
#[test]
225+
fn test_one_click_right() {
226+
let mut dial = Dial(0);
227+
let instruction = Instruction::Right(1);
228+
229+
let ret = dial.rotate(instruction);
230+
assert_eq!(dial.0, 1);
231+
assert_eq!(ret, 0);
232+
}
233+
}

0 commit comments

Comments
 (0)