Trova il numero più piccolo che non divide N


50

Questa sfida è abbastanza semplice che è fondamentalmente tutto nel titolo: si è dato un intero positivo N e si dovrebbe restituire il più piccolo intero positivo che non è un divisore di N .

Un esempio: i divisori di N = 24 sono 1, 2, 3, 4, 6, 8, 12, 24. Il numero intero positivo più piccolo che non è in quell'elenco è 5 , quindi questo è il risultato che la tua soluzione dovrebbe trovare.

Questa è la sequenza OEIS A007978 .

Regole

È possibile scrivere un programma o una funzione e utilizzare uno dei nostri metodi standard per ricevere input e fornire output.

È possibile utilizzare qualsiasi linguaggio di programmazione , ma si noti che queste scappatoie sono vietate per impostazione predefinita.

Questo è , quindi la risposta valida più breve - misurata in byte - vince.

Casi test

I primi 100 termini sono:

2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 
3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 
2, 3, 2, 4, 2, 3, 2, 3, 2, 7, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 
3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3

In particolare, assicurati che la tua risposta funzioni per gli ingressi 1 e 2, nel qual caso il risultato è più grande dell'input.

E per alcuni casi di test più grandi:

N          f(N)
1234567    2
12252240   19
232792560  23

Ho trasformato la stringa di output di esempio in un vettore di numeri e mi sono resa conto che se la formatti su 24 colonne, è estremamente ripetitiva, fatta eccezione per la deviazione dispari.
Carcigenicato il

Questo ha senso, 24 è 0 mod 2, 3 e 4, quindi le uniche differenze sarebbero nelle colonne in cui i numeri sono> 4. È ancora più ripetitivo alla larghezza 120.
CalculatorFeline

Risposte:


18

Mathematica, 19 byte (codifica UTF-8)

1//.x_/;x∣#:>x+1&

Funzione senza nome che accetta un argomento intero diverso da zero e restituisce un numero intero positivo. La barra verticale a metà circa è in realtà il carattere a tre byte U + 2223, che indica la relazione di divisibilità in Mathematica. Spiegazione:

1                   Starting with 1,
 //.                apply the following rule until it stops mattering:
    x_                if you see a number x
      /;x∣#           such that x divides the function argument,
           :>x+1      replace it with x+1.
                &   Cool, that's a function.

Modificato per aggiungere: ngenisis sottolinea che //., per impostazione predefinita, ripeterà un massimo di 65536 volte. Quindi questa implementazione funziona per tutti i numeri di input inferiori al minimo comune multiplo degli interi da 1 a 65538 (in particolare, su tutti i numeri con al massimo 28436 cifre), ma tecnicamente non per tutti i numeri. Si può sostituire x//.ycon ReplaceRepeated[x,y,MaxIterations->∞]per correggere questo difetto, ma ovviamente al costo di 34 byte aggiuntivi.


Modo molto interessante ciclo senza l'utilizzo For, Whileecc
ngenisis

5
L'ho imparato da questo sito! Mi sto sicuramente divertendo a saperne di più su Mathematica trovandomi qui (posso giustificarlo sulla mia scheda attività ...?).
Greg Martin,

3
Quello non sembra matematica O_o
Mama Fun Roll

2
non lasciarti ingannare dalla mancanza di maiuscole e parentesi;)
Greg Martin


14

Pyth, 3 byte

f%Q

Fondamentalmente, fesegue il loop del codice fino a quando %QT( Q % Tdove si Ttrova la variabile di iterazione) è true.

Provalo online qui.


2
Ho visto il problema, fatto questa risposta, sono venuto qui per pubblicarlo, ho trovato il tuo. Molto bene!
Isaacg,

Ho scritto questo e mi sono sentito benissimo su me stesso: ho .V1In%Qb0bBvisto la tua risposta e non mi sento più così fantastico.
John Red,

@JohnRed Lol, penso che devi solo familiarizzare con i built-in in Pyth.
Busukxuan,

14

JavaScript (ES6), 25 23 byte

f=(n,k)=>n%k?k:f(n,-~k)

