@@ -4,7 +4,6 @@ use crate::utils::point::Point;
44use crate :: utils:: surface_range:: SurfaceRange ;
55use itertools:: Itertools ;
66use std:: collections:: HashSet ;
7- use std:: ops:: Neg ;
87
98pub struct Day14 {
109 surface : SurfaceRange ,
@@ -13,10 +12,7 @@ pub struct Day14 {
1312impl Solution for Day14 {
1413 fn part_one ( & self , input : & str ) -> String {
1514 let mut robots = self . parse ( input) ;
16-
17- for _ in 0 ..100 {
18- robots = self . move_all ( robots) ;
19- }
15+ robots = self . move_all ( robots, 100 ) ;
2016
2117 let start_x = self . surface . x ( ) . start ( ) ;
2218 let end_x = self . surface . x ( ) . end ( ) ;
@@ -48,7 +44,7 @@ impl Solution for Day14 {
4844 let mut second = 0 ;
4945 loop {
5046 second += 1 ;
51- robots = self . move_all ( robots) ;
47+ robots = self . move_all ( robots, 1 ) ;
5248
5349 let points = robots. iter ( ) . map ( |robot| robot. position ( ) ) . collect_vec ( ) ;
5450 let points: HashSet < Point > = HashSet :: from_iter ( points) ;
@@ -79,36 +75,18 @@ impl Day14 {
7975 . collect ( )
8076 }
8177
82- fn move_robot ( & self , moving_point : MovingPoint ) -> MovingPoint {
83- let mut next = moving_point. move_ ( ) ;
84-
85- let y = self . surface . y ( ) ;
86- if y. is_before ( next. position ( ) . y ) {
87- let teleport = y. end ( ) - next. position ( ) . y . neg ( ) + 1 ;
88-
89- next = next. with_position_y ( teleport) ;
90- } else if y. is_after ( next. position ( ) . y ) {
91- let teleport = y. start ( ) + next. position ( ) . y - y. end ( ) - 1 ;
78+ fn move_all ( & self , robots : Vec < MovingPoint > , times : isize ) -> Vec < MovingPoint > {
79+ robots
80+ . into_iter ( )
81+ . map ( |r| {
82+ let new = r. position ( ) + ( r. velocity ( ) * times) ;
9283
93- next = next. with_position_y ( teleport) ;
94- }
95-
96- let x = self . surface . x ( ) ;
97- if x. is_before ( next. position ( ) . x ) {
98- let teleport = x. end ( ) - next. position ( ) . x . neg ( ) + 1 ;
84+ let x = new. x . rem_euclid ( self . surface . x ( ) . len ( ) ) ;
85+ let y = new. y . rem_euclid ( self . surface . y ( ) . len ( ) ) ;
9986
100- next = next. with_position_x ( teleport) ;
101- } else if x. is_after ( next. position ( ) . x ) {
102- let teleport = x. start ( ) + next. position ( ) . x - x. end ( ) - 1 ;
103-
104- next = next. with_position_x ( teleport) ;
105- }
106-
107- next
108- }
109-
110- fn move_all ( & self , robots : Vec < MovingPoint > ) -> Vec < MovingPoint > {
111- robots. into_iter ( ) . map ( |r| self . move_robot ( r) ) . collect ( )
87+ r. with_position ( Point :: new ( x, y) )
88+ } )
89+ . collect ( )
11290 }
11391}
11492
@@ -148,22 +126,25 @@ p=9,5 v=-3,-3"#;
148126
149127 #[ test]
150128 fn move_robot_example ( ) {
151- let solution = solution ( ) ;
152129 let robot = MovingPoint :: from ( ( Point :: new ( 2 , 4 ) , Point :: new ( 2 , -3 ) ) ) ;
153130
154- let robot = solution . move_robot ( robot) ;
131+ let robot = move_robot ( robot) ;
155132 assert_eq ! ( Point :: new( 4 , 1 ) , robot. position( ) ) ;
156133
157- let robot = solution . move_robot ( robot) ;
134+ let robot = move_robot ( robot) ;
158135 assert_eq ! ( Point :: new( 6 , 5 ) , robot. position( ) ) ;
159136
160- let robot = solution . move_robot ( robot) ;
137+ let robot = move_robot ( robot) ;
161138 assert_eq ! ( Point :: new( 8 , 2 ) , robot. position( ) ) ;
162139
163- let robot = solution . move_robot ( robot) ;
140+ let robot = move_robot ( robot) ;
164141 assert_eq ! ( Point :: new( 10 , 6 ) , robot. position( ) ) ;
165142 }
166143
144+ fn move_robot ( robot : MovingPoint ) -> MovingPoint {
145+ solution ( ) . move_all ( vec ! [ robot] , 1 ) . pop ( ) . unwrap ( )
146+ }
147+
167148 fn solution ( ) -> Day14 {
168149 Day14 {
169150 surface : SurfaceRange :: from_points ( 0 , 11 - 1 , 0 , 7 - 1 ) ,
0 commit comments