Trouver le plus petit nombre qui ne divise pas N


50

Ce défi est assez simple qu'il est fondamentalement tout dans le titre: on vous donne un entier positif N et vous devez retourner le plus petit entier positif qui n'est pas un diviseur de N .

Un exemple: les diviseurs de N = 24 sont 1, 2, 3, 4, 6, 8, 12, 24. Le plus petit entier positif qui ne figure pas dans cette liste est 5 , c'est donc le résultat que votre solution devrait trouver.

Ceci est la séquence OEIS A007978 .

Règles

Vous pouvez écrire un programme ou une fonction et utiliser l’une quelconque de nos méthodes standard de réception d’entrée et de sortie.

Vous pouvez utiliser n'importe quel langage de programmation , mais notez que ces failles sont interdites par défaut.

C'est du , donc la réponse valide la plus courte - mesurée en octets - est gagnante.

Cas de test

Les 100 premiers termes sont:

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 particulier, assurez-vous que votre réponse fonctionne pour les entrées 1 et 2, auquel cas le résultat est plus grand que l'entrée.

Et pour certains cas de test plus importants:

N          f(N)
1234567    2
12252240   19
232792560  23

J'ai transformé l'exemple de chaîne de sortie en un vecteur de nombres et me suis rendu compte que si vous le formatez sur 24 colonnes, il est extrêmement répétitif, à l'exception de l'écart impair.
Carcigenicate

Cela a du sens, 24 correspond à 0 mod 2, 3 et 4, de sorte que les seules différences sont dans les colonnes où les nombres sont> 4. C'est encore plus répétitif à la largeur 120.
CalculatriceFeline le

Réponses:


18

Mathematica, 19 octets (codage UTF-8)

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

Fonction sans nom prenant un argument entier différent de zéro et renvoyant un entier positif. La barre verticale à peu près à mi-chemin est en fait le caractère à trois octets U + 2223, qui indique la relation de divisibilité dans Mathematica. Explication:

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.

Edité à ajouter: ngenisis indique que //., par défaut, le nombre maximal de répétitions sera de 65 536 fois. Cette implémentation fonctionne donc pour tous les nombres en entrée inférieurs au plus petit commun multiple des nombres entiers compris entre 1 et 65538 (en particulier pour tous les nombres comportant au plus 28 436 chiffres), mais pas techniquement pour tous les nombres. On peut remplacer x//.ypar ReplaceRepeated[x,y,MaxIterations->∞]pour réparer cette faille, mais au prix de 34 octets supplémentaires.


Manière très intéressante à boucle sans utiliser For, Whileetc
ngenisis

5
Je l'ai appris de ce site! J'apprécie vraiment d'apprendre davantage sur Mathematica en étant ici (puis-je justifier cela sur ma feuille de temps ...?).
Greg Martin

3
Cela ne ressemble pas à mathematica O_o
Mama Fun Roll

2
ne laissez pas le manque de majuscules et de crochets vous tromper;)
Greg Martin


14

Pyth, 3 octets

f%Q

Fondamentalement, fboucle le code jusqu'à ce que %QT( Q % TTest la variable d'itération) est vrai.

Essayez-le en ligne ici.


2
Vu le problème, fait cette réponse, est venu ici pour le poster, a trouvé le vôtre. Bien joué!
isaacg

J'ai écrit ceci et je me sentais vraiment bien dans ma .V1In%Qb0bBpeau : Vous avez vu votre réponse et vous ne vous sentez plus aussi bien.
John Red

@JohnRed Lol, je pense que vous avez juste besoin de vous familiariser avec les fonctionnalités intégrées à Pyth.
busukxuan

14

JavaScript (ES6), 25 23 octets

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

Remarque: Une chose intéressante ici est que le kparamètre est initialisé ex nihilo à la première itération. Cela fonctionne car n % undefinedest NaN(fausseté comme prévu) et -~undefinedégal 1. Aux prochaines itérations, -~kest essentiellement équivalent à k+1.

Tester


Exactement ce que j'ai. Je serais surpris si quelque chose de plus court est possible
ETHproductions

@ETHproductions À la réflexion, il y en a un plus court. :-)
Arnauld

5
Hum C'est ... euh ... wow.
ETHproductions

13

Python, 43 36 35 octets

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


11

R, 28 octets

Assez simple, rien d'extraordinaire. Prend l'entrée de stdin, incrémente la valeur Tjusqu'à ce que imodulo Tsoit différent de zéro.

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

Si vous voulez quelque chose d'un peu plus sophistiqué, voici 29 octets :

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

A expliqué:

i=scan(): Lu ide stdin.

