Esse número é fatorial?


38

A tarefa

Dado um número natural como entrada, sua tarefa é gerar um valor de verdade ou falsey com base no fato de a entrada ser um fatorial de qualquer número natural. Você pode assumir que o número de entrada sempre estará no intervalo de números suportados pelo seu idioma, mas não deve abusar dos tipos de números nativos para banalizar o problema .

Aplicam-se brechas padrão .


Entrada

Você receberá um número natural (do tipo Integerou similar).

Você pode receber a entrada da maneira que desejar, exceto assumindo que ela esteja em uma variável predefinida. promptÉ permitida a leitura de arquivo, console, caixa de diálogo ( ), caixa de entrada etc. A entrada como argumento de função também é permitida!


Saída

Seu programa deve gerar um valor de verdade ou falsey com base em se o número de entrada é um fatorial de qualquer número natural.

Certifique-se de que seus valores de verdade / falsey sejam consistentes para todas as entradas, ou seja, se você estiver usando o par de 1 e 0 para denotar valores de verdade e falsey respectivamente, então o seu programa deverá gerar 1 para todas as entradas que devem ter valores de verdade e 0 para todas as entradas que devem ter valores falsey.

Você pode obter a saída da maneira que desejar, exceto gravá-la em uma variável. A gravação em arquivo, console, tela etc. é permitida. A função também returné permitida!

Seu programa não deve produzir erros para nenhuma entrada!


Casos de teste

Input     Output

1         Truthy (0! or 1!)
2         Truthy (2!)
3         Falsey
4         Falsey
5         Falsey
6         Truthy (3!)
7         Falsey
8         Falsey
24        Truthy (4!)
120       Truthy (5!)

Critério vencedor

Isso é , então o código mais curto em bytes vence!


2
Se o idioma suportar apenas números no intervalo {0,1}, posso esperar que a entrada seja sempre 1?
Eush77 # 20/17


1
é 4! uma verdade?
Tuskiomi #

Pergunta: Por que você não está usando os padrões de E / S?
CalculadoraFeline

Respostas:


37

Braquilog , 1 byte

Experimente online!

Explicação

é um built-in que afirma a seguinte relação: sua saída é o fatorial de sua entrada. Simplesmente fornecemos uma saída definida e veremos se é bem-sucedida ou não com uma entrada variável.


6
@BetaDecay Isso é porque é do jeito que está impresso no Prolog (isto tem a ver com o fato de que true.é uma declaração e truenão é)
Fatalize

6
É uma solução trivial, mas é inteligente por causa da maneira como o prólogo funciona.
Esolanging Fruit


17
Primeiro idiomas personalizados, depois codificações personalizadas ... o código golf está morto. Nós subvertida totalmente todo o ponto de estes problemas de diversão em primeiro lugar
Alexander - Reintegrar Monica

13
@Alexander As codificações personalizadas são irrelevantes para qualquer problema que você esteja falando. Eu poderia usar qualquer codificação "existente" e ainda seria 1 byte. Seria apenas muito menos legível.
Fatalize 23/05


19

Gelatina , 4 bytes

Œ?IE

Não é a resposta mais curta da Jelly, mas é bastante eficiente.

Experimente online!

Como funciona

Œ?IE  Main link. Argument: n

Œ?    Yield the n-th permutation of the positive integers, without the sorted tail.
      For 120, this yields [5, 4, 3, 2, 1], the tail being [6, 7, 8, ...].
  I   Increments; compute all forward differences.
      For 120, this yields [-1, -1, -1, -1].
   E  Check if all differences are equal.

2
Porque nós, jogadores de código, preocupamo-nos com a eficiência.
Okx 20/05/19

12
É uma melhoria dramática da complexidade ao custo de um byte e é um uso inteligente de um built-in, se assim posso dizer. ¯ \ _ (ツ) _ / ¯
Dennis

Curiosamente, isso retorna verdadeiro para 0, enquanto a resposta de 3 bytes do @ LeakyNun, embora muito mais lenta em geral, retorna corretamente falso para 0. São necessários bytes extras para retornar falso para 0 em uma resposta em tempo de execução eficiente?
Deadcode

@Deadcode Verificar 0 exigiria dois bytes extras. Se não tiver certeza se a definição de "números naturais" do OP inclui 0 ou não. Os casos de teste não ...
Dennis

17

Regex ECMAScript, 733+ 690+ 158 119 118 (117🐌) bytes

Meu interesse na regex foi despertado com vigor renovado após mais de 4 anos e meio de inatividade. Como tal, procurei conjuntos de números e funções mais naturais para combinar com as expressões regulares ECMAScript, retomei a melhoria do meu mecanismo de expressão regular e comecei a aprimorar o PCRE também.

