É um wordinian?

20

Qual é a maneira mais curta de ver se uma entrada é um wordinian usando alguma linguagem de programação?

Um wordinian é uma palavra que contém palavras com o comprimento 1 em relação ao comprimento da palavra original. Por exemplo,

bin

'I' é uma palavra
'in' é uma palavra
'bin' é uma palavra

Ou,

palco

'a' é uma palavra
'ta' é uma palavra ( sim é )
'age' é uma palavra
'stag' é uma palavra
'stage' é uma palavra

Entrada

Seu código deve incluir uma palavra e um dicionário como entradas, em qualquer formato razoável.

Saída

A saída deve ser um valor para indicar verdadeiro ou falso, para nos dizer se a palavra é um wordinian.

Para mais informações sobre wordinians clique aqui .

Aqui está uma lista de palavras que usarei como entradas e subpalavras. Além disso, em resposta ao @xnor, ele deve conter subpalavras de cada tamanho, não uma cadeia de subpalavras. Observe que apenas uma palavra será usada como entrada.

Jacques Marais
fonte
@FryAmTheEggman Não consigo colocar um dicionário inteiro aqui. E se houver alguma palavra que exista?
Jacques Marais
6
Eu recomendaria passar um dicionário como entrada. Dessa forma, é fácil chegar a casos de teste (como você pode fazer o seu próprio dicionário pequeno)
Nathan Merrill
2
Ele apenas precisa conter subpalavras de cada tamanho ou elas precisam ser uma cadeia em que cada subpalavra adicione uma letra à anterior?
xnor
@FryAmTheEggman Editei minha pergunta para fornecer uma lista de todas as palavras.
Jacques Marais
1
@JacquesMarais, o conceito é pegar uma palavra e um dicionário e retornar verdadeiro se a palavra for um wordinian (de acordo com o dicionário)
Nathan Merrill

Respostas:

4

Pitão, 20 16 15 13 11 bytes

Agradecimentos a Leaky Nun por salvar 4 bytes! Infelizmente, mudei todo o método depois, mas ainda ajudou.

gl{lM}#zQlz

Espera entrada como dicionário seguido por palavra. Saídas True ou False.

Experimente aqui!

Explicação:

        lz   Collects the length of the word  input
g             and compares it to:
 l             The length of the following:
     # Q        Select all words from the dictionary that
    } z         are contained within the input word.
  lM            Map them to their respective lengths, and
 {              then remove any duplicates.

Isso não funciona se a sequência vazia ""for uma palavra válida.

Steven H.
fonte
1
.Epode ser substituído pors
Leaky Nun
1
m}kHpode ser substituído por}RH
Leaky Nun
1
Gostaria apenas de lhe dar o código do golfe
Leaky Nun
11

Python, 52 bytes

lambda w,d:len({len(x)for x in d if x in w})==len(w)

Uma função anônima que leva uma palavra we dicionário d. Ele pega as palavras em dque são substrings de w, forma um conjunto de seus comprimentos e depois verifica se há tantos comprimentos distintos quanto as letras w.