1:(i+1): Génère tous les entiers de 1à i+1(la +1comptabilité pour les cas de 1et 2).

i%%1:(i+1) : Modulo l'entrée par chaque numéro de notre liste.

!i%%1:(i+1): Nie la liste résultante; cela le convertit implicitement en un type logique, tel que 0is FALSEet non nul TRUE. Après négation, les TRUEvaleurs deviennent FALSEet vice-versa. Désormais, toutes les valeurs d'origine non nulles sont codées comme FALSE.

match(0,!i%%1:(i+1)): Retourne l'index de la première instance de 0dans notre liste. 0Ainsi FALSE, ceci retourne l'index du premier FALSEdans la liste, qui est la première valeur différente de zéro à partir de l'opération modulo. Depuis que notre liste initiale a commencé à 1, l'indice est égal à la valeur du plus petit non-diviseur.


Bien, je voulais juste suggérer d’utiliser which.min, mais j’ai vu le montage et il semble matchfaire un travail similaire.
JAD

2
Aussi, bon truc en utilisant T, évitant la nécessité de le définir avant la whileboucle.
JAD

@JarkoDubbeldam Merci! Je ne peux pas trouver un moyen pour que l'approche vectorisée soit plus courte que l' whileapproche, ce qui est correct car elle nécessite beaucoup de mémoire pour les grands N. Le Ttruc est un de ces gâteries qui est excellent pour le golf mais absolument horrible pour la programmation réelle. (Et bien sûr, vous pouvez Faussi utiliser quand vous avez besoin d'un 0.)
rturnbull

Vous pouvez économiser deux octets en utilisant 0: i + 1 au lieu de 1: (i + 1) bien que je ne sois pas sûr de la façon dont cela fonctionne avec l'opérateur %%.
asac - Réintégrez Monica le

@ antoine-sac Malheureusement, la %%priorité est sur +, les parens sont donc toujours nécessaires:, (0:i+1)avec le même nombre d'octets que 1:(i+1). J'avais en fait le premier à l'origine, mais j'ai changé pour le dernier, car il est plus facile à lire.
rturnbull

10

Haskell, 26 octets

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

Tout le monde oublie until!


9

Brachylog , 10 octets

~{=#>:A'*}

Essayez-le en ligne!

Cela est apparu très similaire à (mais plus court que) la solution originale de Fatalize. Fatalize a depuis basculé vers un algorithme différent qui est lié à celui-ci via une méthode différente, je vais donc devoir l'expliquer moi-même:

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

Lorsque nous inversons la fonction, en échangeant "entrée" et "sortie", nous obtenons un algorithme assez raisonnable (juste exprimé de manière maladroite): "essayez les entiers positifs possibles, dans leur ordre naturel (c'est-à-dire 1 et plus), jusqu'à ce que vous trouviez celui qui ne peut être multiplié par rien pour produire l’entrée ". Brachylog ne fait pas de calculs en virgule flottante à moins que toutes les entrées soient connues, donc il ne considérera que l'entier A.


1
Jamais pensé à faire ça, c'est chouette!
Fataliser


8

VACHE, 174 octets

oomMOOMMMmoOmoOmoOMMMmOomOoMoOMMMmoOmoOmoOMMMmOoMOOmoO
MOomoOMoOmOoMOOmoOmoomoOMOOmOoMoOmoOMOomoomOomOoMOOmOo
moomoOMOomoomoOmoOMOOmOomOomOomOoOOMOOOMOomOOmoomOomOo
mOomOomOomoo

Essayez-le en ligne!

Ce code n'est que partiellement le mien - il implémente un algorithme de module que j'ai porté de brainfuck. Le reste du code est le mien. Cependant, comme je n’ai pas écrit l’algorithme de module, je n’ai pas vraiment étudié son fonctionnement et je ne peux pas documenter cette partie du code. Au lieu de cela, je donnerai ma ventilation habituelle, suivie d'une explication plus détaillée de la raison pour laquelle le code fonctionne.

Code ventilation

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.

Explication

Le code lit d'abord le nombre entier dans [0]. Chaque itération de la boucle principale (lignes 2 à 26) incrémente [1], puis copie tout ce qui est nécessaire dans l’algorithme de module, qui extrait son résultat dans [5]. Si [5] contient une valeur, alors [1] est le nombre que nous devons imprimer. Nous l’imprimons, puis nous forçons à quitter le programme.

Puisque COW est un dérivé du brainfuck, il fonctionne relativement de la même manière que le brainfuck: une bande de bande infinie, vous pouvez vous déplacer à gauche ou à droite, augmenter ou diminuer et "boucler" tant que la valeur actuelle de la bande est non nulle. En plus de brainfuck, COW est livré avec quelques fonctionnalités utiles.

(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

Le point d'intérêt réel est l' instruction 3 ici, mOO. L'interprète lit la valeur actuelle de la bande et exécute une instruction en fonction de cette valeur. Si la valeur est inférieure à 0, supérieure à 11 ou égale à 3, l'interpréteur termine le programme. Nous pouvons utiliser cela comme une force rapide et sale de quitter la boucle principale (et le programme entièrement) une fois que nous avons trouvé notre non-diviseur. Tout ce que nous avons à faire, c'est imprimer notre numéro, effacer [1] (avec OOO), le décrémenter à -1 avec MOo, puis exécuter l'instruction -1 via mOOlaquelle se termine le programme.

La bande elle-même pour ce programme fonctionne comme suit:

[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'algorithme de module supprime naturellement [2], [3], [6] et [7] à la fin de l'opération. Le contenu de [4] est écrasé par le registre coller de la ligne 4 et [5] est égal à zéro lorsque [0] est divisible par [1], nous n'avons donc pas à l'effacer. Si [5] est non nul, nous forcons la ligne 23 pour ne pas avoir à nous en préoccuper.


7

05AB1E , 7 octets

Xµ¹NÖ_½

Essayez-le en ligne!

Explication

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, je me demandais comment tu ferais ça de manière itérative dans 05AB1E.
Urne magique Octopus le

7

Gelée , 5 octets

1%@#Ḣ

Essayez-le en ligne!

Explication:

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

Ceci est un abus horrible de #; il y a beaucoup d'opérateurs dans ce programme, mais une tonne d'opérandes manquants. #veut vraiment 1qu'on le donne explicitement pour une raison quelconque (sinon, il essaie de passer par défaut à l'entrée); Cependant, tout ce qui n'est pas spécifié dans le programme est par défaut l'entrée du programme. (Ainsi, par exemple, si vous donnez 24 en entrée, ce programme trouve les 24 premiers nombres qui ne divisent pas 24, puis retourne le premier; genre de gaspillage, mais cela fonctionne.)


Maudite gelée! Pyth vous bat aujourd'hui! : D
John Red

ASCII uniquement:2%@1#
Erik the Outgolfer

7

C, 32 35 octets

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

Edit: ajouté i=1dans la boucle

Usage

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

Version complète du programme, 64 octets:

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

6

C #, 39 37 octets

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

Sauvé deux octets grâce à Martin!


J'aime bien (! (N% ++ i)); mieux, mais bien sûr, c’est le code golf et 1 octet est 1 octet.
John Hamilton

Ça marche? Je ne savais pas que le 0 était automatiquement évalué comme faux
Alfie Goodacre le

Ah, je l'ai essayé en C ++, ouais ça ne marche pas avec C #.
John Hamilton

6

Perl, 19 octets

18 octets de code + -pdrapeau.

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

Pour l'exécuter:

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

Explications peu détaillées :
- $.est une variable spéciale dont la valeur par défaut est le numéro de la ligne du dernier descripteur de fichier utilisé (stdin ici). Ainsi, après avoir lu la première ligne d'entrée, il est mis à 1.
- $_conserve l'entrée et est implicitement imprimée à la fin (merci au -pdrapeau).
- redo(dans ce contexte) considère que le programme est dans une boucle et refait l'itération actuelle (ne $.sera différent que s'il a été incrémenté).
- Donc, si nous trouvons le plus petit nombre (stocké dans $.) qui ne se divise pas $_, alors nous le définissons $_, sinon, nous essayons le nombre suivant (grâce à redo).


6

Octave / MATLAB, 26 à 24 octets

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

find(...,1)renvoie l'index ( 1-based) du premier élément non nul du vecteur dans le premier argument. Le premier argument est que [n mod 1, n mod 2, n mod 3, n mod 4,...,n mod (n+1)]cela signifie que nous devons ajouter +1à l'index, car nous commençons à tester à 1. Merci @ Giuseppe pour -2 octets.

Essayez-le en ligne!


@(n)find(mod(n,1:n+1),1)est plus courte, n'est-ce pas?
Giuseppe

c'est bien, merci!
mardi

5

Gelée , 6 octets

%R;‘TḢ

Essayez-le en ligne!

Explication:

                                               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

Je ne connais pas Jelly, mais pourriez-vous économiser un octet en augmentant N avant de générer la plage?
Emigna

@ Emigna, je ne connais pas Jelly non plus;) Je ne vois pas comment: l'incrémenter plus tôt rend également le test modulo contre N + 1, ou augmente les restes [1, 1, 1, 1, 5, ...].
Steenbergh

Ah, je vois. Je pensais qu'il serait possible de faire N% (1, N + 1), mais si cela augmente le N dans les deux cas, ce n'est pas bon.
Emigna

5

Perl 6 , 17 octets

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

L'essayer

Étendu:

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

Gelée , 5 octets

‘ḍ€i0

Essayez-le en ligne!

Comment ça fonctionne

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

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

Test sur Ideone

Compte récursivement les non-diviseurs potentiels d. Il est plus court d'incrémenter le résultat de manière récursive que d'afficher d. Un décalage de 1est obtenu par le booléen de True, ce qui est égal 1, mais d==1étant toujours un diviseur, la sortie est toujours convertie en un nombre.

Python 2.7.9 est utilisé pour permettre 0or. Les versions commençant à la version 2.7.10 essaieront d’analyser 0orle début d’un nombre octal et une erreur de syntaxe. Voir cela sur Ideone .


3

En fait , 7 octets

;÷@uR-m

Essayez-le en ligne! (note: c'est une solution très lente, et cela prendra beaucoup de temps pour les cas de test volumineux)

Explication:

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

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

L'expression [k|k<-[2..]]crée simplement une liste infinie [2,3,4,5,...]. Avec cette condition, mod n k>0nous n'autorisons que ceux kde la liste qui ne se divisent pas n. Ajouter !!0ne retourne que la première entrée (l'entrée à l'index 0) de cette liste.

Essayez-le en ligne!


3

Dyalog APL , 8 octets

1⍳⍨0≠⍳|⊢

1⍳⍨ position de premier vrai dans

0≠ les valeurs non nulles de

⍳|les restes de division de 1 ... N quand divisé par

N

TryAPL en ligne!

Remarque: cela fonctionne pour 1 et 2 car 1⍳⍨retourne 1 + la longueur de son argument si aucun n'est trouvé.


3

julia, 28 octets

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

Note: comme 1:N+2ne pas allouer de mémoire, il n'y a pas de problèmes de mémoire pour les gros Ns
- @flawr N+2enregistrez pour moi quelques octets
- La suggestion de @Martin a été sauvegardée de 1 octet


3

QBIC , 14 octets

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

Explication:

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

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

si exécuté depuis la console avec -roption (merci à @ ais523)

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

32 octets

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

merci à @manatwork pour la suppression de 1 octet

33 octets (original)

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

3
IIRC, le <?ne doit pas nécessairement faire partie de votre nombre d'octets (parce que PHP a un mode de ligne de commande qui ne l'exige pas).

3
Le vieux truc: comparer contre <1au lieu de ==0.
Manatwork

Dang. J'ai atteint à for(;!($argv[1]%$i);$i++);echo$i;. Le vôtre est l'évolution naturelle de la mienne. Cela a mon vote positif!
Ismael Miguel

3

Cubix , 14 12 octets

I2/L/);?%<@O

Sauvegardé 2 octets grâce à MickyT.

L'essayer

Explication

Sous forme de cube, le code est:

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

Fondamentalement, cela prend juste l'entrée et démarre un compteur. Il vérifie ensuite chaque valeur successive du compteur jusqu'à ce qu'il en trouve une qui n'est pas un facteur de l'entrée.


I2/L/);?%<@Opour quelques octets de moins. Même processus général, chemin différent
MickyT


