Le nombre peut-il atteindre 1 en soustrayant à plusieurs reprises le plus grand nombre premier inférieur à celui-ci?

27

Défi:

Étant donné un nombre, prenez le plus grand nombre premier strictement inférieur à celui-ci, soustrayez-le de ce nombre, recommencez avec ce nouveau nombre avec le plus grand nombre premier inférieur à celui-ci, et continuez jusqu'à ce qu'il soit inférieur à 3. S'il atteint 1, votre le programme devrait sortir une valeur véridique, sinon, le programme devrait sortir une valeur de falsey.

Exemples:

Tous ces éléments devraient donner une valeur véridique:

3
4
6
8
10
11
12
14
16
17
18
20
22
23
24
26
27
29
30
32
34
35
37
38
40
41
42
44
46
47
48
50

Tous ces éléments devraient donner des valeurs de falsey:

5
7
9
13
15
19
21
25
28
31
33
36
39
43
45
49

Règles:

Loovjo
la source
connexes oeis.org/A175071
flawr
1
5-3 = 2, 2 - (- 2) = 4, 4-3 = 1. (/ Wiseguy)
@Hurkyl -2 = -1 × 2, donc ce n'est pas premier ;-)
ETHproductions
1
@ETHProductions: Ah, mais -1 est une unité; cette factorisation ne contredit pas la primauté de -2 pas plus que 2 = (- 1) × (-2) fait de 2. (ou même 2 = 1 × 2)
3
@ETHproductions: Les nombres rationnels sont intéressants car il existe deux approches très différentes qui sont utiles dans la pratique! Les nombres rationnels n'ont pas de nombres premiers (pas même 2!) Car tout est une unité. Cependant, vous pouvez également voir les rationnels comme une construction faite à partir des entiers et les étudier en utilisant les nombres premiers des entiers. (par exemple, toute personne demandant la factorisation principale de 9/10as 2^(-1) 3^2 5^(-1)pense en termes de ce dernier)

Réponses:

8

Gelée , 9 8 octets

’ÆRṪạµ¡Ḃ

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

Comment ça marche

’ÆRṪạµ¡Ḃ  Main link. Argument: n

     µ    Combine all atoms to the left into a chain.
’           Decrement; yield n - 1.
 ÆR         Prime range; yield all primes in [2, ..., n -1].
   Ṫ        Tail; yield p, the last prime in the range.
            If the range is empty, this yields p = 0.
    ạ       Compute the absolute difference of p and n.
      ¡   Call the chain to the left n times.
          This suffices since each iteration decreases n, until one of the fixed
          points (1 or 2) is reached.
       Ḃ  Bit; return the parity of the fixed point.
Dennis
la source
11

Rétine , 31 octets

.+
$*
+`1(?!(11+)\1+$)11+
1
^1$

Impressions 0(fausses) ou 1(véridiques).

Essayez-le en ligne! (La première ligne active une suite de tests séparés par un saut de ligne.)

Explication

.+
$*

Convertissez l'entrée en unaire en transformant l'entrée Nen Ncopies de 1.

+`1(?!(11+)\1+$)11+
1

Supprimez à plusieurs reprises le plus grand nombre premier inférieur à l'entrée. Ceci est basé sur le test de primalité standard avec regex .

^1$

Vérifiez si le résultat est unique 1.

