Meus Quadrados Aproximados

10

Inspirado neste vídeo por tecmath .

Para obter uma aproximação da raiz quadrada de qualquer número x, pegue a raiz quadrada inteira s(ou seja, o maior número inteiro que s * s ≤ x) e faça o cálculo s + (x - s^2) / (2 * s). Vamos chamar essa aproximação S(x). (Nota: isso é equivalente à aplicação de uma etapa do método Newton-Raphson).

Embora isso tenha uma peculiaridade, onde S (n ^ 2 - 1) sempre será √ (n ^ 2), mas geralmente será muito preciso. Em alguns casos maiores, isso pode ter uma precisão> 99,99%.

Entrada e saída

Você receberá um número em qualquer formato conveniente.

Exemplos

Formato: Entrada -> Saída

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

Especificações

  • Sua saída deve ser arredondada para pelo menos a centésima mais próxima (ou seja, se a resposta for 47,2851, você pode gerar 47,29)

  • Sua saída não precisa ter os seguintes zeros e um ponto decimal se a resposta for um número inteiro (por exemplo, 125,00 também pode ser emitido como 125 e 125,0)

  • Você não precisa suportar números abaixo de 1.

  • Você não precisa oferecer suporte a entradas não inteiras. (ou seja, 1,52 etc ...)

Regras

As brechas padrão são proibidas.

Este é um , pelo que a resposta mais curta em bytes vence.

Stan Strum
fonte
Sandbox
Stan Strum 26/17
3
Nota:s + (x - s^2) / (2 * s) == (x + s^2) / (2 * s)
JungHwan Min
Minhas soluções: Pyth , 25 bytes ; 14 bytes
Stan Strum 26/17
Precisa ser preciso com pelo menos 2 dígitos?
totallyhuman 27/10/17
@totallyhuman Sim. 47.2851 pode ser representado como 47.28, mas não mais impreciso.
Stan Strum

Respostas:

2

Geléia ,  8  7 bytes

-1 byte graças à fórmula matemática simplificada de Olivier Grégoire - veja a resposta em Java .

÷ƽ+ƽH

Experimente online!

Como?

÷ƽ+ƽ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
Jonathan Allan
fonte
7 bytes: ÷ƽ+ƽHPrimeira vez tentando usar o Jelly, para que eu possa estar errado. Eu gostaria de saber como armazenar ƽ, no entanto, para não repeti-lo. Isso pode salvar outro byte.
Olivier Grégoire
Obrigado @ OlivierGrégoire! ƽɓ÷⁹+Hnão recalcula a raiz inteira, mas também 7. ɓinicia uma nova cadeia diádica com argumentos trocados e depois se refere ao argumento correto dessa cadeia (ou seja, o resultado de ƽ). ƽɓ÷+⁹Htrabalharia aqui também.
Jonathan Allan
4

Haskell , 34 bytes

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

Experimente online!

Explicação no pseudocódigo imperativo:

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

Java (OpenJDK 8) , 32 bytes

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

Experimente online!

Explicações

O código é equivalente a isso:

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

A matemática por trá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
Olivier Grégoire
fonte
Isto não aparece para lidar com a especificação: Sua saída deve ser arredondado para, pelo menos, o mais próximo centésimo
Ayb4btu
2
Bem, é arredondado para mais baixo que o centésimo mais próximo, por isso é totalmente válido.
Olivier Grégoire
Ah, entendo, meu mal-entendido.
Ayb4btu
4

Python 2 , 47 ... 36 bytes

-3 bytes graças a @JungHwanMin
-1 byte graças a @HyperNeutrino
-2 bytes graças a @JonathanFrech
-3 bytes graças a @ OlivierGrégoire

def f(x):s=int(x**.5);print(x/s+s)/2

Experimente online!

ovs
fonte
-2 bytes: s+(x-s*s)/s/2para(x+s*s)/s/2
JungHwan Min 26/10
-2 bytes usando uma função
HyperNeutrino 26/10
@HyperNeutrino Eu só recebo -1 byte
ovs 26/10
Oh desculpe, eu apagados acidentalmente um personagem depois de testar e, em seguida, contou os bytes depois: P sim apenas -1
HyperNeutrino
Você não pode omitir +.0e substituir /s/2por /2./s, salvando dois bytes?
Jonathan Frech
3

R, 43 bytes 29 bytes

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

Graças a @ Giuseppe pela nova equação e ajuda no golfe de 12 bytes com a solução de divisão inteira. Ao trocar a chamada de função para a verificação, joguei mais alguns bytes.

Experimente online!

