Implementar um FuzzyFinder


14

Inspirado por este link que encontrei no Reddit .

Um FuzzyFinder é um recurso de muitos editores de texto. Quando você começa a digitar o caminho de um arquivo S, o FuzzyFinder entra em ação e mostra todos os arquivos no diretório atual que contém a sequência digitada, classificada pela posição Sno arquivo.

Sua tarefa é implementar um localizador nebuloso. Deve ser um programa ou função que recebe (via stdin, argumento da função ou linha de comando) uma string Se uma lista de strings L, formatadas da maneira que desejar, e retorna ou imprime o resultado da execução do finder difuso. A pesquisa deve fazer distinção entre maiúsculas e minúsculas. Os resultados Sem que a mesma posição está em várias seqüências podem ser classificados da maneira que você desejar.

Exemplo:

Input: mig, [imig, mig, migd, do, Mig]
Output:
    [mig, migd, imig]
OR
    [migd, mig, imig]

Isso é código de golfe, então a solução mais curta vence.


Podemos assumir que todas as entradas estão em minúsculas ou devemos corresponder também a maiúsculas e minúsculas?
Kade

1
@ Vioz- Não; a pesquisa deve fazer distinção entre maiúsculas e minúsculas. Eu atualizei a pergunta e o exemplo.
kirbyfan64sos

Respostas:


5

Pitão, 9 bytes

oxNzf}zTQ

Experimente online: Demonstração

Explicação:

            implicit: z = input string, Q = input list
    f   Q   filter Q for elements T, which satisfy:
     }zT      z is substring of T
o           order the remaining strings N by:
 xNz          the index of z in N

1
Este foi exatamente o mesmo programa Pyth que eu tive durante meus testes. :)
kirbyfan64sos

5

Python 2, 65

def f(s,l):g=lambda x:x.find(s)+1;print sorted(filter(g,l),key=g)

A expressão x.find(s)retorna a posição da primeira ocorrência de sin x, não fornecendo -1correspondência. Acrescentamos 1ao resultado a que não corresponde 0, deixando- filteros sair. Em seguida, classificamos a posição da partida, que não é afetada pela troca de 1.


5

CJam, 18 15 bytes

{1$#)}q~2$,@$p;

Experimente on-line no intérprete CJam .

I / O

Entrada:

"mig" ["imig" "mig" "migd" "do" "Mig"]

Resultado:

["mig" "migd" "imig"]

Como funciona

      q~        e# Read and evaluate the input from STDIN.
                e# Pushes a needle and an array of haystacks.
{    }          e# Define a code block:
 1$             e#   Copy the needle.
   #            e#   Compute the index of the needle in the haystack.
    )           e#   Add 1 to the index.
        2$      e# Copy the block.
          ,     e# Filter: Keep only haystacks for which the code block
                e#         pushed a non-zero value.
           @    e# Rotate the block on top of the stack.
            $   e# Sort: Arrange the haystacks according to the values
                e#       pushed by the code block.
             p  e# Print the filtered and sorted haystacks.
              ; e# Discard the needle.

5

GolfScript, 13 bytes

~{?)}+\1$,\$`

Essa é uma daquelas raras ocasiões em que o GolfScript pode vencer o CJam, usando a concatenação de blocos e obtendo algumas liberdades com a entrada que pode ser formatada da maneira que você desejar .

Experimente online no Web GolfScript .

I / O

Entrada

["imig" "mig" "migd" "do" "Mig"] {"mig"}

Resultado

["migd" "mig" "imig"]

Como funciona

~             # Evaluate the input from STDIN.
              # Pushes an array of haystacks and a needle in a block.
 {?)}         # Push a code block that computes an index and increments it.
     +        # Concatenate that block with the needle block.
      \1$     # Swap the block with the arrays of haystacks and copy the block.
         ,    # Filter: Keep only haystacks for which the code block
              #         pushed a non-zero value.
          \   # Swap the array of haystacks with the code block.
           $  # Sort: Arrange the haystacks according to the values
              #       pushed by the code block.
            ` # Inspect: Format the array for pretty printing.

3

JavaScript ES6, 68 bytes

(s,l,f=j=>j.indexOf(s))=>l.filter(w=>~f(w)).sort((a,b)=>f(a)>f(b))

Esta é uma função anônima que aceita parâmetros s(sequência do caminho do arquivo) e l(matriz de sequências). O snippet de pilha abaixo contém código não-convertido convertido para ES5 para que mais pessoas possam testá-lo facilmente. (Se você possui o Firefox, pode usar o conjunto de testes mais bonito do edc65 encontrado em sua resposta.)

f=function(s,l){
  g=function(j){
    return j.search(s)
  }
  
  return l.filter(function(w){
    return ~g(w)
  }).sort(function(a,b){
    return g(a)>g(b)
  })
}

id=document.getElementById;run=function(){document.getElementById('output').innerHTML=f(document.getElementById('s').value,document.getElementById('l').value.split(', ')).join(', ')};document.getElementById('run').onclick=run;run()
<label>File path: <input type="text" id="s" value="mig" /></label><br />
<label>Files: <input type="text" id="l" value="imig, mig, migd, do, Mig" /></label><br />
<button id="run">Run</button><br />
Output: <output id="output"></output>


Uau! bobo eu perder tempo preparando uma suíte de testes!
Edc65

3

[Hold] Pyth, 24 bytes

JwKcwdVlK=G.)KI}JGaYG))Y

A tentativa está aqui

