Trova il fattoriale!


74

Crea il programma o la funzione più breve che trova il fattoriale di un numero intero non negativo.

Il fattoriale, rappresentato con !è definito come tale

n!:={1n=0n(n1)!n>0

In parole povere il fattoriale di 0 è 1 e il fattoriale di n, dove n è maggiore di 0 è n volte il fattoriale di uno minore di n.

Il codice dovrebbe eseguire input e output utilizzando metodi standard.

Requisiti:

  • Non utilizza librerie integrate in grado di calcolare il fattoriale (questo include qualsiasi forma di eval)
  • Può calcolare fattoriali per numeri fino a 125
  • Può calcolare il fattoriale per il numero 0 (uguale a 1)
  • Completa in meno di un minuto per numeri fino a 125

Vince la domanda più breve, in caso di pareggio vince la risposta con il maggior numero di voti al momento.


10
Quante delle risposte fornite possono effettivamente calcolare fino a 125! senza overflow dei numeri interi? Non era uno dei requisiti? I risultati come approssimazioni esponenziali sono accettabili (ovvero 125! = 1.88267718 × 10 ^ 209)?
Ami,

6
@SHiNKiROU, anche golfscript può gestirne 125! meno di 1/10 di secondo ed è un linguaggio interpretato interpretato!
Gnibbler,

5
@ugoren la soluzione a due caratteri per l'altra domanda utilizza una funzione fattoriale integrata. Non è consentito in questa versione della sfida.
Michael Stern,

4
Il completamento in meno di un minuto sembra un requisito molto dipendente dall'hardware. Si completa in meno di un minuto su quale hardware?
sergiol

4
@sergiol Incredibilmente non è stato un problema negli ultimi 2 anni, sospetto che la maggior parte delle lingue riesca a farlo in meno di un minuto.
Kevin Brown,

Risposte:


66

Golfscript - 12 caratteri

{,1\{)*}/}:f

Introduzione a Golfscript - Factorial passo dopo passo

Ecco qualcosa per le persone che stanno cercando di imparare il golfscript. Il prerequisito è una conoscenza di base di golfscript e la capacità di leggere la documentazione di golfscript.

Quindi vogliamo provare il nostro nuovo strumento golfscript . È sempre bene iniziare con qualcosa di semplice, quindi iniziamo con fattoriale. Ecco un tentativo iniziale, basato su un semplice pseudocodice imperativo:

# pseudocode: f(n){c=1;while(n>1){c*=n;n--};return c}
{:n;1:c;{n 1>}{n c*:c;n 1-:n;}while c}:f

Gli spazi bianchi sono usati molto raramente in golfscript. Il trucco più semplice per sbarazzarsi di spazi bianchi è utilizzare nomi di variabili diverse. Ogni token può essere utilizzato come variabile (vedere la pagina della sintassi ). Gettoni utile utilizzare come variabili sono caratteri speciali come |, &, ?- in genere non niente utilizzato in altre parti del codice. Questi vengono sempre analizzati come token a carattere singolo. Al contrario, variabili come nrichiedono uno spazio per spingere un numero nello stack dopo. I numeri sono essenzialmente variabili preinizializzate.

Come sempre, ci saranno dichiarazioni che possiamo cambiare, senza influire sul risultato finale. In golfscript, tutto tranne che restituisce true 0, [], "", e {}(si veda questo ). Qui, possiamo cambiare semplicemente la condizione di uscita del loop {n}(ripetiamo un altro tempo e terminiamo quando n = 0).

Come per il golf in qualsiasi lingua, aiuta a conoscere le funzioni disponibili. Fortunatamente la lista è molto breve per golfscript. Possiamo cambiare 1-in (per salvare un altro personaggio. Al momento il codice è simile al seguente: (potremmo usare al 1posto di |qui se volessimo, il che lascerebbe cadere l'inizializzazione).

{:n;1:|;{n}{n|*:|;n(:n;}while|}:f

È importante utilizzare bene lo stack per ottenere le soluzioni più brevi (pratica pratica pratica). In generale, se i valori vengono utilizzati solo in un piccolo segmento di codice, potrebbe non essere necessario memorizzarli in variabili. Rimuovendo la variabile del prodotto in esecuzione e semplicemente usando lo stack, possiamo salvare molti caratteri.

{:n;1{n}{n*n(:n;}while}:f

Ecco qualcos'altro a cui pensare. Stiamo rimuovendo la variabile ndalla pila alla fine del corpo del loop, ma poi la spingiamo immediatamente dopo. In effetti, prima che inizi il loop, lo rimuoviamo anche dallo stack. Dovremmo invece lasciarlo nello stack e possiamo mantenere vuota la condizione del loop.

{1\:n{}{n*n(:n}while}:f

Forse possiamo persino eliminare completamente la variabile. Per fare ciò, dovremo mantenere la variabile in pila in ogni momento. Ciò significa che abbiamo bisogno di due copie della variabile in pila alla fine del controllo delle condizioni in modo da non perderle dopo il controllo. Ciò significa che avremo uno ridondante 0nello stack dopo la fine del ciclo, ma è facile da risolvere.

Questo ci porta alla nostra whilesoluzione loop ottimale !

{1\{.}{.@*\(}while;}:f

Ora vogliamo ancora renderlo più breve. L'obiettivo ovvio dovrebbe essere la parola while. Guardando la documentazione, ci sono due alternative praticabili: spiegare e fare . Quando hai una scelta di percorsi diversi da prendere, prova a valutare i vantaggi di entrambi. Unfold è "praticamente un ciclo while", quindi come stima ridurremo i 5 caratteri whiledi 4 in /. Per quanto riguarda do, tagliamo while3 caratteri e arriviamo a unire i due blocchi, il che potrebbe salvare un altro personaggio o due.

In realtà c'è un grosso svantaggio nell'uso di un doloop. Poiché il controllo delle condizioni viene eseguito dopo che il corpo è stato eseguito una volta, il valore di 0sarà errato, quindi potrebbe essere necessaria un'istruzione if. Ti dirò ora che unfold è più breve (alcune soluzioni dosono fornite alla fine). Vai avanti e provalo, il codice che abbiamo già richiede modifiche minime.

{1\{}{.@*\(}/;}:f

Grande! La nostra soluzione ora è super corta e abbiamo finito qui, giusto? No. Sono 17 caratteri e J ha 12 caratteri. Non ammettere mai la sconfitta!


Ora stai pensando con ... ricorsione

L'uso della ricorsione significa che dobbiamo usare una struttura ramificata. Sfortunato, ma dato che il fattoriale può essere espresso in modo così sintetico in modo ricorsivo, questa sembra un'alternativa praticabile all'iterazione.

# pseudocode: f(n){return n==0?n*f(n-1):1}
{:n{n.(f*}1if}:f # taking advantage of the tokeniser

Beh, è ​​stato facile: se avessimo provato la ricorsione in precedenza, forse non avremmo nemmeno guardato usando un whileloop! Tuttavia, siamo solo a 16 caratteri.


Array

Gli array sono generalmente creati in due modi - utilizzando l' [e ]personaggi, o con la ,funzione di. Se eseguito con un numero intero nella parte superiore dello stack, ,restituisce un array di quella lunghezza con arr [i] = i.

Per iterare sugli array, abbiamo tre opzioni:

  1. {block}/: spingere, bloccare, spingere, bloccare, ...
  2. {block}%: [push, block, push, block, ...] (questo ha alcune sfumature, ad esempio i valori intermedi vengono rimossi dallo stack prima di ogni push)
  3. {block}*: spingere, spingere, bloccare, spingere, bloccare, ...

La documentazione di golfscript contiene un esempio di {+}*come sommare il contenuto di un array. Questo suggerisce che possiamo usare {*}*per ottenere il prodotto di un array.

{,{*}*}:f

Sfortunatamente, non è così semplice. Tutti gli elementi sono disattivati ​​di uno ( [0 1 2]anziché di [1 2 3]). Possiamo usare {)}%per correggere questo problema.

{,{)}%{*}*}:f

Beh non proprio. Questo non gestisce zero correttamente. Possiamo calcolare (n + 1)! / (N + 1) per rettificare questo, sebbene ciò costi troppo.

{).,{)}%{*}*\/}:f

Possiamo anche provare a gestire n = 0 nello stesso bucket di n = 1. In realtà questo è estremamente breve da fare, provare e allenarsi il più breve possibile.

Non così bene è l'ordinamento, a 7 caratteri: [1\]$1=. Nota che questa tecnica di ordinamento ha scopi utili, come imporre limiti a un numero (es. `[0 \ 100] $ 1 =)
Ecco il vincitore, con solo 3 caratteri:.! +

Se vogliamo avere l'incremento e la moltiplicazione nello stesso blocco, dovremmo scorrere su ogni elemento dell'array. Dal momento che non stiamo costruendo un array, questo significa che dovremmo utilizzare {)*}/, il che ci porta alla più breve implementazione golfscript di fattoriale! A 12 caratteri, questo è legato a J!

{,1\{)*}/}:f


Soluzioni bonus

A partire da una ifsoluzione semplice per un dociclo:

{.{1\{.@*\(.}do;}{)}if}:f

Ne possiamo spremere un paio in più. Un po 'complicato, quindi dovrai convincerti che questi funzionano. Assicurati di aver compreso tutti questi.

{1\.!!{{.@*\(.}do}*+}:f
{.!{1\{.@*\(.}do}or+}:f
{.{1\{.@*\(.}do}1if+}:f

Un'alternativa migliore è calcolare (n + 1)! / (N + 1), che elimina la necessità di una ifstruttura.

{).1\{.@*\(.}do;\/}:f

Ma la dosoluzione più breve qui richiede alcuni caratteri per mappare da 0 a 1 e tutto il resto su se stesso, quindi non abbiamo bisogno di alcuna ramificazione. Questo tipo di ottimizzazione è estremamente facile da perdere.

{.!+1\{.@*\(.}do;}:f

Per chiunque sia interessato, qui sono fornite alcune soluzioni ricorsive alternative con la stessa lunghezza di cui sopra:

{.!{.)f*0}or+}:f
{.{.)f*0}1if+}:f
{.{.(f*}{)}if}:f

* nota: non ho ancora testato molte delle parti di codice in questo post, quindi sentitevi liberi di informare se ci sono errori.


8
Interessante, sembra essere un bug nel markdown dello spoiler quando si utilizza il codice in uno spoiler ... Qualcuno si preoccupa di menzionarlo su Meta?
Ivo Flipse,

5
Trovo interessante il modo in cui golfscript - un linguaggio golfistico - consente nomi di variabili a più lettere e "ti punisce" per aver usato 1 lettera con spazi necessari
Cyoce

44

Haskell, 17 anni

f n=product[1..n]

2
Non conosco Haskell ... Ma questo calcolerà fattoriale per 0
Il Re

11
@Il re: sì lo farà. [1..0] ==> []eproduct [] ==> 1
JB

5
Direi che questo utilizza la "libreria integrata" che il problema proibisce. Tuttavia, anche l'altro metodo ha f 0=1;f n=n*f$n-117 caratteri.
eternalmatt,

5
@eternalmatt: quella parte delle restrizioni non è specificata per me. Entrambi producte, diciamo, (*)o (-)"possono calcolare il fattoriale", e sono tutti definiti attraverso il Preludio. Perché uno dovrebbe essere figo e non l'altro?
JB,

2
@YoYoYonnY: conto anche 17 caratteri, per una minore leggibilità (soggettiva). IMHO va bene nei commenti.
JB

41

Python - 27

Semplicemente:

f=lambda x:0**x or x*f(x-1)

22
Buon trucco: 0**x.
Alexandru,

Che dire math.factorial? Non è un built-in, vero?

1
@JackBates che conta come incorporato, poiché non hai scritto il codice per calcolare il fattoriale.
FlipTack

1
Qualcuno può dirmi qual è il trucco dietro 0**x?
Pavitra

1
@Pavitra: 0 0 = 1, ed è la prima cosa che valuta in modo che venga restituito. Per ogni altro n, 0 n = 0, quindi il primo operando di o è falso, in modo tale che il secondo operando venga valutato.
Mega Man,

29

APL (4)

×/∘⍳

Funziona come una funzione anonima:

    ×/∘⍳ 5
120

Se vuoi dargli un nome, 6 caratteri:

f←×/∘⍳

Non parlo APL, cosa sta succedendo qui?
Michael Stern,

@MichaelStern: crea un vettore indice, cioè lo ⍳5è 1 2 3 4 5. ×è (ovviamente) moltiplicato, /è ridotto ed è composizione delle funzioni. Quindi, ×/∘⍳è una funzione che accetta un argomento xe fornisce il prodotto dei numeri [1..x].
Marin

Ah, lo stesso approccio della soluzione Mathematica di @Yves Klett. Molto bella.
Michael Stern,

@NBZ: Questo non esisteva ancora nel 2011 quando questa domanda è stata scritta, né nel 2012 quando ho scritto questa risposta. I treni sono stati aggiunti solo in Dyalog 14.0, uscito nel 2014.
Marin

19

J (12)

Una definizione standard in J:

f=:*/@:>:@i.

Meno di 1 secondo per 125!

Per esempio:

 f 0
 1
 f 5
 120
  f 125x
 1882677176888926099743767702491600857595403
 6487149242588759823150835315633161359886688
 2932889495923133646405445930057740630161919
 3413805978188834575585470555243263755650071
 31770880000000000000000000000000000000

perché non solo * />: i. ?
Andbdrew,

Perché OP richiede una funzione e il meglio che possiamo fare in J è definire un verbo.
Eelvex,

2
Non c'è motivo per cui non possa essere una funzione anonima, giusto? Come ([:*/1+i.)per 10 punti, o addirittura 8 poiché le parentesi sono necessarie solo per chiamare la funzione, non per la definizione.
jpjacobs,

in ultimo, f 125xche cosa fa il xfare? È un tipo speciale di numero?
Cyoce,

@Cyoce, sì, è un intero di precisione esteso .
Eelvex,

17

Golfscript - 13 caratteri (SYM)

definisce la funzione !

{),()\{*}/}:!             # happy robot version \{*}/ 

versione alternativa 13 caratteri

{),()+{*}*}:! 

l'intera versione del programma è di 10 caratteri

~),()+{*}*

i test hanno una durata inferiore a 1/10 di secondo:

ingresso:

0!

produzione

1

ingresso

125!

produzione

188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000

1
+1 per l'ingresso simbolico al golf! Vorrei poter votare più di una volta. MrGreen
Chris Jester-Young,

@ ChrisJester-Young Lo farò per te.
Cyoce,

13

Perl 6: 13 caratteri

$f={[*]1..$_}

[*]è uguale a Haskell producted 1..$_è un conto alla rovescia da 1 a $_, l'argomento.


2
Non è più consentito non utilizzare più uno spazio [*](messaggio di errore "Due termini di fila").
Konrad Borowski il

Non è necessario impostare una variabile, un blocco di codice nudo è una risposta accettabile in quanto forma implicitamente una funzione. Funziona anche per 0?
Phil H,

10

Matlab, 15

f=@(x)prod(1:x)

Casi test

>> f(0)
ans =
     1
>> f(4)
ans =
    24
>> tic,f(125),toc
ans =
  1.8827e+209
Elapsed time is 0.000380 seconds.

10

Python, 28 byte

f=lambda x:x/~x+1or x*f(x-1)

(basato sulla soluzione di Alexandru)


9

MATL , 2 byte

:p

Ha spiegato:

:    % generate list 1,2,3,...,i, where i is an implicit input
p    % calculate the product of of all the list entries (works on an empty list too)

Provalo online!


10
: O
Andras Deak

Stavo per pubblicare esattamente questo :-) Potresti voler modificare il link per includere il codice e un input di esempio
Luis Mendo

