Я пытаюсь сделать программу, которая угадывает слово, которое думает пользователь, но сейчас программа основана только на исключении. У кого-нибудь есть идея, как сделать его лучше?
Вот краткое объяснение того, как это работает сейчас:
У меня есть список слов, хранящийся в "palavras.txt", эти слова затем преобразуются в обычный список.
Первый вопрос: «Сколько букв в вашем слове?». На основании этого программа продолжает исключать все остальные слова, которые не имеют такого же количества букв. После этого он создает список, содержащий все буквы, упорядоченные по количеству раз, которое они появляются в заданной позиции.
Тогда у нас есть второй вопрос: "Является ли буква "х" первой буквой вашего слова?". Если ответ «нет», он удаляет все слова, содержащие эту букву в этой позиции, затем переходит ко второй букве, наиболее часто используемой в этой позиции, и так далее, и так далее. Если да, он удаляет все слова, которые не содержат эту букву в этой конкретной позиции, и переходит к следующей букве слова. И так до тех пор, пока слово не будет закончено.
Это работает все время, но иногда это занимает довольно много времени. Есть ли лучший способ сделать это? ИИ? Может машинное обучение?
Код не важен, так как я просто ищу идеи, но если кому интересно, вот как я это сделал:
import os
from unicodedata import normalize
import random
import string
# Define a função que retira os acentos das palavras
def remover_pont(txt):
import string
return txt.translate(str.maketrans('', '', string.punctuation))
def remover_acentos(txt):
return normalize('NFKD', txt).encode('ASCII', 'ignore').decode('ASCII')
# Retorna uma lista com as letras mais usadas naquela posição, em ordem
def letramusada(lista, pletra):
pletraordem = []
pletraordem2 = []
pl = []
for n in lista:
try:
pl.append(n[pletra - 1])
except:
pass
dict = {}
for k in pl:
if k in dict:
dict[k] += 1
else:
dict[k] = 1
pletraordem2 = (sorted(dict.items(), key=lambda t: t[1], reverse=True))
for c in pletraordem2:
pletraordem.append(c[0])
return pletraordem
# Lê o "banco de dados" que contém as palavras e as armazena na variável "palavras", sem acentos
file = open('palavras.txt')
palavras = file.read().split("\n")
# Armazena a quantidade de letras que a palavra pensada tem
nletras = int(input('Digite o número de letras da palavra (considerando hífen, caso haja) que você pensou, com máximo de 8: '))
# Declara listas que serão usadas em seguida
npalavras = []
palavras2 = []
palavras3 = []
# Armazena todas as palavras que contém a quantidade de letras escolhida anteriormente em uma nova lista chamada "nletras", desconsiderando pontos
for n in palavras:
if nletras == len(n):
npalavras.append(remover_acentos(n).lower())
c = 0
n = 0
for k in range(1, nletras + 1):
ordem = letramusada(npalavras, k)
cond = 0
try:
while cond == 0:
if len(npalavras) < 20 and c == 0:
print("\nHmmm, estou chegando perto!\n")
c += 1
if len(npalavras) < 3:
break
for c in ordem:
if c != 0:
r = str(input("A {} letra da sua palavra é a letra \"{}\"? [S/N] ".format(k, c))).lower()
r = r[0]
if r == "s":
for n in npalavras:
if n[k-1] == c:
palavras2.append(n)
npalavras.clear()
npalavras = palavras2[:]
palavras2.clear()
ordem.clear()
cond += 1
break
else:
for n in npalavras:
if n[k-1] != c:
palavras2.append(n)
npalavras.clear()
npalavras = palavras2[:]
palavras2.clear()
r = 0
pass
except:
n = 1
print("\nDesculpe, não achei nenhuma palavra :(")
escolha = random.choice(npalavras)
if n != 0:
print("\nA palavra que você pensou é: \"{}\"".format(escolha))
Это занимает больше времени, так как вы много сканируете каждый вопрос, а список слов может быть очень большим, сообщество проверки кода будет хорошим местом для обсуждения этих вещей, поскольку это выходит за рамки сообщества stackoverflow.
Извините, ребята, это мой первый вопрос, и я не знал, где его разместить. Должен ли я исключить этот?
Мой ответ кажется вам чем-то непонятным? Дайте мне обратную связь, чтобы я мог улучшить. Спасибо.
вы можете сохранить слова, которые уже были использованы, например, первый пользователь использовал слово «карро», затем вы можете добавить его в файл, и после нескольких букв программа может проверить список на наличие уже сказанных слов, посмотреть, есть ли слово соответствует приведенному описанию, например: "имеет ac в качестве первой буквы", и спросите следующего пользователя, является ли "carro" его словом, вы можете улучшить это, добавив счетчик к каждому слову, чтобы слова, которые чаще используются, появлялись на Топ слов, которые используются реже.
Грубая сила Будь твоим другом
Люди могут подумать, что «машинное обучение» — панацея, но чему учиться? Особенно, когда мало информации. Что вы можете оптимизировать? Ваше описание звучит как чистый брутфорс взлом пароля по словарю, и хакеры, живущие сегодня, за это использование мощности графического процессора.
Это может быть немного не по теме, но даже с учетом графического процессора поиск может быть сложным. Если вы не ограничены конкретным языком/платформой, приведенная выше ссылка на hashcat будет полезна. Знаменитый 133 МБ словарь можно перечислить за 5 минут на MacBookPro, что намного мощнее, чем угадывание в Python.
Пространство поиска и шаблоны слов
Также средняя длина английских слов составляет около 8, эта ситуация очень похожа на обычный пароль. т. е. у вас большое пространство для поиска — верхняя граница 26^8 = 208827064576 слов! — за исключением того, что игрок может использовать в игре только ограниченный список слов.
Фактическое пространство поиска может быть немного меньше, так как в английских словах есть закономерности (например, s
— наиболее часто встречающийся алфавит, а ae
, as
может встречаться чаще, чем az
вещи), но вы используете словарь, поэтому я не думаю, это может помочь.
Несловарный подход
И еще одна идея заключается в том, что процесс может быть очень близок к восстановлению последовательности ДНК, которая также имеет некоторые закономерности, но предоставляемая информация может различаться. Думайте об этом как предложение слова. Биоинформатика использует вероятностные закономерности в последовательности ДНК для вменение.
Этот метод может помочь, когда вы можете постепенно угадать слово/последовательность. В противном случае вы можете использовать только подход грубой силы (когда ваше слово может быть восстановлено только из хэша).
Классический метод, используемый для поисковых систем, методов ввода и вменения ДНК, — скрытая марковская модель. Он угадывает следующий символ на основе вашего предыдущего ввода, а вероятность представляет собой статистическое значение, предварительно рассчитанное с использованием реальных слов.
Это можно комбинировать со словарем, чтобы отсортировать ваше предложение (угадать) и обеспечить более точное предположение.
Есть еще один пост, в котором рассказывается об алгоритме подсказки слов, для которого даже есть код Python. Вот ссылка Какой алгоритм дает подсказки в программе проверки орфографии?
Рассмотрите возможность публикации этого вопроса в Раздел проверки кода Stack Exchange.