Implémenter un FuzzyFinder

14

Inspiré par ce lien que j'ai trouvé sur Reddit .

Un FuzzyFinder est une fonctionnalité de nombreux éditeurs de texte. Lorsque vous commencez à taper un chemin de fichier S, le FuzzyFinder entre en action et vous montre tous les fichiers du répertoire actuel contenant la chaîne que vous avez entrée, triés par la position de Sdans le fichier.

Votre tâche consiste à implémenter un chercheur flou. Il doit s'agir d'un programme ou d'une fonction qui prend (via stdin, argument de fonction ou ligne de commande) une chaîne Set une liste de chaînes L, formatées comme vous le souhaitez, et retourne ou imprime le résultat de l'exécution du viseur flou. La recherche doit être sensible à la casse. Les résultats où se Strouve dans la même position dans plusieurs chaînes peuvent être triés comme vous le souhaitez.

Exemple:

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

C'est le golf de code, donc la solution la plus courte l'emporte.

kirbyfan64sos
la source
Pouvons-nous supposer que toutes les entrées sont en minuscules, ou devrions-nous également faire une correspondance floue pour les majuscules?
Kade
1
@ Vioz- Non; la recherche doit être sensible à la casse. J'ai mis à jour la question et l'exemple.
kirbyfan64sos

Réponses:

5

Pyth, 9 octets

oxNzf}zTQ

Essayez-le en ligne: Démonstration

Explication:

            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
la source
1
C'était exactement le même programme Pyth que j'avais lors de mes tests. :)
kirbyfan64sos
5

Python 2, 65

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

L'expression x.find(s)renvoie la position de la première occurrence de sin x, ne donnant -1aucune correspondance. Nous ajoutons 1au résultat auquel correspond cette non-correspondance 0, en les laissant filtersortir. Nous trions ensuite par la position de correspondance, qui n'est pas affectée par le décalage de 1.

xnor
la source
5

CJam, 18 15 octets

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

Essayez-le en ligne dans l' interpréteur CJam .

E / S

Contribution:

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

Production:

["mig" "migd" "imig"]

Comment ça fonctionne

      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
la source
5

GolfScript, 13 octets

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

C'est l'une de ces rares occasions où GolfScript peut battre CJam, en utilisant la concaténation de blocs et en prenant quelques libertés avec l'entrée qui peut être formatée comme vous le souhaitez .

Essayez-le en ligne dans Web GolfScript .

E / S

Contribution

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

Production

["migd" "mig" "imig"]

Comment ça fonctionne

~             # 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
la source
3

JavaScript ES6, 68 octets

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

Il s'agit d'une fonction anonyme qui prend les paramètres s(chaîne de chemin de fichier) et l(tableau de chaînes). L'extrait de pile ci-dessous contient du code non golfé converti en ES5 afin que plus de personnes puissent le tester facilement. (Si vous avez Firefox, vous pouvez utiliser la plus jolie suite de tests d'edc65 trouvée dans sa réponse.)

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>

NinjaBearMonkey
la source
Hou la la! idiot me perdre du temps à préparer une suite de tests!
edc65
3

[Maintenir] Pyth, 24 octets

JwKcwdVlK=G.)KI}JGaYG))Y

Essayez est ici

Je suis assez nouveau chez Code Golfing / Pyth donc je ne suis pas sûr que ce soit optimal, mais j'y travaille!

Mise à jour: je ne pense pas que je trie correctement et je n'arrive pas à le faire fonctionner. Je sais que oc'est par ordre, et j'ai besoin de trier par position de S donc j'utilise .:GlJpour trouver toutes les sous-chaînes de la longueur de S pour l'élément courant Get ensuite xpour trouver l'indice de la première occurrence de S, mais je n'arrive pas à régler correctement lambda.

cmxu
la source
Découvrez zet Q. Leur utilisation vous donne immédiatement 18 octets. Et vous pouvez supprimer le lin VlK=> 17 octets ( lien )
Jakube
Btw, votre code ne fonctionne pas. Essayez le imig mig migd do Mig imig
scénario de
J'ai une solution fonctionnelle de 9 octets. Si vous voulez de l'aide en Pyth, rejoignez le chat.
Jakube
Oh cool! Je vais essayer de comprendre comment tu l'as fait ce soir. Merci pour votre aide! (Je vais devoir gagner 1 point de réputation supplémentaire avant même de pouvoir discuter: P)
cmxu
1
@Changming vous a donné le point. :)
kirbyfan64sos
2

JavaScript ( ES6 ), 68

C'est presque la même chose que la réponse @NBM (même si elle n'est pas copiée), donc je ne m'attends pas à des votes positifs. Profitez de l'extrait quand même

Une fonction avec une chaîne et des arguments de tableau de chaînes, renvoie un tableau de chaînes. Filtrer puis trier.

Testez runnign l'extrait ci-dessous (étant EcmaScript 6, Firefox uniquement)

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
la source
2

ORACLE, 60

Est-ce que cela compte?

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

MonkeyZeus
la source
Cela pourrait compter, mais il faudrait qu'il s'agisse d'une procédure Oracle qui prend les données comme arguments.
kirbyfan64sos
Que cela compte ou non, je pense que c'est cool. La première solution de golf de code que je connaisse vraiment. Bon travail!
Thomas Weller
@ThomasWeller Merci! Ces golfeurs à code peuvent certainement être très brillants mais parfois KISS est tout ce dont vous avez besoin!
MonkeyZeus
2

Haskell, 129 116

116 (Merci à 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)))

Eh bien, c'est assez long, peut-être que je trouverai comment le raccourcir un peu ...

Pion
la source
1
raser 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 octets

Je viens de créer une fonction qui prend scomme chaîne à faire correspondre dans une liste de chaînesn

Edit 1: Merci à Jakube pour avoir joué un octet au golf.

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

Vérifiez le ici.

Kade
la source
1

Rubis, 63

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

Courir

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

Remarques

  1. Trouvez d'abord tous les mots correspondants avec find_all
  2. Trier par position d'index du mot à rechercher.

Modifier (par daneiro)

Rubis, 49

p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
bsd
la source
1
Même chose en 49 caractères:p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
daniero
@daniero Veuillez le poster comme réponse. Je vais voter!
bsd
1
Non, ça va vraiment :) Ma version n'est qu'une amélioration de la vôtre, je pense qu'elles sont trop similaires pour être des réponses distinctes. selectest un alias pour find_all,et sortet sort_by sont fondamentalement les mêmes choses enveloppements légèrement différentes. Je vous voterai plutôt pour avoir pensé à la même solution que moi;)
daniero
0

Raquette 46 octets

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

Usage:

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

Essai:

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

Production:

'("imig" "mig" "migd")
rnso
la source
0

Groovy, 32 octets

{a,b->a.findAll{it.contains(b)}}
Urne de poulpe magique
la source
0

Pip , 15 octets

14 octets de code, +1 pour l' -pindicateur.

Yq_@?ySKyN_FIg

Prend la liste comme arguments de ligne de commande et la chaîne de stdin. Essayez-le en ligne!

Explication

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
la source