Created
November 14, 2014 21:10
-
-
Save Veedrac/f6556c24563db2f5b9ff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy | |
from collections import defaultdict | |
from numpy import newaxis | |
def rotate_packed(packed): | |
""" | |
Return a rotated version of a 55-length | |
array packed into 55 bits. Eg. | |
rotate(0b1101) == 0b01101 | |
rotate(2**54) == 0b1 | |
""" | |
mask = 2**55 - 1 | |
upper = (packed << 1) & mask | |
lower = packed >> 54 | |
return upper | lower | |
# Test data | |
bits = numpy.random.randint(0, 2, (55, 26235)) | |
bits[:, 10] = bits[:, 20] = bits[:, 30] = bits[:, 40] = bits[:, 50] | |
# Pack each into a 64-bit number by multiplying each bit | |
# by its value (2**pos) and summing along the arrays | |
bit_values = 2 ** numpy.arange(55) | |
packed = (bits * bit_values[:, newaxis]).sum(axis=0) | |
# Generate the rotation of each packed list with the | |
# minimum packed value. So 0b0001101 → 0b1101. | |
minimum_rotation = packed | |
for i in range(54): | |
packed = rotate_packed(packed) | |
minimum_rotation = numpy.minimum(minimum_rotation, packed) | |
# Generate a dictionary | |
# {packed value → all indexes with those value} | |
groups = defaultdict(set) | |
for i, value in enumerate(minimum_rotation): | |
groups[value].add(i) | |
# Find the group with the most members | |
max(groups.values(), key=len) | |
#>>> {40, 10, 50, 20, 30} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Could you give as a step by step (in the comments) on what happens to your array as it goes through?