Encuentra el número más pequeño que no divide N


50

Este desafío es bastante simple que es básicamente todo en el título: te dan un número entero positivo N y usted debe devolver el menor entero positivo que no es un divisor de N .

Un ejemplo: los divisores de N = 24 son 1, 2, 3, 4, 6, 8, 12, 24. El entero positivo más pequeño que no está en esa lista es 5 , así que ese es el resultado que debería encontrar su solución.

Esta es la secuencia OEIS A007978 .

Reglas

Puede escribir un programa o una función y utilizar cualquiera de nuestros métodos estándar para recibir entradas y proporcionar salidas.

Puede usar cualquier lenguaje de programación , pero tenga en cuenta que estas lagunas están prohibidas de forma predeterminada.

Este es el , por lo que gana la respuesta válida más corta, medida en bytes .

Casos de prueba

Los primeros 100 términos son:

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

En particular, asegúrese de que su respuesta funcione para las entradas 1 y 2, en cuyo caso el resultado es mayor que la entrada.

Y para algunos casos de prueba más grandes:

N          f(N)
1234567    2
12252240   19
232792560  23

Convertí la cadena de salida de muestra en un vector de números y me di cuenta de que si la formateas 24 columnas, es extremadamente repetitiva, excepto por la desviación impar.
Carcigenicate

Eso tiene sentido, 24 es 0 mod 2, 3 y 4, por lo que las únicas diferencias serían en columnas donde los números son> 4. Es aún más repetitivo en el ancho 120.
CalculatorFeline

Respuestas:


18

Mathematica, 19 bytes (codificación UTF-8)

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

Función sin nombre que toma un argumento entero distinto de cero y devuelve un entero positivo. La barra vertical aproximadamente a la mitad es en realidad el carácter de tres bytes U + 2223, que denota la relación de divisibilidad en Mathematica. Explicación:

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.

Editado para agregar: ngenisis señala que //., por defecto, iterará un máximo de 65536 veces. Entonces, esta implementación funciona para todos los números de entrada menores que el mínimo común múltiplo de los enteros del 1 al 65538 (en particular, en todos los números con un máximo de 28436 dígitos), pero técnicamente no para todos los números. Se puede reemplazar x//.ycon ReplaceRepeated[x,y,MaxIterations->∞]para solucionar este defecto, pero obviamente a costa de 34 bytes adicionales.


Forma muy interesante de bucle sin utilizar For, Whileetc
ngenisis

55
¡Lo aprendí de este sitio! Definitivamente estoy disfrutando aprender más sobre Mathematica al estar aquí (¿puedo justificar eso en mi hoja de tiempo ...?).
Greg Martin

3
Eso no se parece a Mathica O_o
Mama Fun Roll

2
no dejes que la falta de mayúsculas y corchetes te engañe;)
Greg Martin


14

Pyth, 3 bytes

f%Q

Básicamente, frepite el código hasta que %QT( Q % Tdonde Testá la variable de iteración) sea verdadero.

Pruébelo en línea aquí.


2
Vi el problema, hice esta respuesta, vine aquí para publicarlo, encontré el tuyo. ¡Bien hecho!
isaacg

Escribí esto y me sentí increíble conmigo mismo: .V1In%Qb0bBvi tu respuesta y ya no me siento tan increíble.
John Red

@JohnRed Lol, creo que solo necesitas familiarizarte con los elementos integrados en Pyth.
busukxuan

14

JavaScript (ES6), 25 23 bytes

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

Nota: Una cosa interesante aquí es que el kparámetro se inicializa ex nihilo en la primera iteración. Esto funciona porque n % undefinedes NaN(falso como se esperaba) e -~undefinedigual 1. En las próximas iteraciones, -~kes esencialmente equivalente a k+1.

Prueba


Exactamente lo que tengo. Me sorprendería si algo más corto es posible
ETHproductions

@ETHproductions Pensándolo bien, hay uno más corto. :-)
Arnauld

55
Um. Eso es ... uh ... wow.
ETHproductions

13

Python, 43 36 35 bytes

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


11

R, 28 bytes

Bastante sencillo, nada lujoso. Toma la entrada de stdin, incrementa el valor Thasta que el imódulo Tno sea cero.

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

Si quieres algo un poco más elegante, hay lo siguiente para 29 bytes :

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

Explicado:

i=scan(): Leído ide stdin.

1:(i+1): Genera todos los enteros de 1a i+1(la +1contabilidad de los casos de 1y 2).

i%%1:(i+1) : Modula la entrada por cada número en nuestra lista.

