Questo numero è fattoriale?


38

L'obiettivo

Dato un numero naturale come input, il tuo compito è quello di produrre un valore di verità o falsità in base al fatto che l'input sia un fattoriale di qualsiasi numero naturale. Puoi presumere che il numero di input sarà sempre compreso nell'intervallo di numeri supportati dalla tua lingua, ma non devi abusare dei tipi di numeri nativi per banalizzare il problema .

Si applicano scappatoie standard .


Ingresso

Ti verrà dato un numero naturale (di tipo Integero simile).

Puoi prendere l'input nel modo che desideri, tranne supponendo che si trovi in ​​una variabile predefinita. promptÈ consentita la lettura da file, console, finestra di dialogo ( ), casella di input, ecc. È consentito anche l'inserimento come argomento di funzione!


Produzione

Il tuo programma dovrebbe generare un valore di verità o di falso in base al fatto che il numero di input sia un fattoriale di qualsiasi numero naturale.

Assicurati che i tuoi valori di verità / falsità siano coerenti per tutti gli input, ad esempio, se stai usando una coppia di 1 e 0 per indicare rispettivamente i valori di verità e falsità, il tuo programma deve generare 1 per tutti gli input che dovrebbero avere valori di verità e 0 per tutti gli input che dovrebbero avere valori falsi.

Puoi prendere l'output nel modo che desideri tranne che scriverlo in una variabile. È consentita la scrittura su file, console, schermo ecc. Anche la funzione returnè consentita!

Il tuo programma non deve produrre errori per nessun input!


Casi test

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!)

Criterio vincente

Questo è , quindi vince il codice più corto in byte!


2
Se la lingua supporta solo numeri nell'intervallo {0,1}, posso aspettarmi che l'input sia sempre 1?
eush77,

11
@ eush77 L' abuso di tipi di numeri nativi per banalizzare un problema è proibito per impostazione predefinita.
Dennis,

1
è 4! un vero?
tuskiomi,

Domanda: Perché non si utilizzano le impostazioni predefinite I / O?
CalculatorFeline

Risposte:


37

Brachylog , 1 byte

Provalo online!

Spiegazione

è un built-in che afferma la seguente relazione: il suo output è il fattoriale del suo input. Diamo semplicemente un output impostato e vediamo se ha successo o meno con un input variabile.


6
@BetaDecay Questo è perché è il modo in cui è stampato in Prolog (questo ha a che fare con il fatto che true.è una dichiarazione e truenon lo è)
Fatalizza

6
È una soluzione banale, ma è intelligente per il modo in cui funziona il prologo.
Esolanging Fruit,


17
Prima le lingue personalizzate, quindi le codifiche personalizzate ... il codice golf è morto. Abbiamo completamente sovvertito l'intero punto di questi divertenti problemi in primo luogo
Alexander - Reinstate Monica

13
@Alexander Le codifiche personalizzate sono irrilevanti per qualsiasi problema tu stia parlando. Potrei usare qualsiasi codifica "esistente" e sarebbe comunque 1 byte. Sarebbe solo molto meno leggibile.
Fatalizza


19

Gelatina , 4 byte

Œ?IE

Non è la risposta Jelly più breve, ma è piuttosto efficiente.

Provalo online!

Come funziona

Œ?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
Perché noi programmatori di golf ci teniamo all'efficienza.
Okx,

12
È un notevole miglioramento della complessità al costo di un byte ed è un uso intelligente di un built-in, se così posso dire io stesso. ¯ \ _ (ツ) _ / ¯
Dennis,

È interessante notare che questo restituisce vero per 0, mentre la risposta a 3 byte di @ LeakyNun, sebbene molto più lenta in generale, restituisce correttamente falso per 0. Sono necessari byte extra per restituire falso per 0 in una risposta in tempo di esecuzione efficiente?
Deadcode

@Deadcode Il controllo di 0 richiederebbe due byte extra. In caso di dubbi se la definizione di "numeri naturali" dell'OP include 0 o meno. I casi di test non ...
Dennis

17

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