Come tu comandi, mio ​​signore.
flawr

4
@AndrasDeak, No, che produrrebbe tutti i numeri da 1 a i ...
YoYoYonnY

8

Rubino - 21 caratteri

f=->n{n>1?n*f[n-1]:1}

Test

irb(main):009:0> f=->n{n>1?n*f[n-1]:1}
=> #<Proc:0x25a6d48@(irb):9 (lambda)>
irb(main):010:0> f[125]
=> 18826771768889260997437677024916008575954036487149242588759823150835315633161
35988668829328894959231336464054459300577406301619193413805978188834575585470555
24326375565007131770880000000000000000000000000000000

8

Java, 85 caratteri

BigInteger f(int n){return n<2?BigInteger.ONE:new BigInteger(""+n).multiply(f(n-1));}

1
Questo manca alle importazioni: import java.math.*;(quindi, +19 byte).
Olivier Grégoire,

Punto valido. ............
st0le

7

PostScript, 26 caratteri

/f{1 exch -1 1{mul}for}def

Esempio:

GS> 0 f =
1
GS> 1 f =
1
GS> 8 f =
40320

La stessa funzione richiede solo 21 caratteri; il resto è legarlo a una variabile. Per salvare un byte, è anche possibile associarlo a una cifra, in questo modo:

