N-dimensionale Kreise!

16

Schreiben Sie ein Programm, das zwei Zahlen als Eingabe verwendet. Die erste ist die Anzahl der Dimensionen - 0 für einen Punkt, 1 für eine gerade Linie, 2 für einen Kreis, 3 für eine Kugel. Die zweite Zahl ist der Radius des Objekts oder, wenn es eindimensional ist, die Zahl selbst. 0 für 0 Dimensionen ausgeben. Die Ausgabe ist die Länge / Fläche / das Volumen des Objekts.

Wenn wir die erste n, die zweite rund die Ausgabe aufrufen x, erhalten wir Folgendes:

  • für n = 0 ist x = 1

  • für n = 1 ist x = 2 × r

  • für n = 2 ist x = r 2 × π

  • für n = 3, x = ( 4 / 3 ) × r 3 × π

  • und so weiter ... wenn du willst.

Anmerkungen:

  • Fälle, in denen eine oder beide Zahlen negativ sind oder die erste Zahl nicht ganz ist, müssen nicht behandelt werden.

  • Das Programm darf keine Daten aus einer Datei lesen. Die einzige Eingabe sind diese beiden Zahlen.

  • Die Ausgabe sollte nur Ziffern verwenden (z. B. nicht "14 * pi") und auf mindestens zwei Dezimalstellen genau sein.

  • Wie für n = 0 können Sie 0 ausgeben, wenn dies den Code kürzer macht.

  • Extra Beute für eine Antwort, die sogar 4 und mehr dimensionale "Kugeln" abdeckt!

  • Es ist , also gewinnt die kürzeste Antwort in Bytes!

Beispiele:

 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
quelle
2
Yay! Ich liebe falsche MathJax-Gleichungen in Beiträgen!
RudolfJelin
1
Nicht zu kritisieren, aber ich verstehe nicht, wie eine Linie als 1d Kreis angesehen werden kann ...
xem
10
@xem Betrachten Sie einen Kreis als alle Punkte, die sich innerhalb eines bestimmten Abstands vom Zentrum befinden
Luis Mendo
3
Mathe-Typen würden diese "Bälle" mit verschiedenen Dimensionen bezeichnen. Die Menge der Punkte mit Abstand vom Ursprung == rist die Kugel, die Menge der Punkte mit Abstand vom Ursprung <= rist die Kugel. Dann sind dies 0-Ball = Punkt, 1-Ball = Segment, 2-Ball = Scheibe, 3-Ball = Ball, 4-Ball, 5-Ball usw. (aufgeführt als " n-ball = common name").
Eric Towers
3
"Ausgabe 0 für 0 Dimensionen" und "für n = 0, x = 1" widersprechen sich. Könnten Sie bitte eine auswählen (oder klarstellen, dass beide zulässig sind)?
Paŭlo Ebermann,

Antworten:

7

Jelly , 13 Bytes + extra Beute

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

Probieren Sie es online!

Funktioniert für jede Dimension, solange der feste Wert von π, den ØP( 3.141592653589793) liefert, genau genug ist.

Wie?

÷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
quelle
1
Gut gemacht, um Mathematica zu schlagen!
CJ Dennis
Herzlichen Glückwunsch, Sie haben gewonnen!
RudolfJelin,
13

Mathematica, 18 Bytes, bis zu 168,15 Billionen Dimensionen

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

Anonyme Funktion. Nimmt zwei Zahlen als Eingabe und gibt eine ungenaue Zahl als Ausgabe zurück. Funktioniert mit beliebig vielen Dimensionen. Ausgaben 1.für n = 0. Verwendet die Formel aus Volumen eines n-Balls in Wikipedia.

Erläuterung

Wir versuchen, π n / 2 / Γ ( n / 2 + 1) · R n oder N[Pi^(n/2)/Gamma[n/2 + 1] R^n]in Mathematica zu berechnen . In unserem Fall #(erstes Argument) ist n und #2(zweites Argument) ist R . Dies lässt uns mit N[Pi^(#/2)/Gamma[#/2 + 1] #2^#] &, die wie folgt gespielt werden können:

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

und damit unser ursprüngliches Programm.

