@@ -37,25 +37,23 @@ pub fn parse(input: &str) -> FastSet<Hex> {
3737 b'e' => q += 1 ,
3838 b'w' => q -= 1 ,
3939 b'n' => {
40- if b'e' == iter. next ( ) . unwrap ( ) {
40+ r -= 1 ;
41+ if iter. next ( ) . unwrap ( ) == b'e' {
4142 q += 1 ;
4243 }
43- r -= 1 ;
4444 }
4545 b's' => {
46- if b'e' != iter. next ( ) . unwrap ( ) {
46+ r += 1 ;
47+ if iter. next ( ) . unwrap ( ) == b'w' {
4748 q -= 1 ;
4849 }
49- r += 1 ;
5050 }
5151 _ => unreachable ! ( ) ,
5252 }
5353 }
5454
5555 let tile = Hex { q, r } ;
56- if tiles. contains ( & tile) {
57- tiles. remove ( & tile) ;
58- } else {
56+ if !tiles. remove ( & tile) {
5957 tiles. insert ( tile) ;
6058 }
6159 }
@@ -80,7 +78,6 @@ pub fn part2(input: &FastSet<Hex>) -> usize {
8078#[ cfg( not( feature = "simd" ) ) ]
8179mod scalar {
8280 use super :: * ;
83- use std:: array:: from_fn;
8481
8582 pub ( super ) fn simulate ( input : & FastSet < Hex > ) -> usize {
8683 // Determine bounds
@@ -91,30 +88,32 @@ mod scalar {
9188
9289 // Create array with enough space to allow expansion for 100 generations.
9390 // 2 * (100 generations + 1 buffer) + Origin = 203 extra in each dimension
94- let width = q2 - q1 + 203 ;
95- let height = r2 - r1 + 203 ;
96- let neighbors: [ i32 ; 6 ] = [ -1 , 1 , -width, width, 1 - width, width - 1 ] ;
97- let neighbors: [ usize ; 6 ] = from_fn ( |i| neighbors[ i] as usize ) ;
91+ let width = ( q2 - q1 + 203 ) as usize ;
92+ let height = ( r2 - r1 + 203 ) as usize ;
9893
94+ let mut state = vec ! [ 0_u8 ; width * height] ;
9995 let mut active = Vec :: with_capacity ( 5_000 ) ;
10096 let mut candidates = Vec :: with_capacity ( 5_000 ) ;
10197 let mut next_active = Vec :: with_capacity ( 5_000 ) ;
10298
10399 // Create initial active state, offsetting tiles so that all indices are positive.
104100 for hex in input {
105- let index = width * ( hex. r - r1 + 101 ) + ( hex. q - q1 + 101 ) ;
106- active. push ( index as usize ) ;
101+ let index = width * ( hex. r - r1 + 101 ) as usize + ( hex. q - q1 + 101 ) as usize ;
102+ active. push ( index) ;
107103 }
108104
109105 for _ in 0 ..100 {
110- let mut state: Vec < u8 > = vec ! [ 0 ; ( width * height ) as usize ] ;
106+ state. fill ( 0 ) ;
111107
112108 for & tile in & active {
113- for & offset in & neighbors {
114- // Earlier we converted the offsets from signed `i32` to unsigned `usize`. To
115- // achieve subtraction for negative indices, we use a `wrapping_add` that performs
116- // [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement) arithmetic.
117- let index = tile. wrapping_add ( offset) ;
109+ for index in [
110+ tile + 1 ,
111+ tile - 1 ,
112+ tile + width,
113+ tile - width,
114+ tile + 1 - width,
115+ tile - 1 + width,
116+ ] {
118117 state[ index] += 1 ;
119118
120119 if state[ index] == 2 {
@@ -177,9 +176,9 @@ mod simd {
177176 current[ index] = 1 ;
178177 }
179178
180- let zero: Vector = Simd :: splat ( 0 ) ;
181- let one: Vector = Simd :: splat ( 1 ) ;
182- let two: Vector = Simd :: splat ( 2 ) ;
179+ let zero = Simd :: splat ( 0 ) ;
180+ let one = Simd :: splat ( 1 ) ;
181+ let two = Simd :: splat ( 2 ) ;
183182
184183 for round in 0 ..100 {
185184 // The active state boundary expands by 1 horizontally and vertically each round.
0 commit comments