Отвір 1 серії AGM: Обчислити середнє арифметико-геометричне


26

Це питання надихнуло цей HNQ .

Про серію

Зараз це питання є частиною серії про метод AGM. Це перше повідомлення в серії буде про фактично обчислення AGM. Ви можете ставитися до цього, як до будь-якого іншого виклику коду для гольфу, і відповідати на нього, не турбуючись про серію взагалі. Однак існує лідери у всіх викликах.

Що таке середнє арифметико-геометричне

Арифметико-геометричне середнє з двох чисел визначаються як число , яке неодноразово приймаючи арифметичний і геометричним означає , сходиться к. Ваше завдання - знайти це число після деяких nітерацій.

Роз'яснення

  • Ви берете три номери a, b, nв будь-якому розумному форматі.
  • Для nітерацій, взяти середнє арифметичне і середнє геометричне aі bі встановити ті, aі b.
  • Для двох чисел aа b, середнє арифметичне визначається як (a + b) / 2.
  • Середнє геометричне значення визначається як √(a * b).
  • aі bповинні наближатися один до одного.
  • Потім виведіть і aі b.
  • Вам не доведеться турбуватися про неточність поплавця і подібне.
  • Це тому найкоротший код у байтах виграє!

Випробування

[0, [24, 6]] -> [24, 6]    
[1, [24, 6]] -> [15.0, 12.0]
[2, [24, 6]] -> [13.5, 13.416407864998739]
[5, [24, 6]] -> [13.458171481725616, 13.458171481725616]
[10, [100, 50]] -> [72.83955155234534, 72.83955155234534]

The next one is 1/Gauss's Constant:
[10, [1, 1.41421356237]] -> [1.198140234734168, 1.1981402347341683]

Таблиця лідерів

Вкрадено з серії Мартіна.

Наступний фрагмент створить таблицю лідерів у всіх викликах серії.

Щоб відповіді відображалися, почніть кожну відповідь із заголовка, використовуючи такий шаблон Markdown:

# Language Name, N bytes

де N - розмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

# Ruby, <s>104</s> <s>101</s> 96 bytes


1
Чи є початкові числа натуральними числами?
xnor

2
" обидва" aабоb "добре, який з них?" І те, і інше?
Дверна ручка

@Doorknob -_- Його обоє.
Мальтісен

1
@xnor ні. Подивіться на останній тестовий випадок.
Мальтісен

5
Створення цієї частини серії викликає своєрідну нещасну ситуацію. Це настільки просто, що всі рішення виглядатимуть досить схоже. І розміщення подібних рішень мовами, які вже використовувались, як правило, нахмуриться. Я написав своє рішення приблизно за 2 хвилини, але це мовою, яка вже використовувалася, і вона однакової довжини. Якщо я дотримуюся типового етикету розміщення, я не зможу брати участь у серіалі.
Рето Кораді

Відповіді:



9

Діялог APL , 22 21 15 байт

.5∘(+.×,×.*⍨)⍣⎕

Приймає ( a , b ) як правильний аргумент і вимагає n :

(

  +.× крапковий добуток 0,5 та правильний аргумент

, слідом за ним

  ×.*⍨"крапка потужності" правильного аргументу і 0,5 *

)⍣⎕ застосовано число-підказки.

* "потужність крапки" - це як точковий добуток, але використовуючи множення та потужність замість плюса та множення, як це:

      n
A ×.*⍨ B - B i A = B 1 A B 2 A
      i = 1

-3 байти завдяки ngn.


Стара версія:

{((+/÷≢),.5*⍨×/)⍣⍺⊢⍵}

Приймається nяк лівий аргумент і a bяк правий аргумент.

⊢⍵На RightArg
(... )⍣⍺перерахуйте
(+/÷≢)суму лівих часів LeftArg, поділену на підрахунок,
,а потім
.5*⍨×/квадратний корінь продукту.

Усі тестові приклади:

      f←{((.5×+/),.5*⍨×/)⍣⍺⊢⍵}
      0 1 2 5 10 10 f¨ (24 6)(24 6)(24 6)(24 6)(100 50)(1,2*.5)
┌────┬─────┬────────────────┬───────────────────────┬───────────────────────┬───────────────────────┐
│24 6│15 12│13.5 13.41640786│13.45817148 13.45817148│72.83955155 72.83955155│1.198140235 1.198140235│
└────┴─────┴────────────────┴───────────────────────┴───────────────────────┴───────────────────────┘

Це f⍣⍺⊢⍵чи подібна ідіома, яку ви професійно використовуєте?
lirtosiast

@ThomasKwa Так, див. Наприклад, Of⍣core⊢TREEна miserver.dyalog.com (натисніть велике "D" та перейдіть до рядка [266]).
Adám

7

TI-BASIC, 22 байти

Input N
For(I,1,N
{mean(Ans),√(prod(Ans
End
Ans

Робить саме те, що говорить алгоритм. Бере N із підказки, а A і B - Ansяк двоелементний список.

Якщо N дорівнює 0, For(цикл повністю пропускається.



6

MATLAB / Octave, 69 65 байт

function [a,b]=r(a,b,n)
for i=1:n;j=(a+b)/2;b=(a*b)^.5;a=j;end

1
Ви можете зробити це b=(a*b).^5безпосередньо, оскільки не повторно використовуєте bцю ітерацію та збережете 4 байти.
Brain Guider

6

Желе, не конкуруючий

9 байт Ця відповідь не є конкурентоспроможною, оскільки вона використовує функції, які відкладають завдання.

SH;P½¥ðṛ¡

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

Як це працює

SH;P½¥ðṛ¡    Input: x (vector) -- y (repetitions)

SH           Take the sum (S) of x and halve (H) the result.
   P½        Take the product (P) of x and the square root (½) of the result.
     ¥       Combine the last two instructions in a dyadic chain.
  ;          Concatenate the results to the left and to the right.
      ð      Push the preceding, variadic chain; begin a new, dyadic chain.
       ṛ     Return the right argument (y).
        ¡    Repeat the pushed chain y times.

5

Серйозно, 11 байт

,p`;π√@æk`n

Шестнадцятковий дамп:

2c70603be3fb40916b606e

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

Пояснення:

,                    Read in the list as [n,a,b]
 p                   pop list to yield: n [a,b]
  `      `n          Push a quoted function and run it n times.
   ;                 Duplicate [a,b] pair
    π√               Compute its product and square root it (GM)
      @              Swap the other copy of the pair to the top
       æ             Compute its mean.
        k            Compile the stack back into a list.

5

C ++, 108 102 100 байт

Дякую @RetoKoradi та @AlexA, що зберегли мені 6 байт.

Це є неконкурентоспроможним, оскільки C ++ не є гарною мовою для гольфу. Зробив це заради забави :)

#include<cmath>
std::string f(float a,float b,int n){return n==0?a+" "+b:f((a+b)/2,sqrt(a*b),n-1);}

Це проста функція рекурсії, дуже схожа на відповідь JS.


3
Можна позбутися пробілів після коми. Також використання floatзамість цього doubleкоротше.
Рето Коради

1
Ви також можете видалити пробіл у #includeрядку.
Олексій А.

Нічого собі, я дурний, що цього не помічаю. Спасибі!
TheCoffeeCup

Я б вважав, f(float*s)що потрібен покажчик на 3 поплавця, щоб він був у "розумному форматі". Не впевнений, чи насправді це скорочує.
nwp

4

К5, 15 байт

Дуже буквально:

{(+/x%2;%*/x)}/

Дія:

 {(+/x%2;%*/x)}/[0; 24 6]
24 6
 {(+/x%2;%*/x)}/[5; 24 6]
1.345817e1 1.345817e1

На жаль, це не працює в ОК, оскільки той перекладач не підтримує проекцію (прикріплення) прислівників. Працює в реальному k5.

В oK, на даний момент необхідно визначити визначення в лямбда:

  {x{(+/x%2;%*/x)}/y}[5; 24 6]
13.4582 13.4582

4

J, 18 13 байт

-:@+/,%:@*/^:

Використання:

   agm =: -:@+/,%:@*/^:
   5 agm 24 6
13.4582 13.4582

Нічого, це працює. Сполучення дивні. Я б очікував, що цей вираз буде прислівником (яким він може бути), але якщо він подається з аргументами, це також функція.
випадкова

3

Japt , 24 байти 25 33

Збережено 9 7 байт завдяки @ETHproductions

Uo r@[VW]=[V+W /2(V*W q]

Користується руйнуванням ES6.

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

Без пояснення та пояснення

Uo r@[VW]=[V+W /2(V*W q]

       // Implicit: U: 1st input, V: 2nd input, W: 3rd input
Uo     // Range from 0 to 1st input
r@     // Loop over range
  [V,W]=    // Set 2nd and 3rd input to...
   [V+W /2,   // Add 2nd and 3rd inputs, divide by 2
   (V*W q]    // Multiple 2nd and 3rd inputs, find square root
            // Set's to the above respectively 
       // Implicit: return [V,W]

Uoгенерує діапазон чисел від 0 до U, так що Uo m@[V,W]=[V+W /2,(V*W q]має працювати. (Неперевірено)
ETHproductions

О, і вам не знадобиться комами взагалі. :)
ETHproductions

@ETHproductions ще раз дякую! :)
Downgoat

О, дорогий, це не вдається для будь-якого Uіншого, крім 1, виводячи кожну петлю, як вона йде. Ось який працює належним чином:Uo £[VW]=[V+W /2(V*W q]};[VW]
ETHproductions

@ETHproductions спасибі, але використання, rздавалося, також працює
Downgoat

3

Матлаб, 54 байти

function x=f(x,n)
for k=1:n
x=[mean(x) prod(x)^.5];end

Приклад:

>> f([24 6], 2)
ans =
  13.500000000000000  13.416407864998739

3

Піта, 12

u,.OG@*FG2EQ

Тестовий сюїт

Пояснення

u,.OG@*FG2EQ    ##  implicit: Q = eval(input())
u         EQ    ##  reduce eval(input()) times, starting with Q
                ##  the reduce lambda has G as the previous value and H as the next
  .OG           ##  arithmetic mean of last pair
     @*FG2      ##  geometric mean of last pair, uses *F to get the product of the list
                ##  and @...2 to get the square root of that
 ,              ##  join the two means into a two element list

Забувши про @та .O, але я навіть не знаю , нову мету E.
orlp

@orlp ах, не бачив вашої публікації, моє погано, я б просто запропонував це у коментарях. І так, слідкувати за всіма змінами - це
суть

2

Minkolang v0.14, 23 байти

Спробуйте тут !

$n[$d+2$:r*1Mi2%?!r]$N.
$n                      C get all input C
  [                ]    C pop N; repeat inner N times C
   $d                   C duplicate stack [1,2] => [1,2,1,2] C
     +                  C add top two elements C
      2$:               C divide by two C
         r              C reverse stack (get the other two) C
          *             C multiply them together C
           1M           C take square root C
             i2%?!r     C reverse the stack if an odd step number C
                    $N  C output stack
           1M           C take square root C
             i          C get step in for loop C


2

Python 3, 65 55 байт

Завдяки mathmandan за вказівку коротшої версії за допомогою lambdaоператора.

f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)

Моя оригінальна версія:

def f(a,b,n):
 if n:f((a+b)/2,(a*b)**.5,n-1)
 else:print(a,b)

На превеликий жаль, рекурсивна функція (a la JavaScript і C ++ відповіді) була коротшою, ніж проста для циклу.


2
Ви можете трохи вкоротити це за допомогою lambdaі if/elsef=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
термінального

Без проблем! (Також, я думаю, це 53 байти.)
mathmandan

Збережений мною файл .py вказаний як 55 байт. Чи є кращий спосіб розрахувати розмір програми?
Джек Браунштейн

Іноді люди на цьому веб-сайті копіюють і вставляють свій код у mothereff.in/byte-counter . Якщо вам цікаво розбіжність, я б припустив, що Windows вставляє непотрібний символ нового рядка в кінці вашого файлу .py (а Windows вважає новий рядок 2 байти замість 1). Так чи інакше, вам не доведеться рахувати цей останній рядок як частину вашого коду для оцінки балів. Якщо ви публікуєте багаторядковий запис, вам слід нарахувати 1 для кожного нового рядка, а не 2, і не включати жодного нового рядка в кінці останнього рядка коду. (Наскільки я все-таки розумію правила!)
mathmandan

2

R, 66 байт

f=function(a,b,n){while(n){x=(a+b)/2;b=(a*b)^.5;n=n-1;a=x};c(a,b)}

Використання:

> f(24,6,0)
[1] 24  6
> f(24,6,1)
[1] 15 12
> f(24,6,2)
[1] 13.50000 13.41641
> f(24,6,3)
[1] 13.45820 13.45814
> f(24,6,4)
[1] 13.45817 13.45817
> f(100,50,10)
[1] 72.83955 72.83955
> f(1,1.41421356237,10)
[1] 1.19814 1.19814

Ви можете видалити ім'я функції, щоб зберегти 2 байти.
Олексій А.

2

Математика, 31 30 байт

Збережено один байт завдяки Мартіну Бюттнеру.

{+##/2,(1##)^.5}&@@#&~Nest~##&

Використання:

In[1]:= {+##/2,(1##)^.5}&@@#&~Nest~##&[{24, 6}, 5]

Out[1]= {13.4582, 13.4582}

1

Луа, 62 байти

n,a,b=...for i=1,n do a,b=(a+b)/2,math.sqrt(a*b)end print(a,b)

Використовує аргументи командного рядка від, ...щоб призначити n, aі b, чудовий трюк, який я дізнався про Луа нещодавно.


1

Haskell, 40 байт

(!!).iterate(\(a,b)->((a+b)/2,sqrt$a*b))

Анонімна функція. Приклад використання:

>> let f=(!!).iterate(\(a,b)->((a+b)/2,sqrt$a*b)) in f (1.0,1.41421356237) 10
(1.198140234734168,1.1981402347341683)

Функція лямбда (\(a,b)->((a+b)/2,sqrt$a*b))приймає середнє арифметичне та геометричне на кортежі. Це повторюється, починаючи з першого вводу (кортеж), а потім (!!)індексує другий вхід, щоб вказати кількість ітерацій.


1

Perl, 60 байт

perl -ape'F=($F[0]/2+$F[1]/2,sqrt$F[0]*$F[1])for 1..shift@F;$_="@F"'

NB: Згідно з цією мета-публікацією , я вважаю, що я отримав правильну оцінку. Дійсний код (між окремими лапками) - 58 символів, потім я додав +2 для aта pпрапори, оскільки це відмінність від найкоротшого виклику,perl -e'...'

Неясні скарги

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

На початку я заплутався з тим, що використовую $\як другий термін з деяким успіхом, але вищезазначений підхід у кінцевому підсумку був на 2 байти коротшим, навіть із додатковимap прапорами. Аналогічно, уникнути явного $_призначення було б непогано, але цикл робить це важким.

Ці shift@Fпомилки мені теж; якщо я цього не роблю, хоча (або використовую)@F=(0,...,...) натомість, що не зберігає жодних байтів), існує помилка окремо за @Fпризначенням.

Приклад

echo 5 24 6 | perl -ape'F=($F[0]/2+$F[1]/2,sqrt$F[0]*$F[1])for 1..shift@F;$_="@F"'

Виходи

13.4581714817256 13.4581714817256

1

Джулія, 49 байт

(a,b,n)->(for i=1:n;a,b=(a+b)/2,√(a*b)end;(a,b))

Досить прямий ітеративний алгоритм. Використання символу та багаторазового повернення економить кілька байт, але синтаксис циклу коштує кілька.


1

Хаскелл, 47 байт

f a b 0=(a,b)
f a b n=f((a+b)/2)(sqrt$a*b)(n-1)

Ви можете зберегти кілька байт, приймаючи ab як пару в f: fx 0 = x; f (a, b) n = f ((a + b) / 2, sqrt $ a * b) $ n-1
Damien

І визначте функцію infix.
xnor

1

Джулія, 42 байти

f(a,b,n)=n>0?f((a+b)/2,(a*b)^.5,n-1):(a,b)

Це рекурсивна функція f яка приймає три числа і повертає кортеж.

Безголівки:

function f(a::Real, b::Real, n::Integer)
    if n > 0
        # Recurse on the arithmetic and geometric means, decrementing n
        return f((a + b) / 2, sqrt(a * b), n - 1)
    else
        # Return the pair
        return (a, b)
    end
end


1

Python 2, 62 61 62 байт

def f(a,b,n):
 while n:a,b=(a+b)/2.,(a*b)**.5;n-=1
 print a,b

3
Програма повинна надрукувати лише один раз, коли вона закінчується.
ліртосіаст

1
Моє непорозуміння. Виправлено.
wflynny

1

CJam, 16 байт

{{_:+2/\:*mq]}*}

Це анонімна функція. Вхід - це список з двома значеннями (як подвійне) з подальшим підрахунком ітерації. Спробуйте його в режимі он-лайн з кодом вводу-виводу для тестування.

Я зазвичай не розміщував це, оскільки @PeterTaylor розмістив однаково довгий відповідь CJam, перш ніж я побачив це питання. Але оскільки це рекламується як початок серіалу, я хотів залишати свої варіанти відкритими на випадок, коли серія буде цікавою.

Хоча довжина така сама, як і відповідь Петра, код - ні. Я вибрав інший формат введення, взявши два значення у списку, де Пітер використовував окремі значення. Тож, хоча і в цьому форматі вводу не так багато, код виглядає зовсім інакше.

{     Start loop over number of iterations.
  _     Copy the current pair of values.
  :+    Reduce pair with + operator.
  2/    Divide by 2.
  \     Swap second copy of pair to top.
  :*    Reduce pair with * operator.
  mq    Calculate square root.
  ]     Wrap the two new values in a list for next iteration.
}*    End iteration loop.

0

Perl 6 ,  53  47 байт

{(($^a,$^b),->(\a,\b){((a+b)/2,sqrt(a*b))}...*)[$^n]} # 53 bytes

використання:

# give it a name
my &code = {(($^a,$^b),->(\a,\b){((a+b)/2,sqrt(a*b))}...*)[$^n]}

say code 100,50,10;          # (72.8395515523453 72.8395515523453)
say code 1,1.41421356237,10; # (1.19814023473417 1.19814023473417)

Якщо я зміню вхід a,b,nна, (a,b),nя можу зберегти кілька байт.

{($^l,->(\a,\b){((a+b)/2,sqrt(a*b))}...*)[$^n]} # 47 bytes

використання:

my &code = {($^l,->(\a,\b){((a+b)/2,sqrt(a*b))}...*)[$^n]}

say code (100,50),10;          # (72.8395515523453 72.8395515523453)
say code (1,1.41421356237),10; # (1.19814023473417 1.19814023473417)

say code (24,6),$_ for 0,1,2,5;
# (24 6)
# (15 12)
# (13.5 13.4164078649987)
# (13.4581714817256 13.4581714817256)
{
  (
    $^l,          # first 2 element tuple
    ->            # pointy block (lambda)
      (\a,\b)     # take a single tuple, and give its 2 elements each a name
    {
      (           # create a 2 element tuple
        (a+b)/2,  # arithmetic mean
        sqrt(a*b) # geometric mean
      )
    } ... *       # create a lazy infinite sequence of tuples
  )[ $^n ]        # take the nth "tuple" from the outer sequence
}

На самом деле я б поміняти ... *з ... -> (\a,\b) { a =~= b }, то не було б ніякої необхідності для $^nпараметра.
(не використовуйте ==замість цього =~=, або він не зупиниться)

my &code = {($^l,->(\a,\b){((a+b)/2,sqrt(a*b))}...->(\a,\b){a=~=b})[*-1]}

say code (24,6);           # (13.4581714817256 13.4581714817256)
say code (100,50);         # (72.8395515523453 72.8395515523453)
say code (1,1.41421356237) # (1.19814023473417 1.19814023473417)

0

Пролог, 80 байт

Код:

p(A,B,0):-write([A,B]).
p(A,B,N):-X is(A+B)/2,Y is sqrt(A*B),M is N-1,p(X,Y,M).

Приклад:

p(100,50,10).
[72.83955155234534, 72.83955155234534]

Спробуйте його онлайн тут


0

Java, 103 96 84 байт

String f(int n,double a,double b){return n>0?f(n-1,(a+b)/2,Math.sqrt(a*b)):a+","+b;}

Перевірте всі тести.

Стара версія (96 байт):

String f(int n,double a,double b){for(;n>0;a=(a+b)/2,b=Math.sqrt((b-2*a)*b))n--;return a+","+b;}

Стара версія (103 байти):

String f(int n,double a,double b){double t;for(;n>0;t=(a+b)/2,b=Math.sqrt(a*b),a=t)n--;return a+","+b;}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.