Kręgi N-wymiarowe!

16

Napisz program, który przyjmuje dwie liczby jako dane wejściowe. Pierwszy to liczba wymiarów - 0 dla kropki, 1 dla linii prostej, 2 dla koła, 3 dla kuli. Druga liczba to promień obiektu lub, jeśli jest jednowymiarowy, sama liczba. Wyjście 0 dla 0 wymiarów. Dane wyjściowe to długość / powierzchnia / objętość obiektu.

Jeśli wywołamy pierwszy numer n, drugi ri wynik x, otrzymamy:

  • dla n = 0, x = 1

  • dla n = 1, x = 2 × r

  • dla n = 2, x = r 2 × π

  • dla n = 3, x = ( 4 / 3 ) x R 3 x π

  • i tak dalej ... jeśli chcesz.

Uwagi:

  • Przypadki, w których jedna lub obie liczby są ujemne lub gdy pierwsza liczba nie jest pełna, nie muszą być objęte ubezpieczeniem.

  • Program nie może czytać z żadnego pliku, a jedynymi danymi wejściowymi są te dwie liczby.

  • Dane wyjściowe powinny zawierać tylko cyfry (np. Nie „14 * pi”) i powinny mieć dokładność co najmniej dwóch cyfr dziesiętnych.

  • Jeśli chodzi o n = 0, możesz wyprowadzić 0, jeśli spowoduje to, że kod będzie krótszy.

  • Dodatkowy łup dla odpowiedzi obejmującej nawet 4 i bardziej wymiarowe „kule”!

  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach!

Przykłady:

 1 1 -> 2

 2 3 -> 28,27

 3 1 -> 4,19

 3 4,5 -> 381,70

 1 9.379 -> 18.758

 0 48 -> 1
RudolfJelin
źródło
2
Tak! Uwielbiam fałszywe równania MathJax w postach!
RudolfJelin,
1
Nie do krytyki, ale nie rozumiem, jak linię można uznać za okrąg 1d ...
xem
10
@xem Rozważ okrąg jako wszystkie punkty znajdujące się w określonej odległości od centrum
Luis Mendo,
3
Typy matematyczne nazywają te „kulki” o różnych wymiarach. Zbiór punktów z odległością od początku == rjest kulą, zbiór punktów z odległością od początku <= rjest kulą. Są to 0-piłka = punkt, 1-piłka = odcinek, 2-piłka = dysk, 3-piłka = piłka, 4-piłka, 5-piłka itd. (wymienione jako „ n-ball = nazwa zwyczajowa”).
Eric Towers,
3
„Wyjście 0 dla 0 wymiarów” i „dla n = 0, x = 1” są ze sobą sprzeczne. Czy możesz wybrać jeden (lub wyjaśnić, że oba są dozwolone)?
Paŭlo Ebermann

Odpowiedzi:

7

Galaretka , 13 bajtów + dodatkowy swag

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

Wypróbuj online!

Działa dla każdego wymiaru, o ile stała wartość π uzyskana przez ØP( 3.141592653589793) jest wystarczająco dokładna.

W jaki sposób?

÷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)
Jonathan Allan
źródło
1
Gratulacje dla pokonania Mathematiki!
CJ Dennis,
Gratulacje, wygrałeś!
RudolfJelin,
13

Mathematica, 18 bajtów, do ~ 168,15 bilionów wymiarów

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

Funkcja anonimowa. Pobiera dwie liczby jako dane wejściowe i zwraca niedokładną liczbę jako dane wyjściowe. Działa z dowolną liczbą wymiarów. Dane wyjściowe 1.dla n = 0. Używa wzoru z objętości n-piłki na Wikipedii.

Wyjaśnienie

Próbujemy obliczyć π n / 2 / Γ ( n / 2 + 1) · R n lub N[Pi^(n/2)/Gamma[n/2 + 1] R^n]w Mathematica. W naszym przypadku, #(pierwszy argument) jest n i #2(drugi argument) jest R . Pozostaje nam to N[Pi^(#/2)/Gamma[#/2 + 1] #2^#] &, które można zagrać w golfa w następujący sposób:

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

a zatem nasz oryginalny program.