GS> 0{1 exch -1 1{mul}for}def
GS> 8 0 load exec =
40320

1
Ghostscript non può gestire 125 !; niente oltre 34! viene fuori come 1.#INF. (Ho usato lo stock GNU Ghostscript 9.0.7 compilato per Windows x64.)
Ross Presser

7

JavaScript, 25

function f(n)!n||n*f(n-1)

CoffeeScript, 19

f=(n)->!n||n*f(n-1)

Restituisce truenel caso di n = 0, ma JavaScript lo forzerà comunque a 1 comunque.


Non hai bisogno di una returndichiarazione nella funzione JavaScript?
Justin Morgan,

Aggiornamento: fumo santo, non hai bisogno di un return! Ma perchè no?
Justin Morgan,

È JavaScript 1.8 ( developer.mozilla.org/en/new_in_javascript_1.8 ). Divulgazione completa, funziona solo su Firefox!
Casey Chu,

1
Bello, non sapevo di lasciare fuori la dichiarazione di ritorno per JavaScript 1.8. Inoltre, puoi garantire 1 anziché true per il caso n = 0 con lo stesso codice di lunghezza: function f(n)n?n*f(--n):1
Briguy37

10
ES6, 17: f=n=>!n||n*f(n-1)Prendi questo, CoffeeScript!
Ry,