LegionMammal978
quelle
Schöne Antwort - das ging schnell! Nur zur Verdeutlichung: Auf wie viele Stellen ist die Ausgabe korrekt? Wie viele Dimensionen können berechnet werden?
RudolfJelin
@ RudolfL.Jelínek Es gibt ungefähr 5 signifikante Zahlen aus, und es funktioniert für alle n bis zu 168.146.894.169.516 für r = 1 (wenn auch mit weniger Zahlen).
LegionMammal978
@ LegionMammal978 welche Formel? Ich bin mir ziemlich sicher, dass Sie die Gammafunktion dort nicht verwenden
Angs
@Angs n ! = Γ  (  n + 1).
LegionMammal978
2
Oh, !funktioniert auch für Nicht-Integrale. Mathematica dafür zu benutzen, fühlt sich fast wie Schummeln an… :)
Angs
6

JavaScript (ES6), 45 Byte + zusätzlicher Swag

Eine rekursive Formel aus Wikipedia sollte für eine beliebige Anzahl von Dimensionen funktionieren

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

R, 75 40 38 Bytes (plus zusätzliche Beute)

Nun, es sieht so aus, als könnte ich Golf spielen, indem ich die Gamma-Funktion anstelle von rekursiven Funktionen verwende.

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

Definiert eine anonyme Funktion zum Berechnen des Volumens einer neindimensionalen Hypersphäre mit Radius r.

Einige Beispiele:

1 1 -> 2

0 48 -> 1

2 3 -> 28,27433

3 4,5 -> 381,7035

7 7 -> 3891048

100 3 -> 122051813

Swagless Lösung, 38 34 Bytes

Für ein paar Bytes weniger können Sie eine anonyme Funktion haben, die nur für die Dimensionen 1 bis 3 funktioniert. Gibt numeric(0)für n=0und NAfür zurück n>3. ( numeric(0)ist ein numerischer Vektor der Länge 0; NAsteht für "nicht verfügbar".) Die Leistung ist ansonsten identisch mit der obigen allgemeinen Lösung.

function(n,r)c(1,pi,4/3*pi)[n]*r^n
rturnbull
quelle
1
₊₁ für das SSSSSWWWWWAAAAAAAGGGGGGGGGG!
RudolfJelin
5

Haskell, 74 65 36 Bytes + zusätzliche Beute

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

Rekursive Formel, funktioniert für alle Bemaßungen, die genau als Gleitkommazahl mit doppelter Genauigkeit dargestellt werden können, bei nicht ganzzahligen Bemaßungen jedoch eine Endlosschleife ausführen. Die alte Version der Nachwelt zuliebe:

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

Funktioniert für alle Dimensionen. Verwendet die Formel aus dem Tau-Manifest . product[n,n-2..1.1]ist ein doppelter faktorieller Hack, für den keine Null gezählt wirdn==2

Angs
quelle
5

JavaScript, 61 51 49 43 Bytes

0-3-Dimensionen werden unterstützt, da es keine 4. Dimension gibt .

Vielen Dank an @Hedi für das Speichern von 7 Bytes

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

Erzeugt Funktion d. Erhöht rdann die nPotenz und multipliziert sie mit einer Zahl, abhängig von der nVerwendung von ternären Operatoren. Ausgänge 1fürn=0

Gibt eine Ausgabe mit mindestens 2 Dezimalstellen (10+ dp) aus

Hier ist ein Snack-Schnipsel!

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
quelle
Schlagen Sie meine nicht veröffentlichte Lösung um ... um ein Vielfaches. +1!
RudolfJelin
6
Was für ein dummes Video ...
Sarge Borsch
1
@ SargeBorsch Zumindest beweist es meinen Standpunkt :)
Kritixi Lithos
2
@SargeBorsch Haha yup dummes Video - 0:40 3 dimensions that behave in the same way and one that behaves in a different way- An diesem Punkt scheint er zu sagen, dass es eine 4. Dimension gibt, aber keine 1., 2. oder 3.!
Level River St
1
@LevelRiverSt Nun, das war das erste Ergebnis, das ich im Web gesehen habe ¯ \ _ (ツ) _ / ¯
Kritixi Lithos
3

MATL , 17 Bytes

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

Dies funktioniert nur bis zu 3 Dimensionen. Die Eingänge sind in umgekehrter Reihenfolge, das heißt: r, dann n.

Probieren Sie es online!

Betrachten Sie r=3, n=2als Beispiel.

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
quelle
2

Java / C / C ++ / C #, 69 67 Bytes + zusätzlicher Swag!

Bearbeiten: 2 Bytes dank @AlexRacer gespeichert

Eine dyadische Funktion - das erste Argument ist die Anzahl der Dimensionen, das zweite der Radius der n-Kugel.

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

Rekursive Formel für das Volumen einer n-Kugel: V n = (2πr 2 V n-2 )n

