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 Integer
ou 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 é código-golfe , então o código mais curto em bytes vence!
fonte
1
?Respostas:
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.fonte
true.
é uma declaração etrue
não é)Gelatina , 3 bytes
Experimente online!
1 para sim, 0 para não.
Como funciona
fonte
Gelatina , 4 bytes
Não é a resposta mais curta da Jelly, mas é bastante eficiente.
Experimente online!
Como funciona
fonte
Regex ECMAScript,
733+690+158119118(117🐌)bytesMeu 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:
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.
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:
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 quen = 3 ! , 3 - 3 = 0 (e alterar o regex para ser indexado em 1 diminuiria o benefício do golfe).
((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\2
precisa capturar um valor deO 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)
fonte
JavaScript (ES6),
302928 bytesEspera um número inteiro positivo. Retorna
-1
por falsidade e-2
por verdade.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.
fonte
~
no final.Python 3 ,
3938 bytesUma 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
n
pori
, com um valor inicial de1
, até que o restante seja menor ou igual a, e1
então testa se o restante é menor1
, apenas os fatoriais terminam com um restante igual a1
e<
é um byte menor que==
.fonte
1
para todos os fatoriais, exceto1
pelos quais ele retornaTrue
.Java 8, 46 bytes
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:
fonte
Retina ,
5038 bytes12 bytes salvos graças ao @Neil, combinando encurtar o loop e livrando-se do
;
Experimente online!
Saídas
1
para verdadeiro e0
para falso..+
corresponde ao número inteiro1¶$&$*
substituindo-o por1
seguido por uma nova linha e a correspondência convertida em unárioO 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 se1
um múltiplo com muitos1
s na linha inferior e substitua-o por1$1¶$#2$*
a linha superior muitos1
s com outra1
, 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) ) muitos1
s, ou seja, dividindo o número inferior pelo número superiorQuando não for mais possível,
¶.$
forneça o número de correspondências desse regex, ou seja. existe uma1
linha na linha inferior, o que só acontece se o número for um fatorialSe no-crash / crash for permitido em vez de valores verdadeiros / falsos, então eu posso obter
3634 bytes.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.fonte
1
que está implícito$*
no final da substituição.$*
com as outras duas linhas.05AB1E , 4 bytes
Experimente online!
Explicação
fonte
L
exibe? Além disso,Å!
fornece uma lista de fatorial menor ou igual à entrada.D
aqui. Boa capturaÅ!
. Eu sempre esqueço os comandos da lista. Ele não salvará nenhum bytes, mas é mais eficiente, com certeza.C ++,
10210092 bytesPercorre todos os valores de
0
an
e calcula os cheques fatoriais e, em seguida, se é igualn
.Obrigado Christoph! (salvou 8 bytes)
fonte
int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}
.lround
elgamma
já são C ++ 11, então poderia simplesmente#include<cmath>
. Talvez você possa melhorar ainda mais minhas sugestões :) #Haskell ,
4326 bytesExperimente online!
fonte
f n=elem n$scanl1(*)[1..n]
é ridículo ineficiente, mas mais curto.40430
sem demora perceptível.divMod
por[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%)
.Haskell , 38 bytes
Experimente online! Exemplo de utilização:
(2#) 24
. RetornaTrue
ouFalse
.Este é o menor tempo que pude obter, ainda sendo muito eficiente. Mesmo para números tão grandes quanto
o resultado é dado imediatamente. A solução funciona dividindo a entrada
n
porm = 2,3,4,5,...
até que o resultado seja um oun
não seja divisível porm
.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 .fonte
MATL , 5 bytes
Experimente online!
Explicação
fonte
Fourier ,
4039 bytesExperimente 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:
fonte
Japonês ,
86 bytesExperimente online!
Isso gera 0 para falso e 1 para verdadeiro.
Explicação
fonte
aU ¦J
parax¥U
(mapear cadaX
paraX==U
e soma), embora não funcionará em TIO.2
becuaseo
só vai lhe dar[0,1]
. Aqui está uma correção com economia de 1 byte.Perl 5, 31 bytes
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.
fonte
Perl 6 , 29 bytes
Teste-o
Expandido:
fonte
{$_∈[\*] 1..$_}
. Outra abordagem interessante é2>*.polymod(1..*).sum
.setlX , 32 bytes
Cria uma função chamada
f
onde 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)
fonte
C (gcc), 33 bytes
Observe que alguns autores definem "número natural" como um número inteiro positivo . Por isso, não me importo que isso
f(0)
cause uma recursão infinita.fonte
R ,
2822 bytesExperimente online!
fonte
C # (.NET Core) , 68 bytes
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
int
o valor máximo de 2147483647 .C # (.NET Core) , 45 bytes
Experimente online!
Crédito para @KevinCruijssen por jogar no total 3 bytes de ambas as respostas!
fonte
&&
pode ser golfed para&
, e o arrasto;
não tem de ser contado para as funções de lambda. Além disso, não podeulong k=2
estaruint k=2
na sua resposta de 50 bytes?&
vs&&
. Eu pensei que estava recebendo um estouro de pilha, mas parece funcionar depois de tudo.ulong
tem 64 bits euint
32. Parece que outras pessoas estão usando,int
entã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?/
e%
entreulong
euint
, mas nãoulong
eint
. Não sabia disso :)double
você começa a ver o arredondamento em algum momento - por exemplo, 24! e 120! falhou. EnquantoSystem.Numerics.BigInteger
tem a maior precisão,int
é a resposta mais curta :)&&
operador de curto-circuito . Mas isso é código de golfe;) Que bom que você gostou do10000!
exemplo!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:
Versão rápida Ungolfed:
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==0
manipulaçã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!
fonte
Mathematica, 20 bytes
outra versão para testar grandes números (ver comentários)
testa até 1000!
fonte
Range[#]
comRange@#
:)!Range@#!~FreeQ~#&
.Cubix , 24 bytes
Experimente online
Cubificado
Começamos empurrando
1
,I
nput,1
para 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
,O
utilizamos e saímos. Se for negativo, fomos longe demais, então empurramos0
,O
utilizamos e saímos. Caso contrário, vemosfonte
Neim , 8 bytes
Explicação:
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:
Tente!
fonte
> <> ,
2422 bytes-2 bytes graças a @Aaron
Estou tentando um novo idioma (desde que minha licença do Mathematica expirou ...)
Experimente on-line ou no playground de peixes
Assume que o número de entrada já 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.
fonte
v>\n<^
em\\n/
; veja aquiAPL (Dyalog Unicode) , 5
67bytesGolpeou um byte mudando
×/
para!
graças a Erik the OutgolferExperimente online!
Explicação
fonte
N∊×\⍳N←⎕
Como isso leva um argumento? Não vejo emn
lugar algum. Isso é específico do Dyalog?(⊢∊(×/⍳)) right_argument
como você pode ver no link TIO. E o⊢
refere-se ao argumento correto.⊢∊×\ä⍳
. A solução "correta" (mas mais longa) seria0=1|!⍣¯1
; "O fatorial inverso é um número inteiro?"JavaScript (ES6), 71 bytes
Isso recebe a entrada como argumento de função e
alert
é a saída. Saídas0
para falsey e1
para verdade.Explicação
O programa consiste em duas funções,
f
eg
.f
é uma função recursiva de computação fatorial eg
é a principal função do programa.g
assume ter um único argumenton
. Ele define um argumento padrãor
com um valor 0 e outro argumento padrão com um valor igual a0
. Em seguida, itera sobre todos os Inteiros de 0 an
e, em cada iteração, verifica se a funçãof
aplicada sobrei
(o índice atual) é igualn
, ou seja, sen
é um fatorial dei
. Se esse for o caso,r
o valor de é definido como 1. No final da função,r
éalert
ed.Snippet de teste
( Observação: o snippet gera usando
console.log()
como ninguém como muitos dessesalert()
s irritantes . )fonte
QBIC ,
2119 bytesExplicação
Anteriormente
Explicação:
fonte
Java 8, 59 bytes
Testcode
fonte