6

Rubino - 30 29 caratteri

def f(n)(1..n).inject 1,:*end

Test

f(0) -> 1
f(5) -> 120

1
Puoi mettere il enddopo direttamente :*senza una nuova riga o punto e virgola.
sepp2k,

1
Non è necessario passare 1 alla chiamata #inject. (1..10).inject :*# => 3628800
Dogbert

1
@Dogbert, che ne dici di f(0)?
Nemo157,

@ Nemo157, ah! dimenticato.
Dogbert,

4
Shorter di utilizzare la sintassi 1.9 lambda: f=->n{(1..n).inject 1,:*}. Chiamalo con f[n].
Michael Kohl,

6

F #: 26 caratteri

Non esiste una funzione di prodotto integrata in F #, ma puoi crearne una con una piega

let f n=Seq.fold(*)1{1..n}

6

C #, 20 o 39 caratteri a seconda del punto di vista

Come metodo di istanza tradizionale (39 caratteri; testato qui ):

double f(int x){return 2>x?1:x*f(x-1);}

Come espressione lambda (20 caratteri, ma vedi disclaimer; testato qui ):

f=x=>2>x?1:x*f(x-1);

Dobbiamo usare doubleperché 125! == 1.88 * 10 209 , che è molto più alto di ulong.MaxValue.

