Solveur de recherche de mots

13

Hier, je me suis demandé si je pouvais écrire un programme pour passer au peigne fin une recherche de mots donnée et produire les réponses. C'était en fait étonnamment facile. Maintenant, je me demande à quel point nous pouvons être petits.

Règles

  • Votre première entrée est une chaîne ou une collection de n lignes, dont chacune comporte n caractères
  • Votre deuxième entrée est une liste de mots dans n'importe quel format à trouver dans le puzzle
  • Tous les mots de la liste de recherche sont garantis dans le puzzle
  • Les mots peuvent être orientés dans l'une des quatre directions cardinales, ainsi qu'en diagonale vers l'avant et vers l'arrière
  • Seuls les caractères AZ majuscules seront présents dans le puzzle
  • Votre code doit trouver chaque mot dans la chaîne de recherche et afficher la position des coordonnées de la lettre de départ, où 0,0 est le caractère supérieur gauche.
  • Si vous localisez plusieurs instances du même mot, vous pouvez le gérer comme vous le souhaitez. Sortie plusieurs fois, ou une seule fois, c'est à vous

Exemples / cas de test

Étant donné le tableau suivant:

ABCD
EFGH
IJKL
MNOP

Et la chaîne de recherche suivante:

ABCD,CGKO,POMN,NJF,AFKP,CFI,LGB,MJGD

Votre programme doit afficher les éléments suivants, dans n'importe quel ordre:

ABCD at 0,0
CGKO at 0,2
PONM at 3,3
NJF at 3,1
AFKP at 0,0
CFI at 0,2
LGB at 2,3
MJGD at 3,0

Comme toujours, la réponse la plus courte l'emporte

morpen
la source
6
Bienvenue chez PPCG! Joli premier défi!
AdmBorkBork
2
De même , la seule vraie différence semble être l'inclusion de l'emplacement dans la sortie.
FryAmTheEggman
@ NL628 Oui, tous les mots recherchés sont garantis dans le puzzle. S'il y a plus d'une occurrence, vous pouvez soit la sortir deux fois, soit l'ignorer la seconde, c'est à vous de décider.
morpen
@JonathanAllan Excellente idée. Je vais le mettre à jour comme vous l'avez suggéré.
morpen
1
@RickHitchcock Oui, ça devrait :)
morpen

Réponses:

4

JavaScript (Node.js) , 154 152 150 150 141 octets

  • merci à Arnauld pour avoir réduit de 2 octets

renvoie un tableau d'emplacements (c'était une chaîne avec de nouvelles lignes auparavant)

(b,w)=>w.map(s=>[...b].map((_,p)=>[1,-1,r=b.search`
`,-r,~r,++r,-~r,~r].map(d=>[...s].every((c,i)=>c==b[p+d*i])?s+=" at "+[p/r|0,p%r]:0))&&s)

Essayez-le en ligne!

DanielIndie
la source
3

Python 2 , 213 octets

lambda a,W:[(w,i,j)for w in W for i in R(L(a))for j in R(L(a[0]))for U in R(9)if U-4and g(i,j,U/3-1,U%3-1,a).find(w)==0]
g=lambda i,j,u,v,a,s='':L(a)>i>=0<=j<L(a[0])and g(i+u,j+v,u,v,a,s+a[i][j])or s
L=len;R=range

Essayez-le en ligne!

g prend un emplacement de départ i,j et une direction u,vet par récursion extrait la chaîne commençant à cet emplacement dans cette direction.

fvisite ensuite chaque emplacement i,jet direction de départ U/3-1,U%3-1et vérifie chaque mot wpour voir si la chaîne résultante commence par w.

Chas Brown
la source
2

Python 3 , 149 147 octets

def g(b,w):h=b.find('\n')+1;return[f'{y} at {i//h},{i%h}'for y in w for i in range(len(b))for d in(1,h+1,h,h-1,-1,~h,-h,1-h)if y==b[i::d][:len(y)]]

Essayez-le en ligne!

Version non golfée

def g(b,w):
    h = b.find('\n') + 1                              # width of a row plus the '\n'
    a = []
    for y in w:                                       # iterate over the words
        for i in range(len(b)):                       #   iterate over the game board
            for d in(1,h+1,h,h-1,-1,~h,-h,1-h):       #     for each possible direction
                if y==b[i::d][:len(y)]:               #       see if the word matches
                    a.append(f'{y} at {i//h},{i%h}')
    return a

L'idée principale est de b[i::d]sélectionner une tranche sur le plateau de jeu. La tranche commence comme position iet s'étend dans la direction d. Par exemple, d = h+1correspond à la diagonale sud-est, tandis que d = ~h, qui est la même que -h-1, correspond à la diagonale nord-ouest. [:len(y)] coupe la tranche à la même longueur que le mot recherché.

RootTwo
la source