11use crate :: solutions:: Solution ;
22use std:: fmt:: { Display , Formatter } ;
3+ use std:: ops:: Div ;
34use std:: str:: FromStr ;
45
56pub struct Day01 ;
@@ -49,29 +50,33 @@ impl SafeDial {
4950 }
5051
5152 fn rotate ( & self , rotation : Rotation ) -> Self {
52- let diff : i16 = match rotation. direction {
53- Direction :: Left => self . position as i16 - rotation. distance as i16 ,
54- Direction :: Right => self . position as i16 + rotation. distance as i16 ,
53+ let to_apply = match rotation. direction {
54+ Direction :: Left => - ( rotation. distance as i16 ) ,
55+ Direction :: Right => rotation. distance as i16 ,
5556 } ;
57+ let diff: i16 = self . position as i16 + to_apply;
5658
5759 let mut zero_stops = self . zero_stops ;
58- let mut zero_clicks = self . zero_clicks ;
5960
6061 let new_position = diff. rem_euclid ( Self :: DIAL_NUMBERS_COUNT ) as u16 ;
6162 if new_position == 0 {
6263 zero_stops += 1 ;
6364 }
6465
65- let mut new_zero_clicks = diff. div_euclid ( Self :: DIAL_NUMBERS_COUNT ) . unsigned_abs ( ) ;
66-
67- if ( new_position == 0 || self . position == 0 ) && new_zero_clicks > 0 {
68- new_zero_clicks -= 1 ;
69- }
70-
71- zero_clicks += new_zero_clicks;
72-
73- // println!("{} + {} = {}, click: {}, stops: {}", self.position, rotation, new_position, zero_clicks, zero_stops);
74- // let _ = std::io::stdin().read_line(&mut String::new());
66+ let zero_clicks = self . zero_clicks
67+ + match rotation. direction {
68+ Direction :: Left => {
69+ let mut base = 100 - self . position + rotation. distance ;
70+ if self . position == 0 {
71+ base -= 100 ;
72+ }
73+
74+ base. div ( Self :: DIAL_NUMBERS_COUNT as u16 )
75+ }
76+ Direction :: Right => {
77+ ( self . position + rotation. distance ) . div ( Self :: DIAL_NUMBERS_COUNT as u16 )
78+ }
79+ } ;
7580
7681 Self {
7782 position : new_position,
@@ -85,16 +90,7 @@ impl SafeDial {
8590 }
8691
8792 fn points_to_zero ( & self ) -> u16 {
88- self . zero_clicks + self . zero_stops
89- }
90-
91- #[ cfg( test) ]
92- fn with ( value : u16 ) -> Self {
93- Self {
94- position : value,
95- zero_stops : 0 ,
96- zero_clicks : 0 ,
97- }
93+ self . zero_clicks
9894 }
9995}
10096
@@ -196,129 +192,208 @@ L82"#;
196192 }
197193
198194 #[ test]
199- fn safe_dial_rotate_test ( ) {
195+ fn zero_stops_test ( ) {
200196 let mut dial = SafeDial :: new ( ) ;
201197
202198 dial = dial. rotate ( Rotation :: left ( 68 ) ) ;
203199 assert_eq ! ( 82 , dial. position) ;
204- assert_eq ! ( 0 , dial. zero_stops) ;
205- assert_eq ! ( 1 , dial. zero_clicks) ;
200+ assert_eq ! ( 0 , dial. stops_at_zero( ) ) ;
206201
207202 dial = dial. rotate ( Rotation :: left ( 30 ) ) ;
208203 assert_eq ! ( 52 , dial. position) ;
209- assert_eq ! ( 0 , dial. zero_stops) ;
210- assert_eq ! ( 1 , dial. zero_clicks) ;
204+ assert_eq ! ( 0 , dial. stops_at_zero( ) ) ;
211205
212206 dial = dial. rotate ( Rotation :: right ( 48 ) ) ;
213207 assert_eq ! ( 0 , dial. position) ;
214- assert_eq ! ( 1 , dial. zero_stops) ;
215- assert_eq ! ( 1 , dial. zero_clicks) ;
208+ assert_eq ! ( 1 , dial. stops_at_zero( ) ) ;
216209
217210 dial = dial. rotate ( Rotation :: left ( 5 ) ) ;
218211 assert_eq ! ( 95 , dial. position) ;
219- assert_eq ! ( 1 , dial. zero_stops) ;
220- assert_eq ! ( 1 , dial. zero_clicks) ;
212+ assert_eq ! ( 1 , dial. stops_at_zero( ) ) ;
221213
222214 dial = dial. rotate ( Rotation :: right ( 60 ) ) ;
223215 assert_eq ! ( 55 , dial. position) ;
224- assert_eq ! ( 1 , dial. zero_stops) ;
225- assert_eq ! ( 2 , dial. zero_clicks) ;
216+ assert_eq ! ( 1 , dial. stops_at_zero( ) ) ;
226217
227218 dial = dial. rotate ( Rotation :: left ( 55 ) ) ;
228219 assert_eq ! ( 0 , dial. position) ;
229- assert_eq ! ( 2 , dial. zero_stops) ;
230- assert_eq ! ( 2 , dial. zero_clicks) ;
220+ assert_eq ! ( 2 , dial. stops_at_zero( ) ) ;
231221
232222 dial = dial. rotate ( Rotation :: left ( 1 ) ) ;
233223 assert_eq ! ( 99 , dial. position) ;
234- assert_eq ! ( 2 , dial. zero_stops) ;
235- assert_eq ! ( 2 , dial. zero_clicks) ;
224+ assert_eq ! ( 2 , dial. stops_at_zero( ) ) ;
236225
237226 dial = dial. rotate ( Rotation :: left ( 99 ) ) ;
238227 assert_eq ! ( 0 , dial. position) ;
239- assert_eq ! ( 3 , dial. zero_stops) ;
240- assert_eq ! ( 2 , dial. zero_clicks) ;
228+ assert_eq ! ( 3 , dial. stops_at_zero( ) ) ;
241229
242230 dial = dial. rotate ( Rotation :: right ( 14 ) ) ;
243231 assert_eq ! ( 14 , dial. position) ;
244- assert_eq ! ( 3 , dial. zero_stops) ;
245- assert_eq ! ( 2 , dial. zero_clicks) ;
232+ assert_eq ! ( 3 , dial. stops_at_zero( ) ) ;
246233
247234 dial = dial. rotate ( Rotation :: left ( 82 ) ) ;
248235 assert_eq ! ( 32 , dial. position) ;
249- assert_eq ! ( 3 , dial. zero_stops) ;
250- assert_eq ! ( 3 , dial. zero_clicks) ;
236+ assert_eq ! ( 3 , dial. stops_at_zero( ) ) ;
251237 }
252238
253239 #[ test]
254- fn my_input_tests ( ) {
255- let mut dial = SafeDial :: with ( 90 ) ;
256- dial = dial. rotate ( Rotation :: left ( 636 ) ) ;
257- // 1 -100:90, 536
258- // 2 -100:90, 436
259- // 3 -100:90, 336
260- // 4 -100:90, 236
261- // 5 -100:90, 136
262- // 6 -100:90, 36
263- // 6 -36:54
264-
265- assert_eq ! ( 6 , dial. points_to_zero( ) ) ;
266-
267- dial = dial. rotate ( Rotation :: left ( 654 ) ) ;
268- assert_eq ! ( 12 , dial. points_to_zero( ) ) ;
269- }
240+ fn position_at_zero_on_right ( ) {
241+ let mut dial = SafeDial :: new ( ) ; // 50
270242
271- #[ test]
272- fn zero_clicks_test ( ) {
273- let mut dial = SafeDial :: new ( ) ;
243+ dial = dial. rotate ( Rotation :: right ( 12 ) ) ; // 62
244+ assert_eq ! ( 0 , dial. points_to_zero( ) ) ;
274245
275- dial = dial. rotate ( Rotation :: right ( 50 ) ) ; // 0
246+ dial = dial. rotate ( Rotation :: right ( 52 ) ) ; // 14
276247 assert_eq ! ( 1 , dial. points_to_zero( ) ) ;
277248
278- dial = dial. rotate ( Rotation :: right ( 200 ) ) ; // 0
249+ dial = dial. rotate ( Rotation :: right ( 265 ) ) ; // 79
279250 assert_eq ! ( 3 , dial. points_to_zero( ) ) ;
280251
281- dial = dial. rotate ( Rotation :: right ( 1 ) ) ; // 1
282- assert_eq ! ( 3 , dial. points_to_zero( ) ) ;
283-
284- dial = dial. rotate ( Rotation :: right ( 299 ) ) ; // 0
285- assert_eq ! ( 6 , dial. points_to_zero( ) ) ;
286-
287- dial = dial. rotate ( Rotation :: left ( 300 ) ) ; // 0
288- assert_eq ! ( 9 , dial. points_to_zero( ) ) ;
252+ dial = dial. rotate ( Rotation :: right ( 421 ) ) ; // 0
253+ assert_eq ! ( 8 , dial. points_to_zero( ) ) ;
289254
290- dial = dial. rotate ( Rotation :: left ( 301 ) ) ; // 99
291- assert_eq ! ( 12 , dial. points_to_zero( ) ) ;
292-
293- dial = dial. rotate ( Rotation :: right ( 2 ) ) ; // 1
255+ dial = dial. rotate ( Rotation :: right ( 500 ) ) ; // 0
294256 assert_eq ! ( 13 , dial. points_to_zero( ) ) ;
295257
296- dial = dial. rotate ( Rotation :: left ( 202 ) ) ; // 99
297- assert_eq ! ( 16 , dial. points_to_zero( ) ) ;
258+ dial = dial. rotate ( Rotation :: right ( 27 ) ) ; // 27
259+ assert_eq ! ( 13 , dial. points_to_zero( ) ) ;
260+ }
298261
299- dial = dial. rotate ( Rotation :: left ( 98 ) ) ; // 1
300- assert_eq ! ( 16 , dial. points_to_zero( ) ) ;
262+ #[ test]
263+ fn position_at_zero_on_left ( ) {
264+ let mut dial = SafeDial :: new ( ) ; // 50
301265
302- dial = dial. rotate ( Rotation :: right ( 199 ) ) ; // 0
303- assert_eq ! ( 18 , dial. points_to_zero( ) ) ;
266+ dial = dial. rotate ( Rotation :: left ( 12 ) ) ;
267+ assert_eq ! ( 38 , dial. position) ;
268+ assert_eq ! ( 0 , dial. points_to_zero( ) ) ;
304269
305- dial = dial. rotate ( Rotation :: right ( 1 ) ) ; // 1
306- assert_eq ! ( 18 , dial. points_to_zero( ) ) ;
270+ dial = dial. rotate ( Rotation :: left ( 99 ) ) ;
271+ assert_eq ! ( 39 , dial. position) ;
272+ assert_eq ! ( 1 , dial. points_to_zero( ) ) ;
307273
308- dial = dial. rotate ( Rotation :: left ( 102 ) ) ; // 99
309- assert_eq ! ( 20 , dial. points_to_zero( ) ) ;
310- }
274+ // 1 39, 165
275+ // 2 39, 65
276+ // 3 52
277+ dial = dial. rotate ( Rotation :: left ( 265 ) ) ;
278+ assert_eq ! ( 74 , dial. position) ;
279+ assert_eq ! ( 4 , dial. points_to_zero( ) ) ;
280+
281+ // 1 74, 89
282+ // 2 85
283+ dial = dial. rotate ( Rotation :: left ( 189 ) ) ;
284+ assert_eq ! ( 85 , dial. position) ;
285+ assert_eq ! ( 6 , dial. points_to_zero( ) ) ;
311286
312- #[ test]
313- fn zero_clicks_1000_test ( ) {
314- let initial_dial = SafeDial :: new ( ) ;
287+ // 1 85, 120
288+ // 2 85, 20
289+ // 2 65
290+ dial = dial. rotate ( Rotation :: left ( 220 ) ) ;
291+ assert_eq ! ( 65 , dial. position) ;
292+ assert_eq ! ( 8 , dial. points_to_zero( ) ) ;
293+
294+ // 1 65, 265
295+ // 2 65, 165
296+ // 3 65, 65
297+ // 4 0
298+ dial = dial. rotate ( Rotation :: left ( 365 ) ) ; // 0
299+ assert_eq ! ( 12 , dial. points_to_zero( ) ) ;
315300
316- let dial = initial_dial. rotate ( Rotation :: right ( 1000 ) ) ; // 50
317- assert_eq ! ( 0 , dial. zero_stops) ;
318- assert_eq ! ( 10 , dial. zero_clicks) ;
301+ // 1 0, 400
302+ // 2 0, 300
303+ // 3 0, 200
304+ // 4 0, 100
305+ // 5 0
306+ dial = dial. rotate ( Rotation :: left ( 500 ) ) ; // 0
307+ assert_eq ! ( 17 , dial. points_to_zero( ) ) ;
319308
320- let dial = initial_dial. rotate ( Rotation :: right ( 1050 ) ) ; // 0
321- assert_eq ! ( 1 , dial. zero_stops) ;
322- assert_eq ! ( 10 , dial. zero_clicks) ;
309+ dial = dial. rotate ( Rotation :: left ( 27 ) ) ; // 73
310+ assert_eq ! ( 17 , dial. points_to_zero( ) ) ;
323311 }
312+
313+ // #[test]
314+ // fn my_input_tests() {
315+ // let mut dial = SafeDial::with(90);
316+ // dial = dial.rotate(Rotation::left(636));
317+ // // 1 -100:90, 536
318+ // // 2 -100:90, 436
319+ // // 3 -100:90, 336
320+ // // 4 -100:90, 236
321+ // // 5 -100:90, 136
322+ // // 6 -100:90, 36
323+ // // 6 -36:54
324+ //
325+ // assert_eq!(6, dial.points_to_zero());
326+ //
327+ // dial = dial.rotate(Rotation::left(654));
328+ // assert_eq!(12, dial.points_to_zero());
329+ // }
330+ //
331+ // #[test]
332+ // fn zero_clicks_test() {
333+ // let mut dial = SafeDial::new();
334+ //
335+ // dial = dial.rotate(Rotation::right(50)); // 0
336+ // assert_eq!(1, dial.points_to_zero());
337+ //
338+ // dial = dial.rotate(Rotation::right(200)); // 0
339+ // assert_eq!(3, dial.points_to_zero());
340+ //
341+ // dial = dial.rotate(Rotation::right(1)); // 1
342+ // assert_eq!(3, dial.points_to_zero());
343+ //
344+ // dial = dial.rotate(Rotation::right(299)); // 0
345+ // assert_eq!(6, dial.points_to_zero());
346+ //
347+ // dial = dial.rotate(Rotation::left(300)); // 0
348+ // assert_eq!(9, dial.points_to_zero());
349+ //
350+ // dial = dial.rotate(Rotation::left(301)); // 99
351+ // assert_eq!(12, dial.points_to_zero());
352+ //
353+ // dial = dial.rotate(Rotation::right(2)); // 1
354+ // assert_eq!(13, dial.points_to_zero());
355+ //
356+ // dial = dial.rotate(Rotation::left(202)); // 99
357+ // assert_eq!(16, dial.points_to_zero());
358+ //
359+ // dial = dial.rotate(Rotation::left(98)); // 1
360+ // assert_eq!(16, dial.points_to_zero());
361+ //
362+ // dial = dial.rotate(Rotation::right(199)); // 0
363+ // assert_eq!(18, dial.points_to_zero());
364+ //
365+ // dial = dial.rotate(Rotation::right(1)); // 1
366+ // assert_eq!(18, dial.points_to_zero());
367+ //
368+ // dial = dial.rotate(Rotation::left(102)); // 99
369+ // assert_eq!(20, dial.points_to_zero());
370+ // }
371+ //
372+ // #[test]
373+ // fn zero_clicks_1000_test() {
374+ // let initial_dial = SafeDial::new();
375+ //
376+ // let dial = initial_dial.rotate(Rotation::right(1000)); // 50
377+ // assert_eq!(10, dial.points_to_zero());
378+ //
379+ // let dial = initial_dial.rotate(Rotation::right(1050)); // 0
380+ // assert_eq!(11, dial.points_to_zero());
381+ //
382+ // let dial = initial_dial.rotate(Rotation::left(1000)); // 50
383+ // assert_eq!(10, dial.points_to_zero());
384+ //
385+ // // 1 -100:50 950
386+ // // 2 -100:50 850
387+ // // 3 -100:50 750
388+ // // 4 -100:50 650
389+ // // 5 -100:50 550
390+ // // 6 -100:50 450
391+ // // 7 -100:50 350
392+ // // 8 -100:50 250
393+ // // 9 -100:50 150
394+ // // 10 -100:50 50
395+ // // 11 -50:50 0
396+ // let dial = initial_dial.rotate(Rotation::left(1050)); // 0
397+ // assert_eq!(11, dial.points_to_zero());
398+ // }
324399}
0 commit comments