Eu sou bastante novo no Code Golfing / Pyth, então não tenho certeza de que é o ideal, mas estou trabalhando nisso!

Atualização: Eu não acho que estou classificando corretamente e não consigo fazê-lo funcionar. Eu sei que isso oé ordenado por, e eu preciso classificar pela posição de S, então eu estou usando .:GlJpara encontrar todas as substrings do comprimento de S para o elemento atual Ge, xem seguida , para encontrar o índice da primeira ocorrência de S, mas não consigo definir o lambda corretamente.


Confira ze Q. Usá-los fornece imediatamente 18 bytes. E você pode remover o lVlK
arquivo

Btw, seu código não funciona. Experimente o caso de teste:imig mig migd do Mig imig
Jakube 22/06

Eu tenho uma solução de 9 bytes de trabalho. Se você quiser alguma ajuda no Pyth, participe do bate-papo.
Jakube 22/06

Oh fixe! Vou tentar descobrir como você fez essa noite. Obrigado por toda a ajuda! (Vou precisar para ganhar mais 1 ponto reputação antes que eu possa mesmo chat: P)
cmxu

1
@ Changming Deu o ponto. :)
kirbyfan64sos

2

JavaScript ( ES6 ), 68

Isso é quase o mesmo da resposta do @NBM (mesmo que não seja copiado), então não espero votos positivos. Aproveite o snippet de qualquer maneira

Uma função com argumentos de seqüência de caracteres e matriz de seqüência de caracteres, retorna uma matriz de seqüência de caracteres. Filtrar e classificar.

Teste a execução do fragmento abaixo (sendo apenas EcmaScript 6, Firefox)

f=(s,l,i=t=>t.indexOf(s))=>l.filter(t=>~i(t)).sort((t,u)=>i(t)-i(u))

$(function(){
  $("#S,#L").on("keyup", 
   function() { 
     $('#O').val(f(S.value,L.value.split('\n')).join('\n'))
   } );
  $("#S").trigger('keyup');
})
#S,#L,#O { width: 400px }
#L,#O { height: 100px }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Input String<br><input id=S value='mig'><br>
Input List<br><textarea id=L>
imig
mig
migd
do
Mig
</textarea><br>
Output List<br><textarea id=O readonly></textarea>


2

ORACLE, 60

Isso conta?

select * from t where a like '%mig%' order by instr(a,'mig')


Pode contar, mas precisaria ser um procedimento Oracle que aceite os dados como argumentos.
kirbyfan64sos

Se conta ou não, acho legal. A primeira solução de código de golfe que eu realmente entendo. Ótimo trabalho!
Thomas Weller

@ThomasWeller Thanks! Esses jogadores de código certamente podem ser muito brilhantes, mas às vezes o KISS é tudo que você precisa!
MonkeyZeus

2

Haskell, 129 116

116 (Graças a Franky):

import Data.List
h s=map snd.sort.map(\x->((head[c|c<-[0..length x],isPrefixOf s(drop c x)]),x)).filter(isInfixOf s)

129:

import Data.List
f s n=map snd(sort(map(\x->((head [c|c<-[0..length x],isPrefixOf s(drop c x)]),x))(filter(\x->isInfixOf s x)n)))

Bem, é muito longo, talvez eu descubra como diminuir um pouco ...


1
13:h s=map snd.sort.map(\x->((head[c|c<-[0..length x],isPrefixOf s(drop c x)]),x)).filter(isInfixOf s)
Franky

2

Python 2, 69 68 66 bytes

Acabei de criar uma função que leva scomo string para combinar em uma lista de stringsn

Edit 1: Agradecimentos a Jakube por jogar fora um byte.

lambda s,n:sorted([x for x in n if s in x],key=lambda x:x.find(s))

Confira aqui.


1

Ruby, 63

p=->(w,l){l.find_all{|x|x[w]}.sort{|a,b|a.index(w)-b.index(w)}}

Corre

irb(main):022:0> p["mig", ["imig", "mig", "migd", "do", "Mig"]]
=> ["migd", "mig", "imig"]

Notas

  1. Encontre primeiro todas as palavras correspondentes com find_all
  2. Classifique pela posição do índice da palavra a ser pesquisada.

Editar (de daneiro)

Ruby, 49

p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}

1
A mesma coisa em 49 caracteres:p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
daniero 26/06

@daniero Por favor, publique como sua resposta. Eu vou votar!
BSD

1
Não, está tudo bem :) Minha versão é apenas uma melhoria sua, acho que são muito parecidas para serem respostas separadas. selecté um apelido para find_all,e sorte sort_by são basicamente as mesmas coisas em um pouco diferentes envolvimentos. Em vez disso, votarei em você, por pensar na mesma solução que eu;) #
daniero 27/06/2015

0

Raquete 46 bytes

(for/list((i l)#:when(string-contains? i s))i)

Uso:

(define (f s l)
 (for/list((i l)#:when(string-contains? i s))i))

Teste:

(f "mig" '["imig" "mig" "migd" "do" "Mig"])

Resultado:

'("imig" "mig" "migd")


0

Pip , 15 bytes

14 bytes de código, +1 para -psinalizador.

Yq_@?ySKyN_FIg

Leva a lista como argumentos da linha de comando e a string de stdin. Experimente online!

Explicação

Yq              Yank a line of stdin into y
           FIg  Filter array of cmdline args by this function:
        yN_       Count occurrences of y in arg
      SK        Sort the resulting list using this key function:
  _@?y            Index of y in arg
                Print the Pip representation of the list (implicit, -p flag)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.