Voisins de Levenshtein

20

La plupart des nombres carrés ont au moins 1 nombre carré différent avec lequel leur distance Levenshtein est exactement 1. Pour un carré donné x , chaque carré qui remplit cette condition est appelé un voisin Levenshtein de x . Par exemple, 36 est un voisin Levenshtein de 16 , car une seule modification ( 13 ) est requise. Cependant, 64 n'est pas un voisin Levenshtein de 16 , car il nécessite un minimum de 2 modifications. Les nombres qui ont des 0 en tête ( 2025025 ) ne sont pas des voisins de Levenshtein.

Votre tâche consiste à prendre un nombre carré en entrée et à afficher, dans un format raisonnable, la liste complète de ses voisins Levenshtein. Vous pouvez inclure des voisins répétés dans la liste, si vous le souhaitez, mais vous ne pouvez pas inclure l'entrée d'origine, car ce n'est pas un voisin Levenshtein en soi.

Tout format raisonnable devrait inclure une sorte de séparateur entre les sorties, comme ,ou une nouvelle ligne, et peut produire des caractères avec la valeur Unicode correspondante (c'est-à-dire brainfuck) plutôt que les nombres eux-mêmes. L'ordre de sortie n'a pas d'importance.

Cette entrée sera toujours un nombre carré, supérieur à 0 . Votre programme ne devrait avoir aucune limite théorique , mais s'il échoue pour de grands nombres pour des raisons pratiques (par exemple au-delà des nombres 32 bits), c'est tout à fait correct.

Si l'entrée n'a pas de voisins Levenshtein, la sortie doit clairement refléter cela, comme la sortie de rien, un tableau / chaîne vide, un entier négatif, 0 , etc.

Il s'agit de , donc le code le plus court en octets l'emporte.

Cas de test

Voici les résultats pour les carrés de 1 à 20 :

  1: 4, 9, 16, 81
  4: 1, 9, 49, 64
  9: 1, 4, 49
 16: 1, 36, 169, 196
 25: 225, 256, 625
 36: 16, 361
 49: 4, 9
 64: 4
 81: 1, 841
100: 400, 900, 1600, 8100
121: 1521
144: 1444
169: 16, 1369
196: 16, 1296, 1936
225: 25, 625, 1225, 2025, 4225, 7225
256: 25
289: 2809
324: 3249
361: 36, 961
400: 100, 900, 4900, 6400

De plus, 1024n'a pas de voisins, c'est donc un bon cas de test.

caird coinheringaahing
la source
3
Plus intéressant serait ce que sont les voisins de 2025.
Neil
6
Sauf si je manque quelque chose, 32 * 32 = 1024n'a pas de voisins Levenshtein carrés.
xnor
2
@xnor Oui, je crois que vous avez raison, 1024n'a pas de voisins Levenshtein, je vais modifier cet exemple dans
caird coinheringaahing
6
Pour toutes les déclarations de la forme "Pour tous ...", si un contre-exemple peut être trouvé, il s'agit d'une réfutation rigoureuse de la déclaration. (Mais si je me trompe, j'accepterai un contre-exemple comme un avertissement rigoureux.)
Neil
2
Pouvons-nous inclure le numéro d'origine dans la sortie? Par exemple 49 -> 4, 9, 49.
Robin Ryder

Réponses:

7

05AB1E ,  11 10  6 octets

-4 merci à Grimy !! (le carré en premier plutôt que la recherche de carrés enregistre 3; utilisez 10 ^ n enregistre 1)

°Lnʒ.L

Prend un entier, sort une liste, éventuellement vide

Essayez-le en ligne! - C'est fou-lent en raison de la°, donc inutile de l'essayer même pour9.
Ou Essayez une version légèrement plus rapide - celle-ci en ajoute huit à la place,8+puis utilise la même approche.

Comment?

°Lnʒ.L - f(integer)    stack = n
°      - push 10^n             10^n
 L     - range                 [1,2,3,...,10^n]
  n    - square                [1,4,9,...,10^2n]
   ʒ   - filter keep if == 1:
    .L -   Levenshtein distance
Jonathan Allan
la source
1
Le 9s«dans votre 11 octets aurait pu être . Belle réponse au point, cependant! +1 de moi.
Kevin Cruijssen
Plus lent 7: т+Lnʒ.L. 6 ralentir Ridiculously: °Lnʒ.L. 5 ralentir Infiniment: ∞nʒ.L.
Grimmy
1
@Grimy Merci - pourquoi diable ne pensais-je pas à la case départ: /. Est-ce que l'infini est acceptable pour une question «montrer tout»? (Je vois que nous pouvons soumettre des générateurs comme des soumissions de fonctions, mais s'il n'y a pas de point d'arrêt codé, nous ne pouvons pas savoir quand il nous est donné la valeur finale).
Jonathan Allan
Je ne pense pas que la ∞nʒ.Lréponse soit acceptable, car les soumissions doivent prendre fin . Indépendant: votre lien TIO pour la version 7 octets est utilisé , ce qui est environ 100 fois plus lent que T+pour les grands nombres. Mon commentaire utilisé т+(ajouter 100) pour être sûr, mais il s'avère que 8+c'est suffisant dans tous les cas.
Grimmy
@Grimy oups, merci. Je pensais que 100 était exagéré, car il suffit de vérifier les 9 premiers carrés.
Jonathan Allan
5

Rétine 0,8,2 , 142138 octets

.?
$'¶$`#$&$'¶$`#$'¶$`$&
#
0$%'¶$%`1$%'¶$%`2$%'¶$%`3$%'¶$%`4$%'¶$%`5$%'¶$%`6$%'¶$%`7$%'¶$%`8$%'¶$%`9
A`^0
Dr`
\d+
$*
-2G`(\b1|11\1)+\b
%`1

Essayez-le en ligne! Explication:

.?
$'¶$`#$&$'¶$`#$'¶$`$&

Pour chaque chiffre, essayez a) de le retirer b) de le précéder d'un chiffre différent c) de le changer en un chiffre différent. Pour l'instant, le chiffre différent est marqué d'un #.