Nota: una cosa interessante qui è che il kparametro è inizializzato ex nihilo sulla prima iterazione. Questo funziona perché n % undefinedè NaN(falso come previsto) ed è -~undefineduguale 1. Nelle iterazioni successive, -~kè essenzialmente equivalente a k+1.

Test


Esattamente quello che ho ottenuto. Sarei sorpreso se fosse possibile qualcosa di più corto
ETHproductions

@ETHproductions A pensarci bene, ce n'è uno più breve. :-)
Arnauld

5
Um. Questo è ... uhm ... wow.
ETHproductions

13

Python, 43 36 35 byte

f=lambda n,d=2:d*(n%d>0)or f(n,d+1)


11

R, 28 byte

Abbastanza semplice, niente di speciale. Prende input da stdin, incrementa il valore Tfino a quando il imodulo Tè diverso da zero.

i=scan()
while(!i%%T)T=T+1
T

Se vuoi qualcosa di un po 'più elaborato, per 29 byte c'è quanto segue :

i=scan()
match(0,!i%%1:(i+1))

Ha spiegato:

i=scan(): Leggi ida stdin.

1:(i+1): Genera tutti i numeri interi da 1a i+1(la +1contabilità per i casi di 1e 2).

i%%1:(i+1) : Modulo l'ingresso di ogni numero nel nostro elenco.

!i%%1:(i+1): Nega l'elenco risultante; questo lo converte implicitamente in un tipo logico, tale che 0è FALSEe non lo è TRUE. Dopo aver negato, i TRUEvalori diventano FALSEe viceversa. Ora, tutti i valori originariamente diversi da zero sono codificati come FALSE.

match(0,!i%%1:(i+1)): Restituisce l'indice della prima istanza di 0nel nostro elenco. 0è FALSE, quindi questo restituisce l'indice del primo FALSEnell'elenco, che è il primo valore diverso da zero dall'operazione modulo. Da quando è iniziato il nostro elenco originale 1, l'indice è uguale al valore del più piccolo non divisore.


Bello, volevo solo suggerire di usarlo which.min, ma poi ho visto la modifica e sembra che matchfaccia un lavoro simile.
JAD

2
Inoltre, un bel trucco usando T, risparmiando la necessità di definirlo prima del whileciclo.
JAD

@JarkoDubbeldam Grazie! Non riesco a trovare un modo in cui l'approccio vettorializzato sia più breve whiledell'approccio, il che va bene in quanto richiede molta memoria per i grandi numeri. Il Ttrucco è una di quelle prelibatezze che sono ottime per il golf ma assolutamente orribili per la vera programmazione. (E ovviamente puoi usare Fanche quando hai bisogno di un 0.)
rturnbull

Puoi salvare due byte usando 0: i + 1 invece di 1: (i + 1) anche se non sono sicuro di come giochi con l'operatore %%.
antoine-sac

@ antoine-sac Sfortunatamente, %%ha la precedenza +, quindi i parentesi sono ancora necessari:, (0:i+1)con lo stesso numero di byte di 1:(i+1). In realtà avevo il primo in origine, ma l'ho cambiato in quest'ultimo in quanto è più facile da leggere.
rturnbull,

10

Haskell, 26 byte

f n=until((>0).mod n)(+1)1

Tutti se ne dimenticano until!


9

Brachylog , 10 byte

