O desafio:
Escreva um programa ou uma função que insira um número positivo e retorne seu fatorial .
Nota: Esta é uma pergunta de controle de código . Por favor, não leve a sério a pergunta e / ou respostas. Mais informações aqui . Toda pergunta de controle de código também é uma questão de popularidade , de modo que a resposta mais votada vence.
popularity-contest
code-trolling
alefalpha
fonte
fonte
Respostas:
Este é um problema de computação numérica muito simples que podemos resolver com a aproximação de Stirling :
Como você pode ver, essa fórmula possui uma raiz quadrada, da qual também precisaremos uma maneira de aproximar. Vamos escolher o chamado "método babilônico" para isso, porque é sem dúvida o mais simples:
Observe que calcular a raiz quadrada dessa maneira é um bom exemplo de recursão.
Reunir tudo isso em um programa Python nos dá a seguinte solução para o seu problema:
Com uma modificação simples, o programa acima pode gerar uma tabela clara de fatoriais:
Este método deve ser suficientemente preciso para a maioria dos aplicativos.
fonte
C #
Desculpe, mas eu odeio função recursiva.
fonte
Java
fonte
Pitão
Obviamente, a melhor maneira de resolver qualquer problema é usar expressões regulares:
fonte
Haskell
Código curto é um código eficiente, então tente isso.
Por que está trollando:
Eu riria de qualquer codificador que escrevesse isso ... A ineficiência é linda. Provavelmente também incompreensível para qualquer programador Haskell que realmente não possa escrever uma função fatorial.
Edit: Eu postei isso há um tempo atrás agora, mas pensei em esclarecer para futuras pessoas e pessoas que não sabem ler Haskell.
O código aqui pega a lista dos números de 1 a n, cria a lista de todas as permutações dessa lista e retorna o comprimento dessa lista. Na minha máquina, leva cerca de 20 minutos para 13 !. E então deve levar quatro horas para 14! e depois dois dias e meio por 15 !. Exceto que, em algum momento, você ficará sem memória.
Edit 2: Na verdade, você provavelmente não ficará sem memória devido a isso ser Haskell (veja o comentário abaixo). Você pode forçá-lo a avaliar a lista e mantê-la na memória de alguma forma, mas não sei o suficiente sobre como otimizar (e não otimizar) o Haskell para saber exatamente como fazer isso.
fonte
[1..n]
. - Uma permutação específica de[1..n]
, consignada a um thunk pelo restante das permutações (polinômio de entradan
). - Um acumulador para alength
função.C #
Como esse é um problema de matemática, faz sentido usar um aplicativo projetado especificamente para resolver problemas de matemática para fazer esse cálculo ...
Passo 1:
Instale o MATLAB. Acho que um teste funcionará, mas esse problema super complicado é provavelmente importante o suficiente para merecer a compra da versão completa do aplicativo.
Passo 2:
Inclua o componente MATLAB COM no seu aplicativo.
Etapa 3:
fonte
C #
Os fatoriais são uma operação matemática de nível superior que pode ser difícil de digerir de uma só vez. A melhor solução em problemas de programação como esse é dividir uma tarefa grande em tarefas menores.
Agora n! é definido como 1 * 2 * ... * n, portanto, em essência, multiplicação repetida, e multiplicação nada mais é que adição repetida. Portanto, com isso em mente, o seguinte resolve esse problema:
fonte
Trolls:
z = n - 1 + 1
) é na verdade auto-documentado, se você souber o que está acontecendo.p[]
usando um cálculo recursivo dos coeficientes da série!(É a aproximação de Lanczos da função gama )
fonte
- 1 + 1
aqui? Meu compilador o otimiza (não é um número de ponto flutuante, onde a otimização de códigos como esse pode ser perigosa), portanto parece desnecessário.double z = n - 1
faz parte da aproximação da função gama. O+ 1
é do relacionamento quegamma(n + 1) = n!
para o número inteiro n.Todos sabemos da faculdade que a maneira mais eficiente de calcular uma multiplicação é através do uso de logaritmos. Afinal, por que mais as pessoas usariam as tabelas de logaritmos por centenas de anos?
Portanto, a partir da identidade
a*b=e^(log(a)+log(b))
, formamos o seguinte código Python:Ele cria uma lista de números de
1
atéx
(o+1
necessário porque o Python é uma porcaria) calcula o logaritmo de cada um, soma os números, aumenta o e ao poder da soma e finalmente arredonda o valor para o número inteiro mais próximo (porque o Python é uma porcaria) . O Python possui uma função interna para calcular fatoriais, mas funciona apenas para números inteiros, portanto, não pode produzir grandes números (porque o Python é péssimo). É por isso que a função acima é necessária.Aliás, uma dica geral para os alunos é que, se algo não funcionar como o esperado, é provavelmente porque o idioma é péssimo.
fonte
Infelizmente, o Javascript não possui uma maneira integrada de calcular o fatorial. Mas, você pode usar seu significado na combinatória para determinar o valor, no entanto:
O fatorial de um número n é o número de permutações de uma lista desse tamanho.
Assim, podemos gerar todas as listas de números de n dígitos, verificar se é uma permutação e, se sim, incrementar um contador:
Trolls:
O(n)
, nãoO(n!)
, masO(n^n)
. Isso por si só seria suficiente para se qualificar aqui.number.toString(base)
, mas isso não funciona para bases acima de 36. Sim, eu sei 36! é muito , mas ainda assim ...Math.pow
? Não? Ah bem.++
fora dos loops for torna ainda mais misterioso. Além disso,==
é ruim.$i
.new Array
,document.write
(com amigos) ealert
(em vez de um prompt ou um rótulo de entrada) formam um trio completa dos pecados função de escolha. Por que a entrada é adicionada dinamicamente, afinal?=
tornam ainda mais difíceis de ler.fonte
Ruby e WolframAlpha
Esta solução usa a API REST WolframAlpha para calcular o fatorial, com RestClient para buscar a solução e Nokogiri para analisá-la. Não reinventa nenhuma roda e usa tecnologias bem testadas e populares para obter o resultado da maneira mais moderna possível.
fonte
Javascript
Javascript é uma linguagem de programação funcional, isso significa que você precisa usar funções para tudo, porque é mais rápido.
fonte
r = -~(function(){})
certamente resolverá isso.Usando o Bogo-Sort em Java
Na verdade, isso funciona muito devagar e não é preciso para números mais altos.
fonte
PERL
O fatorial pode ser um problema difícil. Uma técnica de mapear / reduzir como - assim como o Google usa - pode dividir a matemática iniciando vários processos e coletando os resultados. Isso fará bom uso de todos esses núcleos ou cpus em seu sistema em uma noite fria de inverno.
Salve como f.perl e chmod 755 para garantir que você possa executá-lo. Você tem o Lister de lixo patologicamente eclético instalado, não é?
Trolls:
fonte
ARGV[0]
é realmente o primeiro argumento e não o script!$ARGV[0]
porque a maioria das línguas que eu sei um pouco tê-lo láPitão
Apenas um algoritmo O (n! * N ^ 2) para encontrar o fatorial. Caixa base manuseada. Sem estouros.
fonte
Bem, existe uma solução fácil no Golfscript. Você pode usar um intérprete Golfscript e executar este código:
Fácil hein :) Boa sorte!
fonte
!
Mathematica
Não parece funcionar para números maiores que 11, e o fatorial [11] congelou meu computador.
fonte
Rubi
A frase mais lenta que posso imaginar. Demora 2 minutos em um processador i7 para calcular
6!
.fonte
A abordagem correta para esses problemas matemáticos difíceis é uma DSL. Então, eu vou modelar isso em termos de uma linguagem simples
Para escrever bem o nosso DSL, é útil visualizá-lo como uma mônada livre gerada pelo functor algébrico
Poderíamos escrever isso em Haskell como
Deixarei ao leitor derivar a implementação trivial de
Agora podemos descrever uma operação para modelar um fatorial neste DSL
Agora que modelamos isso, precisamos fornecer uma função de interpretação real para nossa mônada livre.
E deixarei o resto da denotação para o leitor.
Para melhorar a legibilidade, às vezes é útil apresentar um AST concreto da forma
e depois corrigir uma reflexão trivial
e é fácil avaliar recursivamente o AST.
fonte
Pitão
Abaixo está uma versão Python da solução, que não se limita ao limite de 32 bits (ou 64 bits em um sistema muito recente) para números inteiros no Python. Para contornar essa limitação, devemos usar uma string como entrada e saída para afactorial
rotina e dividir internamente a string em seus dígitos para poder executar a multiplicação.Então, aqui está o código: a
getDigits
função divide uma string que representa um número em seus dígitos, de forma que "1234" se torna[ 4, 3, 2, 1 ]
(a ordem inversa apenas simplifica as funçõesincrease
emultiply
). Aincrease
função pega essa lista e aumenta em um. Como o nome sugere, amultiply
função se multiplica, por exemplo,multiply([2, 1], [3])
retorna[ 6, 3 ]
porque 12 vezes 3 é 36. Isso funciona da mesma maneira que você multiplicaria algo com caneta e papel.Finalmente, a
factorial
função usa essas funções auxiliares para calcular o fatorial real, por exemplo,factorial("9")
fornece"362880"
como saída.Notas
No python, um número inteiro não tem um limite; portanto, se você quiser fazer isso manualmente, basta
Há também a
math.factorial(n)
função muito conveniente .Essa solução é obviamente muito mais complexa do que precisa, mas funciona e, de fato, ilustra como você pode calcular o fatorial no caso de você estar limitado por 32 ou 64 bits. Portanto, embora ninguém acredite que esta é a solução que você encontrou para esse problema simples (pelo menos em Python), você pode realmente aprender alguma coisa.
fonte
Pitão
A solução mais razoável é claramente verificar todos os números até encontrar o fatorial do número fornecido.
fonte
A solução recursiva mais elegante em C
Todos sabem que as soluções mais elegantes para os fatoriais são recursivas.
Fatorial:
Mas a multiplicação também pode ser definida recursivamente como adições sucessivas.
Multiplicação:
E o mesmo pode acontecer com incrementos sucessivos.
Adição:
Em
C
, podemos usar++x
e--x
manipular as primitivas(x + 1)
e(x - 1)
respectivamente, para que tenhamos tudo definido.Vamos tentar:
Perfeito, apesar de 8! demorou muito tempo por algum motivo. Bem, as soluções mais elegantes nem sempre são as mais rápidas. Vamos continuar:
Hmm, eu vou deixar você saber quando voltar ...
fonte
Pitão
Como a resposta de @ Matt_Sieker indicou, os fatoriais podem ser divididos em adição - por que, dividir tarefas é a essência da programação. Mas, podemos dividir isso em adição por 1!
Eu acho que esse código garante um erro SO, porque
Recursão - aquece
Cada camada gera chamadas para multiplicar
que gera chamadas para addnumbers
que gera chamadas para addby1!
Muitas funções, certo?
fonte
Basta ir ao Google e digitar seu fatorial:
http://lmgtfy.com/?q=5!
fonte
TI-Basic 84
Realmente funciona :)
fonte
Javascript
Obviamente, o trabalho de um programador é fazer o mínimo possível de trabalho e usar o maior número possível de bibliotecas. Portanto, queremos importar jQuery e math.js . Agora, a tarefa é simples assim:
fonte
Pitão
Com apenas uma ligeira modificação da implementação fatorial recursiva padrão, torna-se intoleravelmente lento para n> 10.
fonte
Bater
fonte
Vamos tentar fazê-lo pelo método de Monte Carlo . Todos sabemos que a probabilidade de duas n- permutações aleatórias serem iguais é exatamente 1 / n! . Portanto, podemos apenas verificar quantos testes são necessários (vamos chamar esse número b ) até obtermos c hits. Então, n! ~ b / c .
Sage, também deve funcionar em Python
fonte
bater
Os fatoriais são facilmente determinados com ferramentas de linha de comando conhecidas do bash.
Como @Aaron Davies mencionado nos comentários, isso parece muito mais organizado e todos nós queremos um programa agradável e organizado, não é?
fonte
paste
comando altamente subestimado :seq 1 $n | paste -sd\* | bc
paste
parece uma palavra comum em inglês e fácil de lembrar. Nós realmente queremos isso? ; o)