Il mio interesse per regex è stato suscitato con rinnovato vigore dopo oltre 4 anni e mezzo di inattività. Come tale, sono andato alla ricerca di set di numeri e funzioni più naturali da abbinare alle regex ECMAScript unari, ho ripreso a migliorare il mio motore regex e ho iniziato a ripassare anche su PCRE.

Sono affascinato dall'alienità di costruire funzioni matematiche nella regex di ECMAScript. I problemi devono essere affrontati da una prospettiva completamente diversa e fino all'arrivo di una visione chiave, non si sa se siano risolvibili affatto. Costringe a lanciare una rete molto più ampia per scoprire quali proprietà matematiche potrebbero essere utilizzate per rendere risolvibile un particolare problema.

La corrispondenza dei numeri fattoriali era un problema che non avevo nemmeno considerato di affrontare nel 2014 - o se lo fossi, solo momentaneamente, respingerlo perché troppo improbabile. Ma il mese scorso mi sono reso conto che poteva essere fatto.

Come con gli altri miei post regex ECMA, darò un avvertimento: consiglio vivamente di imparare a risolvere i problemi matematici unari in regex ECMAScript. È stato un viaggio affascinante per me e non voglio rovinarlo per nessuno che potrebbe potenzialmente provarlo da solo, in particolare quelli con un interesse per la teoria dei numeri. Vedi questo post precedente per un elenco di problemi raccomandati consecutivamente con tag spoiler da risolvere uno per uno.

Quindi non leggere oltre se non vuoi che qualche magia regex unaria avanzata venga viziata per te . Se vuoi fare un tentativo per capire da solo questa magia, ti consiglio vivamente di iniziare risolvendo alcuni problemi nella regex di ECMAScript come indicato in quel post collegato sopra.

Questa era la mia idea:

Il problema con la corrispondenza di questo set di numeri, come con la maggior parte degli altri, è che in ECMA di solito non è possibile tenere traccia di due numeri che cambiano in un ciclo. A volte possono essere multiplexati (ad esempio, i poteri della stessa base possono essere sommati in modo univoco), ma dipende dalle loro proprietà. Quindi non potevo semplicemente iniziare con il numero di input e dividerlo per un dividendo che aumenta gradualmente fino a raggiungere 1 (o almeno così pensavo).

Quindi ho fatto alcune ricerche sulle molteplicità dei fattori primi nei numeri fattoriali e ho appreso che esiste una formula per questo - ed è probabilmente quella che potrei implementare in una regex ECMA!

Dopo averlo calpestato per un po 'e nel frattempo ho costruito altre regex, mi sono incaricato di scrivere la regex fattoriale. Ci sono volute alcune ore, ma alla fine ha funzionato bene. Come bonus aggiuntivo, l'algoritmo potrebbe restituire fattoriale inverso come una corrispondenza. Non c'era modo di evitarlo, anche; per la natura stessa di come deve essere implementato nell'ECMA, è necessario indovinare quale sia il fattoriale inverso prima di fare qualsiasi altra cosa.

Il rovescio della medaglia è stato che questo algoritmo ha prodotto una regex molto lunga ... ma mi ha fatto piacere che ha finito per richiedere una tecnica utilizzata nella mia regex di moltiplicazione a 651 byte (quella che è risultata obsoleta, perché un metodo diverso ha portato a un 50 byte regex). Speravo che sorgesse un problema che richiedesse questo trucco: operare su due numeri, che sono entrambi poteri della stessa base, in un ciclo, sommandoli in modo univoco e separandoli ad ogni iterazione.

Ma a causa della difficoltà e della lunghezza di questo algoritmo, ho usato lookahead molecolari (della forma (?*...)) per implementarlo. Questa è una caratteristica non presente in ECMAScript o in qualsiasi altro motore regex tradizionale, ma che avevo implementato nel mio motore . Senza catture all'interno di uno sguardo molecolare, è funzionalmente equivalente a uno sguardo atomico, ma con catture può essere molto potente. Il motore tornerà indietro nel lookahead, e questo può essere usato per congetturare un valore che scorre attraverso tutte le possibilità (per i test successivi) senza consumare caratteri dell'input. Il loro utilizzo può rendere l'implementazione molto più pulita. (Lookbehind di lunghezza variabile è quantomeno uguale in potenza allo sguardo molecolare, ma quest'ultimo tende a rendere implementazioni più semplici ed eleganti.)