Martin Ender
la source
Comment pouvez-vous utiliser Retina sans unaire? Oo
Addison Crump
@Syxer les deux premières lignes convertissent l'entrée en unaire.
Martin Ender
Cela ne signifie-t-il pas que vous pouvez les supprimer et demander une entrée unaire?
Addison Crump
2
@Syxer je pourrais, mais j'ai en quelque sorte arrêté de faire ça. Cela ressemble à un format d'E / S douteux, et maintenant que la conversion est de 6 octets (par opposition aux ~ 200 qu'elle était), je ne pense pas que Retina compte comme "ne peut raisonnablement pas prendre d'entrée en décimal".
Martin Ender
Ah, je vois. Je n'ai jamais vu d'entrée unaire dans la rétine, d'où ma confusion.
Addison Crump
8

Pyth, 18 15 14 octets

Merci à @Maltysen pour -1 octet

#=-QefP_TUQ)q1

Un programme qui prend des entrées sur STDIN et imprime Trueou Falseselon le cas.

Essayez-le en ligne

Comment ça marche

#=-QefP_TUQ)q1  Program. Input: Q
#          )    Loop until error statement (which occurs when Q<3):
         UQ      Yield [0, 1, 2, 3, ..., Q-1]
     fP_T        Filter that by primality
    e            Yield the last element of that
 =-Q             Q = Q - that
            q1  Q is 1 (implicit variable fill)
                Implicitly print

Ancienne version avec réduction, 18 octets

qu-G*<HGH_fP_TSQQ1

Essayez-le en ligne

Comment ça marche

qu-G*<HGH_fP_TSQQ1  Program. Input: Q
              SQ    Yield [1, 2, 3, ..., Q]
          fP_T      Filter that by primality
         _          Reverse it
 u                  Reduce it:
                Q    with base case Q and
                     function G, H -> 
     <HG              H<G
    *   H             *H (yields H if H<G, else 0)
  -G                  Subtract that from G
q                1  The result of that is 1
                    Implicitly print
TheBikingViking
la source
Stest de U15 caractères
Maltysen
7

JavaScript (ES6), 64 63 octets

1 octet enregistré grâce à @Neil

g=(x,n=x-1)=>n<2?x:x%n?g(x,n-1):g(x-1)
f=x=>x<3?x%2:f(x-g(x-1))

J'ai écrit ceci en 2 minutes ... et cela a parfaitement fonctionné la première fois. Le premier utilisateur à trouver l'inévitable bogue gagne ...

Essaye le

Comment ça marche

Nous définissons d'abord g (x) comme la fonction qui trouve le premier nombre premier p <= x . Cela se fait en utilisant le processus suivant:

  1. Commencez avec n = x-1 .
  2. Si n <2 , x est premier; retourner x .
  3. Si x est divisible par n , décrémentez x et passez à l'étape 1.
  4. Sinon, décrémentez n et passez à l'étape 2.

La solution à ce défi, f (x) , est maintenant assez simple:

  1. Si x <3 , retournez x = 1 .
  2. Sinon, soustrayez g (x-1) et réessayez.
ETHproductions
la source
4326, qui devrait retourner vrai ne semble pas revenir, mais 4328 (vrai) et 4329 (faux) le font, est-ce une limitation JS ou un bug?
Jonathan Allan
@JonathanAllan 4326 renvoie too much recursionà la console du navigateur dans Firefox 48, donc je suppose que la récursivité dépasse la limite de récursivité de FF.
ETHproductions
Oui, la prochaine baisse de prime est 4297 (et la prochaine hausse est 4327), ce qui explique pourquoi 4328 fonctionne.
Jonathan Allan
4
x%2devrait vous faire économiser un octet x==1.
Neil
@Neil Je n'y aurais jamais pensé :-)
ETHproductions
6

Pyke, 15 11 octets

WDU#_P)e-Dt

Essayez-le ici!

            - stack = input
W           - while continue:
  U#_P)     -     filter(is_prime, range(stack))
       e    -    ^[-1]
 D      -   -   stack-^
         Dt -  continue = ^ != 1

Renvoie 1si vrai et déclenche une exception s'il est faux

Bleu
la source
5

Julia, 32 octets

Bien que cela ne soit pas la solution la plus courte parmi les langues, cela pourrait être la plus courte des langues lisibles par l'homme ...

!n=n>2?!(n-primes(n-1)[end]):n<2

Ou, pour le dire en termes un peu plus clairs

function !(n)
  if n>2
    m=primes(n-1)[end]   # Gets largest prime less than n
    return !(n-m)        # Recurses
  else
    return n<2           # Gives true if n is 1 and false if n is 2
  end
end

Appelé avec, par exemple !37,.

Glen O
la source
3

Mathematica, 32 octets

2>(#//.x_/;x>2:>x+NextPrime@-x)&

Il s'agit d'une fonction sans nom qui prend un entier et renvoie un booléen.

Explication

Il y a beaucoup de syntaxe et d'ordre de lecture drôle ici, alors ...

   #                               This is simply the argument of the function.
    //.                            This is the 'ReplaceRepeated' operator, which applies
                                   a substitution until the its left-hand argument stops
                                   changing.
       x_/;x>2                     The substitution pattern. Matches any expression x as
                                   long as that expression is greater than 2.
              :>                   Replace that with...
                  NextPrime@-x     Mathematica has a NextPrime built-in but no
                                   PreviousPrime built-in. Conveniently, NextPrime
                                   works with negative inputs and then gives you the 
                                   next "negative prime" which is basically a
                                   PreviousPrime function (just with an added minus sign).
                x+                 This gets added to x, which subtracts the previous
                                   prime from it.
2>(                           )    Finally, we check whether the result is less than 2.
Martin Ender
la source
Bat de près #+0~Min~NextPrime@-#&~FixedPoint~#==1&(36 octets). Bonne utilisation de //.!
Greg Martin
1
@GregMartin 35 lorsque vous utilisez <2à la fin.
Martin Ender
3

Python3, 102 92 90 89 88 octets

f=lambda n:n<2if n<3else f(n-[x for x in range(2,n)if all(x%y for y in range(2,x))][-1])

Suggestions de golf bienvenues! Je vois que gmpycontient une fonction next_prime, mais je ne peux pas encore la tester :(

-2 octets, merci à @JonathanAllan !

-1 octet, merci à @Aaron !

Cas de test

f=lambda n:n<2if n<3else f(n-[x for x in range(2,n)if all(x%y for y in range(2,x))][-1])

s="3 4 6 8 10 11 12 14 16 17 18 20 22"
h="5 7 9 13 15 19 21 25 28 31 33 36 39"

for j in s.split(" "):print(f(int(j)))
for j in h.split(" "):print(f(int(j)))

La sortie est de 13 valeurs véridiques et 13 valeurs de falsey. scontient les cas véridiques et hles faux.

Yytsi
la source
1
if all(x%y for...oeuvres
Jonathan Allan
1
n<3 else-> n<3elsepour avoir la même longueur que la mienne;)
Aaron
2

Python, avec sympy, 60 octets

import sympy
f=lambda n:n>2and f(n-sympy.prevprime(n))or n<2

Ma méthode précédente était de 83 octets sans sympy utilisant la récursivité, mais j'ai pris vérité / falsey pour signifier distinguable et cohérente, mais j'ai été informé que c'est une interprétation incorrecte. Je n'arrive pas à le récupérer à cause de la queue, mais je vais le laisser ici au cas où quelqu'un sait comment le faire:

f=lambda n,p=0:n>2and(any(p%x==0for x in range(2,p))and f(n,p-1)or f(n-p,n+~p))or n
Jonathan Allan
la source
@ mbomb007 Je pensais que les spécifications sont "vraies ou fausses" si cela est nécessaire, alors que "véridiques ou falsey" signifie distinctes et cohérentes?
Jonathan Allan
1
Nan. Ils sont définis comme nous l'avons décidé sur le méta site. Toute question qui permet une sortie "distincte et cohérente" doit le spécifier, plutôt que truey / falsey.
mbomb007
OK, je lis ceci , mettra à jour à un moment donné ...
Jonathan Allan
1

Vitsy, 28 26 octets

Cela peut certainement être raccourci.

<]xN0)l1)-1[)/3D-];(pD-1[D

La

<                    Traverse the code in this direction, rotating on the line.
                     For the sake of reading the code easier, I'm reversing the
                     code on this line. This will be the order executed.

 D[1-Dp(;]-D3/)[1-)1l)0Nx]
 D                         Duplicate the top member of the stack.
  [      ]                 Do the stuff in brackets until break is called.
   1-                      Subtract 1 from the top item of the stack.
     D                     Duplicate the top member of the stack.
      p(                   If the top member is a prime...
        ;                  break;
          -                Pop a, b, push a - b.
           D3/)[         ] If this value is less than 3, do the bracketed code.
                1-         Subtract the top item of the stack by 1.
                  )        If the top item is zero...
                   1       Push 1.
                    l)     If the length of the stack is zero...
                      0    Push 0.
                       N   Output the top member of the stack.
                        x  System.exit(0);

