Combien de bonbons pouvez-vous manger?


14

Crédit aux Geobits en TNB pour l'idée

Un article sans suffisamment de détails a récemment proposé un jeu intéressant:

2 enfants sont assis devant une gamme de bonbons. Chaque bonbon est numéroté de 1 à x, avec xla quantité totale de bonbons présents. Il y a exactement 1 occurrence de chaque nombre.

Le but du jeu est que les enfants mangent des bonbons et multiplient les valeurs des bonbons qu'ils ont mangés pour arriver à un score final, le score le plus élevé gagnant.

Cependant, le message d'origine a manqué des informations clés, telles que la façon dont les bonbons sont sélectionnés, de sorte que les enfants de notre histoire ont décidé que le plus âgé allait d'abord et pouvait manger jusqu'à la moitié des bonbons, mais une fois qu'il annonçait la fin de son tour, il ne peut pas changer d'avis.

Un des enfants de ce jeu n'aime pas les bonbons, alors il veut manger le moins possible, et il a vu son père écrire une fois du code une fois, et il peut utiliser les compétences acquises pour calculer la quantité de bonbons il a besoin de manger pour assurer la victoire, tout en mangeant le moins possible.

Le défi

Étant donné le nombre total de bonbons x, votre programme ou fonction devrait produire la plus petite quantité de bonbons qu'il doit manger pour assurer la victoire n, même si son adversaire mange tous les bonbons restants.

Naturellement, de plus grands nombres font de plus grands nombres, donc quelle que soit la quantité que vous lui donnerez, il mangera le nplus grand nombre.

Les règles

  • xsera toujours un entier positif dans la plage 0 < x! <= llest la limite supérieure des capacités de gestion des nombres de votre langue
  • Il est garanti que l'enfant mange toujours le nplus grand nombre, par exemple pour x = 5et n = 2, il mange 4et5

Cas de test

x = 1
n = 1
(1 > 0)

x = 2
n = 1
(2 > 1)

x = 4
n = 2
(3 * 4 == 12 > 1 * 2 == 2)

x = 5
n = 2
(4 * 5 == 20 > 1 * 2 * 3 == 6)

x = 100
n = 42
(product([59..100]) > product([1..58]))

x = 500
n = 220
(product([281..500]) > product([1..280]))

Notation

Malheureusement, notre courageux concurrent n'a rien avec qui écrire son code, il doit donc disposer les bonbons en caractères du code, par conséquent, votre code doit être aussi petit que possible, le plus petit code en octets gagne!


14
Combien de bonbons puis-je manger? Tout. Tous les bonbons.
AdmBorkBork

3
Nouveau titre: "Combien de bonbons avez-vous besoin de manger?"
Sparr

@Skidsdev Doit x = 0également être géré, depuis 0! = 1? (Peut-être xdevrait - on également spécifier un entier positif?)
Chronocidal

@Chronocidal a ajouté un entier "positif"
Skidsdev

J'ai jeté 10 000 morceaux de bonbons par terre. Une petite figure a creusé un trou dans le sol et a trouvé une caverne de bonbons géante à cause de moi. ):
moonheart08

Réponses:


9

Python 3 , 76 octets

F=lambda x:x<2or x*F(x-1)
f=lambda x,n=1:x<2or n*(F(x)>F(x-n)**2)or f(x,n+1)

Essayez-le en ligne!

S'appuie sur le fait que pour manger n bonbons pour gagner encore et le nombre total de bonbons étant x , x!(xn)!>(xn)!doit être vrai, ce qui signifiex!>((xn)!)2.

-1 de Skidsdev

-3 -6 de BMO

-3 de Sparr

+6 à corriger x = 1


1
Vous pouvez enregistrer 1 octet en remplaçant la fonction supérieure parfrom math import factorial as F
Skidsdev

1
Vous pouvez réécrire ces récursions en utilisant un comportement de court-circuit, par exemple. pour le second: n*(F(x)>F(x-n)**2)or f(x,n+1). De même x<2or x*F(x-1)pour le premier qui est plus court que l'importation.
ბიმო

1
Tous les trois sont de bonnes suggestions, merci. (Et ajouté)
nedla2004

1
-3 octets avec import math;F=math.factoriallesquels je devrais probablement aller trouver la méta des astuces python à mentionner ...
Sparr

2
@Sparr: Mais F=lambda x:x<2or x*F(x-1)est-ce que trois octets de moins?
ბიმო

5

JavaScript (ES6), 53 octets