Disclaimer sul conteggio dei caratteri della versione lambda:

Se ricorsioni in una lambda C #, è ovviamente necessario memorizzare la lambda in una variabile denominata in modo che possa chiamarsi. Ma a differenza (ad es.) Di JavaScript, un lambda autoreferenziale deve essere stato dichiarato e inizializzato su una riga precedente. Non puoi chiamare la funzione nella stessa istruzione in cui dichiari e / o inizializzi la variabile.

In altre parole, questo non funziona :

Func<int,double> f=x=>2>x?1:x*f(x-1); //Error: Use of unassigned local variable 'f'

Ma questo fa :

Func<int,double> f=null;            
f=x=>2>x?1:x*f(x-1);  

Non ci sono buoni motivi per questa limitazione, dal momento che fnon può mai essere non assegnato al momento in cui viene eseguito. La necessità della Func<int,double> f=null;linea è una stranezza di C #. Se ciò rende giusto ignorarlo nel conteggio dei personaggi dipende dal lettore.

CoffeeScript, 21 19 caratteri per davvero

f=(x)->+!x||x*f x-1

Testato qui: http://jsfiddle.net/0xjdm971/


6

Brachylog , 7 6 byte

Creando un intervallo e moltiplicandolo

Serbatoi da -1 byte a ovs con l'idea di usare la funzione max ()

;1⌉⟦₁×

Spiegazione

;1          --  If n<1, use n=1 instead (zero case)
  ⟦₁        --      Construct the range [1,n]
    ×       --      return the product of said range

Provalo online!


Brachylog , 10 9 byte

ricorsione

≤1|-₁↰;?×

Spiegazione

            --f(n):
≤1          --  if n ≤ 1: return 1
|           --  else:
 -₁↰        --      f(n-1)
    ;?×     --            *n

Provalo online!


1
Questo funziona per 6 byte. Accettare input come singleton è consentito per impostazione predefinita.
Ovs

@ovs grazie. Ma l'utilizzo ;invece di ,consente solo un input numerico regolare. -1byte comunque
Kroppeb il

5

C (39 caratteri)

double f(int n){return n<2?1:n*f(n-1);}

3
Bello. Ma può salvare alcuni personaggi: double f(n){return!n?1:n*f(n-1);}- 33 caratteri.
ugoren,

2
f(125)traboccherà
jkabrg

4

D: 45 personaggi

T f(T)(T n){return n < 2 ? 1 : n * f(n - 1);}

Più leggibilmente:

T f(T)(T n)
{
    return n < 2 ? 1 : n * f(n - 1);
}

Un dispositivo di raffreddamento (sebbene versione più lunga) è quello modellato che fa tutto in fase di compilazione ( 64 caratteri ):

template F(int n){static if(n<2)enum F=1;else enum F=n*F!(n-1);}

Più leggibilmente:

template F(int n)
{
    static if(n < 2)
        enum F = 1;
    else
        enum F = n * F!(n - 1);
}

I modelli omonimi sono piuttosto dettagliati, quindi non puoi davvero usarli molto bene nel code golf. D è già abbastanza prolisso in termini di conteggio dei caratteri per essere piuttosto scarso per il golf del codice (anche se in realtà funziona davvero bene nel ridurre la dimensione complessiva del programma per programmi più grandi). Tuttavia, è la mia lingua preferita, quindi immagino che potrei anche provare a vedere quanto riesco a farlo nel code golf, anche se artisti del calibro di GolfScript sono tenuti a crema.


