Aproximar mis cuadrados


10

Inspirado en este video de tecmath .

Se xpuede encontrar una aproximación de la raíz cuadrada de cualquier número tomando la raíz cuadrada entera s(es decir, el entero más grande de ese tipo s * s ≤ x) y luego calculando s + (x - s^2) / (2 * s). Llamemos a esto aproximación S(x). (Nota: esto es equivalente a aplicar un paso del método Newton-Raphson).

Aunque esto tiene peculiaridad, donde S (n ^ 2 - 1) siempre será √ (n ^ 2), pero en general será muy preciso. En algunos casos más grandes, esto puede tener una precisión> 99.99%.

Entrada y salida

Tomarás un número en cualquier formato conveniente.

Ejemplos

Formato: Entrada -> Salida

2 -> 1.50
5 -> 2.25
15 -> 4.00
19 -> 4.37               // actually 4.37       + 1/200
27 -> 5.20
39 -> 6.25
47 -> 6.91               // actually 6.91       + 1/300
57 -> 7.57               // actually 7.57       + 1/700
2612 -> 51.10            // actually 51.10      + 2/255
643545345 -> 25368.19    // actually 25,368.19  + 250,000,000/45,113,102,859
35235234236 -> 187710.50 // actually 187,710.50 + 500,000,000/77,374,278,481

Especificaciones

  • Su salida debe redondearse al menos a la centésima más cercana (es decir, si la respuesta es 47.2851, puede generar 47.29)

  • Su salida no tiene que tener los siguientes ceros y un punto decimal si la respuesta es un número entero (es decir, 125.00 también puede salir como 125 y 125.0)

  • No tiene que admitir ningún número inferior a 1.

  • No tiene que admitir entradas no enteras. (es decir, 1.52, etc.)

Reglas

Las lagunas estándar están prohibidas.

Este es un , por lo que la respuesta más corta en bytes gana.



3
Nota:s + (x - s^2) / (2 * s) == (x + s^2) / (2 * s)
JungHwan Min

Mis soluciones: Pyth , 25 bytes ; 14 bytes
Stan Strum

¿Debe tener una precisión de al menos 2 dígitos?
Totalmente humano

@totallyhuman Sí. 47.2851 se puede representar como 47.28, pero no más inexacto.
Stan Strum

Respuestas:


2

Jalea ,  8  7 bytes

-1 byte gracias a la fórmula matemática simplificada de Olivier Grégoire : vea su respuesta Java .

÷ƽ+ƽH

Pruébalo en línea!

¿Cómo?

÷ƽ+ƽH - Link: number, n
 ƽ     - integer square root of n  -> s
÷       - divide                    -> n / s
    ƽ  - integer square root of n  -> s
   +    - add                       -> n / s + s
      H - halve                     -> (n / s + s) / 2

7 bytes: ÷ƽ+ƽHprimera vez que trato de usar Jelly, así que podría estar equivocado. Sin ƽembargo, desearía saber cómo almacenar para no repetirlo. Eso podría salvar otro byte.
Olivier Grégoire

Gracias @ OlivierGrégoire! ƽɓ÷⁹+Hno volvería a calcular la raíz entera, pero también es 7. ɓcomienza una nueva cadena diádica con argumentos intercambiados y luego se refiere al argumento correcto de esa cadena (es decir, el resultado de ƽ). ƽɓ÷+⁹HTrabajaría aquí también.
Jonathan Allan

4

Haskell , 34 bytes

f x=last[s+x/s|s<-[1..x],s*s<=x]/2

Pruébalo en línea!

Explicación en pseudocódigo imperativo:

results=[]
foreach s in [1..x]:
 if s*s<=x:
  results.append(s+x/s)
return results[end]/2

4

Java (OpenJDK 8) , 32 bytes

n->(n/(n=(int)Math.sqrt(n))+n)/2

Pruébalo en línea!

Explicaciones

El código es equivalente a esto:

double approx_sqrt(double x) {
  double s = (int)Math.sqrt(x);  // assign the root integer to s
  return (x / s + s) / 2
}

Las matemáticas detrás:

s + (x - s²) / (2 * s)  =  (2 * s² + x - s²) / (2 * s)
                        =  (x + s²) / (2 * s)
                        =  (x + s²) / s / 2
                        =  ((x + s²) / s) / 2
                        =  (x / s + s² / s) / 2
                        =  (x / s + s) / 2

Esto no parece manejar la especificación: su salida debe redondearse al menos a la centésima más cercana
Ayb4btu

2
Bueno, se redondea a menos que la centésima más cercana, por lo que es totalmente válido.
Olivier Grégoire

Ah, ya veo, mi malentendido.
Ayb4btu



3

R, 43 bytes 29 bytes

x=scan()
(x/(s=x^.5%/%1)+s)/2

Gracias a @Giuseppe por la nueva ecuación y ayuda en el golf de 12 bytes con la solución de división entera. Al cambiar la llamada a la función para escanear, jugué otros dos bytes.

Pruébalo en línea!


1
35 bytes ; de manera más general, puede usar el campo "encabezado" de TIO y poner un f <- para asignar la función. Pero aún así, buena solución, ¡asegúrese de leer Consejos para jugar golf en R cuando tenga la oportunidad!
Giuseppe



2

JavaScript (ES7), 22 bytes

x=>(s=x**.5|0)/2+x/s/2

Realmente no necesitamos una variable intermedia, por lo que en realidad se puede reescribir como:

x=>x/(x=x**.5|0)/2+x/2

Casos de prueba


2

C, 34 bytes

¡Gracias a @Olivier Grégoire!

s;
#define f(x)(x/(s=sqrt(x))+s)/2

