Приблизительно мои квадраты


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 Мин

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

Должен ли он быть точным как минимум до 2 цифр?
полностью человек

@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впервые пытаюсь использовать желе, поэтому я могу ошибаться. Хотел бы я знать, как хранить ƽ, но не повторять это. Это может сохранить еще один байт.
Оливье Грегуар

Спасибо, Оливье Грегуар! ƽɓ÷⁹+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

Похоже, что это не относится к спецификации: ваш вывод должен быть округлен по крайней мере до ближайшей сотой
Ayb4btu

2
Ну, это округляется до ближайшей сотой, так что это полностью верно.
Оливье Грегуар

Ах, я понимаю, мое недоразумение.
Ayb4btu

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 Мин

-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 и поставить a 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 байта

Благодаря @ Оливье Грегуар!

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
ну, вы могли бы сказать, что это неловко. Я покажу себя. edit: первоначально я планировал избежать вопроса, используя sqrt, но ответов слишком много, и я получу правонарушение, если я изменю его, чтобы моя оригинальная идея работала.
Стэн Струм

Игра «AWK» - это весело :)
Роберт Бенсон,

вместо sqrt($1)тебя можно использовать$1^.5
Cabbie407

Спасибо @ Cabbie407, не знаю, почему я не подумал об этом.
Роберт Бенсон,

1
Пожалуйста. Некоторые другие вещи: вам не нужно \nполучать выходные данные, printf в 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, то мы выполняем необходимые вычисления. Вывод неявный.


Ух ты. Мне никогда не удавалось понять, как люди
Стэн Струм,

@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 Обновлено, спасибо
OVS

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.