3
togli lo spazio bianco e puoi farlo scendere a 36 caratteri
maniaco del cricchetto

@Cyoce Puoi spiegarmi?
YoYoYonnY,

Benvenuto nel sito, @ user272735. Nota che non modifichiamo le soluzioni delle persone per apportare miglioramenti qui. Invece lasciamo commenti che suggeriscono quei miglioramenti, come ha fatto il maniaco del cricchetto sopra.
Shaggy,

4

PowerShell - 36

Ingenuo:

filter f{if($_){$_*(--$_|f}else{1}}

Test:

> 0,5,125|f
1
120
1,88267717688893E+209

4

Scala, 39 caratteri

def f(x:BigInt)=(BigInt(1)to x).product

La maggior parte dei caratteri garantisce che BigIntvengano utilizzati gli s in modo da soddisfare i requisiti per valori fino a 125.


Alcune opzioni più brevi:(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
LRLucena,

4

Javascript, ES6 17

f=n=>n?n*f(n-1):1

ES6:

  • Funzione freccia

ES6 è più giovane di questa sfida se ricordo bene e quindi non sono idoneo.
lirtosiast,

C'è qualcosa di strano nell'operatore condizionale. Perché ci sono due punti?
Qwertiy,

@Qwertiy Hai ragione, è stato un errore di battitura, grazie.
Afonso Matos,

4

PowerShell, 42 byte

(salvato 2 caratteri usando il filtro invece della funzione )

filter f($x){if(!$x){1}else{$x*(f($x-1))}}

Produzione:

PS C:\> f 0
1
PS C:\> f 5
120
PS C:\> f 1
1
PS C:\> f 125
1.88267717688893E+209

1
Questo è il modo vecchio, ma ... Può salvare ancora 1 invertendo il if / else: filter f($x){if($x){$x*(f($x-1))}else{1}}. E può essere ulteriormente ridotto a 36 caratteri se viene chiamato tramite pipeline poiché è un filtro (ad esempio 125|f):filter f{if($_){$_*($_-1|f)}else{1}}
Andrew

4

Racchetta (schema) 40 35 29 byte

Calcola 0! essere 1 e calcola 125! in 0 secondi secondo il timer. Approccio ricorsivo regolare

(define(f n)(if(= n 0)1(* n(f(- n 1)))))

Nuova versione per battere lisp comune: moltiplica tutti gli elementi di un elenco (uguale alla soluzione di Haskell)

(λ(n)(apply *(build-list n add1)))

Versione più recente per battere l'altra soluzione di schema e matematica per l'altra soluzione di racchetta usando foldl invece di applicare e usando range anziché buildlist

(λ(n)(foldl * n(range 1 n)))

4

Mornington Crescent , 1827 1698 caratteri

Mi è venuta voglia di imparare una nuova lingua oggi e questo è quello su cui sono atterrato ... (Perché faccio questo a me stesso?) Questa voce non vincerà alcun premio, ma batte tutte le altre 0 risposte finora usando il stessa lingua!

Take Northern Line to Bank
Take Central Line to Holborn
Take Piccadilly Line to Heathrow Terminals 1, 2, 3
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Bank
Take District Line to Parsons Green
Take District Line to Acton Town
Take District Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Bank
Take Circle Line to Temple
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Bank
Take District Line to Upney
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Upney
Take District Line to Bank
Take Circle Line to Embankment
Take Circle Line to Embankment
Take Northern Line to Angel
Take Northern Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Mornington Crescent

Provalo online!

Chiunque abbia viaggiato per Londra lo capirà immediatamente, quindi sono sicuro di non aver bisogno di dare una spiegazione completa.

La maggior parte del lavoro all'inizio riguarda la gestione del caso 0. Dopo aver inizializzato il prodotto su 1, posso usarlo per calcolare il massimo (input, 1) per ottenere il nuovo input, sfruttando il fatto che 0! = 1! Quindi può iniziare il ciclo principale.

(EDIT: un sacco di viaggi sono stati salvati togliendo 1 da "Heathrow Terminals 1, 2, 3" invece di generarlo dividendo 7 (Sisters) da solo. Uso anche un metodo più economico per generare -1 in il prossimo passo.)

Il decremento è costoso in Mornington Crescent (sebbene meno costoso del Tube stesso). Per rendere le cose più efficienti, generi un -1 prendendo il NOT di uno 0 analizzato e lo memorizzo in Hammersmith per gran parte del ciclo.


Ho messo un po 'di lavoro significativo in questo, ma dato che questo è il mio primo tentativo di giocare a golf a Mornington Crescent (in realtà il mio primo tentativo in qualsiasi lingua), mi aspetto di aver perso alcune ottimizzazioni qua e là. Se sei interessato a programmare tu stesso questo linguaggio (e perché non dovresti esserlo?), L'IDE Esoterico - con la sua modalità di debug e la finestra di controllo - è un must!


3

Befunge - 2x20 = 40 caratteri

0\:#v_# 1#<\$v *\<
    >:1-:#^_$>\:#^_$

Questa è una funzione in quanto è un blocco autonomo di codice che non utilizza il wraparound. Devi posizionare l'argomento in cima allo stack, quindi entrare da in alto a sinistra andando a destra, la funzione uscirà da in basso a destra andando a destra con il risultato in cima allo stack.

Ad esempio per calcolare il fattoriale di 125

555**   0\:#v_# 1#<\$v *\<
            >:1-:#^_$>\:#^_$    .@

Test 0

0   0\:#v_# 1#<\$v *\<
        >:1-:#^_$>\:#^_$    .@

So che è piuttosto vecchio, ma penso che sia un po 'più breve e più veloce: &:!#@_>:# 1# -# :# _$>\# :#* _$.@(dove e dovrebbe essere sostituito dall'input). Sono 32 caratteri / byte
FliiFe

3

J - 6 caratteri

*/>:i.

Questo conta? So che è molto simile all'esempio J precedente, ma è un po 'più corto :)

