El método del cuadrado medio

19

Introducción

El método del cuadrado medio se utiliza para generar números pseudoaleatorios. Sin embargo, este no es un buen método en la práctica, ya que su período suele ser muy corto y tiene algunas debilidades graves. ¿Como funciona esto? Tomemos un ejemplo:

Para la semilla, elegimos 123456:

Seed     123456

La semilla al cuadrado (semilla × semilla) es igual a:

Seed²  15241383936

Comenzamos con un número de 6 dígitos . Eso significa que la semilla al cuadrado debe entregar un número de 12 dígitos . Si este no es el caso, se agregan ceros a la izquierda para compensar:

Seed²  015241383936

Luego tomamos la parte central del número, con el mismo tamaño que la semilla:

Seed²  015241383936
          ^^^^^^

Este es entonces nuestra nueva semilla : 241383. Repetimos el mismo proceso que se muestra arriba. Obtenemos lo siguiente:

0:     123456
    015241383936
       |    |
1:     241383
    058265752689
       |    |
2:     265752
    070624125504
       |    |
3:     624125
    389532015625
       |    |
4:     532015
    283039960225
       |    |
5:     039960
    001596801600
       |    |
6:     596801

Y esto continúa por un tiempo ... Ahora que sabemos cuál es el método del cuadrado medio, vamos al desafío:


La tarea

Cada semilla tiene un período . El período de una semilla de n dígitos no puede ser superior a 8 n . Por ejemplo, la semilla 82. Esto daría la siguiente secuencia:

82 > 72 > 18 > 32 > 02 > 00 > 00 > 00 > 00 > 00
|____|____|____|____|____|____|____|____|____|___...
0    1    2    3    4    5    6    7    8    9

Puede ver que el período es igual a 5 , antes de volver a contener el mismo dígito. Su tarea es, cuando se le da una semilla mayor que 0 que no contiene ceros a la izquierda, generar el período de la semilla . Entonces, en este caso, necesita salida 5.

Otro ejemplo es:, 24que da lo siguiente:

24 > 57 > 24
|____|____|___...
0    1    2

Como puede ver, no todas las secuencias terminan en 0. Este ciclo tiene un período de 1 .


Casos de prueba

Input   >   Output
24      >   1
82      >   5
123456  >   146
8989    >   68
789987  >   226

Los pastebins con las secuencias para 123456 , 8989 , 789987

Este es el , por lo que gana el envío con la menor cantidad de bytes.

Puede suponer que la entrada nunca tendrá un número desigual de dígitos.

Adnan
fuente
10
Selección de liendres: eso no es un período. El período implica que la secuencia finalmente regresa a su estado inicial. 24es periódica (con el período 2, diría), 82es eventualmente periódica (con el período 1).
Dennis
1
¿Entonces "período" es el índice 0 del último estado que es diferente de todos los estados anteriores?
Luis Mendo
@LuisMendo Sí, eso es correcto. Mi conocimiento matemático no es el mejor: p.
Adnan
Sería más como 'el número de iteraciones antes de que se estabilice'
solo ASCII
1
@WashingtonGuedes Vea este pastebin . ¿Eso lo deja más claro?
Adnan

Respuestas:

3

Gelatina, 26 24 18 bytes

³DL⁵*
²:¢½¤%¢µÐĿL’

Pruébalo en línea!

Cómo funciona

³DL⁵*         Helper link. No arguments.

³             Yield the original input.
 D            Convert from integer to base 10.
  L           Get l, the length of the decimal representation.
   ⁵*         Compute 10 ** l.


²:¢½¤%¢µÐĿL’  Main link. Input: n (integer)

²             Square n.
  ¢½¤         Call the helper link and take the square root of the result.
 :            Integer division; divide the left result by the right one.
      ¢       Call the helper link.
     %        Take the left result modulo the right one.
       µ      Convert the previous chain into a link, and begin a new chain.
        ÐĿ    Repeat the previous chain until the results are no longer unique,
              updating n in each iteration. Collect the intermediate results.
          L   Get the length of the list of results.
           ’  Decrement.
Dennis
fuente
5

Fiesta pura, 162 131 116 113 107

Guardado 3 bytes usando $c...

Gracias @Dennis por ayudarme a ahorrar 6 bytes más.

---- begin middleSquare ----