Estou fascinado pela estranheza de construir funções matemáticas no regex ECMAScript. Os problemas devem ser abordados de uma perspectiva totalmente diferente e, até a chegada de um insight importante, não se sabe se eles são solucionáveis. Obriga a lançar uma rede muito mais ampla na descoberta de quais propriedades matemáticas podem ser usadas para tornar um problema específico solucionável.

Combinar números fatoriais era um problema que eu nem sequer considerava enfrentar em 2014 - ou se eu fizesse, momentaneamente, descartá-lo como improvável demais para ser possível. Mas, no mês passado, percebi que isso poderia ser feito.

Como nas minhas outras postagens de regex do ECMA, darei um aviso: eu recomendo aprender como resolver problemas matemáticos unários no regex do ECMAScript. Foi uma jornada fascinante para mim, e não quero estragá-la para quem potencialmente queira experimentá-la, especialmente aqueles com interesse em teoria dos números. Consulte esta postagem anterior para obter uma lista de problemas recomendados consecutivamente identificados por spoilers para resolver um por um.

Portanto , não leia mais se não quiser que você estrague uma mágica avançada de expressões regulares unárias . Se você quiser tentar descobrir essa mágica, recomendo começar resolvendo alguns problemas no regex ECMAScript, conforme descrito no post acima.

Essa foi a minha ideia:

O problema de corresponder esse conjunto de números, assim como a maioria dos outros, é que, na ECMA, geralmente não é possível acompanhar dois números alterados em um loop. Às vezes, eles podem ser multiplexados (por exemplo, poderes da mesma base podem ser adicionados sem ambiguidade), mas isso depende de suas propriedades. Portanto, eu não poderia simplesmente começar com o número de entrada e dividi-lo por um dividendo cada vez maior até chegar a 1 (ou pelo menos eu pensava).

Depois, pesquisei sobre as multiplicidades de fatores primos em números fatoriais e aprendi que existe uma fórmula para isso - e é uma que eu provavelmente poderia implementar em um regex do ECMA!

Depois de estufá-lo por um tempo, e construir alguns outros regexes nesse meio tempo, assumi a tarefa de escrever o regex fatorial. Demorou várias horas, mas acabou funcionando bem. Como um bônus adicional, o algoritmo pode retornar o fatorial inverso como uma correspondência. Não havia como evitá-lo; pela própria natureza de como deve ser implementado no ECMA, é necessário adivinhar qual é o fatorial inverso antes de fazer qualquer outra coisa.

A desvantagem foi que esse algoritmo resultou em um regex muito longo ... mas fiquei satisfeito porque acabou exigindo uma técnica usada no meu regex de multiplicação de 651 bytes (aquele que acabou sendo obsoleto, porque um método diferente foi usado para um valor 50) byte regex). Eu esperava que surgisse um problema que exigisse esse truque: operar em dois números, que são os dois poderes da mesma base, em um loop, adicionando-os sem ambiguidade e separando-os a cada iteração.

Mas, devido à dificuldade e extensão desse algoritmo, usei lookaheads moleculares (da forma (?*...)) para implementá-lo. Esse é um recurso que não está no ECMAScript ou em qualquer outro mecanismo regular de regex, mas que eu havia implementado no meu mecanismo . Sem capturas dentro de um lookahead molecular, é funcionalmente equivalente a um lookahead atômico, mas com capturas pode ser muito poderoso. O mecanismo retornará ao lookahead, e isso pode ser usado para conjeturar um valor que alterna entre todas as possibilidades (para testes posteriores) sem consumir caracteres da entrada. Usá-los pode resultar em uma implementação muito mais limpa. (O comprimento variável da aparência é no mínimo igual em potência à aparência molecular, mas o último tende a criar implementações mais diretas e elegantes.)

Portanto, os comprimentos de 733 e 690 bytes não representam realmente encarnações da solução compatíveis com ECMAScript - daí o "+" após elas; certamente é possível portar esse algoritmo para ECMAScript puro (o que aumentaria bastante seu comprimento), mas eu não cheguei a ele ... porque pensei em um algoritmo muito mais simples e compacto! Um que poderia ser facilmente implementado sem olhares moleculares. Também é significativamente mais rápido.

Este novo, como o anterior, deve adivinhar o fatorial inverso, percorrendo todas as possibilidades e testando-as para uma partida. Ele divide N por 2 para liberar espaço para o trabalho que precisa fazer e, em seguida, gera um loop no qual dividirá repetidamente a entrada por um divisor que começa em 3 e aumenta a cada vez. (Como tal, 1! E 2! Não podem ser correspondidos pelo algoritmo principal e devem ser tratados separadamente.) O divisor é rastreado adicionando-o ao quociente em execução; esses dois números podem ser inequivocamente separados porque, assumindo M! == N, o quociente em execução continuará a ser divisível por M até que seja igual a M.