xnor
fonte
Ugh, acabei de escrever exatamente a mesma coisa, exceto que eu tinha W em vez de x e [em vez de {. +1
Daniel
@ Dopapp Não funcionaria se você usasse em [vez de {. {...}é uma compreensão de conjunto (o mesmo que set([...])).
mbomb007
@ mbomb007, tudo bem, seria necessário um conjunto
Daniel
@xnor Desculpe por não selecionar essa resposta, mas como é um golf código, eu tenho que selecionar o mais curto ...
Jacques Marais
4

Python 3, 108 bytes

lambda w,d,r=range:all(any(i in d for i in j)for j in[[w[i:i+s]for i in r(len(w)+1-s)]for s in r(1,len(w))])

Uma função anônima que recebe entrada, via argumento, de uma palavra wcomo uma sequência e um dicionário dcomo uma lista de sequências e retornos Trueou False.

Como funciona

O primeiro passo é uma compreensão de lista que gera uma lista de listas de todas as substrings de w exclusão w, agrupadas por comprimento. Por exemplo, para 'stage', a lista [['s', 't', 'a', 'g', 'e'], ['st', 'ta', 'ag', 'ge'], ['sta', 'tag', 'age'], ['stag', 'tage']]é gerada. Isso é obtido fazendo um loop sobre todos os índices de início válidos ipara cada comprimento de substring se dividindo cada ssubstring de comprimento usando w[i:i+s]. Para cada lista nesta lista, a presença de cada substring no dicionário é verificada; chamando anyretorna um acerto se pelo menos uma correspondência para um determinado comprimento for encontrada. Por fim, a chamada allverifica se uma correspondência foi encontrada para todos os comprimentos de substring e o resultado disso é retornado.

Experimente no Ideone

TheBikingViking
fonte
4

Ruby, 44 bytes

  • 7 bytes de desconto, graças a @NotThatCharles e seus truques de operador de set!
  • 2 bytes de desconto graças a @Jordan com o truque do operador de navegação segura Ruby 2.3 w[x]&.size:)
->w,d{[*1..w.size]-d.map{|x|w[x]&.size}==[]}

É uma função anônima que leva uma palavra we um dicionário (matriz de palavras) d. Cria duas matrizes: a primeira contendo os números 1 até e incluindo o comprimento de w; A segunda matriz é dcom cada palavra mapeada para seu tamanho, se for uma substring w, caso contrário nil. Em seguida, define a subtração para verificar se a segunda matriz contém todos os elementos da primeira matriz.

daniero
fonte
1
Com o "operador de navegação segura" no Ruby 2.3, você pode salvar alguns bytes: em w[x]&.size==ivez de x.size==i&&w[x].
Jordan
Oh uau, obrigado @ Jordan. Não sabia que um, impressionante :)
daniero
1
você pode economizar mais alguns bytes na sua função anônima (e talvez o programa completo) por deixar cair a uniqe -[p]e usando o conjunto subtração vez:[*1..w.size]-d.map{...}==[]
Não que Charles
@NotthatCharles Isso é brilhante! Obrigado :)
daniero
3

PowerShell v3 + v2 +, 127 110 70 65 bytes

param($a,$d)($d|?{$a-match$_}|select length -U).count-eq$a.length

(Vejo agora que minha abordagem é semelhante à @ xnor, embora eu a tenha desenvolvido independentemente)

Leva a palavra $ae o dicionário de entrada $d, esperando $dcomo uma matriz (veja exemplos abaixo). $dFaz um loop na totalidade e executa a Where-Objectpara extrair as entradas em que a palavra atual $_é uma expressão regular em -matchrelação à palavra de entrada $a(ou seja, a palavra atual é uma subcadeia da palavra de entrada).

Coletamos todas essas palavras de substring e as colocamos Select-Objectno lengthparâmetro e na -Urestrição nique. Isso extrairá os comprimentos exclusivos de cada substring. Por exemplo, para a palavra de entrada comb, será uma matriz de (4,2)para ('comb','om').

Pegamos a .countmatriz resultante e a comparamos com a palavra de entrada .length. Se for igual a, significa que todo comprimento de substring está no dicionário; caso $TRUEcontrário, estamos perdendo pelo menos um $FALSE. Esse valor booleano é deixado no pipeline e a saída é implícita.

NB - Isso deve funcionar na v2 +, pois o -inoperador não está mais presente, mas eu não testei essa versão.

Exemplos

PS C:\Tools\Scripts\golfing> .\is-it-a-wordinian.ps1 'stage' (gc .\words.txt)
True

PS C:\Tools\Scripts\golfing> .\is-it-a-wordinian.ps1 'metal' (gc .\words.txt)
True

PS C:\Tools\Scripts\golfing> .\is-it-a-wordinian.ps1 'comb' (gc .\words.txt)
False
AdmBorkBork
fonte
2

Perl, 86 bytes

Requer -Esem custo extra.

chop(($s,@d)=<>);for$=(1..($x=length$s)){$-+=!!grep$s=~/$_/,grep$===y///c,@d}say$-==$x

Aceita todas as entradas via STDIN. A primeira entrada é a palavra alvo, o restante da entrada é o dicionário. Imprime 1com sucesso, seqüência vazia em caso de falha.

Uso

perl -E 'chomp(($s,@d)=<>);for$=(1..($x=length$s)){$-+=!!grep$s=~/$_/,grep$===y///c,@d}say$-==$x' <<< 'stage
a
ta
age
stag
stage'
1
perl -E 'chomp(($s,@d)=<>);for$=(1..($x=length$s)){$-+=!!grep$s=~/$_/,grep$===y///c,@d}say$-==$x' <<< 'stage
a
at
age
stag
stage'

perl -E 'chomp(($s,@d)=<>);for$=(1..($x=length$s)){$-+=!!grep$s=~/$_/,grep$===y///c,@d}say$-==$x' <<< 'bin
i
in
bin'
1
Dom Hastings
fonte
2

Mathematica, 90 bytes

Sort[MemberQ[DictionaryWordQ/@StringPartition[#,t,1],True]~Table~{t,StringLength@#}][[1]]&

Usa o built-in do MathematicaDictionaryWordQ .

Receber a entrada dcomo dicionário é 5 bytes mais curto, mas muito mais lento para listas longas:

m=MemberQ;Sort[m[d~m~#&/@StringPartition[#,t,1],True]~Table~{t,StringLength@#}][[1]]&
Martin
fonte
2

MATL , 15 bytes

1 byte salvo usando uma ideia da resposta do @ xnor .

XXgc32>!suz1Gn=

Saídas 1ou0 para verdade ou falsidade.

Experimente online!

XX      % Take the two inputs implicitly. Apply the second as a regex into the
        % first. Since the second input is a cell array, each of its contents is
        % applied separately as a regex. So for each dictionary word ("sub-word") 
        % this outputs the sub-word if found in the original word, or else an 
        % empty array. Gives a cell array of cells of strings
g       % Remove one level of nestedness
c       % Convert to char. This concatenates all found sub-words as rows of a 2D 
        % char array, padding with spaces as needed
32>!s   % For each row, count how many non-space characters there are. This is 
        % the length of each sub-word
uz      % Number of distinct non-zero elements
1Gn     % Push length of the original word
=       % Are they equal? Implicitly display
Luis Mendo
fonte
1

Perl, 42 bytes

Inclui +2 para -p0

Dê a palavra seguida pelo dicionário no STDIN:

(echo stage; cat dictionary.txt) | ./wordinian.pl

(Ao testar no unix, verifique se o dictionary.txt usa \ncomo terminador de linha, não \r\n)

wordinian.pl:

#!/usr/bin/perl -p0
s%\G.%!/^.*(.{$+[0]})\H*
\1
/%eg;$_=!//
Ton Hospel
fonte
1

JavaScript (Firefox 30-57), 68 bytes

(w,a)=>new Set((for(x of a)if(~w.search(x))x.length)).size==w.length

O uso de uma compreensão de gerador evita a criação de uma matriz intermediária. Versão ES6 de 73 bytes:

(w,a)=>new Set(a.filter(x=>~w.search(x)).map(x=>x.length)).size==w.length
Neil
fonte
1

05AB1E , 8 bytes

ŒÃ€gZLåP

Word como primeira entrada, lista de dicionário como segunda entrada.

Experimente online ou verifique mais alguns casos de teste .

Explicação:

Œ         # Get all possible substrings of the (implicit) input-string
 Ã        # Only keep the ones which are also in the (implicit) dictionary-list
  g      # Get the length of each remaining string
    Z     # Push the maximum length (without popping the list)
     L    # Pop and push a list in the range [1, maximum-length]
      å   # Check for each value if it's in the list of lengths
       P  # And check if this is truthy for all
          # (then output the result implicitly as result)
Kevin Cruijssen
fonte
1

Kotlin , 51 bytes

{w,d->w.indices.all{w.windowed(it+1).any{it in d}}}

Experimente online!

Caracol_
fonte
0

SQF , 147 bytes

Usando o formato de função como um arquivo:

params["w","d"];a=[];c=count w;for"i"from 1 to c do{a=a+[""];for"j"from 0 to c-i do{q=w select[j,i];if(q in d)then{a set[i-1,q]}}};c==count(a-[""])

Ligue como: ["WORD", DICTIONARY] call NAME_OF_COMPILED_FUNCTION

Ungolfed:

//name parameters
params["w", "d"];
a = []; c = count w;
//for each length of subword
for "i" from 1 to c do {
    //add entry to the `a`
    a = a + [""];
    //for each starting position for that length
    for "j" from 0 to c - i do {
        //get subword
        q = w select [j, i];
        //check if in dictionary
        if(q in d) then {
            //set the entry to the wubword
            a set [i - 1, q]
        }
    }
};
//check if length of word is equal to number of subwords
c == count (a - [""])
Furioso
fonte