LegionMammal978
źródło
Dobra odpowiedź - to było szybkie! Tylko dla wyjaśnienia: do ilu cyfr wynik jest poprawny? Ile wymiarów można obliczyć?
RudolfJelin,
@ RudolfL.Jelínek Wyprowadza do około 5 cyfr znaczących i działa dla wszystkich n do 168 146 864 165 516 dla r = 1 (choć z mniejszymi liczbami).
LegionMammal978
@ LegionMammal978 która formuła? Jestem pewien, że nie używasz tam funkcji gamma
2016 Angs
@Angs n ! = Γ  (  n + 1).
LegionMammal978,
2
Och, !działa również na nie-całki. Używanie do tego Mathematiki to prawie oszustwo… :)
Angs
6

JavaScript (ES6), 45 bajtów + dodatkowy swag

Formuła rekurencyjna z wikipedii , powinna działać dla dowolnej liczby wymiarów

f=(n,r)=>n<2?n?2*r:1:f(n-2,r)*2*Math.PI*r*r/n
edc65
źródło
6

R, 75 40 38 bajtów (plus dodatkowy swag)

Wygląda na to, że mógłbym pograć w golfa, poddając się i używając funkcji gamma zamiast funkcji rekurencyjnych.

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

Definiuje anonimową funkcję do obliczania objętości ndwuwymiarowej hipersfery o promieniu r.

Kilka przykładów:

1 1 -> 2

0 48 -> 1

2 3 -> 28,277433

3 4,5 -> 381,7035

7 7 -> 3891048

100 3 -> 122051813

Rozwiązanie Swagless, 38 34 bajtów

Za kilka bajtów mniej możesz mieć anonimową funkcję, która działa tylko dla wymiarów od 1 do 3. Zwraca numeric(0)dla n=0i NAdla n>3. ( numeric(0)jest wektorem numerycznym o długości 0; NAdotyczy „niedostępnego”.) Wydajność jest poza tym identyczna z ogólnym rozwiązaniem powyżej.

function(n,r)c(1,pi,4/3*pi)[n]*r^n
rturnbull
źródło
1
₊₁ dla SSSSSWWWWWAAAAAAAGGGGGGGGGG!
RudolfJelin,
5

Haskell, 74 65 36 bajtów + dodatkowy swag

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

Formuła rekurencyjna działa dla wszystkich wymiarów, które mogą być przedstawione dokładnie jako liczba zmiennoprzecinkowa podwójnej precyzji, ale zapętla się nieskończenie dla wymiarów niezintegrowanych. Stara wersja dla potomności:

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

Działa dla wszystkich wymiarów. Wykorzystuje formułę z manifestu tau . product[n,n-2..1.1]jest podwójnym hackiem silnym, dla którego nie będzie liczone zeron==2

Angs
źródło
5

JavaScript, 61 51 49 43 bajtów

Obsługiwane są wymiary 0-3, ponieważ nie ma czwartego wymiaru .

Dzięki @Hedi za oszczędność 7 bajtów

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

Tworzy funkcję d. Następnie podnosi rdo npotęgi, a następnie mnoży ją przez liczbę zależną od nużycia operatorów trójskładnikowych. Wyjścia 1dlan=0

Daje wynik do co najmniej 2 miejsc po przecinku (10+ dp)

Oto fragment przekąski!

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>

Kritixi Lithos
źródło
Pokonałem moje niepublikowane rozwiązanie przez ... o wiele. +1!
RudolfJelin
6
co za głupi film…
Wyświetl nazwę
1
@SargeBorsch Przynajmniej to potwierdza mój punkt :)
Kritixi Lithos
2
@SargeBorsch Haha, głupi film - 0:40 3 dimensions that behave in the same way and one that behaves in a different way- W tym momencie zdaje się mówić, że istnieje czwarty wymiar, ale nie ma 1, 2 lub 3!
Level River St
1
@LevelRiverSt Cóż, to był pierwszy wynik, który pojawił się w Internecie ¯ \ _ (ツ) _ / ¯
Kritixi Lithos
3

MATL , 17 bajtów

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

Działa to tylko do 3 wymiarów. Wejścia są w odwrotnej kolejności, to znaczy:, ra następnie n.

Wypróbuj online!

Rozważmy r=3, n=2jako przykład.

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
Luis Mendo
źródło
2

Java / C / C ++ / C #, 69 67 bajtów + dodatkowy swag!

Edycja: Zapisano 2 bajty dzięki @AlexRacer

Funkcja dyadyczna - pierwszy argument to liczba wymiarów, drugi to promień n-kuli.

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

