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, якщо це робить код коротшим.

  • Додатковий замах на відповідь, що охоплює навіть 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
Не критикувати, але я не бачу, як рядком можна вважати 1d коло ...
xem

10
@xem Розгляньте коло як усі точки, які знаходяться на певній відстані від центру
Луїс Мендо

3
Математичні типи називали б ці "кулі" різних розмірів. Сукупність точок, що мають відстань від початку, == r- це сфера, множина точок, що мають відстань від початку, <= r- куля. Тоді це 0-бал = точка, 1-куля = відрізок, 2-куля = диск, 3-куля = куля, 4-куля, 5-куля тощо. (вказано як " n-ball = загальна назва").
Ерік Тауерс

3
"Вихід 0 для 0 розмірів" і "для n = 0, x = 1" суперечать один одному. Не могли б ви вибрати одне (або уточнити, що дозволено обидва)?
Paŭlo Ebermann

Відповіді:


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 Dennis

З повагою, ви виграли!
Рудольф Джелін

13

Математика, 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 *)

і, отже, наша оригінальна програма.


Гарна відповідь - це було швидко! Тільки для уточнення: На скільки цифр правильний вихід? Скільки розмірів можна обчислити?
Рудольф Джелін

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

@ LegionMammal978 яка формула? Я впевнений, що ви не використовуєте там функцію гамми
Ангс

@Angs n ! = Γ  (  n + 1).
LegionMammal978

2
О, !працює і для неінтегралів. Використовувати Mathematica для цього майже не схоже на обман… :)
ангс

6

JavaScript (ES6), 45 байт + додатковий swag

Рекурсивна формула з Вікіпедії повинна працювати для будь-якої кількості вимірів

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

Розв’язання Swagless, 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
₊₁ для SSSSSWWWWAAAAAAAAGGGGGGGGGGGG!
Рудольф Джелін

5

Haskell, 74 65 36 байт + додатковий swag

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-го!
Рівень річки Св.

1
@LevelRiverSt Добре, що це був перший результат, який я потрапив у Мережу ¯ \ _ (ツ) _ / ¯
Kritixi Lithos

3

MATL , 17 байт

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

Це працює лише до трьох розмірів. Введення в зворотному порядку, тобто:, 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

Ого! Ява (моя тестова мова) перемагає Scala, завдяки тривалому ?:потрійному синтаксису! Ця функція синтаксично правильна у всіх 4 мовах у заголовку, і я перевірив її за допомогою C (MinGW GCC 5.4.0) та C # (VS Ultimate 2016, C # 6.0). Я припускаю, що він також працюватиме на C ++, так що там. Оскільки ця функція в значній мірі не залежить від бібліотеки, вона повинна працювати будь-якою мовою С-подібної синтаксису.


Оце Так! Я думав, що ніколи не отримаю відповіді на Java! Зрозумів дякую! І, як бонус, він здобув кілька відповідей і отримав додатковий замах! ₊₁
Рудольф Джелін

n==0може бути скорочений до , n<1а також n==1доn<2
AlexRacer

2

Haskell, 52 байти для відступу вкладки 42 байти + додатковий swag

Редагувати: Збережено 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 дні, тому дякую за покажчики. Я помилився в стороні обережності з дужками, оскільки я не впевнений у
перевазі

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

Безгольовий (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 байтах, не є дійсним Ракеткою, як vі незв'язаним (не кажучи вже про інші параметри). Невже вам потрібно порахувати (define(v d r))також? Це піднімає вас до 82 байт…
відказав

… Але ви можете відхилити чотири байти від цього, замінивши 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

… І поголіть ще три, використовуючи a matchget (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)", оскільки це вже у формулі множення.
rnso

1

Perl, 63 байти + додатковий swag

@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. Всі подальші розміри обчислюються за такою формулою:

Recursive volume formula

Оскільки r n - коефіцієнт радіусу в кожній формулі, я залишаю його поза базовим розрахунком і застосовую лише в кінці.

2π апроксимовано в коді на 6.283.


Приємне та рекурсивне, а для показу рекурсивної формули.
Рудольф Джелін

1

Скала, 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 байт + додатковий swag!

Рекурсивний розчин із додатковим розмахом!
Повертається 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 байт + додатковий swag!

Редагувати: збережено 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

Літп , 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-мірну формулу можна переписати як

2г2πг2rгг!!
{            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.