Encontre o fatorial!

74

Crie o programa ou a função mais curta que encontre o fatorial de um número inteiro não negativo.

O fatorial, representado por, !é definido como tal

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

Em inglês simples, o fatorial de 0 é 1 e o fatorial de n, onde n é maior que 0 é n vezes o fatorial de um menor que n.

Seu código deve executar entrada e saída usando métodos padrão.

Requisitos:

  • Não usa bibliotecas internas que possam calcular o fatorial (isso inclui qualquer forma de eval)
  • Pode calcular fatoriais para números de até 125
  • Pode calcular o fatorial para o número 0 (igual a 1)
  • Conclui em menos de um minuto para números de até 125

A finalização mais curta vence, no caso de empate, a resposta com mais votos no momento vence.

Kevin Brown
fonte
10
Quantas das respostas dadas podem realmente computar até 125! sem excesso de número inteiro? Esse não era um dos requisitos? Os resultados como aproximações exponenciais são aceitáveis ​​(ou seja, 125! = 1,88267718 × 10 ^ 209)?
06611 Ami
6
@SHiNKiROU, até o golfscript pode gerenciar 125! menos de 1/10 de segundo e é e linguagem interpretada interpretada!
Gnibbler
5
@ugoren a solução de dois caracteres para a outra pergunta usa uma função fatorial interna. Isso não é permitido nesta versão do desafio.
Michael Stern
4
Concluir em menos de um minuto parece um requisito muito dependente de hardware. Conclui em menos de um minuto em que hardware?
sergiol
4
@sergiol Incrivelmente que não foi um problema nos últimos 2 anos, suspeito que a maioria dos idiomas pode fazê-lo em menos de um minuto.
Kevin Brown

Respostas:

66

Golfscript - 12 caracteres

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

Introdução ao Golfscript - Fatorial passo a passo

Aqui está algo para as pessoas que estão tentando aprender golfe. O pré-requisito é um entendimento básico do golfscript e a capacidade de ler a documentação do golfscript.

Então, queremos experimentar nossa nova ferramenta golfscript . É sempre bom começar com algo simples, então estamos começando com fatorial. Aqui está uma tentativa inicial, baseada em um simples pseudocódigo 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

Espaço em branco é muito raramente usado no golfe. O truque mais fácil para se livrar do espaço em branco é usar diferentes nomes de variáveis. Cada token pode ser usado como uma variável (consulte a página de sintaxe ). Fichas úteis para usar como variáveis são caracteres especiais como |, &, ?- geralmente não qualquer coisa usada em outras partes do código. Estes são sempre analisados ​​como tokens de caracteres únicos. Por outro lado, variáveis ​​como nexigirão um espaço para empurrar um número para a pilha depois. Os números são essencialmente variáveis ​​pré-inicializadas.

Como sempre, haverá declarações que podemos mudar, sem afetar o resultado final. Em golfscript, tudo é avaliada como verdadeira, exceto 0, [], ""e {}(ver este ). Aqui, podemos alterar a condição de saída do loop para simplesmente {n}(fazemos um loop adicional e terminamos quando n = 0).