#
0$%'¶$%`1$%'¶$%`2$%'¶$%`3$%'¶$%`4$%'¶$%`5$%'¶$%`6$%'¶$%`7$%'¶$%`8$%'¶$%`9

Pour chaque chiffre différent potentiel, remplacez chaque chiffre possible.

A`^0

Supprimez les nombres qui commencent maintenant par zéro.

Dr`

Supprimez tous les numéros en double. (Cela laisse juste les lignes vides.)

\d+
$*

Convertissez en unaire.

-2G`(\b1|11\1)+\b

Conservez tous les nombres carrés, sauf le dernier (qui est toujours le numéro d'entrée).

%`1

Convertissez les nombres restants en décimal.

Neil
la source
5

R , 42 41 octets

(9n)2

function(n,y=(1:(9*n))^2)y[adist(n,y)==1]

Essayez-le en ligne!

n91n1911009100(9n)2=81n2n>181n2>91nn=119191 n'est pas un carré, ça va.

1(9n)2

Robin Ryder
la source
4

Python 2 , 173 167 149 148 147 144 139 138 octets

lambda n,I=int:{(I(I(v)**.5)**2==I(v))*I(v)for v in[`n`[:i]+`j-1`[:j]+`n`[i+k:]or 0for j in range(11)for i in range(n)for k in 0,1]}-{0,n}

Essayez-le en ligne!

19 + 3 + 5 + 1 = 28! octets thx à Jonathan Allan .

Chas Brown
la source
Économisez 48 . [p for p in...]est redondant. Nous pouvons retourner un ensemble (ou des doublons). '0'<v[:1]peut être '1'<=v. C'est beaucoup plus lent mais range(len(a)+1)peut l'être range(n). Utilisez une variable pour iet des i+1tranches pour éviter la somme. Utilisez un lambda. EDIT enregistrer 48 de votre précédent.
Jonathan Allan
@Jonathan Allan: J'avais déjà fait certains des mêmes changements; mais appréciez certainement les 18 octets!
Chas Brown
Un autre
Jonathan Allan
@Jonathan Allan: Nice! C'est maintenant à peine lisible :).
Chas Brown
1
@Jonathan Allan: Lol, je vais juste arrêter la mise à jour - je ne peux pas suivre! :)
Chas Brown
3

