0

I have a function createPattern, that, given an array, it returns a list of size 8 containing 7 symbols, say (1,2,3,4,5,6,7). Each symbol can either not appear at all in the list, or appear one or more times.

What i want to do is to create random arrays and, whenever a new pattern is found, append it to circ_pattern_Collection. The difficulty im having is with the following:

I want the code to recognize the pattern independent of the starting "symbol", i.e. recognize only the new circular patterns, for example:

(1,2,3,4,5,6,7,7) = (7,1,2,3,4,5,6,7) = (3,4,5,6,7,7,1,2)… and so on.

(1,1,1,2,3,3,3,3) = (1,1,2,3,3,3,3,1) = (3,3,3,3,1,1,1,2).. and so on.

Something like this :

circ_pattern_Collection=[]
for j in range(10000):
    array = np.random.randint(-1000, 1000, (3, 3))
    patternList = createPattern(array)
    …
    "if new circular pattern found, append to circ_pattern_Collection"
    …
return circ_pattern_Collection

I could ofc do it by lots of if statements but there must be a more elegant/efficient way of doing this? Any tips?

Adam.Er8
  • 12,675
  • 3
  • 26
  • 38
JustANoob
  • 580
  • 1
  • 4
  • 19
  • I assume that it is not always sorted correct? You can use a `dequeue` and just keep rotating it to make sure it doesn't match an existing string but that is not efficient. If there were at least one unique element you could search for that and it would be a lot easier. – Error - Syntactical Remorse Jul 09 '19 at 13:52
  • Consider the matching algorithm proposed [in this answer on the Software Engineering StackExchange](https://softwareengineering.stackexchange.com/a/285560/291751). – Patrick Haugh Jul 09 '19 at 13:53
  • Not sorted, any combination could appear. Not all though, thats why im interested in this algorithm. – JustANoob Jul 09 '19 at 15:05

1 Answers1

4

you can use np.roll to roll the array on all possible patterns,

try this:

import numpy as np


def is_same_circ(a1, a2):
    if len(a1) != len(a2):
        return False
    return any(np.array_equal(a1,np.roll(a2, offset)) for offset in range(len(a1)))


a1 = np.array((1, 2, 3, 4, 5, 6, 7, 7))
print(is_same_circ(a1, np.array((7, 1, 2, 3, 4, 5, 6, 7))))
print(is_same_circ(a1, np.array((7, 7, 7, 3, 4, 5, 6, 7))))

Output:

True
False
Adam.Er8
  • 12,675
  • 3
  • 26
  • 38
  • 1
    notice: if the arrays are long, this means a lot of rolling and comparisons, maybe there are other ways to it faster... – Adam.Er8 Jul 09 '19 at 13:56
  • `deque` rotate would be [faster](https://stackoverflow.com/a/44901770/8150685) for rotations but I don't know the trade off for equality comparisons. May be worth looking into which is faster. – Error - Syntactical Remorse Jul 09 '19 at 13:59