Como no golfe em qualquer idioma, ajuda a conhecer as funções disponíveis. Felizmente, a lista é muito curta para o golfscript. Nós podemos mudar 1-para (salvar outro personagem. No momento, o código se parece com o seguinte: (poderíamos estar usando em 1vez de |aqui, se quiséssemos, o que eliminaria a inicialização.)

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

É importante usar bem a pilha para obter as soluções mais curtas (praticar praticar praticar). Geralmente, se os valores forem usados ​​apenas em um pequeno segmento de código, talvez não seja necessário armazená-los em variáveis. Ao remover a variável de produto em execução e simplesmente usar a pilha, podemos salvar muitos caracteres.

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

Aqui está outra coisa para pensar. Estamos removendo a variável nda pilha no final do corpo do loop, mas depois a pressionamos imediatamente. De fato, antes do início do loop, também o removemos da pilha. Em vez disso, devemos deixá-lo na pilha e podemos manter a condição do loop em branco.

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

Talvez possamos até eliminar completamente a variável. Para fazer isso, precisaremos manter a variável na pilha o tempo todo. Isso significa que precisamos de duas cópias da variável na pilha no final da verificação de condição para não perdê-la após a verificação. O que significa que teremos um redundante 0na pilha após o término do loop, mas isso é fácil de corrigir.

Isso nos leva à nossa whilesolução ideal de loop!

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

Agora ainda queremos tornar isso mais curto. O alvo óbvio deve ser a palavra while. Olhando para a documentação, existem duas alternativas viáveis ​​- desdobrar e fazer . Quando você pode escolher diferentes rotas a seguir, tente pesar os benefícios de ambas. Desdobrar é 'praticamente um loop while', portanto, como uma estimativa, reduziremos o caractere 5 whileem 4 /. Quanto a doisso, cortamos while3 caracteres e fundimos os dois blocos, o que pode salvar outro ou dois caracteres.

Na verdade, há uma grande desvantagem em usar um doloop. Como a verificação da condição é feita depois que o corpo é executado uma vez, o valor de 0estará errado, portanto, podemos precisar de uma instrução if. Vou lhe dizer agora que o desdobramento é mais curto (algumas soluções dosão fornecidas no final). Vá em frente e tente, o código que já temos exige alterações mínimas.

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

Ótimo! Nossa solução agora é super curta e terminamos aqui, certo? Não. São 17 caracteres e J possui 12 caracteres. Nunca admita derrota!


Agora você está pensando com ... recursão

Usar recursão significa que devemos usar uma estrutura de ramificação. Lamentável, mas como fatorial pode ser expresso de forma tão sucinta e recursivamente, isso parece ser uma alternativa viável à iteração.

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

Bem, isso foi fácil - se tivéssemos tentado a recursão antes, talvez nem tivéssemos olhado usando um whileloop! Ainda assim, temos apenas 16 caracteres.


Matrizes

Matrizes geralmente são criadas de duas maneiras - usando os caracteres [e ], ou com a ,função Se executado com um número inteiro no topo da pilha, ,retorna uma matriz desse comprimento com arr [i] = i.

Para iterar sobre matrizes, temos três opções:

  1. {block}/: empurrar, bloquear, empurrar, bloquear, ...
  2. {block}%: [push, block, push, block, ...] (isso tem algumas nuances, por exemplo, valores intermediários são removidos da pilha antes de cada push)
  3. {block}*: empurrar, empurrar, bloquear, empurrar, bloquear, ...

A documentação do golfscript tem um exemplo de uso {+}*para somar o conteúdo de uma matriz. Isso sugere que podemos usar {*}*para obter o produto de uma matriz.

{,{*}*}:f

Infelizmente, não é tão simples assim. Todos os elementos estão desativados por um (em [0 1 2]vez de [1 2 3]). Podemos usar {)}%para corrigir esse problema.

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

Bem, não exatamente. Isso não lida com zero corretamente. Podemos calcular (n + 1)! / (N + 1) para corrigir isso, embora isso custe demais.

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

Também podemos tentar manipular n = 0 no mesmo bloco que n = 1. Isso é extremamente curto, tente e trabalhe o mais curto possível.