Essayez-le en ligne!

Addison Crump
la source
1

MATL , 13 octets

`tqZq0)-t2>}o

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

Explication

`        % Do...while
  t      %   Duplicate. Takes input implicitly in the first iteration
  qZq    %   All primes less than that
  0)     %   Get last one
  -      %   Subtract (this result will be used in the next iteration, if any)
  t      %   Duplicate
  2>     %   Does it exceed 2? If so: next iteration. Else: execute the "finally" 
         %   block and exit do...while loop
}        % Finally
  o      %   Parity. Transforms 2 into 0 and 1 into 1
         % End do...while implicitly
         % Display implicitly
Luis Mendo
la source
1

CJam , 21 16 octets

Merci à Dennis d'avoir économisé 4 octets.

ri{_1|{mp},W=-}h

Essayez-le en ligne!

Explication

ri       e# Read input and convert to integer N.
{        e# Run this block as long as N is positive (or until the program aborts
         e# with an error)...
  _1|    e#   Duplicate and OR 1. This rounds up to an odd number. For N > 2, this
         e#   will never affect the greatest prime less than N.
  {mp},  e#   Get all primes from 0 to (N|1)-1.
         e#   For N > 2, this will contain all primes less than N.
         e#   For N = 2, this will contain only 2.
         e#   For N = 1, this will be empty.
  W=     e#   Select the last element (largest prime up to (N|1)-1).
         e#   For N = 1, this will result in an error and terminate the program, which
         e#   still prints the stack contents though (which are 1, the desired output).
  -      e#   Subtract from N. Note that this gives us 0 for N = 2, which terminates the 
         e#   loop.
}h
Martin Ender
la source
ri_{_1|{mp},W=-}*devrait marcher.
Dennis
@Dennis Merci, 1|c'est vraiment intelligent. :) (Et j'oublie toujours que cela {...},fait une plage implicite ...)
Martin Ender
1