Marca
fonte
11
35 bytes ; de maneira mais geral, você pode usar o campo "header" do TIO e colocar a f <- para atribuir a função. Mas, ainda assim, boa solução, leia Dicas para jogar golfe no R quando tiver chance!
Giuseppe
2

JavaScript (ES7), 22 bytes

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

Nós realmente não precisamos de uma variável intermediária, portanto, isso pode ser reescrito como:

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

Casos de teste

Arnauld
fonte
2

C, 34 bytes

Obrigado a @Olivier Grégoire!

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

Funciona apenas com float entradas.

Experimente online!

C,  41   39  37 bytes

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

Experimente online!

C,  49   47   45  43 bytes

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

Experimente online!


Obrigado a @JungHwan Min por salvar dois bytes!

Steadybox
fonte
11
47 bytes ; edit: Obrigado, mas credite @JungHwanMin por encontrar isso.
Stan Strum
34 bytes
Olivier Grégoire
2

Haskell , 40 bytes

Outro bytes a poeira, graças a H.PWiz.

f n|s<-realToFrac$floor$sqrt n=s/2+n/s/2

Experimente online!

totalmente humano
fonte
2

AWK , 47 44 38 bytes

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

Experimente online!

NOTA: O TIO like possui 2 bytes extras para \ntornar a saída mais bonita. :)

Parece um pouco trapaceiro usar o sqrt para encontrar a raiz quadrada, então aqui está uma versão com mais alguns bytes que não.

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

Experimente online!

Robert Benson
fonte
11
bem, você poderia dizer que isso é estranho. Eu vou me mostrar. edit: originalmente eu planejava que a pergunta evitasse o sqrt, mas há muitas respostas e eu serei prejudicado se eu mudar, para que minha ideia original funcione.
Stan Strum
Trocadilhos 'awk' são divertidos :)
Robert Benson
em vez de sqrt($1)você pode usar$1^.5
Cabbie407
Obrigado @ Cabbie407 não sei por que não pensei nisso.
Robert Benson
11
De nada. Algumas outras coisas: você não precisa \nobter a saída, o printf no awk não precisa de parênteses e a fórmula pode ser reduzida s/2+$1/s/2, o que resulta em {s=int($1^.5);printf"%.2f",s/2+$1/s/2}. Desculpe se este comentário parece rude.
Cabbie407
1

Raquete , 92 bytes

Obrigado a @JungHwan Min pela dica na seção de comentários

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

Experimente online!

Ungolfed

(define(fun x)
  (let ([square (integer-sqrt x)])
    (~r (exact->inexact (/ (+ x (* square square)) (* 2 square)))
        #:precision'(= 2))))
Rodrigo Ruiz Murguía
fonte
1

PowerShell , 54 bytes

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

Experimente online!ou Verifique alguns casos de teste

Recebe entrada $xe, em seguida, faz exatamente o que é solicitado. A |?parte encontra o máximo inteiro que, quando quadrados, é -less-que-ou- equa para a entrada $x, em seguida, realizamos os cálculos necessários. A saída está implícita.

AdmBorkBork
fonte
Uau. Eu nunca fui capaz de entender como as pessoas jogam golfe no Windows Powershell
Stan Strum 26/17
@ StanStrum Você não está sozinho, lol. : D
AdmBorkBork 26/17
1

Casca , 9 bytes

½Ṡ§+K/(⌊√

Experimente online!

Ainda há algo feio nessa resposta, mas não consigo encontrar uma solução mais curta.

Explicação

Estou implementando uma etapa do algoritmo de Newton (que é de fato equivalente à proposta nesta pergunta)

½Ṡ§+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
Leo
fonte
Eu acho que você quer divisão real, ao invés de÷
H.PWiz
@ H.PWiz grita, sim, obrigado. Isso foi o que restou de um experimento para encontrar outras soluções
Leo
1

Pyt , 11 10 bytes

←Đ√⌊Đ↔⇹/+₂

Explicação

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
mudkip201
fonte
Só vi isso e foi um bom minuto até eu perceber que não é Pyth. Ótima resposta.
precisa
Sim, é um pouco da linguagem em que estou pensando há um tempo e decidi realmente fazer.
mudkip201
Os ToS estão no topo da pilha ... e se sim, o que é SoS?
precisa
TOS está no topo da pilha, e SoS é o segundo na pilha
mudkip201
Bom, vou ver se consigo me aprofundar nesse idioma; Eu gosto disso!
precisa
1

Via Láctea , 17 14 bytes

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

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

Experimente online!

Explicação

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
ovs
fonte
isso não deveria ser chão em vez de teto?
mudkip201
@ mudkip201 Atualizado, obrigado
ovs