Приблизні мої квадрати


10

Натхненний цим відео від tecmath .

Наближення квадратного кореня будь-якого числа xможна знайти, взявши цілий квадратний корінь s(тобто найбільше ціле число таке s * s ≤ x), а потім обчисливши s + (x - s^2) / (2 * s). Назвемо це наближення S(x). (Примітка. Це еквівалентно застосуванню одного кроку методу Ньютона-Рафсона).

Хоча в цьому є химерність, де S (n ^ 2 - 1) завжди буде √ (n ^ 2), але загалом це буде дуже точно. У деяких великих випадках це може мати точність> 99,99%.

Вхід і вихід

Ви візьмете один номер у будь-якому зручному форматі.

Приклади

Формат: Введення -> Вихід

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

Технічні умови

  • Вихід має бути округлений принаймні до найближчої сотої (тобто якщо відповідь - 47.2851, ви можете вивести 47.29)

  • У вашому висновку не повинно бути наступних нулів і десяткових знаків, якщо відповідь є цілим числом (тобто 125,00 може бути виведено як 125, так і 125,0)

  • Вам не потрібно підтримувати будь-які цифри нижче 1.

  • Вам не доведеться підтримувати нецілі вводи. (тобто 1,52 і т.д. ...)

Правила

Стандартні лазівки заборонені.

Це , тому найкоротша відповідь у байтах виграє.



3
Примітка:s + (x - s^2) / (2 * s) == (x + s^2) / (2 * s)
JungHwan Min

Мої рішення: Pyth , 25 байт ; 14 байт
Стен Струм

Чи потрібно бути точним принаймні двома цифрами?
абсолютнолюдсько

@totallyhuman Так. 47.2851 можна представити як 47.28, але не більше неточно.
Стен Струм

Відповіді:


2

Желе ,  8  7 байт

-1 байт завдяки спрощеній математичній формулі Олів'є Грегоара - дивіться їх відповідь на Java .

÷ƽ+ƽH

Спробуйте в Інтернеті!

Як?

÷ƽ+ƽ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 байт: ÷ƽ+ƽHПерший раз, коли я намагався використовувати Jelly, щоб я помилявся. Хочеться, щоб я знав, як зберігати ƽ, щоб не повторювати. Це може зберегти ще один байт.
Олів'є Грегоар

Дякую @ OlivierGrégoire! ƽɓ÷⁹+Hне перерахував би цілий корінь, але він також 7. ɓзапускає новий діадічний ланцюг із заміненими аргументами, а потім посилається на правильний аргумент цього ланцюга (тобто результат ƽ). ƽɓ÷+⁹Hпрацювали б і тут.
Джонатан Аллан


4

Java (OpenJDK 8) , 32 байти

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

Спробуйте в Інтернеті!

Пояснення

Код еквівалентний цьому:

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

Математика позаду:

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

Це, здається, не обробляє специфікацію: Ваш вихід повинен бути
округнутим

2
Ну, вона округлена до нижчої, ніж найближча сота, тож цілком справедлива.
Олів'є Грегоар

Ах, бачу, моє непорозуміння.
Айб4бту

4

Python 2 , 47 ... 36 байт

-3 байти завдяки @JungHwanMin
-1 байт завдяки @HyperNeutrino
-2 байти завдяки @JonathanFrech
-3 байти завдяки @ OlivierGrégoire

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

Спробуйте в Інтернеті!


-2 байти: s+(x-s*s)/s/2до(x+s*s)/s/2
JungHwan Min

-2 байти за допомогою функції
HyperNeutrino

@HyperNeutrino я отримую лише -1 байт
ов

Пробачте, я випадково видалив персонажа після тестування, а потім порахував байти після: P так, тільки -1
HyperNeutrino

Ви не можете опустити +.0та замінити /s/2на /2./s, заощадивши два байти?
Джонатан Фрех


3

R, 43 байти 29 байт

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

Дякуємо @Giuseppe за нове рівняння та допомогу в гольфі з 12 байтів із рішенням цілочисельного поділу. Замінивши виклик функції для сканування, я переграв ще пару байтів.

