La grenouille prime 🐾


44

La "prime grenouille" est un animal Ă©trange qui saute entre les entiers, jusqu'Ă  ce qu'il arrive le 3 ou le 19 ...


Votre programme doit accepter un entier nen entrée et afficher le résultat de l'algorithme ci-dessous ( 3ou 19).

Pour un entier donné n >= 2:

  1. Soit fla position de la grenouille. Il est initialement réglé surn
  2. if f = 3ou f = 19: la grenouille arrĂȘte de sauter - arrĂȘtez le programme et la sortie f.
  3. if fis prime: la grenouille saute Ă  la position 2×f-1. Retournez Ă  l'Ă©tape 2.
  4. if fis composite: le plus grand diviseur premier de dbe f. La grenouille saute Ă  la position f-d. Retournez Ă  l'Ă©tape 2.

Exemples:

Un exemple avec n = 5:

5 > 9 > 6 > 3 stop

Le programme devrait sortir 3.

Un autre exemple avec n = 23:

23 > 45 > 40 > 35 > 28 > 21 > 14 > 7 > 13 > 25 > 20 > 15 > 10 > 5 > 9 > 6 > 3 stop

Encore une fois, le programme devrait sortir 3.

Cas de test:

10 => 3
74 => 19
94 => 3
417 => 3
991 => 19
9983 => 19

Vous pouvez supposer 1 < n < 1000000(j'ai vérifié le programme se termine pour ces valeurs).


3
3 boucle est [3 5 9 6 3] et 19 boucle est [19 37 73 145 116 87 58 29 57 38 19]
Arnaud

8
Variation Cool Collatz.
Arthur

3
Si nous ne pouvons pas prouver que la grenouille vient toujours Ă  3ou 19, nous pourrions changer le point 2. dans l'algorithme pour dire que si la grenouille est entrĂ©e dans une boucle quelconque (elle a rencontrĂ© une position qu'elle a dĂ©jĂ  vue), elle arrĂȘte le saut et renvoie le plus petit membre de cette boucle.
Jeppe Stig Nielsen

4
@PyRulez Si cela atteint cela, vous devriez probablement le dire Ă  l'OP.
mbomb007

3
@KeyuGan Peut-ĂȘtre que ce serait une bonne chose de publier sur Math.SE.
mbomb007

RĂ©ponses:



12

C (gcc),  87 à  65 octets

i,k;f(n){for(i=n;i>1;)for(k=i;k%--i;);n=~16&n-3?f(n-k?:n+n-1):n;}

Essayez-le en ligne!

Explication:

i,k;
f(n)
{
    for (i=n; i>1;)              // Loop until `k` is prime (the largest positive
                                 // `i` inequal to `k` that divides `k` is 1).
        for (k=i; k%--i;);       // Find the largest factor `k`

    n =                          // Returning like this is undefined behaviour,
                                 // but happens to work with gcc. This can be
                                 // replaced with `return` at the cost of 4 bytes.

        ~16&n-3                  // If `n` is 3 or 19, this expression equals 0 and
                                 // the algorithm halts. Otherwise the function
                                 // calls itself to perform the next iteration.

        ? f(n-k ?: n+n-1)        // If `n-k` is non-zero, n is not prime.
                                 // In this case call `f` with the value of `n-k`.
                                 // (Omitting the second `n-k` between `?` and `:`
                                 // is a gcc extension)
                                 // Otherwise call `f` with `2*n-1`.

        : n;                     // All done, `n` is returned.
}

Version portable (72 octets):

i,k;f(n){for(i=n;i>1;)for(k=i;k%--i;);return~16&n-3?f(n-k?n-k:n+n-1):n;}

Essayez-le en ligne!

Avec des noms de variables plus appropriés:

f,r;o(g){for(f=g;f>1;)for(r=f;r%--f;);g=~16&g-3?o(g-r?:g+g-1):g;}

Essayez-le en ligne!


5
Totalement aimer le jeu avec le mot grenouille et vos variables. +1
rayryeng

10

Retina , 63 62 octets

