N-мерные круги!


16

Напишите программу, которая принимает два числа в качестве входных данных. Первый - это число измерений - 0 для точки, 1 для прямой, 2 для круга, 3 для сферы. Второе число - это радиус объекта или, если он одномерный, само число. Выведите 0 для 0 измерений. Выходными данными являются длина / площадь / объем объекта.

Если мы позвоним по первому номеру n, второму номеру rи выводу x, мы получим это:

  • для n = 0, x = 1

  • для n = 1, x = 2 × r

  • для n = 2 x = r 2 × π

  • при п = 3, х = ( 4 / 3 ) × г 3 × π

  • и так далее ... если хочешь.

Примечания:

  • Случаи, когда одно или оба числа являются отрицательными, или когда первое число не является целым, не нужно покрывать.

  • Программа не должна читать из какого-либо файла, и единственным вводом являются эти два числа.

  • Выходные данные должны использовать только цифры (например, не «14 * pi») и должны быть с точностью не менее двух десятичных цифр.

  • Что касается n = 0, вы можете вывести 0, если это делает код короче.

  • Дополнительный swag для ответа, охватывающего даже 4 и более мерных "сфер"!

  • Это , поэтому выигрывает самый короткий ответ в байтах!

Примеры:

 1 1 -> 2

 2 3 -> 28,27

 3 1 -> 4,19

 3 4,5 -> 381,70

 1 9.379 -> 18.758

 0 48 -> 1

2
Ура! Я люблю ложные уравнения MathJax в постах!
РудольфДжелин

1
Не для критики, но я не понимаю, как линию можно рассматривать как 1-й круг ...
xem

10
@xem Рассмотрим круг, как все точки, которые находятся на заданном расстоянии от центра
Луис Мендо

3
Математические типы назвали бы эти «шары» различных размеров. Множество точек с расстоянием от начала координат == r- это сфера, множество точек с расстоянием от начала координат <= r- это шар. Тогда это 0-шар = точка, 1-шар = сегмент, 2-шар = диск, 3-шар = шар, 4-шар, 5-шар и т.д. (указан как " n-ball = общее имя").
Эрик Тауэрс

3
«Вывод 0 для 0 измерений» и «для n = 0, x = 1» противоречат друг другу. Не могли бы вы выбрать один (или уточнить, разрешены ли оба варианта)?
Пауло Эберманн,

Ответы:


7

Желе , 13 байт + дополнительная добыча

÷2µØP*÷!
ç×*@

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

Работает для любого измерения, при условии, что фиксированное значение π, полученное с помощью ØP( 3.141592653589793), является достаточно точным.

Как?

÷2µØP*÷! - Link 1: n, r
÷2       - n / 2
  µ      - monadic chain separation
   ØP    - π (3.141592653589793)
     *   - exponentiate: π^(n/2)
       ! - Pi(n/2): Gamma(n/2 + 1)
      ÷  - divide: π^(n/2) / Gamma(n/2 + 1)

ç×*@     - Main link: n, r
ç        - call last link (1) as a dyad: π^(n/2) / Gamma(n/2 + 1)
  *@     - exponentiate with reversed @rguments: r^n
 ×       - multiply: r^n * π^(n/2) / Gamma(n/2 + 1)

1
Молодцы за избиение Mathematica!
CJ Деннис

Поздравляю, вы выиграли!
РудольфДжелин

13

Mathematica, 18 байтов, до ~ 168,15 триллионов измерений