Oracle SQL, 93 octets

select level*level from t where utl_match.edit_distance(x,level*level)=1connect by level<10*x

Testez dans SQL * PLus.

SQL> set heading off
SQL> with t(x) as (select 225 from dual)
  2  select level*level from t where utl_match.edit_distance(x,level*level)=1connect by level<10*x
  3  /

         25
        625
       1225
       2025
       4225
       7225

6 rows selected.
Dr Y Wit
la source
2

PHP , 62 octets

for(;$argn*92>$n=++$i**2;levenshtein($argn,$n)==1&&print$n._);

Essayez-le en ligne!

Ce script imprime les voisins Levenshtein d'entrée séparés par _un séparateur de fin, et si aucun voisin n'est trouvé, n'affiche rien.

Heureusement, PHP a une distance intégrée pour Levenshtein ! Ce script parcourt tous les nombres carrés de 1 à input * 91, car tous les voisins Levenshtein valides (distance de 1) sont dans cette plage. Imprime ensuite chaque numéro de cette plage qui a une distance Levenshtein de 1 avec l'entrée.

Nuit2
la source
2

JavaScript (V8) ,  129 125  123 octets

Prend l'entrée sous forme de chaîne. Imprime les voisins Levenshtein vers STDOUT.

s=>{for(t=9+s;t;t--)(t+='')**.5%1||(g=m=>m*n?1+g(m,--n)*(g(--m)-(s[m]==t[n++]))*g(m):m+n)(s.length,n=t.length)-1||print(t)}

Essayez-le en ligne!

Commenté

s => {                        // s = input
  for(                        // loop:
    t = 9 + s;                //   start with t = '9' + s
    t;                        //   repeat while t > 0
    t--                       //   decrement t after each iteration
  )                           //
    (t += '')                 //   coerce t to a string
    ** .5 % 1 ||              //   abort if t is not a square
    ( g =                     //   g is a recursive function to test whether the
                              //   Levenshtein distance between s and t is exactly 1
      m =>                    //   m = pointer into s (explicit parameter)
                              //   n = pointer into t (defined in the global scope)
        m * n ?               //     if both m and n are greater than 0:
          1 +                 //       add 1 to the final result and add the product of:
          g(m, --n) * (       //         - a recursive call with m and n - 1
            g(--m) -          //         - a recursive call with m - 1 and n - 1
            (s[m] == t[n++])  //           minus 1 if s[m - 1] = t[n - 1]
          ) *                 //
          g(m)                //         - a recursive call with m - 1 and n
        :                     //       else:
          m + n               //         stop recursion and return m + n
    )(s.length, n = t.length) //   initial call to g with m = s.length, n = t.length
    - 1 ||                    //   abort if the final result is not 1
    print(t)                  //   otherwise, print t
}                             //
Arnauld
la source
Je savais que SpiderMonkey avait print()mais je ne savais pas que Node l'avait aussi ...
Neil
@Neil En fait, il n'existe pas dans Node. Je pense que cette version n'est qu'une version shell de V8 - qui est beaucoup plus proche de la version du navigateur.
Arnauld
2

Gelée , 53 38 octets

D;Ɱ⁵ṭJœP,œṖjþ⁵Ẏṭ@ḢF${ʋʋ€$ƲẎ%⁵1ị$ƇḌƲƇḟ

Essayez-le en ligne!

Il n'y a pas de fonction intégrée pour la distance de Levenshtein, donc génère toutes les modifications possibles à 1 distance, puis exclut celles avec un zéro devant et ne conserve que des carrés parfaits. Ne filtre pas les doublons (comme autorisé).

Nick Kennedy
la source