O sistema principal é um dispositivo mnemônico para converter números em palavras, para que possam ser memorizados mais facilmente.
É baseado em como as palavras soam foneticamente, mas para simplificar as coisas para o desafio, apenas nos preocuparemos com a forma como as palavras são escritas. Isso significa que haverá algumas conversões incorretas, mas tudo bem.
Para converter um número em uma palavra usando nosso sistema principal simplificado:
- Substitua cada um
0
pors
ouz
. (Alguns poderiam sers
e outros poderiam serz
. O mesmo se aplica a seguir.)- Substitua cada um
1
port
oud
outh
.- Substitua cada um
2
porn
.- Substitua cada um
3
porm
.- Substitua cada um
4
porr
.- Substitua cada um
5
porl
.- Substitua cada um
6
porj
oush
ouch
.- Substitua cada um
7
pork
ouc
oug
ouq
.- Substitua cada um
8
porf
ouv
.- Substitua cada um
9
porp
oub
.- Adicione as letras
aehiouwxy
em qualquer lugar, em qualquer quantidade, para formar uma palavra em inglês real, se possível .
A única exceção é queh
não pode ser inserido após ums
ouc
.Na verdade, o número pode ser qualquer sequência de dígitos de 0 a 9 (sem decimais, vírgulas ou sinais).
A palavra pode conter apenas as letras minúsculas az.
Exemplos
O número 32
deve ser convertido como ?m?n?
, onde ?
representa qualquer sequência finita feita a partir das letras aehiouwxy
(uma sequência do monóide livre, se você preferir). Há muitas maneiras isso pode ser feito em uma palavra Inglês real: mane
, moon
, yeoman
, etc.
O número 05
pode ser convertido como ?s?l?
ou ?z?l?
. Algumas possibilidades são easily
, hassle
e hazel
. A palavra shawl
não é permitida porque h
não pode ser colocada depois s
; seria incorretamente lido como 65
.
Desafio
Escreva um programa ou função que utilize uma sequência de dígitos de 0 a 9 e encontre todas as palavras nas quais ele pode ser convertido usando o mnemônico simplificado do sistema principal.
Seu programa tem acesso a um arquivo de texto da lista de palavras que define quais são todas as palavras "reais" em inglês. Há uma palavra az em minúscula em cada linha deste arquivo e, opcionalmente, você pode assumir que ela possui uma nova linha à direita. Aqui está uma lista de palavras reais que você pode usar para testar. Você pode assumir que esse arquivo de lista de palavras é chamado f
(ou algo mais) e fica em qualquer diretório conveniente.
Para uma penalidade de 35 bytes (adicione 35 à sua pontuação), você pode assumir que a lista de palavras já está carregada em uma variável como uma lista de cadeias. Isso é principalmente para idiomas que não conseguem ler arquivos, mas qualquer envio pode tirar proveito dele.
Seu programa deve exibir todas as palavras da lista de palavras nas quais o número de entrada pode ser convertido. Eles devem ser impressos em stdout (ou similar), um por linha (com uma nova linha à direita opcional) ou podem ser retornados como uma lista de cadeias, se você optar por escrever uma função. A lista de palavras não é necessariamente alfabetizada e a saída também não precisa ser.
Se não houver palavras possíveis, a saída (ou a lista) estará vazia. A saída também está vazia se a sequência vazia for inserida.
Aceite a entrada via stdin, linha de comando ou como um argumento de string para uma função. A lista de palavras ou o nome do arquivo não deve fazer parte da entrada, apenas a sequência de dígitos.
Você está correspondendo apenas palavras únicas na lista de palavras, não seqüências de palavras. A palavra noon
provavelmente seria um dos resultados para 22
, mas a sequência de palavras no one
não.
Casos de teste
Suponha que esta seja a lista de palavras:
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
zdnmrlshchvb
sthnmrlchgvb
shthnmrlchgvb
bob
pop
bop
bopy
boppy
A entrada 0123456789
deve conter todas as palavras longas, exceto zdnmrlshchvb
e shthnmrlchgvb
:
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb
A entrada 99
deve fornecer:
bob
pop
bop
bopy
(As palavras de saída podem estar em qualquer ordem.)
Pontuação
O menor envio em bytes vence. O desempatador vai para a submissão postada primeiro.
Respostas:
Perl,
8784Recebe entrada como o parâmetro da linha de comandos:
Pode ser um pouco menor se a lista de palavras for permitida na entrada padrão:
fonte
A
significaopen A,f
?<A>
).Python 2,
215208 bytesEssa solução Python cria um regex a partir de partes indexadas pelo argumento da linha de comando e testa cada palavra com esse regex (bastante grande).
Fonte original antes do minificador:
Por exemplo, a regex para o teste
99
é:O
(?<![sc])h
bit é um componente "veja por trás da afirmação negativa" que garante que ah
não siga umas
ouc
nas partes gerais de preenchimento.Obrigado Calvin. Esse desafio me motivou a aprimorar minhas habilidades de regex enferrujadas.
fonte
b=c='((?<![sc])h|[aeiouwxy])*'
irá salvar dois bytes.t|th -> th?
salva um bytePython 3, 170
Versão legível:
O código utiliza o fato de
th
ser redundante (já que mapeia para o mesmo número quet
eh
é um caractere de preenchimento).A
maketrans
função estática cria uma tabela mapeando os caracteres do primeiro argumento para os do segundo argumento e os caracteres do terceiro argumento paraNone
(o que resultará na exclusão desses caracteres).O código final pode ser reduzido em alguns bytes criando a tabela como argumento direto de
translate
.fonte
input()
pode ser usado, porque é chamado dentro de um loop. Além disso, seu regex sugerido tem o mesmo tamanho que eu já estou usando (5 bytes).sed, colar, grep, cortar - 109
Pega um arquivo "w", converte cada palavra em seu número, cola novamente no original, grep pelo número e retorna a palavra correspondente. Observe que o espaço em branco após a citação após grep é uma guia, o delimitador padrão da pasta.
Eu sei que Perl está muito à frente, só queria uma versão melhor do shell como exemplo.
Ah, sim, a parte $ 1 significa que isso deve ser executado a partir de um script de shell (a maioria dos shells deve funcionar), portanto é necessário um argumento na linha de comando.
fonte
sed
para evitar a@ARGV
sobrecarga e a sobrecarga de Perl , mas a falta de intervalos e as funções de exclusão ay///
quebram. Surpreendentemente, embora não haja variáveis em que você possa expressar a própria lógica diretamentesed
. Aqui está a minha solução 92:sed -e'h;s/[sc]h/6/g;y/sztdnmrljkcqgfvpb/00112345677778899/;s/[^0-9]*//g;T;s/^$1$//;x;t;d' f
Bash + coreutils, 216
w
sed
substitui dígitos por suas possíveis substituiçõeseval printf
usos desembolsar expansões cinta para expandir todas as substituições possíveissed
na 1ª linha removeaeiouwxy
eh
(quando não é precedido por[sc]
) da lista de palavrasaeiouwxy
eh
removemos da lista de palavras, o últimosed
transforma os resultados de grep (números de linha de cada correspondência) em outrased
expressão, que é processada pela parte externased
para revelar todas as palavras possíveis da lista de palavras.Resultado:
O arquivo da lista de palavras é especificado como um argumento da linha de comandos, seguido pelo número para mnemonicizar:
fonte
tr, sed, grep, xargs, sh, 77
Espera o número em stdin e a lista de palavras deve ser armazenada no arquivo
f
.Não usa todas as substituições (1 sempre será z, 7 sempre será k); portanto, pode ser chamada de solução lenta, mas encontra pelo menos um mnemônico para 95 números em [1-100].
fonte
1
sempre serz
ou7
semprek
. Isso é inválido.