Quindi le lunghezze di 733 e 690 byte in realtà non rappresentano incarnazioni della soluzione compatibili con ECMAScript - da qui il "+" dopo di esse; è sicuramente possibile trasferire tale algoritmo su puro ECMAScript (che aumenterebbe un po 'la sua lunghezza) ma non ci sono riuscito ... perché ho pensato a un algoritmo molto più semplice e compatto! Uno che potrebbe essere facilmente implementato senza lookahead molecolari. È anche significativamente più veloce.

Questo nuovo, come il precedente, deve fare un'ipotesi sul fattoriale inverso, scorrere tutte le possibilità e testarle per una partita. Divide N per 2 per fare spazio per il lavoro che deve fare, quindi semina un ciclo in cui dividerà ripetutamente l'input per un divisore che inizia da 3 e aumenta ogni volta. (In quanto tale, 1! E 2! Non possono essere associati all'algoritmo principale e devono essere trattati separatamente.) Il divisore viene tenuto sotto controllo aggiungendolo al quoziente corrente; questi due numeri possono essere separati in modo univoco perché, supponendo M! == N, il quoziente corrente continuerà a essere divisibile per M fino a quando non sarà uguale a M.

Questa regex fa divisione per variabile nella porzione più interna del ciclo. L'algoritmo di divisione è lo stesso degli altri miei regex (e simile all'algoritmo di moltiplicazione): per A≤B, A * B = C se presente solo se C% A = 0 e B è il numero più grande che soddisfa B≤C e C% B = 0 e (CB- (A-1))% (B-1) = 0, dove C è il dividendo, A è il divisore e B è il quoziente. (Un algoritmo simile può essere usato nel caso in cui A≥B, e se non si sa come A paragona a B, è sufficiente un ulteriore test di divisibilità.)

Quindi adoro il fatto che il problema sia stato ridotto a una complessità ancora inferiore rispetto alla mia regex di Fibonacci ottimizzata per il golf , ma sospiro di delusione per il fatto che la mia tecnica multiplazione dei poteri della stessa base dovrà attendere un altro problema che in realtà lo richiede, perché questo non lo fa. È la storia del mio algoritmo di moltiplicazione a 651 byte che è stato soppiantato da uno da 50 byte, ancora una volta!

Modifica: sono stato in grado di rilasciare 1 byte (119 → 118) usando un trucco trovato da Grimy che può ridurre ulteriormente la divisione nel caso in cui il quoziente sia garantito maggiore o uguale al divisore.

Senza ulteriori indugi, ecco la regex:

Versione true / false (118 byte):

^((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?$

Provalo online!

Restituisce fattoriale inverso o nessuna corrispondenza (124 byte):

^(?=((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?$

Provalo online!

Restituisce fattoriale inverso o nessuna corrispondenza, in ECMAScript +\K (120 byte):

^((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 la versione a spaziatura libera con commenti:

  ^
  (?=                           # 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

La storia completa delle mie ottimizzazioni golfistiche di queste regex è su github:

regex per l'abbinamento dei numeri fattoriali - metodo di confronto di molteplicità, con lookahead.txt molecolare
regex per l'abbinamento dei numeri fattoriali.txt (quello mostrato sopra)

Si noti che ((x*)x*)può essere modificato in ((x*)+), diminuendo la dimensione di 1 byte (a 117 byte ) senza perdita della funzionalità corretta, ma la regex esplode esponenzialmente con lentezza. Tuttavia, questo trucco, mentre funziona in PCRE e .NET, non funziona in ECMAScript , a causa del suo comportamento quando incontra una corrispondenza di lunghezza zero in un ciclo . ((x+)+)funzionerebbe in ECMAScript, ma questo spezzerebbe la regex, perché per n=3!, \2deve acquisire un valore di 33=0 (e la modifica del regex per essere 1-index annullerebbe il vantaggio del golf di questo).

Il motore regex .NET non emula questo comportamento nella sua modalità ECMAScript, quindi il regex a 117 byte funziona:

Provalo online! (versione esponenziale-rallentamento, con motore regex .NET + emulazione ECMAScript)


14

JavaScript (ES6), 30 29 28 byte

Si aspetta un numero intero positivo. Restituisce -1per falsità e -2verità.

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 : questa funzione supporta input piuttosto grandi (dovresti leggere questo come: "piuttosto grande per JS"). Dovrebbe funzionare in modo sicuro fino a 2 53 - 1 . Certamente fallirà a partire da N = 121.645.100.408.831.992 , questo input essendo arrotondato a 19! = 121.645.100.408.832.000 a causa della sua codifica IEEE-754. Ci possono essere altri risultati falsi positivi prima 121.645.100.408.831.991 a causa di errori di arrotondamento, ma non so per certo.


Bello - mi piace molto l'uso ~alla fine.
Steve Bennett,

Puoi modificare in modo da poter annullare la votazione? (Se vuoi sapere perché ho effettuato il downgrade, è perché mi sono dimenticato delle insolite regole I / O di questa domanda.)
CalculatorFeline

@Arnauld Undownvoted.
CalculatorFeline

11

Python 3 , 39 38 byte

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

Una funzione ricorsiva prendendo un intero, n, restituendo un valore booleano inversley rappresenta il risultato (truthy: False, falsey: True)

Provalo online!

Si divide ripetutamente nper i, con un valore iniziale di 1, fino a quando il resto è inferiore o uguale a 1quindi verifica se quel resto è inferiore a quel momento 1, solo i fattoriali finiranno con un resto uguale a 1, e< è un byte più corto di ==.


@ovs siamo stati limitati a due output coerenti. Ciò, sfortunatamente, ritorna 1per tutti i fattoriali tranne 1per i quali ritorna True.
Jonathan Allan,

11

Java 8, 46 byte

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

Questo si basa sulla voce di Roman Gräf di cui sono stato in grado di eliminare una dozzina di byte. Lo avrei suggerito lì, ma non ho ancora abbastanza reputazione per commentare! Il mio codice Runner test modificato:

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 byte

12 byte salvati grazie a @Neil combinando accorciamento del loop e eliminando il ;

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

Provalo online!

Output 1per vero e 0falso.

.+ corrisponde all'intero numero

1¶$&$*sostituendolo con 1seguito da una nuova riga e la corrispondenza convertita in unaria

Il programma rimanente divide il numero unario nella riga inferiore aumentando successivamente numeri interi positivi, mantenuti traccia nella riga superiore, mentre è possibile farlo.

+` ciclo fino a quando la stringa rimane la stessa

  • ^(1+)¶(\1)+$abbina la riga superiore per molti 1secondi e un multiplo di essa per molti 1secondi sulla riga inferiore e sostituiscilo con

  • 1$1¶$#2$*la linea superiore molte 1s con un'altra 1, cioè aumentando il numero rappresentato dalla linea superiore di 1, seguito dalla linea nuova e dal numero di corrispondenze della linea superiore nella linea inferiore (cioè il conteggio delle partite del secondo gruppo di acquisizione ) molti 1s, cioè dividendo il numero in basso per il numero in alto

Una volta che non è più possibile farlo,

¶.$dare il numero di partite di questa regex, cioè. esiste un solitario 1nella riga inferiore, che accade solo se il numero è fattoriale


Se non sono consentiti crash / crash anziché valori di verità / falsità, allora posso ottenere 36 34 byte.

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

Questo segue lo stesso approccio, ma combina $*la terza e la quarta riga. La terza riga in poi fa parte dello stesso loop, {è l'abbreviazione di +(dove i (gruppi le restanti linee nel loop. I fattoriali finiscono nel programma che esce dal ciclo, mentre i non fattoriali rimangono bloccati nel ciclo per sempre fino a quando Retina non genera un OverflowException causata dall'ultima sostituzione non riuscita, avendo quindi il fondo in unario anziché in decimale e la prima sostituzione del ciclo converte la linea di fondo da decimale a unaria, quindi esplode rapidamente.


Salvare un byte rimuovendo 1come è implicito quando si $*trova alla fine della sostituzione.
Neil,

Meglio ancora, combinare $*le altre due linee.
Neil,


3
Sono impressionato dal fatto che tu abbia trovato il modo di arrestare Retina in modo condizionale. :)
Martin Ender,

2
Puoi aggiungere una spiegazione?
CalculatorFeline

8

05AB1E , 4 byte

L!QO

Provalo online!

Spiegazione

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

1
Non dovresti duplicare prima l'input perché ne Lapre l'input? Inoltre, Å!fornisce un elenco di fattoriale inferiore o uguale all'input.
Neil A.

@NeilA. Fortunatamente l'input viene nuovamente visualizzato se non ci sono abbastanza argomenti nello stack per un'operazione, quindi non ho bisogno Dqui. Buona cattura Å!. Dimentico sempre i comandi di lista. Non salverà alcun byte, ma è sicuramente più efficiente.
Emigna,

Non sapevo che l'input venisse espulso di nuovo ... che sicuramente avrebbe potuto salvare molti byte.
Neil A.

@NeilA. È una funzionalità abbastanza nuova. È stato aggiunto meno di un mese fa, credo.
Emigna,

8

C ++, 102 100 92 byte

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

Passa attraverso tutti i valori da 0a ne calcola il fattoriale e quindi controlla se è uguale a n.

Grazie Christoph! (salvato 8 byte)


Ciao! Benvenuti in PPCG! Bella prima risposta! Buona fortuna per il futuro!
Arjun,

Bella prima risposta! È possibile salvare un paio di byte come questo: int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}. lrounde lgammasono già in C ++ 11, quindi potrebbe semplicemente #include<cmath>. Forse puoi migliorare ulteriormente i miei suggerimenti :)
Christoph,

7

Haskell , 43 26 byte

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

Provalo online!

  • Salvato 17 byte, grazie a Laikoni

2
f n=elem n$scanl1(*)[1..n]è ridicolo inefficiente ma più breve.
Laikoni,

Non c'è qualche regola sull'efficienza del codice?
sudee,

1
Nessuno di cui sono a conoscenza. code-golf richiede una soluzione nel minor numero di byte possibile senza alcuna dichiarazione di efficienza. Anche sulla mia macchina la funzione funziona 40430senza notevoli ritardi.
Laikoni,

Intendevo qualcosa sulla falsariga di "la soluzione dovrebbe terminare entro un lasso di tempo ragionevole", ma immagino che si adatti ai requisiti in entrambi i modi. Grazie!
sudee,

1
Bello e semplice. Pensavo di poter fare meglio con divisione-per esempio, divModper [1..]successivamente fino a raggiungere un resto di zero con un quoziente di 1 (fattoriale) o un residuo diverso da zero (non fattoriale), ma non sembra essere l'approccio giusto. Ho trovato questa soluzione simpatico 46 caratteri, però: f|let x%n=mod n x==0&&(x+1)%div n x||n==1=(1%).
Jon Purdy,

6

Haskell , 38 byte

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

Provalo online! Esempio di utilizzo: (2#) 24. Restituisce Trueo False.

Questo è il più breve che potessi ottenere pur essendo molto efficiente. Anche per numeri grandi come

145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000

il risultato è immediatamente dato. La soluzione funziona dividendo l'inputn per m = 2,3,4,5,...fino a quando il risultato è uno o nnon è divisibile perm .

Per la soluzione più breve ma incredibile inefficiente a 26 byte che calcola gli n!input che non sono fattoriali, guarda qui .


5

MATL , 5 byte

t:Ypm

Provalo online!

Spiegazione

t     % Implicit input. Duplicate
:     % Range from 1 to that
Yp    % Cumulative product
m     % Ismember. Implicit display

5

Fourier , 40 39 byte

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

Provalo su FourIDE!

Moltiplica sostanzialmente il numero N per una quantità crescente fino a quando N è uguale a (uscita 1) o maggiore di (uscita 0) l'ingresso.

Spiegazione Pseudocodice:

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

Japt , 8 6 byte

ol x¥U

Provalo online!

Questo produce 0 per falso e 1 per vero.

Spiegazione

 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
Dovrei davvero aggiungere un "contiene" incorporato: P
ETHproductions

1
Oh, hey, è possibile modificare aU ¦Ja x¥U(mappare ogni Xa X==Ue sum), anche se non funziona su TIO.
ETHproductions

L'errore per 2perché oti darà solo [0,1]. Ecco una correzione con un risparmio di 1 byte.
Shaggy,

4

Perl 5, 31 byte

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

L'ingresso viene preso tramite STDIN, l'output è dato tramite il codice di uscita (1 per fattoriale, 0 per non fattoriale).

L'input è diviso per numeri interi successivi fino a quando è 1 o una frazione inferiore a uno, che viene troncata nel risultato.



4

Perl 6 , 29 byte

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

Provalo

Allargato:

{   # 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 byte: {$_∈[\*] 1..$_}. Un altro approccio interessante è 2>*.polymod(1..*).sum.
nwellnhof,

4

setlX , 32 byte

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

Crea una funzione chiamata f dove usi il tuo potenziale fattoriale come parametro.

Funziona con dimensioni intere arbitrarie ma è abbastanza inefficiente.

(a proposito: questa è la mia prima partecipazione a un puzzle di programmazione)




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);

Try it online!

Not the shortest solution, but works with really big numbers. The TIO link includes an example with 10000!.

Here is a shorter version that uses int which has a maximum value of 2147483647.

C# (.NET Core), 45 bytes

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

Try it online!

Credit to @KevinCruijssen for golfing 3 bytes in total from both answers!


2
The && can be golfed to &, and the trailing ; doesn't have to be counted for lambda functions. Also, can't the ulong k=2 be uint k=2 in your 50-byte answer?
Kevin Cruijssen

1
Good catch on the & vs &&. I thought I was getting a stack overflow, but it seems to work afterall. ulong is 64 bits while uint is 32. It looks like others are using int so maybe I'll just use that for the short version. With regards to the trailing ;, these are full functions, not lambdas, so I think I need include them?
dana

That's really strange how .NET can resolve / and % between ulong and uint, but not ulong and int. Didn't know that :)
dana

1
@Oliver - With double you start to see rounding at some point - for example, 24! and 120! fail. While System.Numerics.BigInteger has the most precision, int is the shortest answer :)
dana

1
@Deadcode - You are right about 0 :) Based on the examples in the challenge, I interpreted "natural numbers" to mean 1,2,... I agree that in the real world, it is better to use the short circuiting && operator. But this is code golf ;) Glad you like the 10000! example!
dana

4

C++ (clang), 51 bytes

Recursion wins out as far as golfing goes.

51 bytes, zero is true:

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

This sacrifices quite a lot of speed for 1 byte of savings. Replace the | with || to make it fast, due to short-circuit evaluation of the logical OR.

Try it online! (51 byte slow version)
Try it online! (52 byte fast version)

Ungolfed slow version:

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);
}

Ungolfed fast version:

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);
}

There are many ways to rearrange this.

52 bytes, nonzero is true:

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

Try it online!

52 bytes, zero is true:

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

Try it online!

Before resorting to recursion, I tried making some iterative versions, and they came close.

54 bytes, nonzero is true:

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

Try it online!

54 bytes, zero is true (based on Roman Gräf's Java 8 submission):

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

Try it online!

Now, for the bottom of the barrel, recursive versions with no n==0 handling (I consider these invalid, because 0 is a natural number, and any definition in which it is not makes for "natural numbers" of very limited use). In the below versions, the infinite recursion of f(0) either triggers a segfault due to overflowing the stack, or with compilers that optimize it to iteration, loops endlessly:

48 bytes, zero is true:

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

Try it online!

48 bytes, zero is true (based on Hagen von Eitzen's 33 byte C (gcc) submission):

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

Try it online!


50 EDIT: 49, without recursion.
Grimmy

Back to recursion for 48. And you probably won’t like this, but 44 by using a global var.
Grimmy

3

Mathematica, 20 bytes

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

other version to test big numbers (see comments)

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

tests up to 1000!


2
As I understand the question, if Mathematica is capable of taking 1001! as an input then this doesn't meet the spec.
Peter Taylor

2
You could even save three bytes while making it valid for all inputs. Just replace 10^3 with # ; you could save another byte with using Range@#
Julien Kluge

@Julien Klugethen searching for 1243234 would take forever...
J42161217

1
I think you can save another byte by replacing Range[#] with Range@# :)
numbermaniac

3
Looks like you can save yet another byte with infix syntax: !Range@#!~FreeQ~#&.
numbermaniac

3

Cubix, 24 bytes

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

Try it online

Cubified

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

We start by pushing 1, Input, 1 onto the stack. These will be our index, our target, and our accumulator, respectively.

We then loop. At each iteration, we subtract the accumulator from the input. If the result is 0, we're done, so we push 1, Output, and exit. If it's negative, we've gone too far, so we push 0, Output, and exit. Otherwise, we see

;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

𝐈Γ𝐈𝐩₁𝔼)𝐠

Explanation:

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]

Try it!

Neim, 3 bytes (non-competing)

Non-competing as the contains token and factorial token were added after the challenge was made.

𝐈𝐓𝕚

Explanation:

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]

Try it!


3

><>, 24 22 bytes

-2 bytes thanks to @Aaron

I'm trying a new language (since my Mathematica licence expired…)

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

Try it online, or at the fish playground

Assumes the input number is already on the stack, and returns 0 or 1. It works by multiplying together the first n numbers until that stops being less than the input, and then printing 1 if it equals the input, and 0 if it doesn't.


You could transform you v>\n<^ into \\n/ ; see here
Aaron

@Aaron, that's brilliant, thank you!
Not a tree

3

APL (Dyalog Unicode), 5 6 7 bytes

Golfed a byte by changing ×/ to ! thanks to Erik the Outgolfer

⊢∊!∘⍳

Try it online!

Explanation

                          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?

Cumulative sum?
Leaky Nun

@LeakyNun Fixed
Kritixi Lithos

One extra byte in GNU APL 1.2 N∊×\⍳N←⎕ How does this take an argument? I don't see n anywhere. Is this a Dyalog-specific thing?
Arc676

2
@Arc676 My solution is a train and you call it like so: (⊢∊(×/⍳)) right_argument as you can see in the TIO link. And the refers to the right argument.
Kritixi Lithos

Notes: AGL will save you a byte; ⊢∊×\ä⍳. The "correct" (but longer) solution would be 0=1|!⍣¯1; "Is the inverse factorial an integer?"
Adám

2

JavaScript (ES6), 71 bytes

This takes in input as function argument and alerts the output. Outputs 0 for falsey and 1 for truthy.

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)}

Explanation

The program consists of two functions, f and g. f is a recursive factorial-computing function, and g is the main function of the program. g assumes to have a single argument n. It defines a default argument r with a value of 0 and another default argument with a value of 0. It, then, iterates over all the Integers from 0 to n, and, in each iteration, checks whether the function f applied over i (the current index) equals n, i.e. whether n is a factorial of i. If that happens to be the case, r's value is set to 1. At the end of the function, r is alerted.

Test Snippet

(Note: The snippet outputs using console.log() as nobody like too many of those pesky alert()s.)

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)


Eval might be shorter than using a code block.
Downgoat

@Downgoat How should I do that? Sorry if it's too obvious! :P
Arjun

2

QBIC, 21 19 bytes

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

Explanation

[:|     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

Previously

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

Explanation:

[:|         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)
        );
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.