Whoa! Java (meine Testsprache) schlägt hier Scala, dank der knappen ?:ternären Syntax! Diese Funktion ist in allen 4 Sprachen der Überschrift syntaktisch korrekt, und ich habe sie mit C (MinGW GCC 5.4.0) und C # (VS Ultimate 2016, C # 6.0) getestet. Ich gehe davon aus, dass es auch in C ++ funktioniert, also dort. Da diese Funktion weitgehend bibliotheksunabhängig ist, sollte sie in jeder C-ähnlichen Sprache mit ähnlicher Syntax funktionieren.

Tamoghna Chowdhury
quelle
Beeindruckend! Ich dachte, ich würde nie eine Java-Antwort bekommen! Danke, verstanden! Und als Bonus schlug es einige Antworten und bekam den Extra-Swag! ₊₁
RudolfJelin
n==0kann auf n<1und auch n==1aufn<2
AlexRacer
2

Haskell, 52 Bytes für Tabulatoreinzug 42 Bytes + zusätzlicher Swag

Bearbeiten: 10 Bytes dank @WChargin gespeichert

Eine dyadische Curry-Funktion - das erste Argument ist die Anzahl der Dimensionen, das zweite der Radius der n-Kugel.

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

Rekursive Formel für das Volumen einer n-Kugel: V n = (2πr 2 V n-2 )n

Speichern Sie diese als separate Skriptdatei und führen Sie sie mit GHCi aus, mit einer Funktion zum Testen der vAusgabe, z.show (v 3 4.5) . Ich habe dies nicht getestet, bitte lassen Sie mich wissen, wenn dies nicht funktioniert.

Altes Programm mit 6.2832-Approximation für 2π ersetzt (50 Bytes mit Tabulatoreinzug):

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