n=>(g=p=>x<n?g(p*++x):q<p&&1+g(p/n,q*=n--))(q=x=1)||n

Essayez-le en ligne!

Plage de travail

Fait intéressant, les différences entre les produits pour enfants sont toujours suffisamment importantes pour que la perte de précision inhérente au codage IEEE 754 ne soit pas un problème.

Par conséquent, cela fonctionne pour 0n170 . Au-delà, à la fois la mantisse et le débordement d'exposant (donnant + Infinity ) et nous aurions besoin de BigInts (+1 octet).

Comment?

Soit p le bonbon de l'autre enfant et q soit notre propre bonbon.

  1. On commence par p=n!(tous les bonbons pour l'autre enfant) et q=1 (rien pour nous).

  2. On répète les opérations suivantes jusqu'à qp :

    • diviser p par n
    • multiplier q par n
    • décrémenter n

Le résultat est le nombre d'itérations requises. (À chaque itération, nous «prenons le bonbon suivant de l'autre enfant».)

Commenté

Ceci est implémenté comme une fonction récursive unique qui calcule d'abord n!puis entre dans la boucle décrite ci-dessus.

n => (           // main function taking n
  g = p =>       // g = recursive function taking p
    x < n ?      //   if x is less than n:
      g(         //     this is the first part of the recursion:
        p * ++x  //     we're computing p = n! by multiplying p
      )          //     by x = 1 .. n
    :            //   else (second part):
      q < p &&   //     while q is less than p:
      1 + g(     //       add 1 to the final result
        p / n,   //       divide p by n
        q *= n-- //       multiply q by n; decrement n
      )          //
)(q = x = 1)     // initial call to g with p = q = x = 1
|| n             // edge cases: return n for n < 2

4

Gelée , 9 octets

ḊPÐƤ<!€TL

Essayez-le en ligne! Ou consultez la suite de tests .

Comment?

ḊPÐƤ<!€TL - Link: integer, x                   e.g. 7
Ḋ         - dequeue (implicit range of x)           [   2,   3,   4,   5,   6,   7]
  ÐƤ      - for postfixes [all, allButFirst, ...]:
 P        -   product                               [5040,2520, 840, 210,  42,   7]
      €   - for each (in implicit range of x):
     !    -   factorial                             [   1,   2,   6,  24, 120, 720, 5040]
    <     - (left) less than (right)?               [   0,   0,   0,   0,   1,   1, 5040]
          -   -- note right always 1 longer than left giving trailing x! like the 5040 ^
       T  - truthy indices                          [                       5,   6, 7   ]
        L - length                                  3

1
c'est impressionnant mais serait plus éducatif si expliqué
Setop

Ce sera ... :)
Jonathan Allan

@Setop - ajouté.
Jonathan Allan

J'aime ça ! et il doit être rapide comparer à toutes les solutions avec des tonnes de factorielles
Setop

Non, calcule toujours tous ces produits et factoriels (plus que certaines autres solutions).
Jonathan Allan

3

R , 70 41 38 octets

-29 parce que Dennis connaît toutes les fonctions internes

-3 commutation sur l'entrée scan ()

sum(prod(x<-scan():1)<=cumprod(1:x)^2)

Essayez-le en ligne!

Implémentation R assez simple de la réponse Python3 de nedla2004 .

J'ai l'impression qu'il y a une mise en œuvre plus propre de la manipulation 1, et j'aimerais perdre les accolades.

Je suis fou, je n'ai pas recommencé à utiliser une approche qui, plus fou que j'ai utilisé un strict moins que, mais encore plus fou que je ne savais pas qu'il y avait une cumprod()fonction. Grande optimisation par Dennis.


3

APL (Dyalog Unicode) , 10 octets

+/!≤2*⍨!∘⍳

Essayez-le en ligne!

Réponse de Port of Dennis . Merci à, bien, Dennis pour cela.

Comment:

+/!≤2*⍨!∘⍳  Tacit function, takes 1 argument (E.g. 5)
           Range 1 2 3 4 5
       !∘   Factorials. Yields 1 2 6 24 120
    2*⍨     Squared. Yields 1 4 36 576 14400
  !         Factorial of the argument. Yields 120.
           Less than or equal to. Yields 0 0 0 1 1
+/          Sum the results, yielding 2.

Étant donné que cette réponse n'a pas été strictement faite par moi, je garderai ma réponse d'origine ci-dessous.


APL (Dyalog Unicode) , 14 12 11 octets

(+/!>×\)⌽∘⍳

Essayez-le en ligne!

