Implemente un FuzzyFinder

14

Inspirado en este enlace que encontré en Reddit .

Un FuzzyFinder es una característica de muchos editores de texto. A medida que comienza a escribir una ruta de archivo S, FuzzyFinder se activa y le muestra todos los archivos en el directorio actual que contiene la cadena que ingresó, ordenados por la posición del Sarchivo.

Su tarea es implementar un buscador difuso. Debe ser un programa o función que tome (a través de stdin, argumento de función o línea de comando) una cadena Sy una lista de cadenas L, formateadas como desee, y devuelva o imprima el resultado de ejecutar el buscador difuso. La búsqueda debe ser sensible a mayúsculas y minúsculas. Los resultados en los que se Sencuentra en la misma posición en varias cadenas se pueden ordenar como desee.

Ejemplo:

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

Este es el código de golf, por lo que gana la solución más corta.

kirbyfan64sos
fuente
¿Podemos suponer que todas las entradas están en minúsculas, o deberíamos hacer una coincidencia difusa también con mayúsculas?
Kade
1
@ Vioz- No; la búsqueda debe ser sensible a mayúsculas y minúsculas. Actualicé la pregunta y el ejemplo.
kirbyfan64sos

Respuestas:

5

Pyth, 9 bytes

oxNzf}zTQ

Pruébelo en línea: demostración

Explicación:

            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
Jakube
fuente
1
Este era exactamente el mismo programa Pyth que tenía durante mis pruebas. :)
kirbyfan64sos
5

Pitón 2, 65

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

La expresión x.find(s)devuelve la posición de la primera aparición de sin x, que -1no da lugar a coincidencias. Agregamos 1al resultado que esa no coincidencia corresponde 0, dejándonos filtersalir. Luego ordenamos por la posición del partido, que no se ve afectada al cambiar por 1.

xnor
fuente
5

CJam, 18 15 bytes

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

Pruébelo en línea en el intérprete de CJam .

I / O

Entrada:

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

Salida:

["mig" "migd" "imig"]

Cómo 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.
Dennis
fuente
5

GolfScript, 13 bytes

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

Esta es una de esas raras ocasiones en las que GolfScript puede vencer a CJam, utilizando la concatenación de bloques y tomándose algunas libertades con la entrada que puede formatearse como desee .

Pruébelo en línea en Web GolfScript .

I / O

Entrada

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

Salida

["migd" "mig" "imig"]

Cómo 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.
Dennis
fuente
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 es una función anónima que toma parámetros s(cadena de ruta de archivo) y l(matriz de cadenas). El Fragmento de pila a continuación contiene un código no codificado convertido a ES5 para que más personas puedan probarlo fácilmente. (Si tiene Firefox, puede usar el conjunto de pruebas más bonito de edc65 que se encuentra en su respuesta).

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>

NinjaOsoMono
fuente
¡Guauu! ¡Qué tonto me estoy perdiendo el tiempo preparando una suite de pruebas!
edc65
3

[Sostener] Pyth, 24 bytes

JwKcwdVlK=G.)KI}JGaYG))Y

Intenta está aquí

Soy bastante nuevo en Code Golfing / Pyth, así que no estoy seguro de que sea óptimo, ¡pero estoy trabajando en ello!

Actualización: No creo que realmente esté ordenando correctamente, y parece que no puedo hacer que funcione. Sé que oes ordenar por, y necesito ordenar por posición de S, así que estoy usando .:GlJpara encontrar todas las subcadenas de la longitud de S para el elemento actual Gy luego xpara encontrar el índice de la primera aparición de S, pero parece que no puedo configurar lambda correctamente.

cmxu
fuente
Echa un vistazo zy Q. Usarlos te da inmediatamente 18 bytes. Y puede eliminar el lin VlK=> 17 bytes ( enlace )
Jakube
Por cierto, tu código no funciona. Pruebe el caso de prueba:imig mig migd do Mig imig
Jakube
Tengo una solución funcional de 9 bytes. Si quieres ayuda en Pyth, únete al chat.
Jakube
Oh genial! Trataré de descubrir cómo lo hiciste esta noche. ¡Gracias por toda la ayuda! (Necesitaré ganar 1 punto de reputación más antes de poder chatear: P)
cmxu
1
@Changming te dio el punto. :)
kirbyfan64sos
2

JavaScript ( ES6 ), 68

Eso es casi lo mismo de la respuesta @NBM (incluso si no está copiada), por lo que no espero votos positivos. Disfruta el fragmento de todos modos

Una función con una cadena y una serie de argumentos de cadena, devuelve una matriz de cadena. Filtrar luego ordenar.

Pruebe ejecutar el fragmento a continuación (siendo EcmaScript 6, solo 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>

edc65
fuente
2

ORACLE, 60

¿Esto cuenta?

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

MonoZeus
fuente
Podría contar, pero necesitaría ser un procedimiento de Oracle que tome los datos como argumentos.
kirbyfan64sos
Ya sea que cuente o no, creo que es genial. La primera solución de código de golf que entiendo realmente. ¡Buen trabajo!
Thomas Weller
@ThomasWeller ¡Gracias! Estos golfistas de código pueden ser muy brillantes, ¡pero a veces KISS es todo lo que necesitas!
MonkeyZeus
2

Haskell, 129 116

116 (Gracias 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)))

Bueno, es bastante largo, tal vez encontraré cómo acortarlo un poco ...

Empeñar
fuente
1
afeitarse 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

Acabo de crear una función que toma sla cadena para que coincida en una lista de cadenasn

Edición 1: Gracias a Jakube por jugar golf en un byte.

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

Compruébalo aquí.

Kade
fuente
1

Rubí, 63

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

correr

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

Notas

  1. Primero encuentre todas las palabras que coincidan con find_all
  2. Ordenar por posición de índice de la palabra a buscar.

Editar (por daneiro)

Rubí, 49

p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
bsd
fuente
1
Lo mismo en 49 caracteres:p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
daniero
@daniero Por favor publíquelo como su respuesta. ¡Votaré!
bsd
1
Nah, está bien realmente :) Mi versión es solo una mejora tuya, creo que son demasiado similares para ser respuestas separadas. selectes un alias para find_all,e sorty sort_by son básicamente las mismas cosas en ligeramente diferentes envoltorios. En cambio, te votaré por pensar en la misma solución que yo;)
daniero
0

Raqueta 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))

Pruebas:

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

Salida:

'("imig" "mig" "migd")
rnso
fuente
0

Groovy, 32 bytes

{a,b->a.findAll{it.contains(b)}}
Urna de pulpo mágico
fuente
0

Pip , 15 bytes

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

Yq_@?ySKyN_FIg

Toma la lista como argumentos de línea de comando y la cadena de stdin. Pruébalo en línea!

Explicación

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)
DLosc
fuente