Dies kann mit GHCi im mehrzeiligen Modus verwendet werden (mit :set +m oder Einschließen des Codes zwischen :{& :}, wobei sich die Gehäuse in eigenen Zeilen befinden. Testerfunktion erforderlich.

Hier kommt die statische Eingabe mit vollständiger Programmtyp-Inferenz ins Spiel, die es Haskell ermöglicht, weitaus bessere Ergebnisse als Scala zu erzielen und Groovy näher zu kommen, diese jedoch dank der Musterübereinstimmung anstelle einer ternären Eingabe nicht ganz zu übertreffen, was einige Zeichenwiederholungen mit sich bringt.

Tamoghna Chowdhury
quelle
51 bei Verwendung von Layout direkt, 49 , wenn Sie ersetzen 2*pifür 6.2832und 47 , wenn Sie die Klammern um den rekursiven Aufruf fallen: let{v 0 r=1;v 1 r=2*r;v n r=2*pi*r*r*v(n-2)r/n}...
wchargin
… Aber typischer ist es, die Bewertung als separate Skriptdatei einzureichen. Löschen Sie das let{}und ersetzen Sie meine Semikolons durch Zeilenvorschübe, um nur 42 Bytes zu erhalten (ohne Zeilenvorschub).
wchargin
@WChargin Ich habe 2 Tage lang Haskell gelernt, also danke für die Hinweise. Ich irrte auf der Seite der Vorsicht mit den Klammern , wie ich vs Funktionsaufruf Vorrang in Haskell nicht sicher Operator bin
Tamoghna Chowdhury
2

Schläger 69 Bytes (plus extra Beute)

Verwendet die rekursive Formel von https://en.wikipedia.org/w/index.php?title=Volume_of_an_n-ball§ion=3#Recursions

Mit Vorschlägen von @wchargin

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

Ungolfed (v = Volumen, d = Abmessungen, r = Radius):

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

Testen:

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

Ausgabe:

2
28.274333882308138
4.1887902047863905
381.7035074111599
18.758
1
rnso
quelle
Ich bezweifle sehr, dass dies legitim ist: Sie verwenden die rekursive Funktion, ohne ihre Definition in der Byteanzahl zu zählen. Das heißt, der Ausdruck, den Sie mit 67 Byte bewerten, vist ungültig, da er ungebunden ist (ganz zu schweigen von den anderen Parametern). Sicher müssen Sie das auch zählen (define(v d r))? Dies bringt Sie auf 82 Bytes ...
wchargin
… Aber Sie können vier Bytes davon condsparen if, indem Sie Ihre durch verschachtelte Ausdrücke ersetzen , wodurch Sie auf 78 Bytes mit reduziert werden (define(v d r)(if(= d 0)1(if(= d 1)(* 2 r)(*(/(* 2 pi(* r r))d)(v(- d 2)r))))).
wchargin
... und abrasieren drei weitere durch eine Verwendung matchzu erhalten (define(v d r)(match d[0 1][1(* 2 r)][_(*(/(* 2 pi(* r r))d)(v(- d 2)r))])).
wchargin
Vielen Dank für tolle Vorschläge. Ich beziehe diese in die Antwort ein.
RNSO
@wchargin: Ich könnte 9 weitere Bytes reduzieren, indem ich (v (- d 2) r) in der Formel neu positioniere und nur "r r" anstelle von "(* rr)" verwende, da es sich bereits in einer Multiplikationsformel befindet.
RNSO
1

Perl, 63 Bytes + zusätzlicher Swag

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

Akzeptiert zwei ganze Zahlen n und r nacheinander und gibt dann das n-Volumen für einen gegebenen Radius r einer n-Kugel aus. Wenn n = 0 ist, ist V = 1 und wenn n = 1 ist, ist V = 2r. Alle weiteren Maße berechnen sich nach folgender Formel:

Rekursive Volumenformel

Seit r n in jeder Formel der Radiusfaktor ist, lasse ich ihn aus der Basisberechnung heraus und wende ihn nur am Ende an.

2π wird im Code durch 6.283 angenähert.

Gabriel Benamy
quelle
Nett und rekursiv, und ₊₁ zum Anzeigen der rekursiven Formel.
RudolfJelin
1

Scala, 53 Bytes

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

Tut mir leid, kein extra Beute für mich :(

Erläuterung:

{                     //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
quelle
1

JavaScript (ES6), 39 Byte, kein Swag

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

Python 3, 76 72 68 Bytes + zusätzliche Beute!

Rekursive Lösung mit extra Beute!
Rückgabe 0fürn=0

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

Alter Ansatz ( 1für 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)

Rekursive Formel aus Wikipedia .

Probieren Sie es online aus.

pajonk
quelle
1

Scala, 81 79 Bytes + extra Beute!

Bearbeiten: 2 Bytes dank @AlexRacer gespeichert

Eine dyadische Funktion - das erste Argument ist die Anzahl der Dimensionen, das zweite der Radius der n-Kugel.

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

Rekursive Formel für das Volumen einer n-Kugel: V n = (2πr 2 V n-2 )n

Die fehlende Typinferenz von Scala für Rückgabetypen von rekursiven Funktionen und Funktionsparametern und die ausführliche ternäre Syntax tun hier einiges weh :(

Tamoghna Chowdhury
quelle
1

Groovy, 49 Jahre alt 47 Bytes + zusätzlicher Swag!

Bearbeiten: 2 Bytes dank @AlexRacer gespeichert

Eine dyadische Funktion - das erste Argument ist die Anzahl der Dimensionen, das zweite der Radius der n-Kugel.

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

Rekursive Formel für das Volumen einer n-Kugel: V n = (2πr 2 V n-2 )n

Dynamisches Tippen FTW!

Meine Scala- und Java-Antworten verwenden dieselbe Logik, aber bei statischer Eingabe sind die Byteanzahlen aufgrund von Typanmerkungen höher :(. Bei Scala und Groovy kann ich jedoch returndas Semikolon und weglassen , sodass die Byteanzahl im Gegensatz zu Java / C verbessert wird ...

Tamoghna Chowdhury
quelle
₊₁ für den extra SWAG!
RudolfJelin
1

Lithp , 96 Zeichen + extra Beute

Zeile zweigeteilt zur besseren Lesbarkeit:

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

Ich denke, ich muss meinen Parser aktualisieren, um weniger Speicherplatz zu benötigen. Die Codegröße würde besonders in diesem ((/ (* (* (* (*Bereich deutlich reduziert .

Verwendung:

% 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

Vielen Dank an Rudolf, der ein paar Bytes gespart hat.

Andrakis
quelle
1
Was ist mit " 3.141592653589793" auf " 3.1416" kürzen, 11 Bytes sparen und trotzdem in die Regeln passen?
RudolfJelin
1

CJam (27 Bytes mit extra Guthaben)

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

Online-Testsuite . Dies ist ein anonymer Block (Funktion), der Argumente akzeptiertd r auf dem Stapel entgegennimmt und das Ergebnis auf dem Stapel belässt.

Präparation

Die allgemeine n-dimensionale Formel kann wie folgt umgeschrieben werden

2d2πd2rdd!!
{            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
quelle