Спробуйте в Інтернеті!


1
35 байт ; більш загально, ви можете використовувати поле "заголовка" TIO і поставити а, f <- щоб призначити функцію. Але все-таки приємне рішення, обов'язково прочитайте Поради щодо гольфу в R, коли отримаєте шанс!
Джузеппе



2

JavaScript (ES7), 22 байти

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

Нам дійсно не потрібна проміжна змінна, тому це насправді може бути переписано як:

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

Тестові справи


2

C, 34 байти

Дякуємо @Olivier Grégoire!

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

Працює лише з floatвходами.

Спробуйте в Інтернеті!

C,  41   39  37 байт

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

Спробуйте в Інтернеті!

C,  49   47   45  43 байт

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

Спробуйте в Інтернеті!


Дякуємо @JungHwan Min за збереження двох байтів!


1
47 байт ; редагувати: Дякую, але вдячний @JungHwanMin за те, що знайшов це.
Стен Струм



2

AWK , 47 44 38 байт

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

Спробуйте в Інтернеті!

ПРИМІТКА. У TIO, як-от, є 2 додаткові байти, \nщоб зробити вихід кращим. :)

Схоже, трохи обдурити, щоб використовувати sqrt, щоб знайти квадратний корінь, тому ось версія з ще кількома байтами, яка цього не робить.

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

Спробуйте в Інтернеті!


1
добре, можна сказати, це AWKward. Я покажу себе. редагувати: спочатку я планував уникати питання, використовуючи sqrt, але відповідей занадто багато, і я отримаю делікт, якщо я його зміню, щоб моя оригінальна ідея спрацювала.
Стен Струм

Каламбури 'AWK' - це весело :)
Роберт Бенсон

замість sqrt($1)вас можна використовувати$1^.5
Cabbie407

Дякую @ Cabbie407 не знаю, чому я про це не думав.
Роберт Бенсон

1
Ласкаво просимо. Ще деякі речі: вам не потрібно \nотримати вихід, printf in awk не потребує дужок, а формулу можна скоротити до s/2+$1/s/2, що призводить до {s=int($1^.5);printf"%.2f",s/2+$1/s/2}. Вибачте, якщо цей коментар здається грубим.
Cabbie407


1

PowerShell , 54 байти

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

Спробуйте в Інтернеті! або Перевірте деякі тестові випадки

Бере введення, $xа потім робить саме те, що вимагається. |?Частина знаходить максимальне ціле , що, коли в квадраті, це -lESS чимось або- eякост на вхід $x, то ми виконуємо необхідні обчислення. Вихід неявний.


Ого. Я ніколи не міг зрозуміти, як люди гольфують у Windows Powershell
Стен Стром

@StanStrum Ти не один, лол. : D
AdmBorkBork

1

Лушпиння , 9 байт

½Ṡ§+K/(⌊√

Спробуйте в Інтернеті!

У цій відповіді все ще є щось потворне, але я не можу знайти коротше рішення.

Пояснення

Я реалізую один крок алгоритму Ньютона (який дійсно еквівалентний запропонованому в цьому питанні)

½Ṡ§+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

Я думаю, ви хочете фактичного поділу, а не÷
H.PWiz

@ H.PWiz отак, я, дякую. Це було результатом експерименту з пошуку інших рішень
Лев

1

Піт , 11 10 байт

←Đ√⌊Đ↔⇹/+₂

Пояснення

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

Чи ToS - топ-стек ... і якщо так, то що таке SoS?
Стен Струм

ToS - це вершина стека, а SoS є другою на стеці
mudkip201

Приємно, я побачу, чи зможу я поглибитися в цю мову; Мені це подобається!
Стен Струм

1

Чумацький Шлях , 17 14 байт

-3 байти, використовуючи формулу Олів'є Грегоара

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

Спробуйте в Інтернеті!

Пояснення

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

чи не повинен це бути підлога замість стелі?
mudkip201

@ mudkip201 Оновлено, дякую
ов

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.