~{=#>:A'*}

Provalo online!

Questo è risultato molto simile alla soluzione originale (ma più breve di) di Fatalize. Da allora Fatalize è passato a un algoritmo diverso che si lega a questo tramite un metodo diverso, quindi dovrò spiegarlo da solo:

~{=#>:A'*}
~{       }    inverse of the following function:
  =           try possible values for the input, if it's unbound
   #>         the input is a positive integer
     :A'*     there is no A for which the input times A is the output

Quando invertiamo la funzione, scambiando "input" e "output", otteniamo un algoritmo abbastanza ragionevole (appena espresso in modo scomodo): "prova possibili numeri interi positivi, nel loro ordine naturale (cioè 1 verso l'alto), fino a trovare uno che non può essere moltiplicato per nulla per produrre l'input ". Brachylog non esegue calcoli in virgola mobile a meno che non siano noti tutti gli input, quindi prenderà in considerazione solo il numero intero A.


1
Non ho mai pensato di farlo, è pulito!
Fatalizza il


8

MUCCA, 174 byte

oomMOOMMMmoOmoOmoOMMMmOomOoMoOMMMmoOmoOmoOMMMmOoMOOmoO
MOomoOMoOmOoMOOmoOmoomoOMOOmOoMoOmoOMOomoomOomOoMOOmOo
moomoOMOomoomoOmoOMOOmOomOomOomOoOOMOOOMOomOOmoomOomOo
mOomOomOomoo

Provalo online!

Questo codice è solo parzialmente mio - implementa un algoritmo di modulo che ho portato da Brainfuck. Il resto del codice è mio. Tuttavia, poiché non ho scritto l'algoritmo del modulo, non ho davvero studiato come funziona e non posso documentare quella parte del codice. Invece, darò la mia solita suddivisione, seguita da una spiegazione più approfondita del perché il codice funziona.

Analisi del codice

oom                          ;Read input into [0].
MOO                          ;Loop while [0].  We never change [0], so the program only terminates forcibly after a print.
  MMMmoOmoOmoOMMMmOomOo      ; Copy [0] to [3] and navigate to [1].
  MoOMMMmoOmoOmoOMMM         ; Increment [1], and copy it to [4]
  mOo                        ; Navigate back to [3].
  MOO                        ; Modulus algorithm.  Direct port of brainfuck algorithm.
    moOMOomoOMoOmOo
    MOO
      moO
    moo
    moO
    MOO
      mOoMoOmoOMOo
    moo
    mOomOo
    MOO
      mOo
    moo
    moOMOo
  moo                        ; End modulus algorithm.
  moOmoO                     ; Navigate to [5].  This contains our modulus.
  MOO                        ; Only perform these operations if [5] is non-zero -- i.e. [0] % [1] != 0
    mOomOomOomOoOOMOOOMOomOO ;  Navigate to [1], print its contents, then error out.
  moo                        ; End condition
  mOomOomOomOomOo            ; Since we're still running, [0] % [1] == 0, so navigate back to [0] and try again.
moo                          ;End main loop.

Spiegazione

Il codice legge prima l'intero in [0]. Ogni iterazione del ciclo principale (linee da 2 a 26) incrementa [1], quindi copia tutto il necessario sull'algoritmo del modulo, che sputa il suo risultato in [5]. Se [5] contiene qualche valore, [1] è il numero che dobbiamo stampare. Lo stampiamo e quindi chiudiamo forzatamente il programma.

Poiché COW è un derivato di Brainfuck, funziona in modo relativamente simile al modo in cui Brainfuck funziona: striscia di nastro infinita, è possibile spostarsi a sinistra o a destra, aumentare o diminuire e "loop" mentre il valore corrente del nastro è diverso da zero. Oltre a Brainfuck, COW include un paio di utili funzioni.

(0) moo -- Equivalent to ]
(1) mOo -- Equivalent to <
(2) moO -- Equivalent to >
(3) mOO -- No equivalent.  Evaluate current tape value as instruction from this list.
(4) Moo -- If tape is 0, equivalent to ,; if tape is non-zero, equivalent to .
(5) MOo -- Equivalent to -
(6) MoO -- Equivalent to +
(7) MOO -- Equivalent to [
(8) OOO -- No equivalent.  Set tape (positive or negative) to 0
(9) MMM -- No equivalent.  If register is empty, copy tape to register.  If register is non-empty, paste register to tape and clear register.
(10) OOM -- No equivalent.  Print an integer from tape to STDOUT
(11) oom -- No equivalent.  Read an integer from STDIN and store it on tape

Il vero punto di interesse qui è l'istruzione 3, mOO. L'interprete legge il valore corrente del nastro ed esegue un'istruzione basata su quel valore del nastro. Se il valore è inferiore a 0, maggiore di 11 o uguale a 3, l'interprete termina il programma. Possiamo usarlo come una chiusura forzata rapida del loop principale (e del programma interamente) una volta trovato il nostro non divisore. Tutto quello che dobbiamo fare è stampare il nostro numero, cancellare [1] (con OOO), ridurlo a -1 con MOo, quindi eseguire l'istruzione -1 tramite la mOOquale termina il programma.

Il nastro stesso per questo programma funziona come segue:

[0]  -- Read-in integer from STDIN.
[1]  -- Current divisor to test
[2]  -- Placeholder for modulus algorithm
[3]  -- Temporary copy of [0] for use for modulus algorithm
[4]  -- Temporary copy of [1] for use for modulus algorithm
[5]  -- Placeholder for modulus algorithm.  Location of remainder at end of loop.
[6]  -- Placeholder for modulus algorithm
[7]  -- Placeholder for modulus algorithm

L'algoritmo del modulo cancella naturalmente [2], [3], [6] e [7] alla fine dell'operazione. I contenuti di [4] vengono sovrascritti con il comando incolla della riga 4 e [5] è zero quando [0] è divisibile per [1], quindi non è necessario cancellarlo. Se [5] è diverso da zero, abbandoniamo forzatamente la riga 23, quindi non dobbiamo preoccuparci.


7

05AB1E , 7 byte

Xµ¹NÖ_½

Provalo online!

Spiegazione

Xµ       # run until counter is 1
  ¹      # push input
   N     # push iteration counter
    Ö_   # push input % iteration counter != 0
      ½  # if true, increase counter
         # output last iteration

Bello, mi chiedevo come avresti fatto questo in modo iterativo in 05AB1E.
Magic Octopus Urn

7

Gelatina , 5 byte

1%@#Ḣ

Provalo online!

Spiegazione:

1%@#Ḣ
1  #      Find the first … numbers, counting up from 1, such that
 %@       dividing those numbers into … gives a truthy remainder
    Ḣ     then return the first

Questo è un orribile abuso di #; ci sono molti operatori in questo programma, ma un sacco di operandi mancanti. #vuole davvero che 1venga dato esplicitamente per qualche motivo (altrimenti cerca di default sull'input); tuttavia, tutto ciò che non è specificato nel programma viene impostato automaticamente sull'input del programma. (Ad esempio, se dai 24 come input, questo programma trova i primi 24 numeri che non dividono 24, quindi restituisce il primo; un po 'dispendioso, ma funziona.)


Accidenti a te Jelly! Pyth ti batte oggi! : D
John Red,

Solo ASCII:2%@1#
Erik the Outgolfer

7

C, 32 35 byte

i;f(x){for(i=1;x%++i<1;);return i;}

Modifica: aggiunto i=1nel ciclo

uso

main(c,v)char**v;{printf("%d",f(atoi(*++v)));}

Versione completa del programma, 64 byte:

main(c,v)char**v;{*++v;for(c=1;atoi(*v)%++c<1;);printf("%d",c);}

6

C #, 39 37 byte

n=>{int i=0;while(n%++i<1);return i;}

Risparmiato due byte grazie a Martin!


Mi piace while (! (N% ++ i)); meglio ma ovviamente, questo è il codice golf e 1 byte è 1 byte.
John Hamilton,

Funziona? Non sapevo che lo 0 fosse valutato automaticamente come falso
Alfie Goodacre,

Ah, l'ho provato in C ++, sì, non funziona con C #.
John Hamilton,

6

Perl, 19 byte

18 byte di codice + -pflag.

$_=$_%++$.?$.:redo

Per eseguirlo:

perl -pE '$_=$_%++$.?$.:redo' <<< 12252240

Spiegazioni non molto dettagliate :
- $.è una variabile speciale il cui valore predefinito è il numero di riga corrente dell'ultimo filehandle a cui si accede (stdin qui), quindi dopo aver letto la prima riga di input, è impostato su 1.
- $_contiene l'input e viene stampato implicitamente alla fine (grazie alla -pbandiera).
- redo(in quel contesto) ritiene che il programma sia in loop e ripeti l'attuale iterazione ( $.sarà solo diversa da quando è stata incrementata).
- Quindi se troviamo il numero più piccolo (memorizzato in $.) che non si divide $_, quindi impostiamo $_su di esso, altrimenti proviamo il numero successivo (grazie a redo).


6

Octave / MATLAB, 26 24 byte

@(n)find(mod(n,1:n+1),1)

find(...,1)restituisce l'indice ( 1basato su) del primo elemento diverso da zero del vettore nel primo argomento. Il primo argomento è [n mod 1, n mod 2, n mod 3, n mod 4,...,n mod (n+1)]Ciò significa che dobbiamo aggiungere +1all'indice, poiché iniziamo a testare a 1. Grazie @Giuseppe per -2 byte.

Provalo online!


@(n)find(mod(n,1:n+1),1)è più corto, no?
Giuseppe,

lo è davvero, grazie!
flawr

5

Gelatina , 6 byte

%R;‘TḢ

Provalo online!

Spiegazione:

                                               Assume 24 is our N
 R      Generate all numbers from 1 to N         [1, 2, 3, 4 .., 24]
  ;‘    Attach N+1 to that list (for cases 1,2)  [1, 2, 3, 4 .., 25]
%       And modulo-divide our input by it
        Yields a list with the remainder         [0, 0, 0, 0, 4 ...]
    T   Return all thruthy indexes               [5, 7, ...]
     Ḣ  Takes the first element of that list -->  5

Non conosco Jelly, ma potresti salvare un byte aumentando N prima di generare l'intervallo?
Emigna,

@Emigna Non conosco neanche Jelly;) Non vedo come: incrementarlo prima fa anche il test del modulo rispetto a N + 1 o aumenta i resti [1, 1, 1, 1, 5, ...].
Steenbergh,

Ah, capisco. Ho pensato che potrebbe essere possibile eseguire l'intervallo N% (1, N + 1), ma se aumenta l'N in entrambi i casi non va bene.
Emigna,

5

Perl 6 , 17 byte

{first $_%*,1..*}

Provalo

Allargato:

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

  # return the first value
  first

  # where the block's argument 「$_」 modulus the current value 「*」
  # doesn't return 0 ( WhateverCode lambda )
  $_ % *,
  # ( 「$_ !%% *」 would be the right way to write it )

  # from 1 to Whatever
  1 .. *
}