for((b=$1;i[c=10#$b]<2;)){ a=${#b}
printf -v b %0$[a*2]d $[c*c]
b=${b:a/2:a};((i[10#$b]++))
};echo ${#i[@]}

---- end middleSquare ----

for testCase in 24 82 123456 8989 789987 111111;do
    printf "%12s: " $testCase
    bash middleSquare $testCase
  done
          24: 2
          82: 5
      123456: 146
        8989: 68
      789987: 226
      111111: 374

Cuadrado formateado, 131

---- begin middleSquare ----

for((b=$1;i[
10#$b]<2;1))
do a="${#b}" 
printf -v b\
 %0$[a*2]d \
$[10#$b**2];
b=${b:a/2:a}
((i[10#$b]++
));done;ech\
o ${#i[@]:0}

---- end middleSquare ----

for testCase in 24 82 123456 8989 789987 111111;do
    printf "%12s: %9d\n" $testCase $(
        bash middleSquare $testCase)
  done
          24:         2
          82:         5
      123456:       146
        8989:        68
      789987:       226
      111111:       374

Viejo pero con salida elegante, 162

---- begin middleSquare ----

for((b=$1;i[10#$b
]<2;1))do a=${#b}
printf -v b %0$[a
*2]d  $[10#$b**2]
b=${b:a/2:a};((i[
10#$b]++));print\
f "%9d %s\n" ${#\
i[@]} $b;done;ec\
ho -- ${#i[@]} --

---- end middleSquare ----

bash middleSquare 24
        1 57
        2 24
        2 57
-- 2 --

for testCase in 24 82 123456 8989 789987 111111
    do while read f v f
        do r=$v;done < <(
        bash middleSquare $testCase)
    printf "%12s: %11d\n" $testCase $r
  done
          24:           2
          82:           5
      123456:         146
        8989:          68
      789987:         226
      111111:         374
F. Hauri
fuente
3

JavaScript (ES7), 82 bytes

f=(n,p={},m=-1,l=n.length)=>p[n]?m:f(`${n*n+100**l}`.substr(l/2+1,l,p[n]=1),p,++m)

Acepta entradas en forma de cadena, por ejemplo, "82", y devuelve un entero. Técnica recursiva de cola simple para verificar cada semilla a su vez contra un hash de semillas que ya se han visto. Agrego 100 ** l al cuadrado para asegurar una longitud consistente.

Neil
fuente
@Downgoat Acepta la entrada en forma de cadena .
Neil
1
oh sí, supongo que no puedo leer: |
Downgoat
@WashingtonGuedes No, eso no funciona cuando el valor intermedio comienza con suficientes ceros. (Es por eso que "desperdicié" 7 bytes agregando 100 ** l.)
Neil
1
@WashingtonGuedes Hay casos en los que no funciona, por ejemplo, intente seguir la cadena desde 5288.
Neil
3

Pitón 3 2, 139 114 97 bytes

¡Gracias a Seeq por jugar golf con 25 bytes y gracias a Dennis por jugar golf con 17 bytes! Código:

s=`input()`;u=[];l=len(s)/2
while not s in u:u+=[s];s=`int(s)**2`.zfill(l*4)[l:3*l]
print~-len(u)

Definitivamente se puede jugar más al golf. Este fue también el código utilizado para hacer los casos de prueba: P.

Adnan
fuente
2

Pyth, 21 bytes

tl.us_<>_`^N2/lz2lzsz

Pruébelo en línea: Demostración o conjunto de pruebas

editar: Encontré el caso límite 1000, que no funcionó con mi código anterior. Lo arregló por 1 byte.

Explicación:

tl.us_<>_`^N2/lz2lzsz   implicit: z = input string
  .u               sz   apply the following instructions to N, starting with N = int(z), 
                        until it runs into a loop:
          ^N2              square it
         `                 convert it to a string
        _                  reverse order
       >     /lz2          remove the first len(z)/2
      <          lz        remove everything but the first len(z)  
     _                     reverse order
    s                      convert to int
  .u                   returns the list of all intermediate values
 l                     compute the length of this list
t                      minus 1
Jakube
fuente
alguna razón para usar en szlugar de Q?
Ven
@ user1737909 Si uso Q, tengo que reemplazar todos loslz con l`Qs.
Jakube
mh, parece sorprendente que Pyth no comparta input . Supongo que realmente está destinado a permitir una segunda lectura stdin ..?
Ven
@ usuario1737909 Sí. La única posibilidad de compartir información es con.z y .Q, aunque leen varias líneas de información y las almacenan en listas. Pero en realidad no he visto a alguien usar esta función. Es solo 1 byte para evaluar una cadena o para stringificar un número.
Jakube
De acuerdo, para que pueda leer la entrada estándar en la mayoría de 4 veces en Pyth, Qz.Q.z?
Ven
2

MATL , 33 35 40 bytes

`t0)2^10GVnXK2/^/k10K^\vtun@>]n2-

Pruébalo en línea!

`           % do...while
  t         %   duplicate. Take input implicitly on first iteration
  0)        %   pick last value of array
  2^        %   square
  10        %   push 10
  GVn       %   number of digits of input
  XK        %   copy that to clipboard K
  2/        %   divide by 2
  ^         %   power
  /k        %   divide and floor. This removes rightmost digits from the square value
  10K^      %   10 ^ number of digits of input
  \         %   modulo. This takes the central part of the squared number
  v         %   concatenate this new number to array of previous numbers
  tun@>     %   does the number of unique values exceed the iteration index?
]           % if so: next iteration. Else: exit loop
n2-         % desired result is the amount of numbers minus 2. Implicitly display
Luis Mendo
fuente
2

Oracle SQL 11.2, 184 bytes

WITH v(v,p,n)AS(SELECT:1,'0',-1 FROM DUAL UNION ALL SELECT SUBSTR(LPAD(POWER(v,2),LENGTH(v)*2,0),LENGTH(v)/2+1,LENGTH(v)),v,n+1 FROM v)CYCLE v SET c TO 1 DEFAULT 0 SELECT MAX(n)FROM v;

Sin golf

WITH v(v,p,n) AS
(
  SELECT :1,'0',-1 FROM DUAL
  UNION ALL
  SELECT SUBSTR(LPAD(POWER(v,2),LENGTH(v)*2,0), LENGTH(v)/2+1, LENGTH(v)),v,n+1 FROM v
)
CYCLE v SET c TO 1 DEFAULT 0
SELECT MAX(n) FROM v;

Utiliza la detección de ciclo incorporado para detener la recursividad.

Jeto
fuente
2

Julia, 64 bytes

f(n,A=[],p=10^endof(dec(n)))=n∈A?-1:f(n^2÷√p%p,[A...n],p)+1

Pruébalo con Coding Ground .

Dennis
fuente
1

Mathematica, 80 bytes

(a=10^⌊Log10@#+1⌋;Length@NestWhileList[⌊#^2/a^.5⌋~Mod~a&,#,Unequal,All]-2)&
njpipeorgan
fuente
1

CJam, 37 bytes

q{__,W*:D;~_*sD2/<D>]___|=:A;~A}g],((

Me encontré con un molesto problema de orden de pila que no puedo ver de inmediato cómo resolver. También es increíblemente lento.

Cómo funciona: cada iteración empuja el nuevo valor en la parte superior de la pila, luego envolvemos la pila en una matriz y vemos si es lo mismo que su unión consigo misma (para ver si tiene elementos duplicados). Cuando tenga elementos duplicados, deténgase y vea cuántos elementos hay en la pila.

Un simmons
fuente
1

Python 2, 82 bytes

def f(n,A=[],l=0):l=l or len(`n`)/2;return-(n in A)or-~f(n*n/10**l%100**l,A+[n],l)

Pruébalo en Ideone .

Dennis
fuente
1

Python, 124 bytes

def f(s,p=-1,n=0,m=[]):
 x=len(str(s))*2
 while n not in m:m+=[s];y=str(s*s).zfill(x);n=int(y[x/4:x*3/4]);p+=1;s=n
 return p
Argenis García
fuente
1

VBSCRIPT, 131 bytes

s=inputbox(c):l=len(s):do:t=t&","&s:s=space(l*2-len(s*s))&s*s:s=mid(s,l/2+1,l):i=i+1:loop until instr(t,","&s)>0:msgbox i-1

Lo mejor que pude hacer con vbscript, póster por primera vez, ¡así que sé fácil!

Traceur
fuente
¡Bienvenido a Programming Puzzles y Code Golf Stack Exchange! Gran primer post! Edité un poco el formato de su publicación para hacerla más legible y cumplir más con nuestros estándares. ¡Feliz golf!
GamrCorps