Fonction tacite de préfixe. Fondamentalement, un port Dyalog de la réponse de Jonathan .

Merci à ngn et H.PWiz pour l'aide dans le chat. Merci aussi à ngn de m'avoir sauvé un octet.

Merci à Dennis d'avoir souligné que mon code d'origine était incorrect. Il s'avère que cela m'a sauvé 2 octets.

Utilise ⎕IO←0.

Comment:

+/(!>×\)∘⌽∘⍳  Tacit function, taking 1 argument (E.g. 5).
             Range 0 1 2 3 4
         ⌽∘   Then reverse, yielding 4 3 2 1 0
  (    )∘     Compose with (or: "use as argument for")
   !          Factorial (of each element in the vector), yielding 24 6 2 1 1
     ×\       Multiply scan. Yields 4 12 24 24 0
    >         Is greater than. Yields 1 0 0 0 1
+/            Finally, sum the result, yielding 2.

1
si +/entre les parenthèses, une des compositions peut être omise:(+/!>×\)⌽∘⍳
ngn


2

Gelée , 7 octets

R!²<!ċ0

Essayez-le en ligne!

Comment ça fonctionne

R!²<!ċ0  Main link. Argument: n

R        Range; yield [1, ..., n].
 !       Map factorial over the range.
  ²      Take the squares of the factorials.
    !    Compute the factorial of n.
   <     Compare the squares with the factorial of n.
     ċ0  Count the number of zeroes.

2

Python 3 , 183 176 149 149 octets

R=reversed
def M(I,r=1):
 for i in I:r*=i;yield r
def f(x):S=[*range(1,x+1)];return([n for n,a,b in zip([0]+S,R([*M(S)]),[0,*M(R(S))])if b>a]+[x])[0]

Essayez-le en ligne!

C'est beaucoup plus rapide que certaines autres solutions - multiplications 0 (N) au lieu de O (N²) - mais je n'arrive pas à réduire la taille du code.

-27 de Jo King



1

05AB1E , 15 11 octets

E!IN-!n›iNq

Essayez-le en ligne!

E!IN-!n›iNq

E                For loop with N from [1 ... input]
 !               Push factorial of input    
  IN-            Push input - N (x - n)
     !           Factorial
      n          Square
       ›         Push input! > (input - N)^2 or x! > (x - n)^2
        i        If, run code after if top of stack is 1 (found minimum number of candies)
         N       Push N
          q      Quit, and as nothing has been printed, N is implicitly printed

Utilise la même approche que ma soumission Python . Très nouveau sur 05AB1E, donc tous les conseils sur le code ou les explications sont grandement appréciés.

-4 octets grâce à Kevin Cruijssen


Bonne réponse! Vous pouvez jouer au golf 3 octets comme celui-ci sans interrompre l'entrée 1. Si l'instruction if est véridique, elle poussera l'index Nvers la pile et quittera le programme (sortie implicite de cet index). Pour l'entrée, 1l'instruction if sera falsey, mais elle affichera 1implicitement son entrée après cette boucle à une seule itération.
Kevin Cruijssen

1
En fait, 4 octets peuvent être enregistrés au lieu de 3: Essayez-le en ligne 11 octets . L'entrée sera utilisée implicitement pour la première factorielle !, maintenant que la pile est vide puisque nous ne dupliquons / tripliquons plus le résultat if.
Kevin Cruijssen

1
Merci pour ces idées. Bien que je ne sois pas arrivé à l'idée d'imprimer à la fin, j'ai pensé à terminer la boucle for tôt. Après avoir cherché break, end, quit et escape, je pensais juste que je ne comprenais pas comment les boucles fonctionnent correctement. D'une manière ou d'une autre, la résiliation ne m'est jamais venue à l'esprit.
nedla2004

1
Votre réponse était déjà assez bonne. Il est généralement plus facile de jouer plus loin sur une réponse existante, puis de la jouer vous-même à partir de rien. Si j'avais relevé ce défi moi-même, je me serais probablement retrouvé à 15 ou 14 octets également. J'ai utilisé votre idée de casser et de le remplacer par une sortie terminale et implicite à la place, après cela, j'ai essayé quelques choses, et à la fin j'ai vu que je n'avais plus besoin du duplicata, ce qui résoudrait également le cas de test 1produisant l'entrée implicitement lorsque la pile est vide. :)
Kevin Cruijssen

1
Pour info: j'ai posté une alternative de 7 octets en portant la réponse Jelly de Dennis ♦ . Comme toujours, Dennis ♦ est capable de faire de la magie en termes de code-golf Jelly ..; p
Kevin Cruijssen


