Skip to content

Instantly share code, notes, and snippets.

@lotabout
Created October 5, 2017 03:19
Show Gist options
  • Save lotabout/891621ae8a01d8e512afd4b5254516b4 to your computer and use it in GitHub Desktop.
Save lotabout/891621ae8a01d8e512afd4b5254516b4 to your computer and use it in GitHub Desktop.
Solution for google foobar: Expanding Nebula
def generate(c1,c2,bitlen):
a = c1 & ~(1<<bitlen)
b = c2 & ~(1<<bitlen)
c = c1 >> 1
d = c2 >> 1
return (a&~b&~c&~d) | (~a&b&~c&~d) | (~a&~b&c&~d) | (~a&~b&~c&d)
from collections import defaultdict
def build_map(n, nums):
mapping = defaultdict(set)
nums = set(nums)
for i in range(1<<(n+1)):
for j in range(1<<(n+1)):
generation = generate(i,j,n)
if generation in nums:
mapping[(generation, i)].add(j)
return mapping
def answer(g):
g = list(zip(*g)) # transpose
nrows = len(g)
ncols = len(g[0])
# turn map into numbers
nums = [sum([1<<i if col else 0 for i, col in enumerate(row)]) for row in g]
mapping = build_map(ncols, nums)
preimage = {i: 1 for i in range(1<<(ncols+1))}
for row in nums:
next_row = defaultdict(int)
for c1 in preimage:
for c2 in mapping[(row, c1)]:
next_row[c2] += preimage[c1]
preimage = next_row
ret = sum(preimage.values())
return ret
Copy link

ghost commented Dec 13, 2020

Can you please explain the logic behind build_map function?

build_map returns a mapping from (row, first row of preimage) to (set of second rows of preimage)

@4Points
Copy link

4Points commented Oct 14, 2021

Brilliant Solution! What does the zero fill left shift on lines on line 12 do? Is the generate function a bitmask? Thanks for the very efficient solution. A for me to learn!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment