1
1
use std:: fs;
2
2
3
3
#[ allow( unused) ]
4
- fn print_grid ( grid : & [ usize ] , w : usize , h : usize ) {
4
+ fn print_grid ( grid : & [ u16 ] , w : usize , h : usize ) {
5
5
for y in 0 ..h {
6
6
for x in 0 ..w {
7
- if grid[ y * w + x] == 0 {
8
- print ! ( "." ) ;
9
- } else {
10
- print ! ( "#" ) ;
7
+ for i in ( 0 ..16 ) . rev ( ) {
8
+ if grid[ y * w + x] & 1 << i > 0 {
9
+ print ! ( "#" ) ;
10
+ } else {
11
+ print ! ( "." ) ;
12
+ }
11
13
}
12
14
}
13
15
println ! ( ) ;
@@ -31,8 +33,10 @@ fn main() {
31
33
let w = 101 ;
32
34
let h = 103 ;
33
35
let mut grid = vec ! [ 0 ; w * h] ;
34
- let mut robots = Vec :: new ( ) ;
36
+ let bw = ( w + 15 ) / 16 ;
37
+ let mut binary_grid = vec ! [ 0u16 ; bw * h] ;
35
38
39
+ let mut robots = Vec :: new ( ) ;
36
40
for l in lines {
37
41
let ( p, v) = l. split_once ( ' ' ) . unwrap ( ) ;
38
42
let ( px, py) = p[ 2 ..]
@@ -45,32 +49,23 @@ fn main() {
45
49
. unwrap ( ) ;
46
50
robots. push ( ( px, py, vx, vy) ) ;
47
51
grid[ py as usize * w + px as usize ] += 1 ;
52
+ binary_grid[ py as usize * bw + px as usize / 16 ] |= 1 << ( 15 - px % 16 ) ;
48
53
}
49
54
50
- let mut total1 = 0 ;
51
- let mut total2 = 0 ;
55
+ let mut total1 = None ;
56
+ let mut total2 = None ;
52
57
let mut steps = 0 ;
53
58
' outer: loop {
54
59
for ( px, py, vx, vy) in & mut robots {
55
- grid[ * py as usize * w + * px as usize ] -= 1 ;
56
-
57
- * px += * vx;
58
- if * px >= w as i32 {
59
- * px -= w as i32 ;
60
- }
61
- if * px < 0 {
62
- * px += w as i32 ;
60
+ let ni = * py as usize * w + * px as usize ;
61
+ grid[ ni] -= 1 ;
62
+ if grid[ ni] == 0 {
63
+ binary_grid[ * py as usize * bw + * px as usize / 16 ] &= !( 1 << ( 15 - * px % 16 ) ) ;
63
64
}
64
-
65
- * py += * vy;
66
- if * py >= h as i32 {
67
- * py -= h as i32 ;
68
- }
69
- if * py < 0 {
70
- * py += h as i32 ;
71
- }
72
-
65
+ * px = ( * px + * vx) . rem_euclid ( w as i32 ) ;
66
+ * py = ( * py + * vy) . rem_euclid ( h as i32 ) ;
73
67
grid[ * py as usize * w + * px as usize ] += 1 ;
68
+ binary_grid[ * py as usize * bw + * px as usize / 16 ] |= 1 << ( 15 - * px % 16 ) ;
74
69
}
75
70
76
71
steps += 1 ;
@@ -80,36 +75,31 @@ fn main() {
80
75
let t2 = count ( & grid, w, 0 , w / 2 , ( h + 1 ) / 2 , h) ;
81
76
let t3 = count ( & grid, w, ( w + 1 ) / 2 , w, 0 , h / 2 ) ;
82
77
let t4 = count ( & grid, w, ( w + 1 ) / 2 , w, ( h + 1 ) / 2 , h) ;
83
- total1 = t1 * t2 * t3 * t4;
84
- if total2 > 0 {
78
+ total1 = Some ( t1 * t2 * t3 * t4) ;
79
+ if total2. is_some ( ) {
85
80
break ;
86
81
}
87
82
}
88
83
89
84
// look for at least 16 robots in a row. this should be our christmas tree.
90
- let min_run = 16 ;
91
85
for y in 0 ..h {
92
- for x in 0 ..w - min_run {
93
- let mut found = true ;
94
- for i in 0 ..min_run {
95
- if grid[ y * w + x + i] == 0 {
96
- found = false ;
97
- break ;
98
- }
99
- }
100
- if found {
86
+ for x in 0 ..bw - 1 {
87
+ if binary_grid[ y * bw + x] . trailing_ones ( )
88
+ + binary_grid[ y * bw + x + 1 ] . leading_ones ( )
89
+ >= 16
90
+ {
101
91
// use print_grid to check if it's really a christmas tree
102
- // print_grid(&grid, w , h);
92
+ // print_grid(&binary_grid, bw , h);
103
93
104
- total2 = steps;
105
- if total1 > 0 {
94
+ total2 = Some ( steps) ;
95
+ if total1. is_some ( ) {
106
96
break ' outer;
107
97
}
108
98
}
109
99
}
110
100
}
111
101
}
112
102
113
- println ! ( "{}" , total1) ;
114
- println ! ( "{}" , total2) ;
103
+ println ! ( "{}" , total1. unwrap ( ) ) ;
104
+ println ! ( "{}" , total2. unwrap ( ) ) ;
115
105
}
0 commit comments