Não tão boa é a classificação, a 7 caracteres: [1\]$1=. Observe que essa técnica de classificação tem objetivos úteis, como impor limites a um número (por exemplo, `[0 \ 100] $ 1 =)
Aqui está o vencedor, com apenas 3 caracteres:.! +

Se queremos ter o incremento e a multiplicação no mesmo bloco, devemos iterar todos os elementos da matriz. Como não estamos construindo uma matriz, isso significa que devemos usá-la {)*}/, o que nos leva à implementação mais curta do fatorial! Com 12 caracteres, isso está associado a J!

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


Soluções bônus

Começando com uma ifsolução direta para um doloop:

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

Podemos extrair mais alguns disso. Um pouco complicado, então você terá que se convencer de que esses funcionam. Certifique-se de entender tudo isso.

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

Uma alternativa melhor é calcular (n + 1)! / (N + 1), o que elimina a necessidade de uma ifestrutura.

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

Mas a dosolução mais curta aqui leva alguns caracteres para mapear de 0 a 1 e tudo o mais para si - portanto, não precisamos de nenhuma ramificação. Esse tipo de otimização é extremamente fácil de perder.

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

Para qualquer pessoa interessada, são fornecidas aqui algumas soluções recursivas alternativas com o mesmo comprimento acima:

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

* Nota: Na verdade, eu não testei muitos dos trechos de código neste post, portanto, fique à vontade para informar se há erros.

Nabb
fonte
8
Interessante, isso parece ser um bug na marcação de spoiler quando você usa código em um spoiler ... Alguém se importa de mencionar isso no Meta?
Ivo Flipse 07/02
5
Acho interessante como o golfscript - uma linguagem de golfe - permite nomes de variáveis ​​com várias letras e "castiga" por usar uma letra com espaço em branco necessário
Cyoce
44

Haskell, 17

f n=product[1..n]
JB
fonte
2
Eu não sei Haskell ... Mas Será que este cálculo fatorial para 0
O Rei
11
@O rei: sim, será. [1..0] ==> []eproduct [] ==> 1
JB
5
Eu argumentaria que isso usa a "biblioteca interna" que o problema proíbe. Ainda assim, o outro método também f 0=1;f n=n*f$n-1possui 17 caracteres.
eternalmatt
5
@ eternalmatt: essa parte das restrições é subespecificada para mim. Ambos producte, digamos, (*)ou (-)"podem calcular o fatorial", e todos são definidos através do Prelúdio. Por que um seria legal e não o outro?
JB
2
@YoYoYonnY: Eu conto 17 caracteres também, para menos legibilidade (subjetiva). IMHO está bem nos comentários.
JB
41

Python - 27

Simplesmente:

f=lambda x:0**x or x*f(x-1)
0xKirill
fonte
22
Bom truque: 0**x.
Alexandru
Que tal math.factorial? Não é um built-in, é?
1
@JackBates que conta como interno, pois você não escreveu o código para calcular o fatorial.
FlipTack
1
Alguém pode me dizer qual é o truque por trás 0**x?
Pavitra
1
@Pavitra: 0 0 = 1, e é a primeira coisa que avalia para que seja retornado. Para qualquer outro n, 0 n = 0, portanto, o primeiro operando de ou é falsey, de modo que o segundo operando seja avaliado.
Mega Man
29

APL (4)

×/∘⍳

Funciona como uma função anônima:

    ×/∘⍳ 5
120

Se você quiser dar um nome, 6 caracteres:

f←×/∘⍳
marinus
fonte
Eu não falo APL, o que está acontecendo aqui?
Michael Stern
@ MichaelStern: cria um vetor de índice, ou seja, ⍳5é 1 2 3 4 5. ×é (obviamente) multiplicado, /reduzido e é composição da função. Portanto, ×/∘⍳é uma função que recebe um argumento xe fornece o produto dos números [1..x].
marinus
Ah, a mesma abordagem da solução Mathematica do @Yves Klett. Muito agradável.
Michael Stern
@NBZ: Isso ainda não existia em 2011, quando esta pergunta foi escrita, nem em 2012, quando escrevi esta resposta. Os trens foram adicionados apenas no Dyalog 14.0, lançado em 2014.
marinus
19

J (12)

Uma definição padrão em J:

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

Menos de 1 segundo para 125!

Por exemplo:

 f 0
 1
 f 5
 120
  f 125x
 1882677176888926099743767702491600857595403
 6487149242588759823150835315633161359886688
 2932889495923133646405445930057740630161919
 3413805978188834575585470555243263755650071
 31770880000000000000000000000000000000
Eelvex
fonte
por que não apenas * />: i. ?
precisa saber é o seguinte
Como o OP solicita uma função e o melhor que podemos fazer em J é definir um verbo.
Eelvex 23/08
2
Não há razão para que não possa ser uma função anônima, certo? Assim como ([:*/1+i.)10 pontos, ou mesmo 8, os parênteses são necessários apenas para chamar a função, não para a definição.
Jspjacobs #
no último, f 125xo que xfaz? É um tipo especial de número?
Cyoce 21/01
@ Cyoce, sim, é um número inteiro de precisão estendido .
Eelvex 21/01
17

Golfscript - 13 caracteres (SYM)

define a função !

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

versão alternativa de 13 caracteres

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

a versão completa do programa é de 10 caracteres

~),()+{*}*

os casos de teste levam menos de 1/10 de segundo:

entrada:

0!

resultado

1

entrada

125!

resultado

188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000
mordedor
fonte
1
+1 para entrada simbólica de golfe! Eu gostaria de poder votar mais de uma vez. :-D
Chris Jester-Young
@ ChrisJester-Young, farei isso por você.
Cyoce 21/01
13

Caracteres do Perl 6: 13

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

[*]é o mesmo que Haskell producte 1..$_é uma contagem de 1 a $_, o argumento.

Ming-Tang
fonte
2
Não é permitido não usar um espaço depois [*](mensagem de erro "Dois termos consecutivos").
Konrad Borowski
Você não precisa definir uma variável, um bloco de código simples é uma resposta aceitável, pois forma implicitamente uma função. Também isso ainda funciona para 0?
Phil H
10

Matlab, 15

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

Casos de teste

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

Python, 28 bytes

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

(com base na solução da Alexandru)

gmanuell
fonte
9

MATL , 2 bytes

:p

Explicado:

:    % 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)

Experimente online!

flawr
fonte
10
: O
Andras Deak
Eu estava indo postar exatamente isso :-) Você pode modificar o link para incluir o código e um exemplo de entrada #
456 M Luis Luis Mendo
Como você ordena, meu senhor.
flawr
4
@AndrasDeak, Não, isso seria a saída todos os números de 1 a i ...
YoYoYonnY
8

Ruby - 21 caracteres

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

Teste

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
Dogbert
fonte
8

Java, 85 caracteres

BigInteger f(int n){return n<2?BigInteger.ONE:new BigInteger(""+n).multiply(f(n-1));}
st0le
fonte
1
Isso perde as importações: import java.math.*;(portanto, +19 bytes).
Olivier Grégoire
Ponto justo. ..............
st0le
7

PostScript, 26 caracteres

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

Exemplo:

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

A função em si tem apenas 21 caracteres; o resto é vinculá-lo a uma variável. Para salvar um byte, também é possível vinculá-lo a um dígito, assim:

GS> 0{1 exch -1 1{mul}for}def
GS> 8 0 load exec =
40320
KirarinSnow
fonte
1
Ghostscript não pode lidar com 125 !; qualquer coisa além de 34! sai como 1.#INF. (Eu usei estoque GNU Ghostscript 9.0.7 compilado para x64 do Windows.)
Ross Presser
7

JavaScript, 25

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

CoffeeScript, 19

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

Retorna trueno caso de n = 0, mas o JavaScript coagirá esse tipo para 1 de qualquer maneira.

Casey Chu
fonte
Você não precisa de uma returndeclaração na função JavaScript?
Justin Morgan
Atualização: Fumo Santo, você não precisa de um return! Mas porque não?
Justin Morgan
É o JavaScript 1.8 ( developer.mozilla.org/en/new_in_javascript_1.8 ). Divulgação completa, só funciona no Firefox!
Casey Chu
1
Bom, eu não sabia como deixar de fora a declaração de retorno do JavaScript 1.8. Além disso, você pode garantir 1 em vez de true para o caso n = 0 com o mesmo código de comprimento: function f(n)n?n*f(--n):1
Briguy37 3/11
10
ES6, 17: f=n=>!n||n*f(n-1)Pegue isso, CoffeeScript!
Ry-
6

Ruby - 30 29 caracteres

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

Teste

f(0) -> 1
f(5) -> 120
Arnaud Le Blanc
fonte
1
Você pode colocar o enddiretamente depois :*sem uma nova linha ou ponto e vírgula.
sepp2k
1
Não há necessidade de passar 1 para a chamada #inject. (1..10).inject :*# => 3628800
Dogbert
1
@Dogbert, e para f(0)quê?
Nemo157
@ Nemo157, ah! esqueci disso.
Dogbert
4
Shorter usar 1,9 sintaxe lambda: f=->n{(1..n).inject 1,:*}. Ligue com f[n].
Michael Kohl
6

F #: 26 caracteres

Não há função de produto embutida em F #, mas você pode criar uma com uma dobra

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

C #, 20 ou 39 caracteres, dependendo do seu ponto de vista

Como um método de instância tradicional (39 caracteres; testado aqui ):

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

Como uma expressão lambda (20 caracteres, mas veja o aviso de isenção de responsabilidade; testado aqui ):

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

Temos que usar doubleporque 125! == 1,88 * 10 209 , que é muito maior que ulong.MaxValue.

Isenção de responsabilidade sobre a contagem de caracteres da versão lambda:

Se você recursionar em um C # lambda, obviamente precisará armazenar o lambda em uma variável nomeada para que ela possa se chamar. Porém, diferente do JavaScript (por exemplo), um lambda auto-referente deve ter sido declarado e inicializado em uma linha anterior. Você não pode chamar a função na mesma instrução na qual declara e / ou inicializa a variável.

Em outras palavras, isso não funciona :

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

Mas isso faz :

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

Não há uma boa razão para essa restrição, pois fnunca pode ser desassociada no momento em que é executada. A necessidade da Func<int,double> f=null;linha é uma peculiaridade de C #. Se isso faz com que seja justo ignorá-lo na contagem de caracteres, depende do leitor.

CoffeeScript, 21 19 caracteres de verdade

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

Testado aqui: http://jsfiddle.net/0xjdm971/

Justin Morgan
fonte
6

Braquilog , 7 6 bytes

Fazendo um intervalo e multiplicando-o

Tanques de -1 byte a ovs, com a ideia de usar a função max ()

;1⌉⟦₁×

Explicação

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

Experimente online!


Braquilog , 10 9 bytes

recursão

≤1|-₁↰;?×

Explicação

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

Experimente online!

Kroppeb
fonte
1
Isso funciona para 6 bytes. Tomar entrada como um singleton é permitido por padrão.
ovs 22/08/19
@ obrigado obrigado. Mas usar em ;vez de ,permite apenas uma entrada numérica regular. -1byte de qualquer maneira
Kroppeb 22/08
5

C (39 caracteres)

double f(int n){return n<2?1:n*f(n-1);}
migf1
fonte
3
Agradável. Mas pode salvar alguns caracteres: double f(n){return!n?1:n*f(n-1);}- 33 caracteres.
ugoren
2
f(125)vai transbordar #
117415 jkabrg
4

D: 45 caracteres

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

Mais legível:

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

Um cooler (embora versão mais longa) é o modelo que faz tudo em tempo de compilação ( 64 caracteres ):

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

Mais legível:

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

Os modelos de mesmo nome são bastante detalhados, portanto, você não pode realmente usá-los muito bem no código golf. D já é detalhado o suficiente em termos de contagem de caracteres para ser bastante ruim para o código de golfe (embora realmente seja muito bom em reduzir o tamanho geral do programa para programas maiores). É a minha linguagem favorita, portanto, acho que é melhor tentar ver como é possível fazê-lo no código do golfe, mesmo se pessoas como o GolfScript quiserem usá-lo.

Jonathan M Davis
fonte
3
tirar o espaço em branco e você pode obtê-lo para baixo para 36 caracteres
catraca aberração
@Cyoce Você pode explicar?
YoYoYonnY
Bem-vindo ao site, @ user272735. Observe que não editamos as soluções das pessoas para fazer melhorias aqui. Em vez disso, deixamos comentários sugerindo essas melhorias, como a catraca fez acima.
Shaggy
4

PowerShell - 36

Ingênuo:

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

Teste:

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

Scala, 39 caracteres

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

A maioria dos caracteres garante que BigInts sejam usados ​​para que os requisitos de valores até 125 sejam atendidos.

Gareth
fonte
Algumas opções mais curtas:(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:

  • Função de seta
Afonso Matos
fonte
O ES6 é mais novo que esse desafio se eu estiver lembrando corretamente e, portanto, não for elegível.
lirtosiast
Há algo estranho com o operador condicional. Por que existem dois pontos?
Qwertiy
@ Qwertiy Você está certo, isso foi um erro de digitação, obrigado.
Afonso Matos
4

PowerShell, 42 bytes

(salvou 2 caracteres usando filtro em vez de função )

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

Resultado:

PS C:\> f 0
1
PS C:\> f 5
120
PS C:\> f 1
1
PS C:\> f 125
1.88267717688893E+209
Ty Auvil
fonte
1
Esta é a maneira de idade agora, mas ... Pode poupar mais 1 caráter invertendo o if / else: filter f($x){if($x){$x*(f($x-1))}else{1}}. E pode ser reduzido ainda mais para 36 caracteres se for chamado via pipeline, pois é um filtro (por exemplo 125|f):filter f{if($_){$_*($_-1|f)}else{1}}
Andrew
4

Raquete (esquema) 40 35 29 bytes

Calcula 0! para ser 1 e calcula 125! em 0 segundos de acordo com o temporizador. Abordagem recursiva regular

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

Nova versão para vencer o lisp comum: multiplica todos os elementos de uma lista (o mesmo que a solução Haskell)

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

Versão mais recente para superar a outra solução de esquema e matemática a outra solução de raquete usando foldl em vez de aplicar e usando range em vez de buildlist

(λ(n)(foldl * n(range 1 n)))
kronicmage
fonte
4

Mornington Crescent , 1827 1698 caracteres

Eu estava com vontade de aprender um novo idioma hoje, e foi nisso que eu pousei ... (Por que eu faço isso comigo mesmo?) Essa entrada não ganhará nenhum prêmio, mas será melhor que todas as outras 0 respostas até agora usando o mesmo idioma!

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

Experimente online!

Qualquer pessoa que viajou por Londres entenderá isso instantaneamente, é claro, então tenho certeza de que não preciso dar uma explicação completa.

A maior parte do trabalho no início é no tratamento do caso 0. Após inicializar o produto em 1, posso usá-lo para calcular o máximo (entrada, 1) para obter a nova entrada, aproveitando o fato de que 0! = 1! Então o loop principal pode começar.

(EDIT: Um monte de viagens foram salvas removendo o 1 dos "Terminais 1, 2, 3 de Heathrow" em vez de gerá-lo dividindo 7 (Irmãs) por si só. Também uso um método mais barato para gerar -1 em o próximo passo.)

Decrementar é caro em Mornington Crescent (embora seja menos caro que o próprio metrô). Para tornar as coisas mais eficientes, eu gero um -1 pegando o NOT de um 0 analisado e o armazeno em Hammersmith durante grande parte do loop.


Coloquei um trabalho significativo nisso, mas como essa é minha primeira tentativa de jogar golfe em Mornington Crescent (na verdade, minha primeira tentativa em qualquer idioma), espero ter perdido algumas otimizações aqui e ali. Se você está interessado em programar nessa linguagem (e por que não estaria?), O Esoteric IDE - com seu modo de depuração e janela de visualização - é obrigatório!

Alevya
fonte
3

Befunge - 2x20 = 40 caracteres

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

Essa é uma função, pois é um bloco de código independente que não utiliza a envolvente. Você deve colocar o argumento no topo da pilha e, em seguida, digite a partir do canto superior esquerdo, indo para a direita; a função sairá do canto inferior direito, indo para a direita, com o resultado no topo da pilha.

Por exemplo, para calcular o fatorial de 125

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

Teste 0

0   0\:#v_# 1#<\$v *\<
        >:1-:#^_$>\:#^_$    .@
Nemo157
fonte
Eu sei que isso é bastante antigo, mas acho que isso é um pouco mais rápido e mais rápido: &:!#@_>:# 1# -# :# _$>\# :#* _$.@(onde & deve ser substituído pela entrada). É 32 caracteres / bytes
FliiFe
3

J - 6 caracteres

*/>:i.

Isso conta? Eu sei que é muito parecido com o exemplo anterior de J, mas é um pouco mais curto :)

Sou iniciante com J, mas até agora é muito divertido!

Andbdrew
fonte
3

Em C (23 caracteres)

Isso abusa do "recurso" do GCC que faz com que a última atribuição conte como retorno, se nenhum retorno for especificado.

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

Em C adequado, 28 caracteres

f(a){return a>0?f(a-1)*a:1;}
Kaslai
fonte
+1 para o "recurso" do GCC. Acho GCC ainda permite que um valor bloco de retorno (pode lembro de ter feito algo parecido com isso)0 == ({printf("Hello, world!"); 0;});
YoYoYonnY
3

Kona ( 11 6)

*/1.+!

K funciona da direita para a esquerda (na maior parte), por isso enumeramos x(fazemos uma lista / matriz de números de 0até x-1), adicionamos 1a ela (a faixa varia 0de x) e multiplicamos todos os números juntos. Se não fosse necessário calcular 125!, eu poderia economizar mais 1 byte, eliminando .próximo a 1. De qualquer forma, 125! é calculado em meros milissegundos:

  */1.+!125.
1.882677e+209
Kyle Kanos
fonte
Você não precisa de muito disso. K está currying, então a resposta inteira se torna */1.+!: 6 bytes.
kirbyfan64sos
@ kirbyfan64sos: Verdadeiro e vou editá-lo. Acho que quando escrevi isso ~ 18 meses atrás, eu ainda estava preso em tudo que deveria ser exigível (ou seja, função).
Kyle Kanos