Проверка условий вхождений символов в строку

Рейтинг: 0Ответов: 2Опубликовано: 09.02.2023

"""Алексей составляет таблицу кодовых слов для передачи сообщений, каждому сообщению соответствует своё кодовое слово. В качестве кодовых слов Алексей использует 4-буквенные слова, в которых есть только буквы A, B, C, D, X, причём буква X может появиться на первом месте или не появиться вовсе. Сколько различных кодовых слов может использовать Алексей?""" - условие задачи. Ответ - 320. По большинству вариантов реализуется через библиотеку intertools:

import itertools
alphabet = "ABCDX"
ar = itertools.product(alphabet, repeat=4) #Размещение с повторением
arl = []
for i in ar:
    arl.append(list(i))
count = 0
for e in arl:
    if (e[0] == 'X' or e[0] != 'X') and e[1] != 'X' and e[2] != 'X' and e[3] != 'X':
        count += 1
print(count) #->320

Хотел реализовать через циклы, ручную проверку каждого элемента строки (символа), но по-прежнему выдает те строки, которые не соответствуют условию подстрок:

letters = "ABCDX"
counter = 0
s = ""
for l1 in range(len(letters)):
    for l2 in range(len(letters)):
        for l3 in range(len(letters)):
            for l4 in range(len(letters)):
                s = s + letters[l1] + letters[l2] + letters[l3] + letters[l4]

                if s.count("Х") == 0 or (letters[0] == 'X' and letters[1] != 'X' and letters[2] != 'X'  and letters[3] != 'X'):
                    counter = counter + 1
                    print(counter, ":", s)
                s = ""

print(counter) #->625

Извиняюсь за корявый код (хотелось бы реализовать через код выше, если возможно), заранее спасибо.

Ответы

▲ 3Принят

Немного упростил код и поправил условие проверки (скобки).

letters = "ABCDX"
counter = 0
for l1 in letters:
    for l2 in letters:
        for l3 in letters:
            for l4 in letters:
                s = l1 + l2 + l3 + l4

                if (s.count("Х") == 0 or s[0] == 'X') and s[1] != 'X' and s[2] != 'X' and s[3] != 'X':
                    counter += 1
                    print(counter, ":", s)

print(counter)  # ->320

Дополнительно. Код с двумя циклами, можно менять количество букв и длину сочетаний.

letters = "ABCDX"
base, n_symbols = len(letters), 4
counter = 0
for x in range(base ** n_symbols):
    s, y = '', x
    for n in range(n_symbols):
        y, c = divmod(y, base)
        s += letters[c]
    if (s.count('Х') == 0 or s[0] == 'X') and s[1:4].count('X') == 0:
        counter += 1
        print(f'{counter}: {s}')

print(counter)  # ->320
▲ 4

Для решения этой задачи вовсе не нужно генерировать все строки. (А для больших длин это просто нереально)

Количество строк, начинающихся с Х, равно 4^3, а количество строк без Х равно 4^4. Итого 64+256=320