Esse regex faz divisão por variável na parte mais interna do loop. O algoritmo de divisão é o mesmo que em meus outros regexes (e semelhante ao algoritmo de multiplicação): para A≤B, A * B = C se houver apenas se C% A = 0 e B é o maior número que satisfaz B≤C e C% B = 0 e (CB- (A-1))% (B-1) = 0, onde C é o dividendo, A é o divisor e B é o quociente. (Um algoritmo semelhante pode ser usado para o caso A≥B e, se não se souber como A se compara a B, basta um teste extra de divisibilidade.)

Portanto, adoro que o problema possa ser reduzido a uma complexidade ainda menor do que o meu regex de Fibonacci otimizado para golfe , mas suspiro com desapontamento que minha técnica de multiplexação de poderes da mesma base tenha que esperar por outro problema isso realmente exige, porque este não. É a história do meu algoritmo de multiplicação de 651 bytes sendo suplantado por um de 50 bytes, mais uma vez!

Edit: Consegui soltar 1 byte (119 → 118) usando um truque encontrado por Grimy que pode reduzir ainda mais a divisão no caso de garantir que o quociente seja maior ou igual ao divisor.

Sem mais delongas, aqui está o regex:

Versão verdadeira / falsa (118 bytes):

^((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\3$|^xx?$

Experimente online!

Devolva fatorial inverso ou sem correspondência (124 bytes):

^(?=((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\3$)\3|^xx?$

Experimente online!

Retorne fatorial inverso ou sem correspondência, em ECMAScript +\K (120 bytes):

^((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\K\3$|^xx?$

E a versão em espaço livre com comentários:

  ^
  (?=                           # Remove this lookahead and the \3 following it, while
                                # preserving its contents unchanged, to get a 119 byte
                                # regex that only returns match / no-match.
    ((x*)x*)(?=\1$)             # Assert that tail is even; \1 = tail / 2;
                                # \2 = (conjectured N for which tail == N!)-3; tail = \1
    (?=(xxx\2)+$)               # \3 = \2+3 == N; Assert that tail is divisible by \3
    # The loop is seeded: X = \1; I = 3; tail = X + I-3
    (
      (?=\2\3*(x(?!\3)xx(x*)))  # \5 = I; \6 = I-3; Assert that \5 <= \3
      \6                        # tail = X
      (?=\5+$)                  # Assert that tail is divisible by \5
      (?=
        (                       # \7 = tail / \5
          (x*)                  # \8 = \7-1
          (?=\5(\8*$))          # \9 = tool for making tail = \5\8
          x
        )
        \7*$
      )
      x\9                       # Prepare the next iteration of the loop: X = \7; I += 1;
                                # tail = X + I-3
      (?=x\6\3+$)               # Assert that \7 is divisible by \3
    )*
    \2\3$
  )
  \3                            # Return N, the inverse factorial, as a match
|
  ^xx?$                         # Match 1 and 2, which the main algorithm can't handle

O histórico completo das minhas otimizações de golfe dessas regexes está no github:

regex para correspondência de números fatoriais - método de comparação de multiplicidade, com lookahead.txt molecular
regex para correspondência de números fatoriais.txt (o mostrado acima)

Observe que ((x*)x*)pode ser alterado para ((x*)+), diminuindo o tamanho em 1 byte (para 117 bytes ) sem perda da funcionalidade correta - mas o regex explode exponencialmente em lentidão. No entanto, esse truque, embora funcione no PCRE e no .NET, não funciona no ECMAScript , devido ao seu comportamento ao encontrar uma correspondência de comprimento zero em um loop . ((x+)+)funcionaria no ECMAScript, mas isso quebraria o regex, porque para n=3!, \2precisa capturar um valor de 3-3=0 0 (e alterar o regex para ser indexado em 1 diminuiria o benefício do golfe).

O mecanismo regex .NET não emula esse comportamento no modo ECMAScript e, portanto, o regex de 117 bytes funciona:

Experimente online! (versão exponencial-lenta, com mecanismo regex .NET + emulação ECMAScript)


14

JavaScript (ES6), 30 29 28 bytes

Espera um número inteiro positivo. Retorna -1por falsidade e -2por verdade.

f=(n,k=2)=>n>1?f(n/k,k+1):~n

console.log(1,  '-->',f(1))   // Truthy (0! or 1!)
console.log(2,  '-->',f(2))   // Truthy (2!)
console.log(3,  '-->',f(3))   // Falsey
console.log(4,  '-->',f(4))   // Falsey
console.log(5,  '-->',f(5))   // Falsey
console.log(6,  '-->',f(6))   // Truthy (3!)
console.log(7,  '-->',f(7))   // Falsey
console.log(8,  '-->',f(8))   // Falsey
console.log(24, '-->',f(24))  // Truthy (4!)
console.log(120,'-->',f(120)) // Truthy (5!)

Nota : Esta função suporta entradas muito grandes (você deve ler isso como: 'bastante grande para JS'). Deve funcionar com segurança até 2 53 - 1 . Falhará com certeza começando em N = 121.645.100.408.831.992 , sendo esta entrada arredondada para 19! = 121.645.100.408.832.000 devido à sua codificação IEEE-754. Não pode haver outros resultados falsos positivos antes 121.645.100.408.831.991 por causa de erros de arredondamento, mas eu não sei ao certo.


Bom - realmente gosto do uso de ~no final.
21317 Steve Bennett

Você pode editar para que eu possa cancelar a votação? (Se você quiser saber por que eu downvoted, é porque eu esqueci regras I / O incomuns desta pergunta.)
CalculatorFeline

@Arnauld Undownvoted.
CalculatorFeline

11

Python 3 , 39 38 bytes

f=lambda n,i=1:n>1and f(n/i,i+1)or n<1

Uma função recursiva tendo um número inteiro, n, retornando um valor booleano inversley que representa o resultado (truthy: False, Falsey: True)

Experimente online!

Divide-se repetidamente npor i, com um valor inicial de 1, até que o restante seja menor ou igual a, e 1então testa se o restante é menor 1, apenas os fatoriais terminam com um restante igual a 1e <é um byte menor que ==.


@ovs, ficamos restritos a duas saídas consistentes. Infelizmente, isso retorna 1para todos os fatoriais, exceto 1pelos quais ele retorna True.
Jonathan Allan

11

Java 8, 46 bytes

i->{int j=1,c=0;for(;j<i;j*=++c);return j==i;}

Isso se baseia na entrada de Roman Gräf, da qual consegui extrair uma dúzia de bytes. Eu teria sugerido lá, mas ainda não tenho reputação suficiente para comentar! Meu código do executor de teste modificado:

import java.util.function.Function;
import java.util.stream.IntStream;

public class IsFactorial {
    public static Function<Integer, Boolean> isFactorial = i->{int j=1,c=0;for(;j<i;j*=++c);return j==i;};
    public static int[] truthyCases = {1,2,6,24,120};
    public static int[] falsyCases = {3,4,5,7,8};
    public static void main(String[] args){
        System.out.println(
            IntStream.of(truthyCases).allMatch(i->isFactorial.apply(i)) &&
            IntStream.of(falsyCases).allMatch(i->!isFactorial.apply(i)));
    }
}

9

Retina , 50 38 bytes

12 bytes salvos graças ao @Neil, combinando encurtar o loop e livrando-se do ;

.+
1¶$&$*
+`^(1+)¶(\1)+$
1$1¶$#2$*
¶.$

Experimente online!

Saídas 1para verdadeiro e 0para falso.

.+ corresponde ao número inteiro

1¶$&$*substituindo-o por 1seguido por uma nova linha e a correspondência convertida em unário

O programa restante divide o número unário na linha inferior, aumentando sucessivamente números inteiros positivos, acompanhados na linha superior, enquanto é possível fazer isso.

+` loop até que a string permaneça a mesma

  • ^(1+)¶(\1)+$combine a linha superior com muitos se 1um múltiplo com muitos 1s na linha inferior e substitua-o por

  • 1$1¶$#2$*a linha superior muitos 1s com outra 1, ou seja, aumentando o número representado pela linha superior em 1, seguido pela nova linha e o número de correspondências da linha superior na linha inferior (ou seja, contagem de correspondências do segundo grupo de captura) ) muitos 1s, ou seja, dividindo o número inferior pelo número superior

Quando não for mais possível,

¶.$forneça o número de correspondências desse regex, ou seja. existe uma 1linha na linha inferior, o que só acontece se o número for um fatorial


Se no-crash / crash for permitido em vez de valores verdadeiros / falsos, então eu posso obter 36 34 bytes.

^
1¶
{`.+$
$*
^(1+)¶(\1)+$
1$1¶$#2

Isso segue a mesma abordagem, mas combina $*a terceira e a quarta linhas. A terceira linha em diante faz parte do mesmo loop, {é uma abreviação de +(onde os (grupos remanescem as linhas no loop. Os fatoriais terminam no programa interrompendo o loop, enquanto os não fatoriais ficam presos no loop para sempre até que Retina lança uma OverflowException causada pela falha da última substituição, tendo o fundo em unário em vez de decimal, e a primeira substituição do loop converte a linha inferior de decimal em unária, para que ela exploda rapidamente.


Salve um byte removendo o 1que está implícito $*no final da substituição.
Neil

Melhor ainda, combine as $*com as outras duas linhas.
Neil


3
Estou impressionado que você encontrou uma maneira de travar a Retina condicionalmente. :)
Martin Ender

2
Você pode adicionar uma explicação?
CalculatorFeline

8

05AB1E , 4 bytes

L!QO

Experimente online!

Explicação

L      # range [1 ... input]
 !     # calculate factorial of each
  Q    # compare with input for equality
   O   # sum

1
Você não precisaria duplicar a entrada primeiro porque a Lexibe? Além disso, Å!fornece uma lista de fatorial menor ou igual à entrada.
Neil A.

@NeilA. Felizmente, a entrada é exibida novamente se não houver argumentos suficientes na pilha para uma operação, por isso não preciso Daqui. Boa captura Å!. Eu sempre esqueço os comandos da lista. Ele não salvará nenhum bytes, mas é mais eficiente, com certeza.
Emigna

Eu não sabia que a entrada estava sendo exibida novamente ... que com certeza poderia economizar muitos bytes.
Neil A.

@NeilA. É um recurso relativamente novo. Foi adicionado há menos de um mês, eu acho.
Emigna

8

C ++, 102 100 92 bytes

#include<cmath>
int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}

Percorre todos os valores de 0a ne calcula os cheques fatoriais e, em seguida, se é igual n.

Obrigado Christoph! (salvou 8 bytes)


Oi! Bem-vindo ao PPCG! Boa primeira resposta! Boa sorte para o futuro!
Arjun

Boa primeira resposta! Você pode salvar alguns bytes como este: int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}. lrounde lgammajá são C ++ 11, então poderia simplesmente #include<cmath>. Talvez você possa melhorar ainda mais minhas sugestões :) #
Christoph

7

Haskell , 43 26 bytes

f n=elem n$scanl1(*)[1..n]

Experimente online!

  • Economizou 17 bytes, graças a Laikoni

2
f n=elem n$scanl1(*)[1..n]é ridículo ineficiente, mas mais curto.
Laikoni

Não há alguma regra sobre a eficiência do código?
Sudee 20/05

1
Nada que eu saiba. O code-golf pede uma solução no menor número de bytes possível, sem nenhuma declaração de eficiência. Também na minha máquina, a função funciona 40430sem demora perceptível.
Laikoni

Eu quis dizer algo como "a solução deve terminar dentro de um prazo razoável", mas acho que se encaixa nos requisitos de qualquer maneira. Obrigado!
Sudee 20/05

1
Agradável e simples. Eu pensei que eu poderia fazer melhor com a divisão-digamos, divModpor [1..]sucessivamente até atingir um saldo zero, com um quociente de 1 (factorial) ou um resto diferente de zero (não-fatorial), mas não parece ser a abordagem correta. Eu encontrei esta solução bonito 46 caracteres, no entanto: f|let x%n=mod n x==0&&(x+1)%div n x||n==1=(1%).
22617 Jon Purdy

6

Haskell , 38 bytes

m#n=n<2||mod n m<1&&(m+1)#div n m
(2#)

Experimente online! Exemplo de utilização: (2#) 24. Retorna Trueou False.

Este é o menor tempo que pude obter, ainda sendo muito eficiente. Mesmo para números tão grandes quanto

145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000

o resultado é dado imediatamente. A solução funciona dividindo a entrada npor m = 2,3,4,5,...até que o resultado seja um ou nnão seja divisível por m.

Para a solução ineficiente de 26 bytes mais curta, mas incrível, que calcula n!entradas que não são fatoriais, veja aqui .



5

Fourier , 40 39 bytes

I~Q1~N(i^~i*N~N{Q}{1~Xo}N>Q{1}{1~X0o}X)

Experimente no FourIDE!

Basicamente, multiplica o número N por uma quantidade crescente até N ser igual a (saída 1) ou maior que (saída 0) a entrada.

Explicação Pseudocódigo:

Q = Input
N = 1
While X != 1
    i += 1
    N = N*i
    If N = Q Then
        Print 1
        X = 1
    End If
    If N > Q Then
        Print 0
        X = 1
    End If
End While

5

Japonês , 8 6 bytes

ol x¥U

Experimente online!

Isso gera 0 para falso e 1 para verdadeiro.

Explicação

 ol x¥ U
Uol x==U
Uo       # Create the range [0 ... input]
  l      # Replace each element by its factorial
     ==U # Compare each element to the input (yielding 1 if equal and 0 otherwise)
    x    # And sum the result

1
Eu realmente devo adicionar um "contém" embutido: P
ETHproductions

1
Oh hey, você poderia mudar aU ¦Jpara x¥U(mapear cada Xpara X==Ue soma), embora não funcionará em TIO.
ETHproductions

Falha por 2becuase osó vai lhe dar [0,1]. Aqui está uma correção com economia de 1 byte.
Shaggy

4

Perl 5, 31 bytes

$a=<>;$a/=++$i while$a>1;exit$a

A entrada é obtida via STDIN, a saída é fornecida pelo código de saída (1 para fatorial, 0 para não fatorial).

A entrada é dividida por números inteiros sucessivos até que seja 1 ou uma fração menor que um, que é truncada no resultado.



4

Perl 6 , 29 bytes

{($_,{$_/++$}...2>*).tail==1}

Teste-o

Expandido:

{   # bare block lambda with implicit parameter 「$_」

  (              # generate a sequence

    $_,          # starting with the input

    {
      $_ / ++$   # divide previous element by an ever increasing number
                 # 1,2,3,4,5,6,7,8 ... *
    }

    ...          # keep generating until

    2 > *        # 2 is greater than what was generated
                 # ( 1 or a fractional number )

  ).tail == 1    # check if it ended at 1
}

17 bytes: {$_∈[\*] 1..$_}. Outra abordagem interessante é 2>*.polymod(1..*).sum.
Nwellnhof 11/1118

4

setlX , 32 bytes

f:=n|=>exists(x in{0..n}|n==x!);

Cria uma função chamada fonde você usa seu fatorial potencial como parâmetro.

Funciona com tamanho inteiro arbitrário, mas é bastante ineficiente.

(a propósito: esta é minha primeira participação em um quebra-cabeça de programação)




4

C # (.NET Core) , 68 bytes

bool f(System.Numerics.BigInteger n,int k=2)=>n<2||n%k<1&f(n/k,k+1);

Experimente online!

Não é a solução mais curta, mas funciona com números realmente grandes. O link TIO inclui um exemplo com 10000!.

Aqui está uma versão mais curta que usa into valor máximo de 2147483647 .

C # (.NET Core) , 45 bytes

bool f(int n,int k=2)=>n<2||n%k<1&f(n/k,k+1);

Experimente online!

Crédito para @KevinCruijssen por jogar no total 3 bytes de ambas as respostas!


2
A &&pode ser golfed para &, e o arrasto ;não tem de ser contado para as funções de lambda. Além disso, não pode ulong k=2estar uint k=2na sua resposta de 50 bytes?
Kevin Cruijssen 22/01

1
Boa captura no &vs &&. Eu pensei que estava recebendo um estouro de pilha, mas parece funcionar depois de tudo. ulongtem 64 bits e uint32. Parece que outras pessoas estão usando, intentão talvez eu apenas use isso na versão curta. No que diz respeito à trilha ;, essas são funções completas, não lambdas, então acho que preciso incluí-las?
dana

É realmente estranho como o .NET pode resolver /e %entre ulonge uint, mas não ulonge int. Não sabia disso :)
dana

1
@ Oliver - Com doublevocê começa a ver o arredondamento em algum momento - por exemplo, 24! e 120! falhou. Enquanto System.Numerics.BigIntegertem a maior precisão, inté a resposta mais curta :)
dana

1
@Deadcode - Você está certo com 0 :) Com base nos exemplos do desafio, interpretei "números naturais" como 1,2, ... Concordo que, no mundo real, é melhor usar o &&operador de curto-circuito . Mas isso é código de golfe;) Que bom que você gostou do 10000!exemplo!
dana

4

C ++ (clang), 51 bytes

A recursão vence tanto quanto o golfe.

51 bytes, zero é verdadeiro:

int f(int n,int i=2){return n<2?!n:n%i|f(n/i,i+1);}

Isso sacrifica bastante velocidade por 1 byte de economia. Substitua |por ||para torná-lo mais rápido, devido à avaliação de curto-circuito do OR lógico.

Experimente online! (Versão lenta de 51 bytes)
Experimente online! (Versão rápida de 52 bytes)

Versão lenta Ungolfed:

int isFactorial(int n, int i=2)
// returns 0 for true, and nonzero for false
{
    if (n < 2) // same as "if (n==0 || n==1)" in our natural number input domain
    {
        if (n==0)
            return 1; // not factorial
        else // n==1
            return 0; // is factorial (could be either 0! or 1!)
    }

    // Because any nonzero value represents "false", using "|" here is equivalent
    // to "||", provided that the chain of recursion always eventually ends. And
    // it does always end, because whether or not "n" is factorial, the "n / i"
    // repeated division will eventually give the value of zero or one, satisfying
    // the above condition of termination.
    return (n % i) | isFactorial(n / i, i+1);
}

Versão rápida Ungolfed:

int isFactorial(int n, int i=2)
// returns 0 for true, and nonzero for false
{
    if (n < 2) // same as "if (n==0 || n==1)" in our natural number input domain
    {
        if (n==0)
            return 1; // not factorial
        else // n==1
            return 0; // is factorial (could be either 0! or 1!)
    }

    if (n % i != 0)
        return 1; // not factorial
    else
        return isFactorial(n / i, i+1);
}

Existem muitas maneiras de reorganizar isso.

52 bytes, diferente de zero é verdadeiro:

int f(int n,int i=2){return n<2?n:n%i?0:f(n/i,i+1);}

Experimente online!

52 bytes, zero é verdadeiro:

int f(int n,int i=2){return!n?1:n%i?n-1:f(n/i,i+1);}

Experimente online!

Antes de recorrer à recursão, tentei fazer algumas versões iterativas e elas chegaram perto.

54 bytes, diferente de zero é verdadeiro:

int f(int n){for(int i=2;n>1;)n=n%i?0:n/i++;return n;}

Experimente online!

54 bytes, zero é verdadeiro (com base no envio do Java 8 de Roman Gräf ):

int f(int n){int a=1,i=0;for(;a<n;a*=++i);return a-n;}

Experimente online!

Agora, para o fundo do barril, versões recursivas sem n==0manipulação (eu as considero inválidas, porque 0 é um número natural e qualquer definição em que não seja usada para "números naturais" de uso muito limitado). Nas versões abaixo, a recursão infinita def(0) ou outro dispara um segfault devido ao transbordamento da pilha ou com compiladores que o otimizam para iteração, fazem um loop infinito:

48 bytes, zero é verdadeiro:

int f(int n,int i=2){return n%i?n-1:f(n/i,i+1);}

Experimente online!

48 bytes, zero é verdadeiro (com base na submissão de 33 bytes C (gcc) de Hagen von Eitzen ):

int f(int n,int e=0){return n%++e?n-1:f(n/e,e);}

Experimente online!


50 EDIT: 49 , sem recursão.
Grimmy

Voltar à recursão para 48 . E você provavelmente não vai gostar disso, mas 44 usando uma var global.
Grimmy

3

Mathematica, 20 bytes

!FreeQ[Range[#]!,#]&

outra versão para testar grandes números (ver comentários)

Range[10^3]!~MemberQ~#&

testa até 1000!


2
Pelo que entendi a pergunta, se o Mathematica é capaz de tomar 1001! como entrada, isso não atende às especificações.
Peter Taylor

2
Você pode até salvar três bytes, tornando-o válido para todas as entradas. Apenas substitua 10 ^ 3 por #; você pode salvar outro byte usando o Range @ #
Julien Kluge

@Julien Klugethen procurando por 1243234 levaria uma eternidade ...
J42161217

1
Eu acho que você pode salvar outro byte, substituindo Range[#]com Range@#:)
numbermaniac

3
Parece que você pode economizar ainda um outro byte com a sintaxe infix: !Range@#!~FreeQ~#&.
Numbermaniac

3

Cubix , 24 bytes

U0O@1I1>-?1u>*w;W;@Orq)p

Experimente online

Cubificado

    U 0
    O @
1 I 1 > - ? 1 u
> * w ; W ; @ O
    r q
    ) p

Começamos empurrando 1, Input, 1para a pilha. Estes serão nosso índice, nossa meta e nosso acumulador, respectivamente.

Nós então fazemos um loop. A cada iteração, subtraímos o acumulador da entrada. Se o resultado for 0, terminamos, pressionamos 1, Outilizamos e saímos. Se for negativo, fomos longe demais, então empurramos 0, Outilizamos e saímos. Caso contrário, vemos

;p)*rq;
;         Pop the difference off the stack.
 p)       Move the index to the top of the stack and increment it.
   *      Multiply the accumulator by the index to get the next factorial.
    rq;   Put the stack back in the right order.

3

Neim , 8 bytes

𝐈Γ𝐈𝐩₁𝔼)𝐠

Explicação:

Example input: 6
𝐈         Inclusive range [1 .. input]
          [1, 2, 3, 4, 5, 6]
 Γ        For each...
  𝐈         Inclusive range [1 .. element]
            [[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6]]
   𝐩        Product
            [1, 2, 6, 24, 120, 720]
     𝔼      Check for equality with
    ₁       the first line of input
            [[0, 0, 1, 0, 0, 0]]
      )   End for each
       𝐠  Select largest element
          [1]

Tente!

Neim , 3 bytes (não competitivo)

Não competitivos, pois o token contém e o token fatorial foram adicionados após o desafio.

𝐈𝐓𝕚

Explicação:

Example input: 6
𝐈     Inclusive range [1 .. input]
      [[1, 2, 3, 4, 5, 6]
 𝐓    Factorial each
      [[1, 2, 6, 24, 120, 720]]
  𝕚   Check that the [cycled] input is in the list
      [1]

Tente!


3

> <> , 24 22 bytes

-2 bytes graças a @Aaron

Estou tentando um novo idioma (desde que minha licença do Mathematica expirou ...)

01\{=n;
?!\$1+:@*:{:}(

Experimente on-line ou no playground de peixes

Assume que o número de entrada está na pilha e retorna 0 ou 1. Ele funciona multiplicando os primeiros n números até que isso pare de ser menor que a entrada e, em seguida, imprimindo 1 se for igual à entrada e 0 se não ' t.


Você poderia transformá-lo v>\n<^em \\n/; veja aqui
Aaron

@ Aaron, isso é brilhante, obrigado!
Não é uma árvore

3

APL (Dyalog Unicode) , 5 6 7 bytes

Golpeou um byte mudando ×/para !graças a Erik the Outgolfer

⊢∊!∘⍳

Experimente online!

Explicação

                          Range of numbers from 1 to argument, 1 2 3 4 .. n
   !                       Factorial; 1! 2! 3! 4! .. n!
⊢∊                         Is the right argument a member of this list?

Soma acumulada?
Freira vazando

@LeakyNun Fixed
Kritixi Lithos

Um byte extra no GNU APL 1.2 N∊×\⍳N←⎕Como isso leva um argumento? Não vejo em nlugar algum. Isso é específico do Dyalog?
Arc676

2
@ Arc676 Minha solução é um trem e você chama assim: (⊢∊(×/⍳)) right_argumentcomo você pode ver no link TIO. E o refere-se ao argumento correto.
Kritixi Lithos

Notas: O AGL economizará um byte; ⊢∊×\ä⍳. A solução "correta" (mas mais longa) seria 0=1|!⍣¯1; "O fatorial inverso é um número inteiro?"
Adám

2

JavaScript (ES6), 71 bytes

Isso recebe a entrada como argumento de função e alerté a saída. Saídas 0para falsey e 1para verdade.

f=n=>n?n*f(n-1):1;g=(n,r=0,i=0)=>{while(i<=n){r=f(i)==n|r;i++}alert(r)}

Explicação

O programa consiste em duas funções, fe g. fé uma função recursiva de computação fatorial e gé a principal função do programa. g assume ter um único argumento n. Ele define um argumento padrão rcom um valor 0 e outro argumento padrão com um valor igual a 0. Em seguida, itera sobre todos os Inteiros de 0 a ne, em cada iteração, verifica se a função faplicada sobre i(o índice atual) é igual n, ou seja, se né um fatorial de i. Se esse for o caso, ro valor de é definido como 1. No final da função, ré alerted.

Snippet de teste

( Observação: o snippet gera usando console.log()como ninguém como muitos desses alert()s irritantes . )

f=n=>n?n*f(n-1):1;g=(n,r=0,i=0)=>{while(i<=n){r=f(i)==n|r;i++}console.log(r)}

g(1)
g(2)
g(3)
g(4)
g(5)
g(6)
g(7)
g(8)
g(24)
g(120)


A avaliação pode ser mais curta do que usar um bloco de código.
Downgoat

@Downgoat Como devo fazer isso? Desculpe se é muito óbvio! : P
Arjun

2

QBIC , 21 19 bytes

[:|q=q*a~q=b|_x1}?0

Explicação

[:|     Start a FOR loop from 1 to n
q=q*a   q starts as 1 and is multiplied by the FOR loop counter
        consecutively: q=1*1, *2, *3, *4 ... *n
~q=b|   If that product equals n
_x1     Then quit, printing a 1
}       Close the IF and the FOR
?0      If we're here, we didn't quit early and didn't find a factorial, print 0

Anteriormente

[:|q=q*a┘c=c+(q=b)}?c

Explicação:

[:|         Start a FOR loop from 1 to n
q=q*a       q starts as 1 and is multiplied by the FOR loop counter
            consecutively: q=1*1, *2, *3, *4 ... *n
┘           Syntactic line break
c=c+        c starts out at 0 and then keeps track of 
    (q=b)       how often our running total == n
}           Closes the FOR-loop
?c          Print c, which is 0 fir non-factorials and -1 otherwise.

2

Java 8, 59 bytes

i->{for(int j=1,c=0;j<=i;j*=++c)if(j==i)return 1;return 0;}

Testcode

import java.util.function.IntFunction;
import java.util.stream.IntStream;

public class IsFactorial
{
    public static IntFunction<Integer> isFactorial = i->
    {
        for(int j=1,c=0;j<=i;j*=++c)
            if(j==i)return 1;return 0;
    };

    public static int[] truthyCases = {1,2,6,24,120};
    public static int[] falsyCases = {3,4,5,7,8};

    public static void main(String[] args)
    {
        System.out.println
        (
            IntStream.of(truthyCases)
                .allMatch(i->isFactorial.apply(i)==1)
            && IntStream.of(falsyCases)
                .allMatch(i->isFactorial.apply(i)==0)
        );
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.