Skip to content

Instantly share code, notes, and snippets.

@william-silversmith
Last active January 31, 2018 04:53
Show Gist options
  • Save william-silversmith/a5d0cfd594112ea75038e128ea881c60 to your computer and use it in GitHub Desktop.
Save william-silversmith/a5d0cfd594112ea75038e128ea881c60 to your computer and use it in GitHub Desktop.
COUNTLESS8 + Avoiding trouble with 0
from itertools import combinations
from functools import reduce
import numpy as np
def countless3d(data):
"""Now write countless8 in such a way that it could be used
to process an image."""
sections = []
# shift zeros up one so they don't interfere with bitwise operators
# we'll shift down at the end
data = data + 1 # don't use += as it'll modify the original image
# This loop splits the 2D array apart into four arrays that are
# all the result of striding by 2 and offset by (0,0,0), (0,0,1), (0,1,0), etc
factor = (2,2,2)
for offset in np.ndindex(factor):
part = data[tuple(np.s_[o::f] for o, f in zip(offset, factor))]
sections.append(part)
p2 = lambda q,r: q * (q == r) # PICK(A,B)
p3 = lambda q,r,s: q * ( (q == r) & (r == s) ) # PICK(A,B,C)
p4 = lambda p,q,r,s: p * ( (p == q) & (q == r) & (r == s) ) # PICK(A,B,C,D)
lor = lambda x,y: x + (x == 0) * y # logical or
# important to use generator expressions here to reduce peak memory usage
results4 = ( p4(x,y,z,w) for x,y,z,w in combinations(sections, 4) )
results4 = reduce(lor, results4)
results3 = ( p3(x,y,z) for x,y,z in combinations(sections, 3) )
results3 = reduce(lor, results3)
# We can always omit the last section because we'll "|| section[-1]" at the end
results2 = ( p2(x,y) for x,y in combinations(sections[:-1], 2) )
results2 = reduce(lor, results2)
return reduce(lor, (results4, results3, results2, sections[-1])) - 1 # combine and shift down
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment