Отверстие 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]

Leaderboard

Похищен из серии Мартина.

Следующий фрагмент создаст таблицу лидеров по всем задачам серии.

Чтобы убедиться, что ваши ответы отображаются, начните каждый ответ с заголовка, используя следующий шаблон уценки:

# Language Name, N bytes

где N - размер вашей заявки. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

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


1
Начальные числа положительные целые числа?
xnor

2
" оба aилиb " - ну, какой? Оба или один?
Дверная ручка

@ Doorknob -_- Это оба.
Maltysen

1
@xнор нет. Посмотрите на последний тест-кейс.
Maltysen

5
Создание этой части серии вызывает некую печальную ситуацию. Это так просто, что все решения будут выглядеть очень похоже. И публикация подобных решений на языках, которые уже использовались, обычно не одобряется. Я написал свое решение примерно за 2 минуты, но оно на языке, который уже использовался, и такой же длины. Если я буду следовать общепринятому этикету, я не смогу участвовать в серии.
Рето Коради

Ответы:



9

Дьялог АПЛ , 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]).
Адам

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

С ++, 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.

В порядке, в настоящее время необходимо заключить определение в лямбду:

  {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.

Попробуйте онлайн

Ungolfed && Объяснение

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

Matlab, 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 ах, не видел твоего поста, мой плохой, я бы просто предложил это в комментариях. И да, отследить все изменяющиеся вещи - это небольшая борьба: P
FryAmTheEggman

2

Минколанг 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

Питон 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)

К моему огорчению, рекурсивная функция (а-ля ответы JavaScript и C ++) была короче простого цикла for.


2
Вы можете немного сократить это с помощью lambdaи троичного if/elseоператора:f=lambda a,b,n:f((a+b)/2,(a*b)**.5,n-1)if n else(a,b)
mathmandan

Нет проблем! (Кроме того, я думаю, что это 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

Mathematica, 31 30 байт

Сохранено один байт благодаря Мартину Бюттнеру.

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

Использование:

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

Out[1]= {13.4582, 13.4582}

1

Lua, 62 байта

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

Использует аргументы командной строки from, ...чтобы назначить n, aи bотличный трюк, который я недавно узнал о Lua.


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))

Довольно прямой итерационный алгоритм. Использование символа и множественного возврата экономит несколько байтов, но синтаксис цикла for стоит несколько.


1

Haskell, 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
Дэмиен

И определить функцию инфикс.
xnor

1

Юлия, 42 байта

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

Это рекурсивная функция, fкоторая принимает три числа и возвращает кортеж.

Ungolfed:

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
Программа должна печатать только один раз, когда она заканчивается.
lirtosiast

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
}

На самом деле я бы поменял с ... *with ... -> (\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.