Perl, 42 octets

Comprend +1 pour -p

Exécuter avec entrée sur STDIN

reach1.pl:

#!/usr/bin/perl -p
$_=1x$_;$_=$`while/\B(?!(11+)\1+$|$)|11$/

Utilise l'expression régulière de primalité

Ton Hospel
la source
1

.NET Regex, 38 octets

Juste pour montrer qu'il peut être vérifié en une seule expression régulière.

^(?>(?<=(.*))..+(?<!^\1\2+(.+.)|$))+.$

L'entrée est supposée être unaire.

Explication

Il implémente simplement l'exigence au mot, en supprimant à plusieurs reprises le plus grand nombre premier et vérifie s'il reste 1.

  • (?>(?<=(.*))..+(?<!^\1\2+(.+.)|$))+: Le groupe sans retour arrière s'assure que le plus grand nombre premier que nous avons trouvé n'est pas annulé, et +répète simplement le processus de correspondance avec le plus grand nombre premier.

    • (?<=(.*))..+(?<!^\1\2+(.+.)|$): Correspondre au plus grand nombre premier inférieur au nombre restant

      • (?<=(.*)): Enregistrez combien nous avons soustrait pour établir un point d'ancrage pour l'assertion.

      • ..+: Cherchez le plus grand nombre ...

      • (?<!^\1\2+(.+.)|$): ... qui est premier et inférieur au nombre restant.
        • (?<!^\1\2+(.+.)): La routine de test principale habituelle, avec ^\1clouée devant pour nous assurer que nous vérifions le montant correspondant à..+
        • (?!<$): Affirmer moins que le nombre restant
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
la source
La (?<=(.*))partie est plutôt maladroite. Je ne sais pas s'il y a une meilleure façon. Aussi, je suis curieux de savoir s'il existe une solution dans PCRE.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
0

Perl 6 ,  54 53 52  51 octets

{($_,{$_-($_-1...2).first: *.is-prime}...3>*)[*-1]==1}
{($_,{$_-($_-1...2).first: *.is-prime}...3>*).any==1}
{any($_,{$_-($_-1...2).first: *.is-prime}...3>*)==1}
{any($_,{$_-(^$_).grep(*.is-prime)[*-1]}...3>*)==1}

Explication:

# bare block lambda with implicit parameter 「$_」
# used to generate all of the rest of the elements of the sequence
{
  # create an any Junction of the following list
  any(
    $_, # initialize sequence with the inner block's argument

    # bare block lambda with implicit parameter 「$_」
    {
      # take this inner block's argument and subtract
      $_ -

      ( ^$_ )            # Range up-to and excluding 「$_」
      .grep(*.is-prime)\ # find the primes
      [ * - 1 ]          # return the last value
    }

    ...   # keep doing that until

    3 > * # the result is less than 3

  # test that Junction against 「1」
  # ( returns an 「any」 Junction like 「any(False, False, True)」 )
  ) == 1
}

Exemple:

# show what is returned and if it is truthy
sub show ($_) {
  # 「.&{…}」 uses the block as a method and implicitly against 「$_」
  my $value = .&{any($_,{$_-(^$_).grep(*.is-prime)[*-1]}...3>*)==1}
  say join "\t", $_, ?$value, $value.gist;
}

show 3;  # 3    True    any(False, True)
show 4;  # 4    True    any(False, True)
show 5;  # 5    False   any(False, False)
show 10; # 10   True    any(False, False, True)
show 28; # 28   False   any(False, False, False)
show 49; # 49   False   any(False, False)
show 50; # 50   True    any(False, False, True)
Brad Gilbert b2gills
la source
0

Irrégulier , 63 octets

p~?1_$-1p:;
n=i(0)?1_$-1p:;
_~
N=n
1(?!(11+)\1+$)11+~1
^11$~0
N

J'ai créé ce langage il y a deux jours, et les prémisses de base sont qu'il n'y a pas de boucles intégrées, les seules fonctionnalités sont l'arithmétique et la prise de décision de base, et l'évaluation du programme est basée sur des expressions régulières.

Explication

p~?1_$-1p:;
n=i(0)?1_$-1p:;
_~
N=n

Cette partie convertit l'entrée en unaire. Il soustrait à plusieurs reprises 1 de l'entrée jusqu'à ce qu'il soit égal à 0, en ajoutant à 1_chaque fois. Il supprime ensuite tous les par _. Si je n'avais pas oublié un breakdans mon code cela pourrait s'écrire ainsi:

p~?1_$-1p:;
_~
n=i(0)?1_$-1p:;

La partie suivante supprime à plusieurs reprises le plus grand nombre premier de l'entrée jusqu'à ce qu'il soit égal à 1ou 11, en 11étant remplacé par 0.

1(?!(11+)\1+$)11+~1
^11$~0
N

J'ai utilisé l'expression régulière de la réponse de Martin Ender .

DanTheMan
la source
0

Haskell, 79 octets

Pas vraiment court mais sans point :)

(<2).until(<3)(until(flip(`until`(+1))2.(.)(<1).mod>>=(==))pred.pred>>=flip(-))
Damien
la source
0

PowerShell v2 +, 81 octets

param($n)while($n-gt2){$n-=(($n-1)..2|?{'1'*$_-match'^(?!(..+)\1+$)..'})[0]}!--$n

Prend des informations $n. Entre dans une whileboucle tant qu'elle $nest encore 3ou supérieure. Chaque itération, soustrait un nombre de $n. Le nombre correspond aux résultats du test de primalité des expressions rationnelles appliqué à une plage ($n-1)..2via l' opérateur Where-Object( ?), puis au premier [0]des résultats (puisque la plage diminue, cela entraîne la sélection de la plus grande). Après avoir conclu la boucle, $nsoit va être, 1soit 2, par définition, donc nous pré-décrémentons $n(en la transformant en ou 0ou 1), et prenons le booléen-pas de !celui - ci. Cela reste sur le pipeline et la sortie est implicite.

Exemples

PS C:\Tools\Scripts\golfing> 3..20|%{"$_ --> "+(.\can-the-number-reach-one.ps1 $_)}
3 --> True
4 --> True
5 --> False
6 --> True
7 --> False
8 --> True
9 --> False
10 --> True
11 --> True
12 --> True
13 --> False
14 --> True
15 --> False
16 --> True
17 --> True
18 --> True
19 --> False
20 --> True
AdmBorkBork
la source
0

Matlab, 51 octets

v=@(x)x-max(primes(x-1));while(x>=3)x=v(x);end;x==1

Ceci est TRÈS similaire à la solution JS6 par ETHProductions , mais a besoin que la variable soit dans l'espace de travail.

ptev
la source
0

Python 2.7: 88 87 octets

r=lambda n:n>2and r(n-[a for a in range(2,n)if all(a%b for b in range(2,a))][-1])or n<2

Thx @TuukkaX pour -1 octet de plus!

Aaron
la source
1
Mettez à jour votre description;) Vous pouvez également enregistrer un octet en disant à la n<2place de n==1.
Yytsi
0

Clojure, 125 octets

#(loop[x %](if(> x 2)(recur(- x(loop[y(dec x)](if(some zero?(vec(for[z(range 2 y)](mod y z))))(recur(dec y))y))))(quot 1 x)))

Oui, c'est un long morceau de code. La langue la plus verbeuse frappe à nouveau!

Non golfé:

(defn subprime [n]
  (loop [x n]
    (if (> x 2)
      (recur
        (- x
          (loop [y (dec x)]
            (if (some zero? (vec (for [z (range 2 y)] (mod y z))))
              (recur (dec y)) y))))
      (quot 1 x))))
clismique
la source