Sono un principiante con J, ma finora è molto divertente!


3

In C (23 personaggi)

Ciò abusa della "caratteristica" GCC che fa valere l'ultimo incarico come ritorno se non viene specificato alcun ritorno.

f(a){a=a>0?f(a-1)*a:1;}

Nella corretta C, 28 caratteri

f(a){return a>0?f(a-1)*a:1;}

+1 per la "caratteristica" GCC. Penso che GCC permetta persino un valore di ritorno del blocco (ricordo di aver fatto qualcosa del genere)0 == ({printf("Hello, world!"); 0;});
YoYoYonnY

3

Kona ( 11 6)

*/1.+!

K lavora da destra a sinistra (per la maggior parte), quindi enumeriamo x(facciamo un elenco / matrice di numeri da 0a x-1), aggiungiamo 1ad esso (elenca gli intervalli 0a x), quindi moltiplichiamo tutti i numeri insieme. Se non fosse un requisito da calcolare 125!, potrei salvare un altro byte eliminando .accanto al 1. In ogni caso, 125! viene calcolato in pochi millisecondi:

  */1.+!125.
1.882677e+209

Non hai bisogno di molto di questo. K ha il curry, quindi l'intera risposta diventa */1.+!: 6 byte.
kirbyfan64sos,

@ kirbyfan64sos: True e lo modificherò. Penso che quando ho scritto questo ~ 18 mesi fa, ero ancora bloccato su tutto ciò che doveva essere richiamabile (cioè, funzione).
Kyle Kanos,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.