Wzór rekurencyjny dla objętości kuli n: V n = (2πr 2 V n-2 ) n

Zaraz! Java (mój język testowy) bije tutaj Scalę dzięki ?:składni potrójnej trójki! Ta funkcja jest poprawna pod względem składniowym we wszystkich 4 językach w nagłówku i przetestowałem ją z C (MinGW GCC 5.4.0) i C # (VS Ultimate 2016, C # 6.0). Zakładam, że będzie działać również w C ++, więc tam. Ponieważ ta funkcja jest w dużej mierze niezależna od biblioteki, powinna działać w dowolnym języku podobnym do C o podobnej składni.

Tamoghna Chowdhury
źródło
Łał! Myślałem, że nigdy nie dostanę odpowiedzi w języku Java! Mam to, dzieki! A jako bonus pobił kilka odpowiedzi i zyskał dodatkowy łup! ₊₁
RudolfJelin,
n==0można skrócić, n<1a także n==1don<2
AlexRacer
2

Haskell, 52 bajty na wcięcie tabulatora 42 bajty + dodatkowy swag

Edycja: Zapisano 10 bajtów dzięki @WChargin

Dyadyczna funkcja curry - pierwszy argument to liczba wymiarów, drugi to promień n-kuli.

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

Wzór rekurencyjny dla objętości kuli n: V n = (2πr 2 V n-2 ) n

Zapisz to jako osobny plik skryptu i uruchom z GHCi, z funkcją testowania vdanych wyjściowych, np.show (v 3 4.5) . Nie testowałem tego, proszę dać mi znać, jeśli to nie działa.

Stary program z przybliżeniem 6,2832 dla zastąpienia 2π (50 bajtów z wcięciem tab):

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