!i%%1:(i+1): Negar la lista resultante; esto lo convierte implícitamente a un tipo lógico, tal como 0is FALSEy non-zero is TRUE. Después de negar, los TRUEvalores se convierten FALSEy viceversa. Ahora, todos los valores originalmente distintos de cero se codifican como FALSE.

match(0,!i%%1:(i+1)): Devuelve el índice de la primera instancia de 0en nuestra lista. 0es decir FALSE, esto devuelve el índice del primero FALSEen la lista, que es el primer valor distinto de cero de la operación de módulo. Como nuestra lista original comenzó en 1, el índice es igual al valor del no divisor más pequeño.


Bien, solo quería sugerir el uso which.min, pero luego vi la edición y parece que matchhace un trabajo similar.
JAD

2
Además, es un buen truco T, ahorrando la necesidad de definirlo antes del whileciclo.
JAD

@JarkoDubbeldam ¡Gracias! No puedo encontrar una manera de que el enfoque vectorizado sea más corto que el whileenfoque, lo cual está bien, ya que requiere mucha memoria para el gran N. El Ttruco es una de esas delicias que es excelente para el golf pero absolutamente horrible para la programación real. (Y, por supuesto, también puedes usarlo Fcuando necesites a 0.)
rturnbull

Puede guardar dos bytes usando 0: i + 1 en lugar de 1: (i + 1) aunque no estoy seguro de cómo se juega con el operador %%.
antoine-sac

@ antoine-sac Desafortunadamente, %%tiene prioridad sobre +, por lo que los parens todavía son necesarios: (0:i+1)con el mismo número de bytes que 1:(i+1). De hecho, tuve el primero originalmente, pero lo cambié por el segundo ya que es más fácil de leer.
rturnbull

10

Haskell, 26 bytes

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

¡Todo el mundo se olvida until!


9

Brachylog , 10 bytes

