17_conway_cubes.rb
# Take advantage of symmetry in the non-XY dimensions:
# All dimensions are interchangeable so can be reordered,
# and the starting state has no components in non-XY, so coordinates can be negated.
Take advantage of symmetry in the non-XY dimensions:
All dimensions are interchangeable so can be reordered,
and the starting state has no components in non-XY, so coordinates can be negated.
Take advantage of symmetry in the non - XY dimensions : All dimensions are interchangeable so can be reordered and the starting state has no components in non - XY so coordinates can be negated .
def step(now_active, rounds, weights, ybits, wzbits)
  neigh_and_self = Hash.new(0)
  wzshift = wzbits * (rounds + 1)
  wzmask = (1 << wzshift) - 1
  pos_per_dy = 1 << wzshift
  pos_per_dx = pos_per_dy << ybits
  dxys = [0, -1, 1].repeated_permutation(2).map { |dx, dy|
    dx * pos_per_dx + dy * pos_per_dy
  }.freeze
  now_active.each { |pos|
    weights[pos & wzmask].each { |nwz, weight|
      npos = pos & ~wzmask | nwz
      dxys.each { |dxy|
        neigh_and_self[npos + dxy] += weight << 1
      }
    }
    dxys[1..].each { |dxy|
      neigh_and_self[pos + dxy] += 1 << 1
    }
    neigh_and_self[pos] += 1
  }
  neigh_and_self.filter_map { |pos, count|
    pos if 5 <= count && count <= 7
  }
end
def step ( now_active , rounds , weights , ybits , wzbits ) neigh_and_self = Hash . new ( 0 ) wzshift = wzbits * ( rounds + 1 ) wzmask = ( 1 << wzshift ) - 1 pos_per_dy = 1 << wzshift pos_per_dx = pos_per_dy << ybits dxys = [ 0 , - 1 , 1 ] . repeated_permutation ( 2 ) . map { | dx , dy | dx * pos_per_dx + dy * pos_per_dy } . freeze now_active . each { | pos | weights [ pos & wzmask ] . each { | nwz , weight | npos = pos & ~ wzmask | nwz dxys . each { | dxy | neigh_and_self [ npos + dxy ] += weight << 1 } } dxys [ 1 .. ] . each { | dxy | neigh_and_self [ pos + dxy ] += 1 << 1 } neigh_and_self [ pos ] += 1 } neigh_and_self . filter_map { | pos , count | pos if 5 <= count && count <= 7 } end
Take advantage of symmetry in the non-XY dimensions:
All dimensions are interchangeable so can be reordered,
and the starting state has no components in non-XY, so coordinates can be negated.
Take advantage of symmetry in the non - XY dimensions : All dimensions are interchangeable so can be reordered and the starting state has no components in non - XY so coordinates can be negated .
# (neighbour count << 1) | self # for e.g. [x, y, z, w] -> [x + 1, y, z, w] # NOTE that if a cell is a representative of one of its own neighbours, # e.g, [x, y, 0, 1] -> [x, y, 1, 0] (which is represented by [x, y, 0, 1]), # the above weights will already have included that fact. # This is only for the single extra neighbour for nonequal [x, y]. # alive if: # 101 (2 neigh + self) 5 # 110 (3 neigh)        6 # 111 (3 neigh + self) 7
now_active
<not_specific>
rounds
<not_specific>
weights
<not_specific>
ybits
<not_specific>
wzbits
<not_specific>