Условие генерации строки
Есть код, который генерирует последовательность символов. Но в нем должно быть условие, что буквы не могут идти больше 4-х раз подряд (т.е может быть строчка 'aaa', но не должно быть 'aaaa'). Сама программа реализована на Python, код прикладываю ниже. Реализация происходит при помощи модуля random.
import random
text = 'abcdef'
num = '1234567890'
qua = 10
sym = []
sym.extend(list(text))
sym.extend(list(num))
random.shuffle(sym)
key = []
for yx in range(qua):
key.append(''.join([random.choice(sym) for x in range(32)]))
file = open('Password.txt', 'w')
file.write('\n'.join(key))
file.close()
print('\n'.join(key))
print('\n')
Что следует добавить в код, чтобы вывод был с условием?
Ответы (2 шт):
Очевидно, что добавить счетчик количества одинаковых элементов. Обратите внимание, что первый элемент мы добавляем в список до цикла, чтобы нам было с чем сравнивать последующие
import random
text = 'ab'
num = '12'
qua = 10
sym = []
sym.extend(list(text))
sym.extend(list(num))
random.shuffle(sym)
key = []
counter = 1 # Добавляем счетчик
key.append(''.join([random.choice(sym) for x in range(32)]))
for yx in range(qua):
sumbol = [random.choice(sym) for x in range(32)] # Генерируем символ
if sumbol == key[-1] and counter <3: # Если символ повторяется, и счетчик меньше трех, то добавляем увеличивая счетчик
counter += 1
key.append(''.join(sumbol))
elif sumbol != key[-1]: # Если символ другой, то обнуляем счетчик
counter = 1
key.append(''.join(sumbol))
else: # Иначе генерируем символы до тех пор, пока, не сгенерируется символ отличающийся от последних трех
while sumbol == key[-1]:
sumbol = [random.choice(sym) for x in range(32)]
key.append(''.join(sumbol))
counter = 1
print('\n'.join(key))
print('\n')
в принципе можно не делать проверки при каждой генерации символа, а проверять целиком строку на наличие нежелательной последовательности (хотя не знаю что будет работать быстрее). если использовать модуль itertools, то ваш код может выглядеть примерно так:
from random import choices
from itertools import groupby
k = []
for i in range(10):
while True:
p = ''.join(choices('abcd1234567890', k=32))
if max(len(list(g)) for _,g in groupby(p))<4:
k.append(p)
break
>>> k
'''
['6c3097a070db48a03524d471d19ab946',
'7653c7d043805bd945824c3c33729c1c',
'683cda6b1527511b033b5239d756d4dd',
'4b9503428d597d4a41c4da63bd7cc114',
'83258d224d43d5623b0bbcad15b80621',
'3441029358676405055cdb602abddd23',
'28336b1d19dd5c3c579b7206da505b4b',
'04ab80660654971a9886a69c8aa30a5c',
'a638b626568cb5d709a26695916c5b99',
'6bca4796218b49392a889668b8c5302c']
UPD
проверил скорость, этот вариант работает немного быстрее чем если проверять каждый символ отдельно: 341 µs ± 2.71 µs против 447 µs ± 3.06 µs
вариант с регуляркой работает еще быстрее (188 µs ± 2.23 µs):
from random import choices
from re import search
k = []
for i in range(10):
while True:
p = ''.join(choices('abcd1234567890', k=32))
if not search(r'(\w)\1\1\1', p):
k.append(p)
break