~{=#>:A'*}

Pruébalo en línea!

Esto salió muy similar a (pero más corto que) la solución original de Fatalize. Fatalize ha cambiado a un algoritmo diferente que se vincula con este a través de un método diferente, por lo que tendré que explicarlo yo mismo:

~{=#>: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

Cuando invertimos la función, intercambiando "entrada" y "salida", obtenemos un algoritmo bastante razonable (expresado de una manera incómoda): "intente posibles enteros positivos, en su orden natural (es decir, 1 hacia arriba), hasta que encuentre uno que no se puede multiplicar por nada para producir la entrada ". Brachylog no realiza cálculos de punto flotante a menos que se conozcan todas las entradas, por lo que solo considerará el entero A.


1
Nunca pensé en hacer eso, ¡eso está bien!
Fatalize


8

VACA, 174 bytes

oomMOOMMMmoOmoOmoOMMMmOomOoMoOMMMmoOmoOmoOMMMmOoMOOmoO
MOomoOMoOmOoMOOmoOmoomoOMOOmOoMoOmoOMOomoomOomOoMOOmOo
moomoOMOomoomoOmoOMOOmOomOomOomOoOOMOOOMOomOOmoomOomOo
mOomOomOomoo

Pruébalo en línea!

Este código es solo parcialmente mío: implementa un algoritmo de módulo que porté desde brainfuck. El resto del código es mío. Sin embargo, como no escribí el algoritmo de módulo, no he investigado realmente cómo funciona y no puedo documentar esa parte del código. En cambio, daré mi desglose habitual, seguido de una explicación más detallada de por qué funciona el código.

Desglose de código

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.

Explicación

El código primero lee el entero en [0]. Cada iteración del bucle principal (líneas 2 a 26) incrementa [1], luego copia todo lo necesario al algoritmo de módulo, que escupe su resultado en [5]. Si [5] contiene algún valor, entonces [1] es el número que necesitamos imprimir. Lo imprimimos y luego forzamos a salir del programa.

Dado que COW es un derivado de brainfuck, funciona de manera relativamente similar a la forma en que funciona brainfuck: una tira infinita de cinta, puede moverse hacia la izquierda o hacia la derecha, aumentar o disminuir, y hacer un "bucle" mientras el valor actual de la cinta no es cero. Además de brainfuck, COW viene con un par de características útiles.

(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

El verdadero punto de interés aquí es la instrucción 3, mOO. El intérprete lee el valor de la cinta actual y ejecuta una instrucción basada en ese valor de la cinta. Si el valor es menor que 0, mayor que 11 o igual a 3, el intérprete finaliza el programa. Podemos usar esto como una salida rápida y sucia del bucle principal (y del programa por completo) una vez que hayamos encontrado nuestro no divisor. Todo lo que tenemos que hacer es imprimir nuestro número, borrar [1] (con OOO), disminuirlo a -1 con MOo, y luego ejecutar la instrucción -1 a través de la mOOcual finaliza el programa.

La cinta en sí para este programa funciona de la siguiente manera:

[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

El algoritmo de módulo borra naturalmente [2], [3], [6] y [7] al final de la operación. El contenido de [4] se sobrescribe con el registro pegar en la línea 4, y [5] es cero cuando [0] es divisible por [1], por lo que no tenemos que borrarlo. Si [5] no es cero, forzamos el cierre en la línea 23 para no tener que preocuparnos por eso.


7

05AB1E , 7 bytes

Xµ¹NÖ_½

Pruébalo en línea!

Explicación

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

Bien, me preguntaba cómo harías esto iterativamente en 05AB1E.
Magic Octopus Urn

7

Jalea , 5 bytes

1%@#Ḣ

Pruébalo en línea!

Explicación:

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

Este es un horrendo abuso de #; Hay muchos operadores en este programa, pero un montón de operandos faltantes. #realmente quiere 1que se proporcione explícitamente por alguna razón (de lo contrario, intenta ingresar la entrada por defecto); sin embargo, todo lo demás que no se especifica en el programa por defecto es la entrada del programa. (Entonces, por ejemplo, si da 24 como entrada, este programa encuentra los primeros 24 números que no dividen 24, luego devuelve el primero; es un poco despilfarrador, pero funciona).


¡Maldita sea Jelly! ¡Pyth te gana hoy! : D
John Red

Solo para ASCII:2%@1#
Erik the Outgolfer

7

C, 32 35 bytes

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

Editar: agregado i=1en el bucle

Uso

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

Versión completa del programa, 64 bytes:

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

6

C #, 39 37 bytes

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

¡Ahorré dos bytes gracias a Martin!


Me gusta while (! (N% ++ i)); mejor, pero por supuesto, este es el código de golf y 1 byte es 1 byte.
John Hamilton

¿Eso funciona? No sabía que el 0 evaluado a falso automáticamente
Alfie Goodacre

Ah, lo probé en C ++, sí, no funciona con C #.
John Hamilton

6

Perl, 19 bytes

18 bytes de código + -pbandera.

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

Para ejecutarlo:

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

Explicaciones no muy detalladas :
- $.es una variable especial cuyo valor predeterminado es el número de línea actual del último identificador de archivo al que se accedió (stdin aquí), por lo que después de leer la primera línea de entrada, se establece en 1.
- $_contiene la entrada y se imprime implícitamente al final (gracias a la -pbandera).
- redo(en ese contexto) considera que el programa está en un bucle y rehace la iteración actual (solo $.será diferente ya que se incrementó).
- Entonces, si encontramos el número más pequeño (almacenado $.) que no se divide $_, entonces lo configuramos, $_de lo contrario, probamos el siguiente número (gracias a redo).


6

Octava / MATLAB, 26 24 bytes

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

find(...,1)devuelve el índice ( 1basado en) del primer elemento distinto de cero del vector en el primer argumento. El primer argumento es [n mod 1, n mod 2, n mod 3, n mod 4,...,n mod (n+1)]Eso significa que tenemos que agregar +1al índice, ya que comenzamos a probar en 1. Gracias @Giuseppe por -2 bytes.

Pruébalo en línea!


@(n)find(mod(n,1:n+1),1)es más corto, ¿no es así?
Giuseppe

es de hecho, gracias!
falla

5

Jalea , 6 bytes

%R;‘TḢ

Pruébalo en línea!

Explicación:

                                               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

No conozco a Jelly, pero ¿podrías salvar un byte aumentando N antes de generar el rango?
Emigna

@Emigna, tampoco conozco a Jelly;) No veo cómo: incrementarlo antes también hace que la prueba de módulo contra N + 1 o aumente los restos [1, 1, 1, 1, 5, ...].
steenbergh

Ah, ya veo. Pensé que podría ser posible hacer un rango de N% (1, N + 1), pero si aumenta el N en ambos casos, no es bueno.
Emigna

5

Perl 6 , 17 bytes

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

Intentalo

Expandido:

{  # 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 bytes

ÌL¹ÑK¬

Pruébalo en línea!

Además, deletrea "¡ENLACE!" ... Un poco ...

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

@Zgarb perdió esa parte, el incremento inicial de 2 soluciona el problema.
Magic Octopus Urn

1
¡Agradable! Siempre olvido que 05ab1e tiene una función divisor :)
Emigna

5

Jalea , 5 bytes

‘ḍ€i0

Pruébalo en línea!

Cómo funciona

‘ḍ€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 bytes

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

Prueba de ideona

Recursivamente cuenta los posibles no divisores d. Es más corto recursivamente el incremento del resultado que la salida d. El 1booleano de logra un desplazamiento de True, que es igual 1, pero como d==1siempre es un divisor, la salida siempre se convierte en un número.

Python 2.7.9 se utiliza para permitir permitir 0or. Las versiones que comienzan con 2.7.10 intentarán analizarse 0orcomo el inicio de un número octal y recibirán un error de sintaxis. Mira esto en Ideone .


3

En realidad , 7 bytes

;÷@uR-m

Pruébalo en línea! (nota: esta es una solución muy lenta y tomará mucho tiempo para casos de prueba grandes)

Explicación:

;÷@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 bytes

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

La expresión [k|k<-[2..]]solo crea una lista infinita [2,3,4,5,...]. Con la condición mod n k>0solo permitimos aquellos ken la lista que no se dividen n. Anexar !!0solo devuelve la primera entrada (la entrada en el índice 0) de esa lista.

Pruébalo en línea!


3

Dyalog APL , 8 bytes

1⍳⍨0≠⍳|⊢

1⍳⍨ posición del primer verdadero en

0≠ los valores distintos de cero de

⍳|los restos de división de 1 ... N cuando se divide por

norte

TryAPL en línea!

Nota: esto funciona para 1 y 2 porque 1⍳⍨devuelve 1 + la longitud de su argumento si no se encuentra ninguno.


3

julia, 28 bytes

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

Nota: como 1:N+2no asigna memoria, no hay problemas de memoria para Ns grandes
- @flawr N+2guarda algunos bytes
- La sugerencia de @Martin guardó 1 bytes


3

QBIC , 14 bytes

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

Explicación:

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

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

si se ejecuta desde la consola con la -ropción (thx a @ ais523)

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

32 bytes

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

gracias a @manatwork por eliminar 1 byte

33 bytes (original)

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

3
IIRC, <?no tiene que ser parte de su recuento de bytes (porque PHP tiene un modo de línea de comandos que no lo requiere).

3
El viejo truco: comparar contra en <1lugar de ==0.
manatwork

Dang Alcancé a for(;!($argv[1]%$i);$i++);echo$i;. La tuya es la evolución natural de la mía. ¡Esto tiene mi voto a favor!
Ismael Miguel

3

Cubix , 14 12 bytes

I2/L/);?%<@O

Guardado 2 bytes gracias a MickyT.

Intentalo

Explicación

En forma de cubo, el código es:

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

Básicamente, esto solo toma la entrada y comienza un contador. Luego verifica cada valor sucesivo del contador hasta que encuentre uno que no sea un factor de la entrada.


I2/L/);?%<@Opor un par de bytes menos. El mismo proceso general, solo un camino diferente
MickyT

2

> <> , 15 +3 = 18 bytes

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

Se espera que la entrada esté en la pila al inicio del programa, por lo que +3 bytes para el -vindicador. Pruébalo en línea!


2

Medusa , 12 10 bytes

p\~~|1
 >i

Toma entradas de STDIN y salidas a STDOUT. Pruébalo en línea!

Martin Ender ahorró 2 bytes, ¡gracias!

Explicación

 \~~|
 >i

Esta parte es una función que utiliza el valor de entrada en su definición.

   ~|

Esta ~celda tiene una función, por lo que voltea sus argumentos: produce la función binaria "argumento izquierdo módulo ( |) argumento derecho". La función de módulo incorporada en Jellyfish toma sus argumentos en el orden inverso.

  ~~|
  i

A esta ~celda se le asigna un valor y una función, por lo que realiza una aplicación parcial: produce la función binaria "input ( i) modulo right argumento". Llamemos a esa función f .

 \~~|
 >i

La \celda-tiene dos funciones, por lo que realiza la iteración: produce la función unaria "increment ( >) hasta que la función f aplicada a valores anteriores y actuales da un resultado verdadero (distinto de cero), luego devuelve el valor actual". Esto significa que el argumento se incrementa hasta que no divide la entrada.

p\~~|1
 >i

Finalmente, aplicamos esta función al valor inicial 1e imprimimos el resultado con p.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.