Można tego używać z GHCi w trybie wielowierszowym (używając :set +mlub zamykając kod między :{& :}, a obudowy są na swoich liniach. Wymagana funkcja testera.

W grę wchodzi wpisywanie statyczne z wnioskowaniem typu pełnego programu, dzięki czemu Haskell radzi sobie znacznie lepiej niż Scala i zbliża się do Groovy, ale nie do końca pokonuje go dzięki dopasowaniu wzorców zamiast trójki, co wymaga powtórzenia postaci.

Tamoghna Chowdhury
źródło
51 w przypadku korzystania bezpośrednio układ, 49 jeśli podstawić 2*piza 6.2832, a 47 jeśli spadek nawiasy wokół rekurencyjnego wywołania: let{v 0 r=1;v 1 r=2*r;v n r=2*pi*r*r*v(n-2)r/n}...
wchargin
… Ale bardziej typową punktacją jest przesłanie jako osobny plik skryptu; upuść let{}i zamień moje średniki na linie, aby uzyskać tylko 42 bajty (bez końcowego znaku nowej linii).
wchargin
@WChargin Uczyłem się Haskell przez całe 2 dni, więc dziękuję za wskazówki. Popełniłem błąd po stronie nawiasów, ponieważ nie jestem pewien pierwszeństwa wywołania funkcji operator vs funkcja w Haskell
Tamoghna Chowdhury,
2

Rakieta 69 bajtów (plus dodatkowy swag)

Wykorzystuje rekurencyjną formułę z https://en.wikipedia.org/w/index.php?title=Volume_of_an_n-ball§ion=3#Recursions

W tym sugestie @wchargin

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

Nie golfowane (v = objętość, d = wymiary, r = promień):

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

Testowanie:

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

Wynik:

2
28.274333882308138
4.1887902047863905
381.7035074111599
18.758
1
rnso
źródło
Bardzo wątpię, czy jest to uzasadnione: używasz funkcji rekurencyjnej bez liczenia jej definicji w liczbie bajtów. Oznacza to, że wyrażenie, które oceniasz jako 67 bajtów, nie jest poprawne Rakieta, ponieważ vjest niezwiązane (nie wspominając o innych parametrach). Na pewno też musisz liczyć (define(v d r))? Daje to do 82 bajtów…
wchargin
… Ale możesz zmniejszyć cztery bajty, zastępując condje ifwyrażeniami zagnieżdżonymi , co prowadzi do 78 bajtów (define(v d r)(if(= d 0)1(if(= d 1)(* 2 r)(*(/(* 2 pi(* r r))d)(v(- d 2)r))))).
wchargin
… I ogol jeszcze trzy, używając „ matchget” (define(v d r)(match d[0 1][1(* 2 r)][_(*(/(* 2 pi(* r r))d)(v(- d 2)r))])).
wchargin
Dzięki za świetne sugestie. Uwzględniam je w odpowiedzi.
rnso
@wchargin: Mógłbym zmniejszyć jeszcze 9 bajtów, zmieniając położenie (v (- d 2) r) w formule i używając tylko „r r” zamiast „(* rr)”, ponieważ jest już w formule mnożenia.
rnso
1

Perl, 63 bajty + dodatkowy swag

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

Akceptuje dwie liczby całkowite n i r, po jednym na raz, a następnie wyprowadza objętość n dla danego promienia r kuli n. Gdy n = 0, V = 1, a gdy n = 1, V = 2r. Wszystkie dalsze wymiary są obliczane według następującego wzoru:

Recursive volume formula

Ponieważ r n jest czynnikiem promienia w każdym wzorze, zostawiam go z podstawy obliczania i tylko stosuje się go na końcu.

2π jest przybliżone w kodzie przez 6,283.

Gabriel Benamy
źródło
Ładne i rekurencyjne oraz ₊₁ za pokazanie rekurencyjnej formuły.
RudolfJelin
1

Scala, 53 bajty

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

Przepraszam, nie ma dla mnie dodatkowego łupu :(

Wyjaśnienie:

{                     //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
}
corvus_192
źródło
1

JavaScript (ES6), 39 bajtów, bez swaga

(n,r)=>[1,r+r,a=Math.PI*r*r,a*r*4/3][n]
Neil
źródło
1

Python 3, 76 72 68 bajtów + dodatkowy łup!

Rozwiązanie rekurencyjne z dodatkowym łupem!
Zwraca 0zan=0

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

Stare podejście ( 1dla 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)

Recursywna formuła z Wikipedii .

Wypróbuj online.

pajonk
źródło
1

Scala, 81 79 bajtów + dodatkowy łup!

Edycja: Zapisano 2 bajty dzięki @AlexRacer

Funkcja dyadyczna - pierwszy argument to liczba wymiarów, drugi to promień n-kuli.

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

Wzór rekurencyjny dla objętości kuli n: V n = (2πr 2 V n-2 ) n

Brak wnioskowania typu przez Scalę dla typów zwracanych funkcji rekurencyjnych i parametrów funkcji oraz pełna składnia trójskładnikowa bardzo boli tutaj :(

Tamoghna Chowdhury
źródło
1

Groovy, 49 47 bajtów + dodatkowy łup!

Edycja: Zapisano 2 bajty dzięki @AlexRacer

Funkcja dyadyczna - pierwszy argument to liczba wymiarów, drugi to promień n-kuli.

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

Wzór rekurencyjny dla objętości kuli n: V n = (2πr 2 V n-2 ) n

Dynamiczne pisanie FTW!

Moje odpowiedzi Scala i Java używają tej samej logiki, ale przy wpisywaniu statycznym, więc większa liczba bajtów dzięki adnotacjom typu :(. Jednak Scala i Groovy pozwalają mi pominąć returnśrednik i średnicę, więc pomaga to w liczeniu bajtów, w przeciwieństwie do Java / C ...

Tamoghna Chowdhury
źródło
₊₁ za dodatkowy SWAG!
RudolfJelin,
1

Lithp , 96 znaków + dodatkowy łup

Podział linii na 2 dla czytelności:

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

Myślę, że muszę zaktualizować parser, aby wymagał mniej miejsca. Rozmiar kodu zostałby ładnie zmniejszony, szczególnie w tej ((/ (* (* (* (*sekcji.

Stosowanie:

% 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

Dzięki Rudolfowi za zgolenie kilku bajtów.

Andrakis
źródło
1
Co powiesz na skrócenie „ 3.141592653589793” do „ 3.1416”, zaoszczędzenie 11 bajtów i dopasowanie do reguł?
RudolfJelin
1

CJam (27 bajtów z dodatkowym kredytem)

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

Zestaw testów online . Jest to anonimowy blok (funkcja), który pobiera argumentyd r na stos i pozostawia wynik na stosie.

Sekcja

Ogólny wzór n-wymiarowy można przepisać jako

2)re2)πre2)rrere!!
{            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
}
Peter Taylor
źródło