Merci à Neil d'avoir sauvegardé 1 octet.

{`^(11+)(?<!^\2+(11+))(?=\1+$)

^(?!(11+)\1+$|111$|1{19}$)1
$_

Essayez-le en ligne!

Entrée et sortie en unaire (la suite de tests utilise décimal pour plus de commodité). Cette solution devient incroyablement lente pour les entrées plus volumineuses. Le 9983cas de test expire sur TIO.

Explication

En raison de la {, les deux étapes du programme sont simplement exécutées en boucle jusqu'à ce qu'elles n'affectent plus la chaßne. Nous alternons entre des composites de traitement de scÚne et des primers de traitement de scÚne. Cela nous permet d'éviter un conditionnel réel (qui n'existe pas vraiment dans la rétine). Si la valeur actuelle est incorrecte pour la scÚne, la scÚne ne fait simplement rien.

^(11+)(?<!^\2+(11+))(?=\1+$)

Cela traite les composites. Nous correspondons à un diviseur potentiel (11+), mais nous vérifions ensuite que ce n'est pas composite (?<!^\2+(11+)), nous ne considérons donc que les facteurs premiers. En raison de la gourmandise de +, cela donne la priorité au facteur le plus important. Ensuite, nous vérifions que ce diviseur potentiel est un diviseur réel en essayant de faire correspondre le reste de la chaßne à des répétitions (?=\1+$). Ce diviseur est simplement supprimé de la chaßne, ce qui vous permet de soustraire quelque chose de maniÚre unaire.

^(?!(11+)\1+$|111$|1{19}$)1
$_

Cela traite les nombres premiers, sauf 3 et 19 . La perspective nĂ©gative s'assure que l'entrĂ©e n'est pas composite, ni 3 ni 19 . Ensuite, nous correspondons Ă  un seul 1et le remplaçons par la chaĂźne entiĂšre. Il s’agit d’une forme unaire de calcul n - 1 + n , qui est bien sĂ»r 2n - 1 .

Une fois que nous avons atteint 3 ou 19 , aucune étape ne peut correspondre à la chaßne et elle ne sera plus changée.


1
N'est-ce pas 1$'la mĂȘme chose $_?
Neil

4
@Neil Yes ......
Martin Ender

8

Coque , 15 octets

Ω₏p57§|o←Dáč -o→p

Essayez-le en ligne!

Explication

Ω₏p57§|o←Dáč -o→p  Implicit input n.
Ω                Do this to n until
 €p57            you get a prime factor of 57 (which are 3 and 19):
            o→p   Take last element of the prime factors of n
          áč -      and subtract it from n,
     §|           or if this gives 0 (so n is prime),
       o←D        double and decrement n.

8

Gelée , 12 octets

_Æfáč‚oក’$”Ðាáč‚

Essayez-le en ligne!

Comment ça marche

_Æfáč‚oក’$”Ðាáč‚  Maink link. Argument: n

        ”     Combine the links to the left into a chain.
         Ðា   Repeatedly call the chain monadically until the results are no longer
              unique. Yield the loop, i.e., the first occurrence of the first
              repeated integer, up to and excluding the repetition.
              Let's call the argument of the chain k.
_Æf             Subtract all prime factors of k from k.
   áč‚            Take the minimum of the differences. This yields 0 iff k is prime.
     ក’$        Compute 2k-1.
    o           Take the logical OR of the results.
              The result is now a rotation of either [3, 5, 9, 6] or
              [19, 37, 73, 145, 116, 87, 58, 29, 57, 38].
          áč‚   Take the minimum, yielding either 3 or 19.

7

Wolfram Language (Mathematica) , 65 ans66 68 octets

#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
  • -1 octets, merci Ă  Misha Lavrov!
  • -2 octets, merci Ă  Martin!

Essayez-le en ligne!

Inspiré par la pointe . Fondamentalement, il ne fait que recréer l'algorithme.

//.est RepeatedReplaceet /;est Condition. Ainsi, le code remplacera i_(une seule quantitĂ©) par If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i], jusqu’à i!=3&&!=19Ă©valuation True.

Référence:

référence


3
fait amusant: ce code ne fonctionnerait pas pour les grands nombres comme 10000000010parce quemaximum number of iterations is 2^16 (= 65536)
J42161217 Le

1
Un moyen un peu plus court de vérifier 3 et 19 est#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
Misha Lavrov

@MishaLavrov mais le résultat est incorrect?
Keyu Gan

@KeyuGan Pour moi, les deux fonctions donnent exactement le mĂȘme rĂ©sultat pour les entiers de 1 Ă  1000.
Misha Lavrov

1
Le problĂšme que vous rencontrez est peut-ĂȘtre l'insertion de caractĂšres non imprimables lorsque vous copiez et collez Ă  partir des commentaires, ce qui se produit parfois.
Misha Lavrov

6

05AB1E , 19 18 17 octets

[ĂÆ”Î·fsĂ„#pi·<Ă«DfΞ-

Essayez-le en ligne!

Explication

[      #            # loop until
 Ð   sÄ             # a copy of the current value is contained in
  Ɣηf               # the unique prime factors of 171
        pi          # if the current value is prime
          ·<        # double and decrement
            Ă«   -   # else subtract
             DfΞ    # the largest prime factor of a copy of the current value

4
+1 pour avoir une grenouille réelle dans votre code source<ë
Arnaud

Pour 57991 plus d'1 minute
RosLuP

@RosLuP: Vous feriez mieux de lancer de trĂšs longs cas de test hors ligne;)
Emigna

5

JavaScript (ES6), 73 71 69 octets

f=n=>57%n?f(n-(g=(k,d=1)=>++d<k?k%d?g(k,d):g(k/d):d<n?d:1-n)(n)):n%38

Cas de test

Formaté et commenté

f = n =>                 // given n
  57 % n ?               // if n is neither 3, 19 or 57 (and assuming that n is > 1):
    f(                   //   do a recursive call to f() with:
      n -                //     n minus
      (g = (k, d = 1) => //     the result of the recursive function g():
        ++d < k ?        //       increment d; if d is less than k:
          k % d ?        //         if d is not a divisor of k:
            g(k, d)      //           recursive call to g() with k and d unchanged
          :              //         else:
            g(k / d)     //           recursive call to g() with k = k / d, d = 1
        :                //       else, d is now the highest prime divisor of n:
          d < n ?        //         if d is less than n:
            d            //           n is composite: return d, which results in f(n - d)
          :              //         else:
            1 - n        //           n is prime: return 1 - n, which results in f(2n - 1)
      )(n)               //     initial call to g()
    )                    //   end of recursive call to f()
  :                      // else:
    n % 38               //   return n % 38 (gives 19 as expected if n = 57)

1
Intelligent, utiliser 57%net n%38au lieu de n==3|n==19. Sauvé 1 octet dans ma réponse Java aussi, alors merci!
Kevin Cruijssen

Dans l'idéone 57991, générez prog.js: 2: 26 InternalError: trop de récursion
RosLuP

In tio f = n => 57% nf (n- (g = (k, d = 1)) => ++ d <k? K% dg (k, d): g (k / d) : d <n? d: 1-n) (n)): n% 38 imprimer (f (57991)) gĂ©nĂ©rer un programme d'arrĂȘt pas de sortie, me semble-t-il
RosLuP

1
@RosLuP Il s'agit d'un dĂ©fi code-golf sans contrainte spĂ©cifique. Le consensus actuel est que les limitations de vitesse ou de mĂ©moire (telles que la taille de la pile d'appels) peuvent ĂȘtre ignorĂ©es, sauf indication contraire explicite dans la question. Je prends pour acquis que la limite de 1000000 est juste informative car la sĂ©quence n'a pas Ă©tĂ© testĂ©e au-delĂ . Incidemment, votre solution de 70 octets convient parfaitement et est probablement plus pertinente que la version de 93 octets pour un dĂ©fi code-golf.
Arnauld


4

Python 2 , 110 105 103 101 octets

-2 octets grĂące Ă  @Lynn

f=lambda n,i=2,k=0:i/n and(n*(n&~16==3)or f((2*i-1,k-i)[k>0]))or n%i and f(n,i+1,k)or f(n/i,2,k or n)

Essayez-le en ligne!


Python 2 , 116 112 105 octets

f=lambda n,i=2:i/n*i or n%i and f(n,i+1)or f(n/i)
n=input()
while~16&n-3:n=[2*n-1,n-f(n)][f(n)<n]
print n

Essayez-le en ligne!


1

n*(n&~16==3)or
enregistre 2 octets.
Lynn

Pour entrée 57991 sys.setrecursionlimit (20000)
RosLuP

4

MATL , 22 21 octets

Merci Ă  @Giuseppe pour la suppression de 1 octet!

`tZp?Eq}tYfX>-]tI19h-

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