0

charbon , 20 octets

NθI⊕ΣEθ‹Π⊕…ιθ∨Π…¹⊕ι¹

Essayez-le en ligne!Le lien est vers la version détaillée du code. Explication:

Nθ                      Input `n`
    Σ                   Sum of
      θ                 `n`
     E                  Mapped over implicit range
        Π               Product of
           ι            Current value
          …             Range to
            θ           `n`
         ⊕              Incremented
       ‹                Less than
              Π         Product of
                ¹       Literal 1
               …        Range to
                  ι     Current value
                 ⊕      Incremented
             ∨          Logical Or
                   ¹    Literal 1
   ⊕                    Incremented
  I                     Cast to string
                        Implicitly print

Productsur une liste vide dans Charcoal renvoie Noneplutôt que 1, donc je dois le logiquement Or.


Êtes-vous sûr que ces caractères sont 8 bits chacun?
RosLuP

@RosLuP Charcoal est l'une des nombreuses langues que vous pourriez trouver ici qui utilise une page de codes personnalisée au lieu, disons, de l'ASCII. Cela signifie que chaque valeur de huit bits est mappée sur un symbole personnalisé; ces symboles sont conçus pour aider le programmeur à se souvenir de ce que chaque octet fait un peu plus facilement que s'ils étaient simplement dispersés de manière aléatoire sur l'une des pages de code normalisées. N'hésitez pas à demander plus de détails dans le chat PPCG .
Phlarx

0

PHP , 107 octets

<?php $x=fgets(STDIN);function f($i){return $i==0?:$i*f($i-1);}$n=1;while(f($x)<f($x-$n)**2){$n++;}echo $n;

Essayez-le en ligne!

Utilise le même X2>((X-1)!)2 méthode que d'autres ont utilisé.

Utilise la fonction factorielle de la soumission PHP pour ce défi (merci à @ donutdan4114)



0

05AB1E , 7 octets

L!ns!@O

Port de Dennis ♦ 'Jelly answer , alors assure-toi de voter pour lui si tu aimes cette réponse!

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

Explication:

L          # List in the range [1, (implicit) input]
 !         # Take the factorial of each
  n        # Then square each
   s!      # Take the factorial of the input
     @     # Check for each value in the list if they are larger than or equal to the
           # input-faculty (1 if truthy; 0 if falsey)
      O    # Sum, so determine the amount of truthy checks (and output implicitly)

0

Japt -x, 7 octets

Solution de gelée du port de Dennis.

Ne fonctionne que dans la pratique jusqu'à ce n=4que nous entrions dans la notation scientifique ci-dessus.

õÊ®²¨U²

Essayez-le

õ           :Range [1,input]
 Ê          :Factorial of each
  ®         :Map
   ²        :  Square
    ¨       :  Greater than or equal to
     U²     :  Input squared
            :Implicitly reduce by addition


0

C (gcc) , 68 octets

n;f(x){int i=2,j=x,b=1,g=x;while(i<j)b*i>g?g*=--j:(b*=i++);n=x-j+1;}

Essayez-le en ligne!

Edit: échange d'octets contre mults, pas de faire 2 * x mults au lieu de x + n

Edit: revenir à int au lieu de long par macro. Échouerait à 34 ans avec long.

Eh bien, je l'ai dans C. Échoue à 21 ans.

Il y a une ambiguïté possible quant à savoir si le bon garçon veut toujours gagner ou ne jamais perdre ... qu'en pensez-vous?


En règle générale, nous ne permettons pas à la façon dont vous avez défini T d'être de n'importe quel type. Vous pouvez obtenir 72 octets en supprimant toutes les références à T, mais vous devez toujours déclarer i / j / b / g. Essayez-le en ligne!
LambdaBeta

OK, je remets la version avec int, qui est toujours de 68 octets. Donc je ne trichais pas vraiment;)
Balzola

Je laisserais la version T là-dedans ainsi qu'une alternative. Il est intéressant d'essayer des types plus grands / plus petits. Bonne soumission cependant!
LambdaBeta

0

Python 3 , 75 octets

f=lambda n:n<1or f(n-1)*n
n=lambda x:x-sum(f(n)**2<f(x)for n in range(1,x))

Essayez-le en ligne!

Version 74 octets

f=lambda n:n<1or f(n-1)*n
n=lambda x:1+sum(f(n)>f(x)**.5for n in range(x))

mais cette version a débordé pour 500 ...

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.