Erstellen Sie das kürzeste Programm oder die kürzeste Funktion, die die Fakultät einer nicht negativen Ganzzahl findet.
Die Fakultät, dargestellt mit, !
ist als solche definiert
Im Klartext ist die Fakultät von 0 1 und die Fakultät von n, wobei n größer als 0 ist, das n-fache der Fakultät von eins weniger als n.
Ihr Code sollte die Eingabe und Ausgabe mit Standardmethoden durchführen.
Bedarf:
- Verwendet keine eingebauten Bibliotheken, die die Fakultät berechnen können (dies schließt jede Form von ein
eval
) - Kann Fakultäten für Zahlen bis zu 125 berechnen
- Kann die Fakultät für die Zahl 0 (gleich 1) berechnen
- Wird in weniger als einer Minute für Nummern bis zu 125 ausgeführt
Die kürzeste Einsendung gewinnt, bei Stimmengleichheit gewinnt die Antwort mit den meisten Stimmen.
code-golf
arithmetic
factorial
Kevin Brown
quelle
quelle
Antworten:
Golfscript - 12 Zeichen
Erste Schritte mit Golfscript - Factorial Schritt für Schritt
Ist hier etwas für die Leute, die versuchen, golfscript zu erlernen. Voraussetzung ist ein grundlegendes Verständnis von Golfscript und die Fähigkeit, die Golfscript-Dokumentation zu lesen.
Also wollen wir unser neues Tool Golfscript ausprobieren . Es ist immer gut, mit etwas Einfachem zu beginnen, also fangen wir mit Fakultät an. Hier ist ein erster Versuch, der auf einem einfachen imperativen Pseudocode basiert:
Leerzeichen werden im Golfscript sehr selten verwendet. Der einfachste Trick, um Whitespace zu entfernen, ist die Verwendung verschiedener Variablennamen. Jedes Token kann als Variable verwendet werden (siehe Syntaxseite ). Nützliche Token zu verwenden , als Variablen sind Sonderzeichen wie
|
,&
,?
- in der Regel alles , was nicht an anderer Stelle im Code verwendet. Diese werden immer als einzelne Zeichen-Token analysiert. Im Gegensatzn
dazu benötigen Variablen wie ein Leerzeichen, um eine Zahl auf den Stapel zu verschieben. Zahlen sind im Wesentlichen vorinitialisierte Variablen.Wie immer wird es Aussagen geben, die wir ändern können, ohne das Endergebnis zu beeinflussen. In golfscript wertet alles wahr , außer
0
,[]
,""
und{}
(siehe diese ). Hier können wir die Schleifenausgangsbedingung in einfach ändern{n}
(wir schleifen eine zusätzliche Zeit und beenden, wenn n = 0 ist).Wie beim Golfspielen jeder Sprache hilft es, die verfügbaren Funktionen zu kennen. Zum Glück ist die Liste für golfscript sehr kurz. Wir können ändern
1-
,(
um einen anderen Charakter zu speichern. Gegenwärtig sieht der Code so aus: (Wir könnten1
anstelle von|
hier verwenden, wenn wir wollten, was die Initialisierung fallen lassen würde.)Es ist wichtig, den Stapel gut zu verwenden, um die kürzesten Lösungen zu erhalten (üben üben üben). Wenn Werte nur in einem kleinen Codesegment verwendet werden, ist es im Allgemeinen möglicherweise nicht erforderlich, sie in Variablen zu speichern. Durch Entfernen der aktiven Produktvariablen und einfaches Verwenden des Stapels können wir eine ganze Reihe von Zeichen speichern.
Hier ist noch etwas zum Nachdenken. Wir entfernen die Variable
n
aus dem Stapel am Ende des Schleifenkörpers, verschieben sie jedoch sofort danach. In der Tat, bevor die Schleife beginnt, entfernen wir sie auch vom Stapel. Wir sollten es stattdessen auf dem Stapel belassen, und wir können die Schleifenbedingung leer lassen.Vielleicht können wir die Variable sogar komplett entfernen. Dazu müssen wir die Variable immer auf dem Stapel halten. Dies bedeutet, dass wir am Ende der Bedingungsprüfung zwei Kopien der Variablen auf dem Stapel benötigen, damit wir sie nach der Prüfung nicht verlieren. Das bedeutet, dass wir
0
nach dem Ende der Schleife eine Redundanz auf dem Stack haben, die aber leicht zu beheben ist.Dies führt uns zu unserer optimalen
while
Schleifenlösung!Jetzt wollen wir das noch kürzer machen. Das offensichtliche Ziel sollte das Wort sein
while
. In der Dokumentation gibt es zwei praktikable Alternativen - entfalten und tun . Wenn Sie die Wahl zwischen verschiedenen Routen haben, versuchen Sie, die Vorteile von beiden abzuwägen. Unfold ist so gut wie eine while-Schleife. Als Schätzung werden wir also die 5 Zeichenwhile
um 4 verringern/
. Wasdo
wir schneidenwhile
von 3 Zeichen, und erhalten die beiden Blöcke zu fusionieren, die einen anderen Charakter oder zwei retten könnte.Die Verwendung einer
do
Schleife hat tatsächlich einen großen Nachteil . Da die Bedingungsprüfung nach einmaliger Ausführung des Körpers durchgeführt wird, ist der Wert von0
falsch, sodass möglicherweise eine if-Anweisung erforderlich ist. Ich sage Ihnen jetzt, dass die Entfaltung kürzer ist (einige Lösungendo
werden am Ende bereitgestellt). Probieren Sie es aus, der Code, den wir bereits haben, erfordert nur minimale Änderungen.Toll! Unsere Lösung ist jetzt superkurz und wir sind hier fertig, oder? Nee. Dies ist 17 Zeichen und J hat 12 Zeichen. Gib niemals eine Niederlage zu!
Jetzt denkst du mit ... Rekursion
Rekursion bedeutet , dass wir müssen eine Verzweigungsstruktur verwenden. Leider, aber da Fakultät so prägnant rekursiv ausgedrückt werden kann, scheint dies eine gangbare Alternative zur Iteration zu sein.
Nun, das war einfach - hätten wir früher eine Rekursion versucht, hätten wir uns vielleicht nicht einmal die Verwendung einer
while
Schleife angeschaut ! Trotzdem sind wir nur bei 16 Zeichen.Arrays
Arrays werden in der Regel auf zwei Arten erstellt - die Verwendung
[
und]
Zeichen oder mit der,
Funktion. Bei Ausführung mit einer Ganzzahl oben im Stapel wird,
ein Array dieser Länge mit arr [i] = i zurückgegeben.Für die Iteration über Arrays haben wir drei Möglichkeiten:
{block}/
: schieben, blockieren, schieben, blockieren, ...{block}%
: [push, block, push, block, ...] (dies hat einige Nuancen, zB Zwischenwerte werden vor jedem Push vom Stack entfernt){block}*
: drücken, drücken, blockieren, drücken, blockieren, ...In der Golfscript-Dokumentation wird beispielhaft
{+}*
der Inhalt eines Arrays summiert. Dies legt nahe, dass wir{*}*
das Produkt eines Arrays erhalten können.Ganz so einfach ist es leider nicht. Alle Elemente sind um eins (
[0 1 2]
anstelle von[1 2 3]
) deaktiviert. Wir können{)}%
dieses Problem beheben.Nicht ganz. Dies behandelt Null nicht richtig. Wir können (n + 1)! / (N + 1) berechnen, um dies zu korrigieren, obwohl dies viel zu viel kostet.
Wir können auch versuchen, n = 0 im selben Bucket wie n = 1 zu behandeln. Dies ist tatsächlich extrem kurz zu tun, versuchen Sie, so schnell wie möglich zu trainieren.
Wenn wir das Inkrement und die Multiplikation im selben Block haben wollen, sollten wir jedes Element im Array durchlaufen. Da wir kein Array erstellen
{)*}/
, sollten wir es verwenden , was uns zur kürzesten Implementierung von Fakultät bringt! Bei einer Länge von 12 Zeichen ist dies mit J verknüpft!Bonuslösungen
Beginnen Sie mit einer einfachen
if
Lösung für einedo
Schleife:Wir können ein paar mehr herausholen. Ein bisschen kompliziert, also müssen Sie sich selbst davon überzeugen, dass diese Arbeiten funktionieren. Stellen Sie sicher, dass Sie alle diese verstehen.
Eine bessere Alternative ist die Berechnung von (n + 1)! / (N + 1), wodurch die Notwendigkeit einer
if
Struktur entfällt .Die kürzeste
do
Lösung benötigt hier jedoch ein paar Zeichen, um 0 zu 1 und alles andere für sich selbst zuzuordnen - wir brauchen also keine Verzweigung. Diese Art der Optimierung ist sehr leicht zu übersehen.Für alle Interessierten gibt es hier einige alternative rekursive Lösungen mit der gleichen Länge wie oben:
* Hinweis: Ich habe noch nicht viele der Code-Teile in diesem Beitrag getestet. Sie können sich also jederzeit informieren, wenn Fehler auftreten.
quelle
Haskell, 17
quelle
[1..0] ==> []
undproduct [] ==> 1
f 0=1;f n=n*f$n-1
besteht aus 17 Zeichen.product
und, sagen wir,(*)
oder(-)
"können die Fakultät berechnen", und sie sind alle durch das Prelude definiert. Warum sollte einer cool sein und nicht der andere?Python - 27
Einfach einfach:
quelle
0**x
.math.factorial
? Es ist nicht eingebaut, oder?0**x
?APL (4)
Funktioniert als anonyme Funktion:
Wenn Sie ihm einen Namen geben möchten, 6 Zeichen:
quelle
⍳
einen Indexvektor , dh⍳5
ist1 2 3 4 5
.×
ist (offensichtlich) multiplizieren,/
ist reduzieren und∘
ist Funktionszusammensetzung. Ist×/∘⍳
also eine Funktion, die ein Argument annimmtx
und das Produkt der Zahlen liefert[1..x]
.J (12)
Eine Standarddefinition in J:
Weniger als 1 Sekunde für 125!
Z.B:
quelle
([:*/1+i.)
für 10 Punkte oder sogar 8, da die Klammern nur zum Aufrufen der Funktion benötigt werden, nicht für die Definition.f 125x
Was macht der im letztenx
? Ist es eine besondere Art von Nummer?Golfscript - 13 Zeichen (SYM)
definiert die Funktion
!
alternative 13 char version
Die gesamte Programmversion besteht aus 10 Zeichen
Testfälle dauern weniger als 1/10 Sekunde:
Eingang:
Ausgabe
Eingang
Ausgabe
quelle
Perl 6: 13 Zeichen
[*]
ist dasselbe wie Haskellproduct
und1..$_
zählt von 1 bis$_
zum Argument hoch .quelle
[*]
mehr verwendet werden (Fehlermeldung "Zwei Begriffe hintereinander").Matlab, 15
Testfälle
quelle
Python, 28 Bytes
(basierend auf Alexandru's Lösung)
quelle
MATL , 2 Bytes
Erklärt:
Probieren Sie es online!
quelle
Ruby - 21 Zeichen
Prüfung
quelle
Java, 85 Zeichen
quelle
import java.math.*;
(also +19 Bytes).PostScript, 26 Zeichen
Beispiel:
Die Funktion selbst benötigt nur 21 Zeichen. der Rest ist, es an eine Variable zu binden. Um ein Byte zu speichern, kann man es auch wie folgt an eine Ziffer binden:
quelle
1.#INF
. (Ich habe GNU Ghostscript 9.0.7 verwendet, das für x64-Windows kompiliert wurde.)JavaScript, 25
CoffeeScript, 19
Gibt
true
im Fall von n = 0 zurück, aber JavaScript wird dies sowieso auf 1 setzen.quelle
return
Anweisung in der JavaScript-Funktion?return
! Aber warum nicht?function f(n)n?n*f(--n):1
f=n=>!n||n*f(n-1)
Nimm das, CoffeeScript!Ruby -
3029 ZeichenPrüfung
quelle
end
direkt danach:*
ohne Zeilenumbruch oder Semikolon setzen.(1..10).inject :*
# => 3628800f(0)
?f=->n{(1..n).inject 1,:*}
. Nennen Sie es mitf[n]
.F #: 26 Zeichen
Es gibt keine eingebaute Produktfunktion in F #, aber Sie können eine mit einer Falte erstellen
quelle
C #, 20 oder 39 Zeichen, abhängig von Ihrer Sichtweise
Als traditionelle Instanzmethode (39 Zeichen; hier getestet ):
Als Lambda-Ausdruck (20 Zeichen, siehe Haftungsausschluss; hier getestet ):
Wir müssen
double
da 125 verwenden! == 1,88 * 10 209 , was viel höher ist alsulong.MaxValue
.Haftungsausschluss zur Anzahl der Zeichen in der Lambda-Version:
Wenn Sie in einem C # -Lambda rekursiv arbeiten, müssen Sie das Lambda offensichtlich in einer benannten Variablen speichern, damit es sich selbst aufrufen kann. Im Gegensatz zu (z. B.) JavaScript muss jedoch ein selbstreferenzierendes Lambda in einer vorherigen Zeile deklariert und initialisiert worden sein. Sie können die Funktion nicht in derselben Anweisung aufrufen, in der Sie die Variable deklarieren und / oder initialisieren.
Mit anderen Worten, das funktioniert nicht :
Aber das macht :
Es gibt keinen guten Grund für diese Einschränkung, da
f
die Zuordnung zum Zeitpunkt der Ausführung nicht aufgehoben werden kann. Die Notwendigkeit derFunc<int,double> f=null;
Zeile ist eine Eigenheit von C #. Ob dies dazu führt, dass es fair ist, es bei der Anzahl der Zeichen zu ignorieren, liegt beim Leser.CoffeeScript,
2119 Zeichen für echtHier getestet: http://jsfiddle.net/0xjdm971/
quelle
Brachylog ,
76 BytesIndem Sie einen Bereich bilden und ihn multiplizieren
-1-Byte-Tanks zu Ovs, die die Idee haben, die Funktion max () zu verwenden
Erläuterung
Probieren Sie es online!
Brachylog ,
109 BytesRekursion
Erläuterung
Probieren Sie es online!
quelle
;
anstelle von,
ermöglicht jedoch nur eine regelmäßige numerische Eingabe. -1Byte sowiesoC (39 Zeichen)
quelle
double f(n){return!n?1:n*f(n-1);}
- 33 Zeichen.f(125)
wird überlaufenD: 45 Zeichen
Besser leserlich:
Eine coolere (wenn auch längere) Version ist die Vorlage, die beim Kompilieren alles erledigt ( 64 Zeichen ):
Besser leserlich:
Namensgebende Vorlagen sind jedoch ziemlich ausführlich, so dass Sie sie im Codegolf nicht wirklich gut verwenden können. D ist bereits ausführlich genug in Bezug auf die Anzahl der Zeichen, um für Code-Golf ziemlich schlecht zu sein (obwohl es tatsächlich wirklich gut darin ist, die Gesamtprogrammgröße für größere Programme zu reduzieren). Es ist jedoch meine Lieblingssprache, also denke ich, dass ich genauso gut versuchen kann zu sehen, wie gut ich es beim Codegolf machen kann, auch wenn GolfScript-Typen daran gebunden sind, es zu cremen.
quelle
PowerShell - 36
Naiv:
Prüfung:
quelle
Scala, 39 Zeichen
Die meisten Zeichen stellen sicher, dass
BigInt
s verwendet werden, damit die Anforderung für Werte bis zu 125 erfüllt wird.quelle
(x:Int)=>(BigInt(1)to x).product
def f(x:Int)=(BigInt(1)to x).product
def f(x:BigInt)=(x.to(1,-1)).product
def f(x:BigInt)=(-x to-1).product.abs
Javascript, ES6 17
ES6:
quelle
PowerShell, 42 Byte
(2 Zeichen mit Filter anstelle von Funktion gespeichert )
Ausgabe:
quelle
filter f($x){if($x){$x*(f($x-1))}else{1}}
. Und es kann weiter auf 36 Zeichen reduziert werden, wenn es per Pipeline aufgerufen wird, da es ein Filter ist (zB125|f
):filter f{if($_){$_*($_-1|f)}else{1}}
Schläger (Schema)
403529 BytesBerechnet 0! 1 zu sein und berechnet 125! in 0 Sekunden nach Timer. Regelmäßige rekursive Annäherung
Neue Version gegen gängiges Lispeln: Multipliziert alle Elemente einer Liste (wie bei dieser Haskell-Lösung)
Neuere Version, um die andere Schemalösung zu übertreffen und die andere Racket-Lösung zu berechnen, indem Sie foldl anstelle von apply und range anstelle von buildlist verwenden
quelle
Mornington Crescent ,
Jahre 1827Jahre 1698 ZeichenIch wollte heute eine neue Sprache lernen, und das ist es, worauf ich gelandet bin ... (Warum mache ich das für mich selbst?) Dieser Beitrag gewinnt keine Preise, übertrifft aber alle 0 anderen Antworten mit der dieselbe Sprache!
Probieren Sie es online!
Jeder, der durch London gereist ist, wird das natürlich sofort verstehen, daher bin ich mir sicher, dass ich keine vollständige Erklärung geben muss.
Die meiste Arbeit zu Beginn besteht in der Behandlung des 0-Falls. Nachdem ich das Produkt auf 1 initialisiert habe, kann ich damit das Maximum (Eingabe, 1) berechnen, um die neue Eingabe zu erhalten. Dabei wird die Tatsache ausgenutzt, dass 0! = 1! Dann kann die Hauptschleife beginnen.
(BEARBEITEN: Eine ganze Reihe von Reisen wurden durch Entfernen der 1 von "Heathrow Terminals 1, 2, 3" gespeichert, anstatt sie durch Teilen der 7 (Schwestern) durch sich selbst zu generieren. Ich benutze auch eine billigere Methode, um die -1 in zu generieren der nächste Schritt.)
Dekrementierung ist in Mornington Crescent teuer (obwohl billiger als die Tube selbst). Um die Effizienz zu steigern, erzeuge ich ein -1, indem ich das NOT einer analysierten 0 nehme und das für einen Großteil der Schleife in Hammersmith speichere.
Ich habe einiges an Arbeit investiert, aber da dies mein erster Versuch ist, in Mornington Crescent Golf zu spielen (tatsächlich mein erster Versuch in einer Sprache), habe ich hier und da einige Optimierungen verpasst. Wenn Sie selbst in dieser Sprache programmieren möchten (und warum nicht?), Ist Esoteric IDE mit Debug-Modus und Überwachungsfenster ein Muss!
quelle
Befunge - 2x20 = 40 Zeichen
Dies ist eine Funktion, bei der es sich um einen eigenständigen Codeblock handelt, bei dem der Umlauf nicht verwendet wird. Sie müssen das Argument oben auf dem Stapel platzieren und dann von links oben nach rechts eingeben. Die Funktion wird von rechts unten nach rechts mit dem Ergebnis oben auf dem Stapel beendet.
ZB um die Fakultät von 125 zu berechnen
Testen 0
quelle
&:!#@_>:# 1# -# :# _$>\# :#* _$.@
(wobei & durch die Eingabe ersetzt werden sollte). Es ist 32 Zeichen / BytesJ - 6 Zeichen
Zählt das? Ich weiß, dass es dem früheren J-Beispiel sehr ähnlich ist, aber es ist etwas kürzer :)
Ich bin ein Anfänger mit J, aber es macht bis jetzt viel Spaß!
quelle
In C (23 Zeichen)
Dies missbraucht die GCC-"Funktion", die die letzte Zuweisung als Rückgabe zählt, wenn keine Rückgabe angegeben ist.
In richtigem C 28 Zeichen
quelle
0 == ({printf("Hello, world!"); 0;});
Kona (
116)K arbeitet von rechts nach links (größtenteils), also zählen wir auf
x
(bilden eine Liste / ein Array von Zahlen von0
bisx-1
), addieren1
dazu (listen Bereiche0
bisx
) und multiplizieren dann alle Zahlen miteinander. Wenn es nicht erforderlich wäre, zu berechnen125!
, könnte ich 1 weiteres Byte einsparen, indem ich.
neben "" entferne1
. Auf jeden Fall 125! wird in Millisekunden berechnet:quelle
*/1.+!
: 6 Bytes.