2

Méduse , 12 à 10 octets

p\~~|1
 >i

Prend l'entrée de STDIN et les sorties vers STDOUT. Essayez-le en ligne!

Martin Ender a économisé 2 octets, merci!

Explication

 \~~|
 >i

Cette partie est une fonction qui utilise la valeur d’entrée dans sa définition.

   ~|

Cette ~fonction reçoit une fonction, elle retourne donc ses arguments: elle produit la fonction binaire "argument gauche argument modulo ( |) argument droit". La fonction modulo intégrée à Jellyfish prend ses arguments dans l'ordre inverse.

  ~~|
  i

Cette ~-cellule reçoit une valeur et une fonction, elle effectue donc une application partielle: elle produit la fonction binaire "input ( i) modulo right argument". Appelons cette fonction f .

 \~~|
 >i

La \cellule a deux fonctions, elle effectue donc une itération: elle produit la fonction unaire "increment ( >) jusqu'à ce que la fonction f appliquée aux valeurs précédentes et actuelles donne un résultat véridique (différent de zéro), puis renvoie la valeur actuelle". Cela signifie que l'argument est incrémenté jusqu'à ce qu'il ne divise pas l'entrée.

p\~~|1
 >i

Enfin, nous appliquons cette fonction à la valeur initiale 1et imprimons le résultat avec p.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.