Skip to main content
added 569 characters in body
Source Link
RootTwo
  • 10.7k
  • 1
  • 14
  • 30

itertools.product()

This is a task made for itertools.product(). As the docs say, product(A, B, C) is equivalent to ((a,b,c) for a in A for b in B for c in C). The c cycles the fastest, then 'b' and a is the slowest. Like an odometer.

The trick is how to set up the iterables A, B, CAs @AustinHastings pointed out, etc. to get the pattern you wantitertools. In the codeproduct solution below, pattern is the set of wheels in the odometer. If a doesn't work right unless you start value is provided, the wheels are rotated so the first position in the wheel matchesat the startbeginning. So here's an alternate solution:

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
    
    if start:
        forindices pos,= [pattern[i].index(char, seqc) for i,c in enumerate(zip(start,)]
    else:
        indices = [0]*len(pattern)):
     
    while True:
    print    yield ''.join(f"{pos},pat[i] {char},for {seq}"pat,i end="in ->zip(pattern, "indices))
         
    index = seq.index  for i in range(charlen(indices)
 -1, -1, -1):
          pattern[pos] = seq[index:]indices[i] ++= seq[:index]1
            printif indices[i] < len(f"{char}pattern[i]): 
 {pattern[pos]}")               break
            
    yield from (''.join(seq) for seq in it.product(*pattern))  indices[i] = 0
MBIs = list(it.islice(mbi_gen('3C12D34EF56'), 10000)

itertools.product()

This is a task made for itertools.product(). As the docs say, product(A, B, C) is equivalent to ((a,b,c) for a in A for b in B for c in C). The c cycles the fastest, then 'b' and a is the slowest. Like an odometer.

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
                
    yield from (''.join(seq) for seq in it.product(*pattern))

itertools.product()

This is a task made for itertools.product(). As the docs say, product(A, B, C) is equivalent to ((a,b,c) for a in A for b in B for c in C). The c cycles the fastest, then 'b' and a is the slowest. Like an odometer.

The trick is how to set up the iterables A, B, C, etc. to get the pattern you want. In the code below, pattern is the set of wheels in the odometer. If a start value is provided, the wheels are rotated so the first position in the wheel matches the start.

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
    
    if start:
        for pos, (char, seq) in enumerate(zip(start, pattern)):
            print(f"{pos}, {char}, {seq}", end=" -> ")
            index = seq.index(char)
             pattern[pos] = seq[index:] + seq[:index]
            print(f"{char}: {pattern[pos]}")
        
    yield from (''.join(seq) for seq in it.product(*pattern))
MBIs = list(it.islice(mbi_gen('3C12D34EF56'), 10000)

As @AustinHastings pointed out, the itertools.product solution below doesn't work right unless you start at the beginning. So here's an alternate solution:

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
    if start:
        indices = [pattern[i].index(c) for i,c in enumerate(start)]
    else:
        indices = [0]*len(pattern)
     
    while True:
        yield ''.join(pat[i] for pat,i in zip(pattern, indices))
         
        for i in range(len(indices)-1, -1, -1):
            indices[i] += 1
            if indices[i] < len(pattern[i]): 
                break
            
            indices[i] = 0
MBIs = list(it.islice(mbi_gen('3C12D34EF56'), 10000)

itertools.product()

This is a task made for itertools.product(). As the docs say, product(A, B, C) is equivalent to ((a,b,c) for a in A for b in B for c in C). The c cycles the fastest, then 'b' and a is the slowest. Like an odometer.

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
                
    yield from (''.join(seq) for seq in it.product(*pattern))
Added an explanation.
Source Link
RootTwo
  • 10.7k
  • 1
  • 14
  • 30

itertools.product()

This is a task made for itertools.product(). As the docs say, product(A, B, C) is equivalent to ((a,b,c) for a in A for b in B for c in C). The c cycles the fastest, then 'b' and a is the slowest. Like an odometer.

The trick is how to set up the iterables A, B, C, etc. to get the pattern you want. In the code below, pattern is the set of wheels in the odometer. If a start value is provided, the wheels are rotated so the first position in the wheel matches the start.

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
    
    if start:
        for pos, (char, seq) in enumerate(zip(start, pattern)):
            print(f"{pos}, {char}, {seq}", end=" -> ")
            index = seq.index(char)
            pattern[pos] = seq[index:] + seq[:index]
            print(f"{char}: {pattern[pos]}")
        
    yield from (''.join(seq) for seq in it.product(*pattern))

mbi_gen() is a generator and can be used like so:

MBI = mbi_gen()

for n in range(10000):
    print(next(MBI))

or to generate a list of 10000 MBIs:

MBIs = list(it.islice(mbi_gen('3C12D34EF56'), 10000)

itertools.product()

This is a task made for itertools.product()

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
    
    if start:
        for pos, (char, seq) in enumerate(zip(start, pattern)):
            print(f"{pos}, {char}, {seq}", end=" -> ")
            index = seq.index(char)
            pattern[pos] = seq[index:] + seq[:index]
            print(f"{char}: {pattern[pos]}")
        
    yield from (''.join(seq) for seq in it.product(*pattern))

mbi_gen() is a generator and can be used like so:

MBI = mbi_gen()

for n in range(10000):
    print(next(MBI))

or to generate a list of 10000 MBIs:

MBIs = list(it.islice(mbi_gen('3C12D34EF56'), 10000)

itertools.product()

This is a task made for itertools.product(). As the docs say, product(A, B, C) is equivalent to ((a,b,c) for a in A for b in B for c in C). The c cycles the fastest, then 'b' and a is the slowest. Like an odometer.

The trick is how to set up the iterables A, B, C, etc. to get the pattern you want. In the code below, pattern is the set of wheels in the odometer. If a start value is provided, the wheels are rotated so the first position in the wheel matches the start.

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
    
    if start:
        for pos, (char, seq) in enumerate(zip(start, pattern)):
            print(f"{pos}, {char}, {seq}", end=" -> ")
            index = seq.index(char)
            pattern[pos] = seq[index:] + seq[:index]
            print(f"{char}: {pattern[pos]}")
        
    yield from (''.join(seq) for seq in it.product(*pattern))

mbi_gen() is a generator and can be used like so:

MBI = mbi_gen()

for n in range(10000):
    print(next(MBI))

or to generate a list of 10000 MBIs:

MBIs = list(it.islice(mbi_gen('3C12D34EF56'), 10000)
Source Link
RootTwo
  • 10.7k
  • 1
  • 14
  • 30

itertools.product()

This is a task made for itertools.product()

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
    
    if start:
        for pos, (char, seq) in enumerate(zip(start, pattern)):
            print(f"{pos}, {char}, {seq}", end=" -> ")
            index = seq.index(char)
            pattern[pos] = seq[index:] + seq[:index]
            print(f"{char}: {pattern[pos]}")
        
    yield from (''.join(seq) for seq in it.product(*pattern))

mbi_gen() is a generator and can be used like so:

MBI = mbi_gen()

for n in range(10000):
    print(next(MBI))

or to generate a list of 10000 MBIs:

MBIs = list(it.islice(mbi_gen('3C12D34EF56'), 10000)