Vecinos de Levenshtein

20

La mayoría de los números cuadrados tienen al menos 1 número cuadrado diferente con el cual su distancia de Levenshtein es exactamente 1. Para un cuadrado dado X , cada cuadrado que cumple con esta condición se llama vecino de X de Levenshtein . Por ejemplo, 36 es un vecino de Levenshtein de dieciséis , ya que solo se requiere 1 edición ( 13 ). Sin embargo, 64 no es un vecino de Levenshtein de dieciséis , ya que requiere un mínimo de 2 ediciones. Los números que tienen ceros a la izquierda ( 2025025 ) no son vecinos de Levenshtein.

Su tarea es tomar un número cuadrado como entrada y generar, en cualquier formato razonable, la lista completa de sus vecinos de Levenshtein. Puede incluir vecinos repetidos en la lista, si lo desea, pero no puede incluir la entrada original, ya que no es un vecino de Levenshtein en sí mismo.

Cualquier formato razonable debe incluir algún tipo de separador entre las salidas, como ,o una nueva línea, y puede generar caracteres con el valor Unicode correspondiente (es decir, brainfuck) en lugar de los números en sí. El orden de la salida no importa.

Esta entrada siempre será un número cuadrado, mayor que 0 . Su programa no debería tener un límite teórico , pero si falla por grandes números por razones prácticas (por ejemplo, más allá de los números de 32 bits), está completamente bien.

Si la entrada no tiene ningún vecino de Levenshtein, la salida debe reflejar esto claramente, como no generar nada, una matriz / cadena vacía, un entero negativo, 0 , etc.

Este es el , por lo que gana el código más corto en bytes.

Casos de prueba

Estos son los resultados para los cuadrados del 1 al 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

Adicionalmente, 1024 no tiene vecinos, por lo que es un buen caso de prueba.

caird coinheringaahing
fuente
3
Más interesante sería lo que son los vecinos de 2025.
Neil
66
A menos que me falte algo, 32 * 32 = 1024no tiene vecinos Levenshtein cuadrados.
xnor
2
@xnor Sí, creo que tienes razón, 1024no tiene ningún vecino de Levenshtein,
editaré
66
Para todas las declaraciones de la forma "Para todos ...", si se puede encontrar un contraejemplo, entonces esta es una prueba rigurosa de la declaración. (Pero si me equivoco, aceptaré un contraejemplo como una prueba rigurosa).
Neil
2
¿Podemos incluir el número original en la salida? Por ejemplo 49 -> 4, 9, 49.
Robin Ryder

Respuestas:

7

05AB1E ,  11 10  6 bytes

-4 gracias a Grimy !! (el cuadrado primero en lugar de buscar cuadrados ahorra 3; use 10 ^ n guarda 1)

°Lnʒ.L

Toma un número entero, genera una lista, posiblemente vacía

Pruébalo en línea! - Esto es muy lento debido a la°, por lo que no tiene sentido intentarlo incluso9.
O pruebe una versión un poco más rápida : esta agrega ocho en su lugar con8+ luego usa el mismo enfoque.

¿Cómo?

°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
fuente
1
El 9s«en su 11-byter podría haber sido . ¡Buena respuesta al punto, sin embargo! +1 de mi parte
Kevin Cruijssen
Más lento 7: т+Lnʒ.L. Ridículamente lento 6: °Lnʒ.L. Infinitamente lenta 5: ∞nʒ.L.
Grimmy
1
@ Grimy Gracias, ¿por qué no pensé en cuadrar primero: /. ¿Es ese infinito aceptable para una pregunta de "mostrar todo"? (Veo que podemos enviar generadores como presentaciones de funciones, pero si no hay un punto de parada codificado, entonces no podemos saber cuándo nos ha dado el valor final).
Jonathan Allan
No creo que ∞nʒ.Lsea ​​aceptable como respuesta porque los envíos tienen que terminar . Sin relación: su enlace TIO para la versión de 7 bytes utiliza , que es ~ 100 veces más lento que T+para grandes números. Mi comentario solía т+(agregar 100) para estar seguro, pero resulta que 8+es suficiente en todos los casos.
Grimmy
@ Grimy oops, gracias. Supuse que 100 era exagerado ya que 1 solo necesita verificar los primeros 9 cuadrados.
Jonathan Allan
5

Retina 0.8.2 , 142 138 bytes

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

Pruébalo en línea! Explicación:

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

Para cada dígito, intente a) eliminarlo b) precederlo con un dígito diferente c) cambiarlo a un dígito diferente. Por ahora, el dígito diferente está marcado con a #.

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

Para cada dígito potencial diferente, sustituya cada dígito posible.

A`^0

Elimina los números que ahora comienzan con cero.

Dr`

Eliminar todos los números duplicados. (Esto solo deja las líneas en blanco).

\d+
$*

Convierte a unario.

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

Mantenga todos los números cuadrados excepto el último (que siempre es el número de entrada).

%`1

Convierta los números restantes de nuevo a decimal.

Neil
fuente
5

R , 42 41 bytes

(9 9norte)2

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

Pruébalo en línea!

norte91 91norte191 911009100(9 9norte)2=81norte2norte>181norte2>91 91nortenorte=1191 9191 91 No es un cuadrado, estamos bien.

1(9 9norte)2

Robin Ryder
fuente
4

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

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}

Pruébalo en línea!

19 + 3 + 5 + 1 = 28! bytes gracias a Jonathan Allan .

Chas Brown
fuente
Ahorra 48 . [p for p in...]Es redundante. Podemos devolver un conjunto (o duplicados). '0'<v[:1]puede ser '1'<=v. Es mucho más lento pero range(len(a)+1)puede ser range(n). Use una variable para iy i+1rebanadas para evitar la suma. Usa una lambda. EDITAR guardar 48 de su anterior.
Jonathan Allan
@ Jonathan Allan: ya había hecho algunos de los mismos cambios; pero definitivamente aprecio los 18 bytes!
Chas Brown
Otro
Jonathan Allan
@ Jonathan Allan: ¡Qué bien! Ahora es apenas legible :).
Chas Brown
1
@ Jonathan Allan: Lol, voy a dejar de actualizar, ¡no puedo seguir el ritmo! :)
Chas Brown
3

Oracle SQL, 93 bytes

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

Prueba en 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
fuente
2

PHP , 62 bytes

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

Pruébalo en línea!

Este script imprime los vecinos de entrada de Levenshtein separados por _un separador final y, si no se encuentran vecinos, no imprime nada.

Afortunadamente, PHP tiene una distancia incorporada para Levenshtein . Este script recorre todos los números cuadrados del 1 al input * 91, ya que todos los vecinos válidos de Levenshtein (distancia de 1) están en ese rango. Luego imprime cada número en ese rango que tiene una distancia de Levenshtein de 1 con la entrada.

Noche2
fuente
2

JavaScript (V8) ,  129125123  bytes

Toma la entrada como una cadena. Imprime los vecinos de Levenshtein en 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)}

Pruébalo en línea!

Comentado

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
fuente
Sabía que SpiderMonkey tenía print()pero no me di cuenta de que Node también lo tenía ...
Neil
@Neil En realidad, no existe en Node. Creo que esta versión es solo una versión de shell de V8, que está mucho más cerca de la versión del navegador.
Arnauld
2

Gelatina , 53 38 bytes

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

Pruébalo en línea!

No hay una función integrada para la distancia de Levenshtein, por lo que genera todas las ediciones posibles de 1 distancia y luego excluye aquellas con cero a la izquierda y mantiene solo cuadrados perfectos. No filtra los duplicados (según lo permitido).

Nick Kennedy
fuente