9f3296b027f55b4f23b12045009f29b706d5cafc
3 use nalgebra
::{DMatrix
, Point2
, Vector2
};
6 type Position
= Point2
<i64>;
7 type Velocity
= Vector2
<i64>;
9 pub fn read(reader
: &mut dyn BufRead
) -> Vec
<(Position
, Velocity
)> {
10 let regex_line
= Regex
::new(r
#"([+-]?\d+),([+-]?\d+).*?([+-]?\d+),([+-]?\d+)"#).unwrap();
16 let captures
= regex_line
.captures(&l
).unwrap();
19 captures
[1].parse
::<i64>().unwrap(),
20 captures
[2].parse
::<i64>().unwrap(),
23 captures
[3].parse
::<i64>().unwrap(),
24 captures
[4].parse
::<i64>().unwrap(),
31 fn robot_positions
<'a
>(
32 robots
: &'a
[(Position
, Velocity
)],
33 area_size
: (i64, i64),
35 ) -> impl Iterator
<Item
= (i64, i64)> + use<'a
> {
36 robots
.into_iter().map(move |(pos
, vel
)| {
37 let pos
= pos
+ vel
* seconds
;
39 pos
[0].rem_euclid(area_size
.0),
40 pos
[1].rem_euclid(area_size
.1),
45 pub fn safety_factor(robots
: &[(Position
, Velocity
)], area_size
: (i64, i64), seconds
: i64) -> u32 {
46 let quadrants
= robot_positions(robots
, area_size
, seconds
).fold(
48 |(q1
, q2
, q3
, q4
), (x
, y
)| {
49 if x
> area_size
.0 / 2 {
50 if y
< area_size
.1 / 2 {
51 return (q1
+ 1, q2
, q3
, q4
);
52 } else if y
> area_size
.1 / 2 {
53 return (q1
, q2
, q3
, q4
+ 1);
55 } else if x
< area_size
.0 / 2 {
56 if y
< area_size
.1 / 2 {
57 return (q1
, q2
+ 1, q3
, q4
);
58 } else if y
> area_size
.1 / 2 {
59 return (q1
, q2
, q3
+ 1, q4
);
65 quadrants
.0 * quadrants
.1 * quadrants
.2 * quadrants
.3
69 robots
: &[(Position
, Velocity
)],
70 area_size
: (i64, i64),
73 let mut area
= DMatrix
::<u32>::repeat(area_size
.1 as usize, area_size
.0 as usize, 0);
74 for (x
, y
) in robot_positions(robots
, area_size
, seconds
) {
75 area
[(y
as usize, x
as usize)] += 1;
77 let mut str = String
::new();
78 for i
in 0..area
.nrows() {
79 for j
in 0..area
.ncols() {
96 static POSITIONS_AND_VELOCITIES
: &str = "p=0,4 v=3,-3
111 let robots
= read(&mut POSITIONS_AND_VELOCITIES
.as_bytes());
112 assert_eq!(safety_factor(&robots
, (11, 7), 100), 12);