5

05AB1E , 6 byte

ÌL¹ÑK¬

Provalo online!

Inoltre, scrive "LINK!" ... Kinda ...

ÌL     # Push [1..n+2]
  ¹Ñ   # Push divisors of n.
    K¬ # Push a without characters of b, and take first item.

@Zgarb ha perso quella parte, l'incremento iniziale di 2 risolve il problema.
Magic Octopus Urn

1
Bello! Dimentico sempre che 05ab1e ha una funzione di divisione :)
Emigna,

5

Gelatina , 5 byte

‘ḍ€i0

Provalo online!

Come funziona

‘ḍ€i0  Main link. Argument: n

‘      Increment; yield n+1.
 ḍ€    Divisible each; test 1, ..., n+1 for divisibility by n.
   i0  Find the first index of 0.

4

Python 2.7.9, 32 byte

f=lambda n,d=1:n%d>0or-~f(n,d+1)

Test su Ideone

Ricorsivamente conta potenziali non divisori d. È più breve incrementare in modo ricorsivo il risultato rispetto all'output d. Un offset di 1viene raggiunto dal booleano di True, che è uguale 1, ma poiché d==1è sempre un divisore, l'output viene sempre convertito in un numero.

Python 2.7.9 viene utilizzato per consentire consentire 0or. Le versioni a partire dalla 2.7.10 tenteranno di analizzare 0orcome l'inizio di un numero ottale e avranno un errore di sintassi. Vedi questo su Ideone .