Pi^(a=.5#)/a!#2^#&

Анонимная функция. Принимает два числа в качестве входных данных и возвращает неточное число в качестве выходных данных. Работает с любым количеством измерений. Выходы 1.для n = 0. Использует формулу из тома n-шара в Википедии.

объяснение

Мы пытаемся вычислить π n / 2 / Γ ( n / 2 + 1) · R n или N[Pi^(n/2)/Gamma[n/2 + 1] R^n]в Mathematica. В нашем случае #(первый аргумент) является п и #2(второй аргумент) является R . Это оставляет нас с N[Pi^(#/2)/Gamma[#/2 + 1] #2^#] &, что можно играть в гольф следующим образом:

N[Pi^(#/2)/Gamma[#/2 + 1] #2^#] &
Pi^(.5#)/Gamma[.5# + 1] #2^# &    (* replace exact with approximate numbers*)
Pi^(.5#)/(.5#)! #2^# &            (* n! == Gamma[n + 1] *)
Pi^(a=.5#)/a! #2^# &              (* replace repeated .5# *)
Pi^(a=.5#)/a!#2^#&                (* remove whitespace *)

и, таким образом, наша оригинальная программа.


Хороший ответ - это было быстро! Просто для пояснения: на сколько цифр вывод правильный? Сколько размеров можно рассчитать?
RudolfJelin

@ RudolfL.Jelínek Выводит до 5 значащих цифр и работает для всех n до 168 146 894 169 516 для r = 1 (хотя и с меньшим количеством цифр).
LegionMammal978

@ LegionMammal978 какая формула? Я совершенно уверен, что вы не используете там гамма-функцию
Angs

@ Ответы n ! = Γ  (  n + 1).
LegionMammal978

2
Ох, !работает и для нецелых. Использование Mathematica для этого почти похоже на обман… :)
Angs

6

JavaScript (ES6), 45 байт + дополнительная замена

Рекурсивная формула из Википедии , должна работать для любого числа измерений

f=(n,r)=>n<2?n?2*r:1:f(n-2,r)*2*Math.PI*r*r/n

6

R, 75 40 38 байт (плюс дополнительный свэг)

Ну, похоже, я мог бы проиграть это, отдавая и используя гамма-функцию, а не рекурсивные функции.

function(n,r)pi^(n/2)/gamma(n/2+1)*r^n

Определяет анонимную функцию для вычисления объема nмногомерной гиперсферы радиусаr .

Несколько примеров:

1 1 -> 2

0 48 -> 1

2 3 -> 28,27433

3 4,5 -> 381,7035

7 7 -> 3891048

100 3 -> 122051813

Бесшабашное решение, 38 34 байта

На несколько байт меньше у вас может быть анонимная функция, которая работает только для измерений с 1 по 3. Возвращает numeric(0)для n=0и NAдля n>3. ( numeric(0)является числовым вектором длины 0; NAпредназначен для «недоступен».) В остальном производительность аналогична общему решению, приведенному выше.

function(n,r)c(1,pi,4/3*pi)[n]*r^n

1
₊₁ для SSSSSWWWWWAAAAAAAGGGGGGGGGG!
RudolfJelin

5

Haskell, 74 65 36 байт + дополнительная добыча

0%r=1
1%r=2*r
n%r=2*pi*r^2/n*(n-2)%r

Рекурсивная формула, работает для всех измерений, которые могут быть представлены точно как число с плавающей запятой двойной точности, но будут бесконечно циклическими для нецелых измерений. Старая версия для потомства:

n%r=(max 1$1-(-1)**n)*(2*pi)^(floor$n/2)*r**n/product[n,n-2..1.1]

Работает для всех размеров. Использует формулу из манифеста Тау . product[n,n-2..1.1]это двойной факторный хак, который не будет считать ноль дляn==2


5

JavaScript, 61 51 49 43 байта

Поддерживаются 0-3 измерения, потому что нет 4-го измерения .

Спасибо @Hedi за сохранение 7 байтов

d=(n,r)=>r**n*(n<2?n+1:Math.PI*(n<3?1:4/3))

Создает функцию d. Затем возводится rв nстепень и затем умножается на число в зависимости от nиспользования троичных операторов. Выходы 1дляn=0

Дает вывод как минимум до 2 десятичных знаков (10+ dp)

Вот фрагмент закуски!

var N = document.getElementById("n");
var R = document.getElementById("r");
N.value="3";//default
R.value="4.5";//default
d=(n,r)=>r**n*(n<2?n+1:Math.PI*(n<3?1:4/3));
var b = document.getElementById("b");
b.onclick = function() {
  var s = document.getElementById("s");
  var n = document.getElementById("n").value;
  var r = document.getElementById("r").value;
  s.textContent = d(parseFloat(n),parseFloat(r));
}
span {border:1px solid black;padding:10px;font-size:30px;}
Value of n: <input id="n" type="number"></input>
Value of r: <input id="r" type="number"></input><br>
<button id="b">Calculate!</button><br><br><br>
<span id="s">THERE IS NO 4TH DIMENSION</span>


Побей мое неопубликованное решение ... много. +1!
РудольфДжелин

6
какое тупое видео…
отображаемое имя

1
@SargeBorsch По крайней мере, это подтверждает мою точку зрения :)
Kritixi Lithos

2
@SargeBorsch Хаха, да тупое видео - 0:40 3 dimensions that behave in the same way and one that behaves in a different way- В этот момент он, кажется, говорит, что есть 4-е измерение, но нет 1-го, 2-го или 3-го!
Уровень Река St

1
@LevelRiverSt Ну, это был первый результат, который я был в сети ¯ \ _ (ツ) _ / ¯
Kritixi Lithos

3

MATL , 17 байт

3:^[2P4*P/3]*1hi)

Это работает только до 3-х измерений. Входы в обратном порядке, то есть:, rзатем n.

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

Рассмотрим r=3, в n=2качестве примера.

3:         % Push array [1 2 3]
           % STACK: [1 2 3]
^          % Take r implicitly, and raise it to [1 2 3] element-wise
           % STACK: [3 9 27]
[2P4*P/3]  % Push array [2 pi 4*pi/3]
           % STACK: [3 9 27], [2 pi 4*pi/3]
*          % Multiply element-wise
           % STACK: [6 28.2743 113.0973]
1h         % Append 1
           % STACK: [6 28.2743 113.0973, 1]
i)         % Input n and use it as modular index into the array. Display implicitly
           % STACK: 28.2743

2

Java / C / C ++ / C #, 69 67 байт + дополнительная замена!

Редактировать: 2 байта сохранены благодаря @AlexRacer

Диадическая функция - первый аргумент - число измерений, второй - радиус n-шара.

float v(int n,float r){return n<1?1:n<2?2*r:6.283f*r*r*v(n-2,r)/n;}

Рекурсивная формула для объема n-шара: V n = (2πr 2 V n-2 )n

Вау! Java (мой тестовый язык) превосходит Scala здесь, благодаря краткому ?:троичному синтаксису! Эта функция синтаксически верна на всех 4 языках в заголовке, и я протестировал ее с C (MinGW GCC 5.4.0) и C # (VS Ultimate 2016, C # 6.0). Я предполагаю, что это будет работать и в C ++, так что там. Поскольку эта функция практически не зависит от библиотеки, она должна работать на любом C-подобном языке с похожим синтаксисом.


Вот это да! Я думал, что никогда не получу ответ Java! Понял, спасибо! И, в качестве бонуса, он побил некоторые ответы и получил дополнительную награду! ₊₁
РудольфДжелин

n==0может быть сокращен до , n<1а также n==1кn<2
AlexRacer

2

Haskell, 52 байта для отступа табуляции 42 байта + дополнительная замена

Изменить: 10 байтов сохранено благодаря @WChargin

Диадическая функция карри - первый аргумент - число измерений, второй - радиус n-шара.

v 0 r=1
v 1 r=2*r
v n r=2*pi*r*r*v(n-2)r/n

Рекурсивная формула для объема n-шара: V n = (2πr 2 V n-2 )n

Сохраните это как отдельный файл сценария и запустите с GHCi, с функцией для проверки vвывода, например,show (v 3 4.5) . Я не проверял это, пожалуйста, дайте мне знать, если это не работает.

Старая программа с аппроксимацией 6.2832 для замены 2π (50 байтов с отступом табуляции):

let v 0 r=1
    v 1 r=2*r
    v n r=2*pi*r*r*(v(n-2)r)/n

Это может использоваться с GHCi в многострочном режиме (с использованием :set +mили заключением кода между :{& :}, вложения находятся в своих собственных строках. Требуется функция тестера.

Здесь вступает в игру статическая типизация с полным выводом типа программы, что позволяет Haskell работать намного лучше, чем Scala, и приближается к Groovy, но не совсем превосходит его благодаря сопоставлению с шаблоном вместо троичного, включая некоторое повторение символов.


51 при использовании макета непосредственно, 49 , если заменить 2*piна 6.2832, и 47 , если отбросить скобки вокруг рекурсивного вызова: let{v 0 r=1;v 1 r=2*r;v n r=2*pi*r*r*v(n-2)r/n}...
wchargin

… Но более типичная оценка - это предоставление в виде отдельного файла сценария; бросьте let{}и замените мои точки с запятой переводом строки, чтобы получить только 42 байта (без завершающего символа новой строки).
wchargin

@WChargin Я изучаю Haskell целых 2 дня, так что спасибо за указатели. Я допустил ошибку из-за круглых скобок, так как не уверен насчет приоритетов операторов и вызовов функций в Haskell
Tamoghna Chowdhury

2

Ракетка 69 байт (плюс дополнительная добыча)

Использует рекурсивную формулу из https://en.wikipedia.org/w/index.php?title=Volume_of_an_n-ball§ion=3#Recursions

Включая предложения @wchargin

(define(v d r)(match d[0 1][1(* 2 r)][_(/(* 2 pi r r(v(- d 2)r))d)]))

Ungolfed (v = объем, d = размеры, r = радиус):

(define(v d r)
  (match d
    [0 1]
    [1 (* 2 r)]
    [_ (/ (*  2   pi   r   r   (v (- d 2) r)  )
          d)]
    ))

Тестирование:

(v 1 1)
(v 2 3)
(v 3 1)
(v 3 4.5)
(v 1 9.379)
(v 0 48)

Выход:

2
28.274333882308138
4.1887902047863905
381.7035074111599
18.758
1

Я очень сомневаюсь, что это законно: вы используете рекурсивную функцию, не считая ее определение в счетчике байтов. То есть выражение, которое вы оцениваете как 67 байт, не является допустимым Racket, так как vявляется несвязанным (не говоря уже о других параметрах). Конечно, вам нужно посчитать, (define(v d r))а? Это приносит вам до 82 байт ...
wchargin

... но вы можете сбрить четыре байта из этого, заменив свои condвложенные ifвыражения, уменьшив до 78 байтов (define(v d r)(if(= d 0)1(if(= d 1)(* 2 r)(*(/(* 2 pi(* r r))d)(v(- d 2)r))))).
wchargin

... и побрей еще три, используя, matchчтобы получить (define(v d r)(match d[0 1][1(* 2 r)][_(*(/(* 2 pi(* r r))d)(v(- d 2)r))])).
wchargin

Спасибо за отличные предложения. Я включаю их в ответ.
rnso

@wchargin: я мог бы уменьшить еще 9 байтов, переместив (v (- d 2) r) в формулу и используя только «r r» вместо «(* rr)», поскольку он уже находится в формуле умножения.
Рнсо

1

Perl, 63 байта + дополнительная замена

@a=1..2;push@a,6.283/$_*@a[$_-2]for 2..($b=<>);say$a[$b]*<>**$b

Принимает два целых числа n и r, по одному за раз, затем выводит n-объем для заданного радиуса r n-сферы. Когда n = 0, V = 1, а когда n = 1, V = 2r. Все дальнейшие размеры рассчитываются по следующей формуле:

Рекурсивная формула объема

Так как г п является коэффициентом радиуса в каждой формуле, я оставляю его вне базового расчета и применяю его только в конце.

2π аппроксимируется в коде 6,283.


Хороший и рекурсивный, и ₊₁ для показа рекурсивной формулы.
РудольфДжелин

1

Scala, 53 байта

{import math._;(n,r)=>pow(r,n)*Seq(1,2,Pi,Pi*4/3)(n)}

Извините, для меня нет дополнительной добычи :(

Объяснение:

{                     //define a block, the type of this is the type of the last expression, which is a function
  import math._;        //import everything from math, for pow and pi
  (n,r)=>               //define a function
    pow(r,n)*             //r to the nth power multiplied by
    Seq(1,2,Pi,Pi*4/3)(n) //the nth element of a sequence of 1, 2, Pi and Pi*4/3
}

1

JavaScript (ES6), 39 байт, без разборчивости

(n,r)=>[1,r+r,a=Math.PI*r*r,a*r*4/3][n]

1

Python 3, 76 72 68 байт + дополнительная добыча!

Рекурсивное решение с дополнительной добычей!
Возвращает 0заn=0

from math import*
f=lambda n,r:n*r*2*(n<2or pi*r/n/n*(f(n-2,r)or 1))

Старый подход ( 1для n=1):

from math import*
f=lambda n,r:1*(n<1)or r*2*(n<2)or 2*pi*r*r/n*f(n-2,r)

Рекурсивная формула из Википедии .

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



1

Scala, 81 79 байт + дополнительная добыча!

Редактировать: 2 байта сохранены благодаря @AlexRacer

Диадическая функция - первый аргумент - число измерений, второй - радиус n-шара.

def v(n:Int,r:Float):Float=if n<1 1 else if n<2 2*r else 6.2832f*r*r*v(n-2,r)/n

Рекурсивная формула для объема n-шара: V n = (2πr 2 V n-2 )n

Отсутствие в Scala вывода типов для возвращаемых типов рекурсивных функций и параметров функций, а также многословный троичный синтаксис вредит здесь :(


1

Groovy, 49 47 байт + дополнительная добыча!

Редактировать: 2 байта сохранены благодаря @AlexRacer

Диадическая функция - первый аргумент - число измерений, второй - радиус n-шара.

def v(n,r){n<1?1:n<2?2*r:6.2832*r*r*v(n-2,r)/n}

Рекурсивная формула для объема n-шара: V n = (2πr 2 V n-2 )n

Динамический набор текста FTW!

Мои ответы Scala и Java используют ту же логику, но со статической типизацией, поэтому большее количество байтов из-за аннотаций типов :(. Однако Scala и Groovy позволяют опустить returnточку с запятой и, таким образом, помогает подсчет байтов, в отличие от Java / C ...


₊₁ для дополнительной SWAG!
РудольфДжелин

1

Lithp , 96 символов + дополнительная добыча

Строка разделена на 2 для удобства чтения:

#N,R::((if (< N 2) ((? (!= 0 N) (* 2 R) 1)) ((/ (* (* (* (* (f (- N 2) R) 2)
        3.1416) R) R) N))))