Funciona solo con floatentradas.

Pruébalo en línea!

C,  41   39  37 bytes

s;
#define f(x).5/(s=sqrt(x))*(x+s*s)

Pruébalo en línea!

C,  49   47   45  43 bytes

s;float f(x){return.5/(s=sqrt(x))*(x+s*s);}

Pruébalo en línea!


¡Gracias a @JungHwan Min por guardar dos bytes!


1
47 bytes ; editar: Gracias, pero dale crédito a @JungHwanMin por encontrar eso.
Stan Strum



2

AWK , 47 44 38 bytes

{s=int($1^.5);printf"%.2f",$1/2/s+s/2}

Pruébalo en línea!

NOTA: El TIO like tiene 2 bytes adicionales para \nque la salida sea más bonita. :)

Se siente como engañar un poco usar sqrt para encontrar la raíz cuadrada, así que aquí hay una versión con algunos bytes más que no lo hace.

{for(;++s*s<=$1;);s--;printf("%.3f\n",s+($1-s*s)/(2*s))}

Pruébalo en línea!


1
Bueno, se podría decir que esto es AWKward. Me mostraré afuera. editar: originalmente planeé que la pregunta evitara usar sqrt, pero hay demasiadas respuestas y tendré un agravio si la cambio para que mi idea original funcione.
Stan Strum

Los juegos de palabras 'AWK' son divertidos :)
Robert Benson

en lugar de sqrt($1)que pueda usar$1^.5
Cabbie407

Gracias @ Cabbie407 no sé por qué no pensé en eso.
Robert Benson

1
De nada. Algunas otras cosas: no necesita el \npara obtener la salida, el printf en awk no necesita paréntesis y la fórmula puede acortarse s/2+$1/s/2, lo que da como resultado {s=int($1^.5);printf"%.2f",s/2+$1/s/2}. Lo siento si este comentario parece grosero.
Cabbie407

1

Raqueta , 92 bytes

Gracias a @JungHwan Min por el consejo en la sección de comentarios

(λ(x)(let([s(integer-sqrt x)])(~r(exact->inexact(/(+ x(* s s))(* 2 s)))#:precision'(= 2))))

Pruébalo en línea!

Sin golf

(define(fun x)
  (let ([square (integer-sqrt x)])
    (~r (exact->inexact (/ (+ x (* square square)) (* 2 square)))
        #:precision'(= 2))))

1

PowerShell , 54 bytes

param($x)($x+($s=(1..$x|?{$_*$_-le$x})[-1])*$s)/(2*$s)

Pruébalo en línea! o verificar algunos casos de prueba

Toma entrada $xy luego hace exactamente lo que se solicita. La |?parte encuentra el número entero máximo que, cuando se eleva al cuadrado, es mayor -lque ela entrada $x, luego realizamos los cálculos requeridos. La salida es implícita.


Guau. Nunca he podido comprender cómo la gente juega golf en Windows Powershell
Stan Strum

@StanStrum No estás solo, jajaja. : D
AdmBorkBork

1

Casco , 9 bytes

½Ṡ§+K/(⌊√

Pruébalo en línea!

Todavía hay algo feo en esta respuesta, pero parece que no puedo encontrar una solución más corta.

Explicación

Estoy implementando un paso del algoritmo de Newton (que de hecho es equivalente al propuesto en esta pregunta)

½Ṡ§+K/(⌊√
  §+K/       A function which takes two numbers s and x, and returns s+x/s
 Ṡ           Call this function with the input as second argument and
      (⌊√    the floor of the square-root of the input as first argument
½            Halve the final result

Creo que quieres una división real, en lugar de÷
H.PWiz

@ H.PWiz whoops, sí, gracias. Eso fue un remanente de un experimento para encontrar otras soluciones
Leo

1

Pyt , 11 10 bytes

←Đ√⌊Đ↔⇹/+₂

Explicación

code                explanation                        stack
←                   get input                          [input]
 Đ                  duplicate ToS                      [input,input]
  √⌊                calculate s                        [input,s]
    Đ               duplicate ToS                      [input,s,s]
     ↔              reverse stack                      [s,s,input]
      ⇹             swap ToS and SoS                   [s,input,s]
       /            divide                             [s,input/s]
        +           add                                [s+input/s]
         ₂          halve                              [(s+input/s)/2]
                    implicit print

Acabo de ver esto y fue un buen minuto hasta que me di cuenta de que no era Pyth. Gran respuesta.
Stan Strum

Sí, es un pequeño lenguaje en el que he estado pensando durante un tiempo y que decidí hacer.
mudkip201

¿Es ToS el primero de la pila ... y si es así, qué es SoS?
Stan Strum

ToS es el primero de la pila, y SoS es el segundo en la pila
mudkip201

Bien, veré si puedo profundizar en este idioma; ¡Me gusta!
Stan Strum

1

Vía Láctea , 17 14 bytes

-3 bytes usando la fórmula de Olivier Grégoire

^^':2;g:>/+2/!

Pruébalo en línea!

Explicación

code              explanation                   stack layout

^^                clear preinitialized stack    []
  ':              push input and duplicate it   [input, input]
    2;            push 2 and swap ToS and SoS   [input, 2, input]
      g           nth root                      [input, s=floor(sqrt(input))]
       :          duplicate ToS                 [input, s, s]
        >         rotate stack right            [s, input, s]
         /        divide                        [s, input/s]
          +       add                           [s+input/s]
           2/     divide by 2                   [(s+input/s)/2]
             !    output                        => (s+input/s)/2

¿No debería ser piso en lugar de techo?
mudkip201

@ mudkip201 Actualizado, gracias
ovs

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.