3

In realtà , 7 byte

;÷@uR-m

Provalo online! (nota: questa è una soluzione molto lenta e richiederà molto tempo per casi di test di grandi dimensioni)

Spiegazione:

;÷@uR-m
;÷       duplicate N, divisors
  @uR    range(1, N+2)
     -   set difference (values in [1, N+1] that are not divisors of N)
      m  minimum

3

Haskell , 29 byte

f n=[k|k<-[2..],mod n k>0]!!0

L'espressione [k|k<-[2..]]crea semplicemente un elenco infinito [2,3,4,5,...]. Con la condizione mod n k>0consentiamo solo quelli knell'elenco che non si dividono n. L'aggiunta !!0restituisce solo la prima voce (la voce all'indice 0) da quell'elenco.

Provalo online!


3

Dyalog APL , 8 byte

1⍳⍨0≠⍳|⊢

1⍳⍨ posizione del primo True in

0≠ i valori diversi da zero di

⍳|i resti di divisione di 1 ... N se divisi per

N

ProvaAPL online!

Nota: funziona per 1 e 2 perché 1⍳⍨restituisce 1 + la lunghezza del suo argomento se non ne viene trovato nessuno.


3

julia, 28 byte

N->findfirst(x->N%x>0,1:N+2)

Nota: poiché 1:N+2non alloca memoria non ci sono problemi di memoria per grandi Ns
- @flawr N+2salva per me alcuni byte
- Il suggerimento di @Martin ha salvato 1 byte