Думая, что мне нужно обновить парсер, чтобы он занимал меньше места. Размер кода будет сокращен, особенно в этом ((/ (* (* (* (*разделе.

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

% n-circle.lithp
(
    (def f #N,R::((if (< N 2) ((? (!= 0 N) (* 2 R) 1)) ((/ (* (* (* (* (f (- N 2) R) 2) 3.1416) R) R) N)))))
    (print (f 1 1))
    (print (f 2 3))
    (print (f 3 1))
    (print (f 3 4.5))
    (print (f 1 9.379))
    (print (f 0 48))
)

#./run.js n-circle.lithp
2
28.274333882308138
4.1887902047863905
381.7035074111598
18.758
1

Спасибо Рудольфу за то, что он сбрил несколько байтов.


1
А как насчет сокращения " 3.141592653589793" до " 3.1416", сохранения 11 байтов и при этом соответствия правилам?
РудольфДжелин

1

CJam (27 байт с дополнительным кредитом)

{1$_[2dP]*<f*\,:)-2%./1+:*}

Набор онлайн-тестов . Это анонимный блок (функция), который принимает аргументыd r в стеке и оставляет результат в стеке.

рассечение

Общая n-мерная формула может быть переписана как

2d2πd2рdd!!
{            e# Begin block: stack holds d r
  1$_[2dP]*< e#   Build a list which repeats [2 pi] d times and take the first d elements
  f*         e#   Multiply each element of the list by r
  \,:)-2%    e#   Build a list [1 ... d] and take every other element starting at the end
  ./         e#   Pointwise divide. The d/2 elements of the longer list are untouched
  1+:*       e#   Add 1 to ensure the list is non-empty and multiply its elements
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.