`           % Do...while
  t         %   Duplicate. Takes (implicit) input the first time
  Zp        %   Is it prime? 
  ?         %   If so
    Eq      %     Times 2, minus 1
  }         %   Else
    t       %     Duplicate
    YfX>-   %     Prime divisors, maximum, subtract
  ]         %   End
  t         %   Duplicate
  I19h      %   Push array [3 19]
  -         %   Subtract, element-wise. The result is truthy if and only if
            %   it doesn't contain any zero
            % End (implicit). Next iteraton if top of the stack is truthy
            % Display (implicit)

4

Haskell - 154 octets

f 3=3
f 19=19
f n
 |(c==[1])=f$2*n-1
 |True=f$n-head c
 where c=z n;v b=reverse[x|x<-[1..(b-1)],b`rem`x==0];z j=case v j of[1]->[1];s->filter((==[1]).v)$s

Probablement il me manque quelques tours de golf ici, c’est ma premiùre tentative de golf haskell.


Bonjour et bienvenue sur le site. Vous n'avez pas besoin de nouvelles lignes ni d'espaces pour les patrons. Vous pouvez Ă©galement utiliser 1>0pour la Trueplupart du temps , mais souvent il pourrait ĂȘtre prĂ©fĂ©rable d'utiliser une assignation, par exemple c<-z n.
Wheat Wizard

1
[x|x<-[b-1,b-2..1],rem b x==0]est aussi court que reverse[x|x<-[1..(b-1)],brem x==0].
Wheat Wizard

2
Et une derniĂšre chose, si vous souhaitez parler de golf haskell, vous pouvez nous rejoindre dans Of Monads and Men .
Wheat Wizard

3

Neim , 17 16 octets

Í»Yđđ•šĂ·DđŒÎžáš«<#D𝐏𝐠𝕊

Explication:

Í»                   Start infinite loop
 D                  Duplicate
  Y                 Push 57
   𝐏                Prime factors: [3 19]
     𝕚              If the second-to-top of stack is in the list
      Ă·             Break the loop
       D            Duplicate
        đŒÎžáš«<       If prime, double and decrement
            #D𝐏𝐠𝕊   Otherwise, subtract the largest prime factor

Essayez-le en ligne!


3

Numéros R + , 102 à 99 octets

function(n){while(!n%in%c(3,19))n="if"(isPrime(n),2*n-1,n-max(primeFactors(n)))
n}
library(numbers)

Essayez-le en ligne!

R n'est pas connu pour ses programmes intĂ©grĂ©s de courte durĂ©e, et mĂȘme les packages en font autant!


3

Java 8, 140 135 134 94 octets

n->{for(int f,t,m=0;57%n>0;n=f>n?2*n-1:n-m)for(t=n,f=1;f++<t;)for(;t%f<1;t/=m=f);return n%38;}

-5 octets convertissant la méthode Java 7 récursive en lambda Java 8 avec boucle.
-1 octet implicite grùce à la réponse JavaScript de @Arnauld en changeant n!=3&n!=19et return n;en 57%n>0et return n%38;.
Je pense qu'il devrait ĂȘtre possible de combiner d'une maniĂšre ou d'une autre les deux boucles et de vĂ©rifier si nest un nombre premier et d'obtenir le facteur premier le plus important en mĂȘme temps, mais je ne peux pas le comprendre (pour le moment). Donc, ce sera la version initiale pour le moment.
-40 octets énormes grùce à @ Nevay, en faisant ce que je ne pouvais pas faire: combiner les boucles pour vérifier les nombres premiers et le plus grand facteur premier à la fois.

Explication:

Essayez-le ici (s’exĂ©cute mĂȘme 999999en moins d’une seconde).

n->{                  // Method with integer as both parameter and return-type
  for(int f,          //  Flag-integer
          t,          //  Temp-integer
          m=1;        //  Max prime factor integer, starting at 0
      57%n>0;         //  Loop (1) as long as `n` is not 3, not 19 and not 57:
      n=f>n?          //    After every iteration: if `f` is larger than `n`:
         2*n-1        //     Change `n` to `2*n-1`
        :             //    Else:
         n-m)         //     Change `n` to `n-m`
    for(t=n,          //   Reset `t` to `n`
        f=1;          //   Reset `f` to 1
        f++<t;)       //   Inner loop (2) from 2 to `t` (inclusive)
      for(;t%f<1;     //    Inner loop (3) as long as `t` is divisible by `f`
        t/=m=f;       //     Set `m` to `f`, and set `t` to `t/f`
      );              //    End of inner loop (3)
                      //   End of inner loop (2) (implicit / single-line body)
                      //  End of loop (1) (implicit / single-line body)
  return n%38;        //  Return `n%38`, which is now either 3 or 19
}                     // End of method

1
1 personnage avant d'ĂȘtre un polyglotte en C # :(
Ian H.

@IanH. Hehe, oui, c'est généralement le cas: n=>au lieu de n->. Et parfois, appels en minuscules / majuscules. ;)
Kevin Cruijssen

1
94 octets:n->{for(int f,t,m=0;57%n>0;n=f>n?2*n-1:n-m)for(t=n,f=1;f++<t;)for(;t%f<1;)t/=m=f;return n%38;}
Nevay

@ Merci! Je savais juste qu'il devrait ĂȘtre possible de combiner les boucles, mais je ne pouvais pas le comprendre. Un Ă©norme 40 octets sauvĂ©s grĂące Ă  vous!
Kevin Cruijssen

3

Bash, 73 octets

((57%$1))&&$0 $[(x=$1-`factor $1|sed 's/.* //'`)?x:2*$1-1]||echo $[$1%38]

Essayez-le en ligne! Modifié légÚrement pour travailler sur TIO.

Appelle rĂ©cursivement son propre fichier de script Ă  l'aide de $0, ce qui ne fonctionne pas dans TIO car il doit ĂȘtre exĂ©cutĂ© en tant que./filename.sh . Accepte l'entrĂ©e en tant qu'argument de ligne de commande.

Utilise la mĂȘme astuce de module que la rĂ©ponse JS de @ Arnauld .

Cas de test

$ for t in 5 23 10 74 94 417 991 9983;{ echo -n "$t -> "; ./prime-frog.sh $t; }
5 -> 3
23 -> 3
10 -> 3
74 -> 19
94 -> 3
417 -> 3
991 -> 19
9983 -> 19


1

Pyth , 19 octets

.W!/P57H?P_ZtyZ-ZeP

VĂ©rifiez tous les cas de test!

La réponse Husk m'a inspiré pour économiser 2 octets ( ,3 19to P57).

Comment ça marche

.W! / P57H? P_ZtyZ-ZeP - Programme complet.

.W - Tout en fonctionnel. Alors que A (valeur) est la vérité, valeur = B (valeur). Retourne la derniÚre valeur.
    P57 - Les facteurs premiers de 57 ([3, 19]).
   / H - Compter les occurrences de la valeur actuelle.
  ! - NON logique. 0 -> Vérité, tout le reste -> Falsy.
        ? P_Z - Si la valeur actuelle est prime, alors:
            tyZ - Double la valeur actuelle, décrémente.
               -ZeP - Sinon, soustrayez le facteur premier maximal de la valeur actuelle de lui-mĂȘme.
                     - Imprimer implicitement.

1

PowerShell , 150 126 octets

for($n="$args";57%$n){$a=$n;$d=for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}};if($n-in$d){$n+=$n-1}else{$n-=$d[-1]}}$n%38

Essayez-le en ligne! (avertissement: lent pour les grands nombres)

Méthode itérative. PowerShell ne comporte pas de factorisation intégrée, elle emprunte donc le code de ma réponse dans Prime Factors Buddies .

La premiÚre est notre forboucle. La configuration définit $nla valeur d'entrée et la conditionnelle maintient la boucle aussi longtemps qu'elle 57%$nest non nulle (merci à Arnauld pour cette astuce). A l'intérieur de la boucle, nous obtenons d'abord une liste de facteurs premiers de $a(définie sur $n). C'est le code emprunté à Prime Factors Buddies. Si l'entrée $aest déjà primordiale, cela reviendra juste $a(important plus tard). Cela (potentiellement juste $a) est stocké dans $d.

Suivant est un if/ elseconditionnel. Pour la ifpartie, nous vĂ©rifions si $nest -in $d. Si c’est le cas, cela signifie que $nc’est primordial, alors nous prenons $n=2*$n-1ou $n+=$n-1. Sinon, c'est composite, nous devons donc trouver le plus grand facteur premier. Cela signifie que nous devons prendre le dernier [-1]de $det soustrayez de $navec $n-=. Cela fonctionne parce que nous bouclons depuis 2et donc le dernier Ă©lĂ©ment de $dva dĂ©jĂ  ĂȘtre le plus grand.

Une fois que nous avons terminé la mise en boucle, il suffit de placer $n%38(encore une fois, merci Arnauld) sur le pipeline et la sortie est implicite.


1

APL (Dyalog Unicode) , 113 90 59 octets

⎕CY 'dfns'
g←{1pco ⍔:f(2Ă—â”)-1⋄f⍔-⊃⌜3pco ⍔}
f←{⍔∊3 19:⍔⋄g ⍔}

Essayez-le en ligne!

TIO fonctionne avec des valeurs allant jusqu'à ~ 3200. Testé sur mon PC pour le dernier test. Pour tester sur TIO, ajoutez simplement f valueau bas du code. Ne s'applique plus, merci à @ Adåm d'avoir signalé que mon algorithme de vérification de primalité était vraiment mauvais et m'a fourni un remplacement; également pour la sauvegarde de 23 octets.

ÉditĂ© pour corriger le nombre d'octets.

Comment ça marche

⎕CY 'dfns'                      # Imports every Defined Function, which is shorter than importing just the function I used (pco).

g←{1pco ⍔:f(2Ă—â”)-1⋄f⍔-⊃⌜3pco ⍔} 
g←                              # define g as
   1pco ⍔:                      # if the argument ⍔ is prime
          f(2Ă—â”)-1              # Call f over 2Ă—â”-1
                  ⋄f            # else, call f over
                    ⊃           # the first element of the
                      3pco ⍔    # list of prime factors of ⍔
                     ⌜          # reversed

f←{⍔∊3 19:⍔⋄g ⍔}
f←                              # Define f as
   ⍔     :                      # if the argument ⍔
    ∊                           # is in
     3 19                       # the list [3, 19]
          ⍔                     # return the argument ⍔
           ⋄                    # else
            g ⍔                 # call g over the argument ⍔

1

Axiome, 93 octets

h(n)==(repeat(n=3 or n=19 or n<2=>break;prime? n=>(n:=2*n-1);n:=n-last(factors(n)).factor);n)

tester:

(4) -> [[i,h(i)] for i in [10,74,94,417,991,9983]]
   (4)  [[10,3],[74,19],[94,3],[417,3],[991,19],[9983,19]]
                                                  Type: List List Integer

Il y aurait 68 octets fonction

q x==(n<4=>3;n=19=>n;prime? n=>q(2*n-1);q(n-last(factors n).factor))

mais pour n = 57991 (si je me souviens bien), l’espace de pile rĂ©servĂ© est Ă©puisĂ©.


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.