3

QBIC , 14 byte

:[a+1|~a%b|_Xb

Spiegazione:

:      Read the first cmd line param as a number, called 'a'
[a+1|  FOR (b=1 ; b <= a+1; b++) <-- a+1 for cases a = 1 or 2
~a%b   IF A modulo B ( == 0, implicit)
|_Xb   THEN exit the program, printing b
       [IF and FOR implicitly closed by QBIC]

3

PHP, 30 byte

for(;$argv[1]%++$i<1;);echo$i;

se eseguito dalla console con -ropzione (da thx a @ ais523)

php -r 'for(;$argv[1]%++$i<1;);echo$i;' 232792560

32 byte

<?for(;$argv[1]%++$i<1;);echo$i;

grazie a @manatwork per la rimozione di 1 byte

33 byte (originale)

<?for(;$argv[1]%++$i==0;);echo$i;

3
IIRC, <?non deve far parte del conteggio dei byte (poiché PHP ha una modalità a riga di comando che non lo richiede).

3
Il vecchio trucco: confronta contro <1anziché ==0.
arte

Dang. Ho raggiunto for(;!($argv[1]%$i);$i++);echo$i;. La tua è la mia naturale evoluzione. Questo ha il mio voto!
Ismael Miguel,

3

Cubix , 14 12 byte

I2/L/);?%<@O

Salvato 2 byte grazie a MickyT.

Provalo

Spiegazione

In forma cubica, il codice è:

    I 2
    / L
/ ) ; ? % < @ O
. . . . . . . .
    . .
    . .

Fondamentalmente, questo prende solo l'input e avvia un contatore. Quindi controlla ogni valore successivo del contatore fino a quando non trova uno che non è un fattore dell'input.


I2/L/);?%<@Oper un paio di byte in meno. Stesso processo generale, solo percorso diverso
MickyT

2

> <> , 15 +3 = 18 byte

1\n;
?\1+:{:}$%

Si prevede che l'input sia nello stack all'avvio del programma, quindi +3 byte per il -vflag. Provalo online!


2

Meduse , 12 10 byte

p\~~|1
 >i

Riceve input da STDIN e output su STDOUT. Provalo online!

Martin Ender ha salvato 2 byte, grazie!

Spiegazione

 \~~|
 >i

Questa parte è una funzione che utilizza il valore di input nella sua definizione.

   ~|

A questa ~cella viene assegnata una funzione, quindi capovolge i suoi argomenti: produce la funzione binaria "argomento sinistro modulo ( |) argomento destro". La funzione modulo integrata in Jellyfish prende i suoi argomenti in ordine inverso.

  ~~|
  i

A questa ~cella viene assegnato un valore e una funzione, quindi esegue un'applicazione parziale: produce la funzione binaria "input ( i) modulo right argomento". Chiamiamo quella funzione f .

 \~~|
 >i

A \-cell vengono assegnate due funzioni, quindi esegue l'iterazione: produce la funzione unaria "incremento ( >) fino a quando la funzione f applicata ai valori precedenti e correnti fornisce un risultato veritiero (diverso da zero), quindi restituisce il valore corrente". Ciò significa che l'argomento viene incrementato fino a quando non divide l'input.

p\~~|1
 >i

Infine, applichiamo questa funzione al valore iniziale 1e stampiamo il risultato con p.

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.