Chicken McNugget Numbers


29

La description

Les numéros de Chicken McNugget sont des nombres qui peuvent être exprimés comme une somme de 6, 9 ou 20 - les tailles initiales des célèbres boîtes de Chicken McNuggets vendues par McDonald's. Dans cette somme, un nombre peut apparaître plusieurs fois, tout 6 + 6 = 12comme un tel nombre, et le nombre doit "contenir" au moins une des tailles mentionnées. Les premiers numéros de Chicken McNugget sont:

6
9
6 + 6 = 12
6 + 9 = 15
9 + 9 = 6 + 6 + 6 = 18
20
6 + 6 + 9 = 21
...

Défi

Votre tâche consiste à écrire un programme ou une fonction qui, étant donné un entier positif, détermine si ce nombre peut être exprimé de la manière décrite, il s'agit donc d'un tel nombre Chicken McNugget. Il devrait ensuite produire une valeur vraie ou fausse en fonction de sa décision.

Cas de test

6 -> true
7 -> false
12 -> true
15 -> true
21 -> true
40 -> true
42 -> true

Il s'agit de , donc la réponse la plus courte en octets l'emporte et les lacunes standard s'appliquent!


15
Il convient de noter que "Tous les nombres entiers sont des nombres de McNugget sauf 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23, 25, 28, 31, 34, 37 et 43. " ( mathworld )
Leaky Nun

1
Eh bien, prenons-le comme un défi de compression, mais merci pour la note
racer290

3
Quelqu'un a-t-il un lien OEIS pour cela ???
CraigR8806

2
Qu'avez-vous contre le pack de 4 pépites? mcdonalds.com/us/en-us/product/chicken-mcnuggets-4-piece.html
Dan Neely

Réponses:


37

Python, 27 octets

lambda n:0x82492cb6dbf>>n&1

Essayez-le en ligne!


11
Quel est ce code magique o_O c'est incroyable
HyperNeutrino

Vous pouvez supprimer le ~car vous pouvez échanger les sorties.
Leaky Nun

1
En outre, 8953174650303a exactement la même longueur avec 0x82492cb6dbf(bien que moins lisible).
Leaky Nun

2
@HyperNeutrino le nombre magique n'a que les bits définis qui correspondent aux nombres qui ne sont pas des nombres Chicken McNugget. Regardez sa représentation binaire et ce sera beaucoup plus clair.
David Z

1
Dommage que vous ne puissiez pas facilement utiliser cette même idée avec la base 64
Jacob Garby

29

Python 3 , 24 octets

lambda n:0<=n--n%3*20!=3

Essayez-le en ligne!

Explication

Avec 6et 9seul, on peut rendre tous les entiers divisibles par 3lesquels sont supérieurs à 3, comme indiqué dans le commentaire des ovs au défi . On suppose que l'on peut également faire0 . En conclusion, on peut faire0,6,9,12,15,... .

Avec une instance de 20, on peut faire:20,26,29,32,35,... .

Avec deux instances de 20, on peut faire:40,46,49,52,55,... .

Trois instances ne sont jamais nécessaires, car 3 x 20 = 10 x 6.


Notez que les cas où aucun 20n'est nécessaire sont également divisibles par 3; les cas où l'on 20est nécessaire laisse un reste de 2; les cas où deux 20sont nécessaires laisse un reste de1 .

Le nombre de 20besoin peut donc être calculé par (-n)%3. Ensuite, nous faisons n-(((-n)%3)*20)pour supprimer le nombre de 20nécessaire du nombre. Nous vérifions ensuite que ce nombre n'est pas négatif, mais ne l'est pas 3.



@ Mr.Xcoder mis à jour.
Leaky Nun

f=lambda n:n%3<1<n-2or n>20and f(n-20)ça marche?
Zacharý

@ Merci Zacharý, mis à jour.
Leaky Nun

1
Vous pouvez supprimer le f=maintenant car il n'est pas récursif.
notjagan

8

Python 2 , 28 octets

lambda n:-n%3-n/20<(n%20!=3)

Essayez-le en ligne!


En utilisant quelques essais et erreurs et en mappant la première partie de la plage, j'ai une idée approximative de son fonctionnement. Cependant, j'aimerais savoir comment vous avez trouvé cette solution.
Leaky Nun

@LeakyNun Drôle, je pensais que c'était la méthode naturelle et la vôtre était la plus intelligente :). J'ai noté que les valeurs possibles (n%3,n/20)de votre liste d'exclusion sont {(2, 0), (1, 0), (1, 1)}. Utiliser à la -n%3place a donné une inégalité n/20>=(-n)%3. À partir de là, j'ai joué un peu pour inverser {3,23,43}qui sont 3 mod 20 sans affecter 63,83, ... J'ai trouvé que le décalage du point de terminaison des inégalités fonctionnait le mieux.
xnor

Eh bien, ma méthode consiste à vraiment résoudre le problème alors que votre méthode joue avec les valeurs de la liste exclue, alors je dirais que ma méthode est plus naturelle :)
Leaky Nun

7

Gelée , 11 octets

ṗ3’æ.“©µÞ‘ċ

Essayez-le en ligne!

Comment ça marche

ṗ3’æ.“©µÞ‘ċ  Main link. Argument: n

ṗ3           Cartesian power; yield all 3-tuples over [1, ..., n].
  ’          Decrement all coordinates.
     “©µÞ‘   Yield [6, 9, 20].
   æ.        Take the dot product of each 3-tuple and [6, 9, 20].
          ċ  Count the occurrences of n (Positive for Chicken McNuggets numbers).

4
Chicken McNuggets ™ et Jelly! Mmmm !!!
CJ Dennis

@CJDennis En fait, c'est Chicken McNuggets © et Jelly.
caird coinheringaahing

@cairdcoinheringaahing En fait, c'est Chicken McNuggets® et Jelly.
Dan

5

Haskell , 36 octets

f n|n<1=n==0
f n=any(f.(n-))[6,9,20]

Essayez-le en ligne!

Explication

Cette solution est à peu près aussi simple que possible. La première ligne déclare que pour tout nombre inférieur à 1, il s'agit d'un nombre McNugget if n==0. C'est-à-dire que0 s'agit d'un nombre McNugget et que tous les nombres négatifs ne le sont pas.

La deuxième ligne déclare que pour tous les autres numéros, n est un nombre McNugget si elle moins une des tailles Nugget est un nombre McNugget.

Il s'agit d'une recherche récursive assez simple.



3

Gelée , 11 octets

_20$%3$¿o>3

Essayez-le en ligne!

Port de ma réponse Python , mais légèrement modifié: soustrayez 20jusqu'à divisible par 3, puis vérifiez s'il appartient 0,6,9,...en mappant 0sur l'entrée (en utilisant or), puis vérifiez s'il est supérieur à3 .

Les trois seuls nombres qui produisent 0à la fin de la première étape sont 0, 20ou 40, avec le premier étant hors du domaine, et le reste étant supérieur à 3.


Je ne sais pas comment entrer l'entrée ..
racer290

@ racer290 Argument de ligne de commande.
Erik the Outgolfer

3

Mathematica, 53 octets

!Flatten@Table[Tr/@Tuples[{6,9,20},i],{i,#}]~FreeQ~#&

Vous pouvez peut-être utiliser la FrobeniusSolvefonction.
alephalpha


3

Mathematica, 20 octets

0<=#-20Mod[-#,3]!=3&

Fonction anonyme. Prend un nombre en entrée et retourne Trueou Falseen sortie. Logique copiée de la réponse de Leaky Nun , avec quelques abus supplémentaires de Inequality.


3

Code machine x86-64, 22 octets

48 B8 41 92 34 6D DB F7 FF FF 83 F9 40 7D 03 48 D3 E8 83 E0 01 C3

Les octets ci-dessus définissent une fonction dans le code machine x86 64 bits qui détermine si la valeur d'entrée est un nombre Chicken McNugget. Le paramètre entier positif unique est transmis dans le ECXregistre, conformément à la convention d'appel Microsoft 64 bits utilisée sous Windows. Le résultat est une valeur booléenne renvoyée dans le EAXregistre.

Mnémoniques d'assemblage non golfés:

; bool IsMcNuggetNumber(int n)
; n is passed in ECX
    movabs  rax, 0xFFFFF7DB6D349241   ; load a 64-bit constant (the bit field)
    cmp     ecx, 64
    jge     TheEnd                    ; if input value >= 64, branch to end
    shr     rax, cl
TheEnd:
    and     eax, 1                    ; mask off all but LSB
    ret

De toute évidence, cela joue fortement hors de la solution Anders Kaseorg en Python , en ce sens qu'elle est basée sur un champ de bits représentant les valeurs qui sont des nombres de Chicken McNugget. Plus précisément, chaque bit de ce champ qui correspond à un numéro Chicken McNugget valide est défini sur 1; tous les autres bits sont définis sur 0. (Cela considère 0 comme un nombre valide de Chicken McNugget, mais si vous n'aimez pas cela, votre préférence est une modification à un seul bit.)

Nous commençons par charger simplement cette valeur dans un registre. C'est une valeur de 64 bits, qui prend déjà 8 octets à coder, et nous avons besoin d'un préfixe REX.W d'un octet, donc nous sommes vraiment très dépensiers en termes d'octets, mais c'est le cœur de la solution, donc Je suppose que ça vaut le coup.

Nous décalons ensuite le champ vers la droite de la valeur d'entrée. * Enfin, nous masquons tout sauf le bit de poids faible, et cela devient notre résultat booléen.

Cependant, puisque vous ne pouvez pas décaler de plus que le nombre de bits réellement dans la valeur, cela ne fonctionne que pour les entrées de 0 à 63. Pour prendre en charge des valeurs d'entrée plus élevées, nous insérons un test en haut de la fonction qui se ramifie au bas de la valeur d'entrée est> = 64. La seule chose intéressante à ce sujet est que nous préchargeons la constante de champ de bits dans RAX, puis branchons jusqu'à l'instruction qui masque le bit de poids faible, garantissant ainsi que nous renvoyons toujours 1.

Essayez-le en ligne!
(L'appel de fonction C y est annoté avec un attribut qui fait que GCC l'appelle à l'aide de la convention d'appel Microsoft que mon code d'assembly utilise. Si TIO avait fourni MSVC, cela ne serait pas nécessaire.)

__
* Comme alternative à un shift, nous aurions pu utiliser l' BTinstruction x86 , mais c'est 1 octet de plus à encoder, donc aucun avantage. Sauf si nous avons été obligés d'utiliser une convention d'appel différente qui ne transmettait pas commodément la valeur d'entrée dans le ECXregistre. Ce serait un problème car il SHR faut que son opérande source soit CLpour un compte de décalage dynamique. Par conséquent, une convention d'appel différente nécessiterait que nous MOVéditions la valeur d'entrée du registre dans ECXlequel elle a été transmise , ce qui nous coûterait 2 octets. L' BTinstruction peut utiliser n'importe quelle registre comme opérande source, à un coût de seulement 1 octet. Donc, dans cette situation, ce serait préférable.BT valeur pour mettre le bit correspondant dans l'indicateur de report (CF), vous utiliserez donc unSETC instruction pour obtenir cette valeur dans un registre entier commeAL pour qu'elle puisse être renvoyée à l'appelant.


Implémentation alternative, 23 octets

Voici une implémentation alternative qui utilise des opérations de modulo et de multiplication pour déterminer si la valeur d'entrée est un nombre Chicken McNugget.

Il utilise la convention d'appel System V AMD64 , qui transmet la valeur d'entrée dans le EDIregistre. Le résultat est toujours un booléen retourné EAX.

Notez, cependant, que contrairement au code ci-dessus, il s'agit d'un booléen inverse (pour la commodité de l'implémentation). Il renvoie falsesi la valeur d'entrée est un nombre Chicken McNugget ou truesi la valeur d'entrée n'est pas un nombre Chicken McNugget.

                    ; bool IsNotMcNuggetNumber(int n)
                    ; n is passed in EDI
8D 04 3F            lea    eax, [rdi+rdi*1]   ; multiply input by 2, and put result in EAX
83 FF 2B            cmp    edi, 43
7D 0E               jge    TheEnd             ; everything >= 43 is a McNugget number
99                  cdq                       ; zero EDX in only 1 byte
6A 03               push   3
59                  pop    rcx                ; short way to put 3 in ECX for DIV
F7 F1               div    ecx                ; divide input value by 3
6B D2 14            imul   edx, edx, 20       ; multiply remainder of division by 20
39 D7               cmp    edi, edx
0F 9C C0            setl   al                 ; AL = (original input) < (input % 3 * 20)
                 TheEnd:
C3                  ret

Ce qui est laid à ce sujet, c'est la nécessité de gérer explicitement les valeurs d'entrée> = 43 par une comparaison et une branche en haut. Il existe évidemment d'autres façons de le faire qui ne nécessitent pas de branchement, comme l'algorithme de caird coinheringaahing , mais cela prendrait beaucoup plus d'octets à coder, ce n'est donc pas une solution raisonnable. Je pense qu'il me manque probablement une astuce de twiddling qui rendrait cela plus élégant et serait moins d'octets que la solution basée sur le champ de bits ci-dessus (car l'encodage du champ de bits lui-même prend tellement d'octets), mais j'ai étudié cela pour un moment et ne peut toujours pas le voir.

Eh bien, essayez quand même en ligne !


3

05AB1E, 17 16 octets

ŽGç₂в©IED®âO«]I¢

Essayez-le en ligne!

Explication

  ŽGç₂в                 The list [6, 9, 20]
       ©                Store this list in register_c
        IE              Loop <input> number of times
           ®â           Cartesian product stack contents with list in register_c
             O          Sum up the contents of each sub array
          D   «         List duplicated before taking Cartesian product, concat
               ]        End for loop
                I¢      Count occurences of input

1
Vous avez des liens TIO en double.
Incarnation de l'ignorance

1
Bonne réponse. Bienvenue chez PPCG et dans le monde de 05AB1E. :) Une chose au golf est d'utiliser pour la chaîne (il y a buitins pour 1, 2 et chaînes 3 caractères, étant ', et respectivement). J'ai l'impression que l'on peut jouer davantage au golf, peut-être en utilisant une approche différente, mais quelle que soit la bonne première réponse. +1 de moi.
Kevin Cruijssen

1
Était en effet correct. Trouvé un 12 byter en utilisant la fonction interne Åœ: … ÇIÅœåPOĀ. C'est une approche complètement différente, donc si vous voulez que je l'affiche comme réponse séparée plutôt que comme un de vos golfs, faites le moi savoir. PS: je ne suis pas sûr à 100% si les non imprimables sont autorisés dans la page de code 05AB1E . Dans ce cas, le codage pourrait devoir être différent, ce qui ferait que certains caractères compteraient à la place pour 2 octets chacun. Dans ce cas, cela ŽBo21вpourrait être une alternative pour +1 octet.
Kevin Cruijssen

Comme Kevin le mentionne, aucun des 3 octets de votre chaîne ne se trouve dans la page de code 05ab1e et ne peut donc pas être utilisé sans compter l'ensemble du programme dans utf-8, ce qui le rendrait beaucoup plus long. Vous pouvez cependant utiliser à la ŽGç₂вplace de la chaîne tout en enregistrant simultanément un octet dans le processus.
Emigna

Kevin, fonce. Ce serait bien de voir différentes approches. Emigna, merci pour votre suggestion, je ferai le changement
rev

2

JavaScript (ES6), 69 64 octets

n=>'ABCDEFHIKLNOQRTWXZ]`cfl'.includes(String.fromCharCode(n+65))

Sorties falsepour les numéros de Chicken McNugget, truesinon.


Je voudrais au moins un lien "essayez-le" ..
racer290

@ racer290 Ajouté.
darrylyeo

n=>~'ABCDEFHIKLNOQRTWXZ]`cfl'.search(String.fromCharCode(n+65))pour 63 octets
Oki

2

Java, 21 57 24 octets

Essayez-le en ligne!

Golfé:

n->(n-=n*2%3*20)>=0&n!=3

Non golfé:

import java.util.*;

public class ChickenMcNuggetNumbers {

  private static final Set<Integer> FALSE_VALUES = new HashSet<>(Arrays.asList(
    new Integer[] { 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23,
    25, 28, 31, 34, 37, 43 }));

  public static void main(String[] args) {
    for (int i = 0; i < 45; ++i) {
      System.out.println(i + " -> expected=" + !FALSE_VALUES.contains(i)
        + ", actual=" + f(n->(n-=n*2%3*20)>=0&n!=3, i));
    }
  }

  public static boolean f(java.util.function.Function<Integer, Boolean> f, int n) {
    return f.apply(n);
  }
}

Result is wrong for 26 = 20 + 6.
Leaky Nun

@LeakyNun Algorithm was too naive. I had to go with plan B which added some bytes, but appears to produce correct results all of the time now. I should have iterated all of the values to begin with instead of relying on the test cases in the question.


1
24 bytes (see above)
Leaky Nun

1
@LeakyNun thanks! I still have a lot to learn about golfing.

1

Python 2, 51 bytes

-1 byte thanks to @LeakyNun

lambda n:max(n>43,25<n>n%3>1,5<n>n%3<1,n in[20,40])

Try it online! Footer prints all non McNugget numbers


n%3 can only be 0 or 1 or 2, so n%3==2 is equivalent to n%3>1.
Leaky Nun


1

Haskell, 64 56 bytes

I didn't do any bit trickery, but looking at the other answers it might actually be shorter to import the Bits module and use those methods. This approach checks much more directly.

f x=(\l->elem x[i*6+j*9+k*20|i<-l,j<-l,k<-l,x/=0])[0..x]

1
The byte count is 66 not 64. But you you can save a lot of parenthesis and put an x/=0 guard to save some bytes, see here.
ბიმო

1

Javascript, 92 78 72 bytes

*saved 14 bytes thanks to @Jonasw

a=>!(a in[0,1,2,3,4,5,7,8,10,11,13,14,16,17,19,22,23,25,28,31,34,37,43])

Uses the fact that "All integers are McNugget numbers except 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23, 25, 28, 31, 34, 37, and 43." from @LeakyNun's comment


using a simple array would save the bytes for .split ...
Jonas Wilms

@Jonas array is 108 bytes, splitted string is 73 bytes
SuperStormer




1

Add++, 35 bytes

D,f,@,A6$%0=@20$%0=A3$%0=A8<A43<s1<

Try it online!

Look ma, no while loops. Or strings. Or lists. Or really anything that helps save bytes. But mainly because Add++ doesn't know what any of those are.

3 months later, I realised that this was invalid, and fixed it. Somehow, that golfed it by 13 bytes. This is a function that takes one argument and tests whether that argument is a Chicken McNugget number or not.

How it works

D,f,@,                        - Create a monadic (one argument) function called f (example argument: 3)
A                             - Push the argument again; STACK = [3 3]
 6                            - Push 6;                  STACK = [3 3 6]
  $                           - Swap the top two values; STACK = [3 6 3]
   %                          - Modulo;                  STACK = [3 3]
    0                         - Push 0;                  STACK = [3 3 0]
     =                        - Are they equal?          STACK = [3 0]
      @                       - Reverse the stack;       STACK = [0 3]
       20                     - Push 20;                 STACK = [0 3 20]
         $                    - Swap the top two values; STACK = [0 20 3]
          %                   - Modulo;                  STACK = [0 3]
           0                  - Push 0;                  STACK = [0 3 0]
            =                 - Are they equal?          STACK = [0 0]
             A                - Push the argument;       STACK = [0 0 3]
              3               - Push 3;                  STACK = [0 0 3 3]
               $              - Swap the top two values; STACK = [0 0 3 3]
                %             - Modulo;                  STACK = [0 0 0]
                 0            - Push 0;                  STACK = [0 0 0 0]
                  =           - Are they equal?          STACK = [0 0 1]
                   A          - Push the argument;       STACK = [0 0 1 3]
                    8         - Push 8;                  STACK = [0 0 1 3 8]
                     <        - Less than;               STACK = [0 0 1 0]
                      A       - Push the argument;       STACK = [0 0 1 0 3]
                       43     - Push 43;                 STACK = [0 0 1 0 3 43]
                         <    - Less than;               STACK = [0 0 1 0 0]
                          s   - Sum;                     STACK = [1]
                           1  - Push 1;                  STACK = [1 1]
                            < - Less than;               STACK = [0]

1

Excel, 87 bytes

=AND(OR(MOD(A1,3)*MOD(A1,20)*IF(A1>43,MOD(A1-40,3),1)*IF(A1>23,MOD(A1-20,3),1)=0),A1>5)

Alternatively, 92 bytes:

=CHOOSE(MOD(A1,3)+1,A1>3,IF(A1>43,MOD(A1-40,3)=0,A1=40),IF(A1>23,MOD(ABS(A1-20),3)=0,A1=20))

1

PHP, 69+1 bytes

for($n=$argn;$n>0;$n-=20)if($n%3<1)for($k=$n;$k>0;$k-=9)$k%6||die(1);

exits with 1 for a Chicken McNugget Number, 0 else.

Run as pipe with -n or try it online.



0

Mathematica, 59 bytes

!Select[IntegerPartitions@#,{6,9,20}~SubsetQ~#&]=={}&&#!=0&

0

Javascript 37 bytes

Takes a positive integer n and outputs true for Chicken McNugget numbers and false for others.

F=n=>!(n<0||(n%6&&!F(n-9)&&!F(n-20)))

Explanation

F=n=>!(            // negate the internal test for non-Chicken McNugget numbers
    n<0 || (       // if n < 0, or
        n%6 &&     // if n % 6 is truthy,
        !F(n-9) && // and n-9 is not a Chicken McNugget number
        !F(n-20)   // and n-20 is not a Chicken McNugget number
                   // then n is not a Chicken McNugget number
    )
)

The recursion on this function is heinous, and for any sufficiently large n, you will exceed call stack limits. Here's a version that avoids those limits by checking if n is larger than the largest non-Chicken McNugget number (43 bytes [bonus points for being the largest non-Chicken McNugget number?]):

F=n=>n>43||!(n<0||(n%6&&!F(n-9)&&!F(n-20)))


0

JavaScript ES5, 46 bytes

n=>n>5&&(!(n%20)||(n<24?!(n%3):n<44?n%3-1:1));

Explicit boolean answer, 50 bytes:

n=>!!(n>5&&(!(n%20)||(n<24?!(n%3):n<44?n%3-1:1)));

Clumsy, but it gets the job done. Returns false or 0 for every value that isn't 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23, 25, 28, 31, 34, 37, or 43, and true, -1, or 1 for everything else.

Explicit solution returns true or false only.

n=>!!(                                          ); forces Boolean type (optional)
      n>5                                          false for 0, 1, 2, 3, 4, 5 (and negative inputs)
            !(n%20)                                explicit true for 20, 40
                      n<24?!(n%3)                  false for 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23
                                  n<44?n%3-1       false for 25, 28, 31, 34, 37, 43

0

Clojure 33 bytes

An on ok quick attempt: #(-> %(rem 20)(rem 9)(rem 6)(= 0))


0

Pari/GP, 48 bytes

0 is falsy. everything else is truthy.

n->n*Vec(1/(1-x^6)/(1-x^9)/(1-x^20)+O(x^n++))[n]

Try it online!


Irrelevant comment : what was the problem with this answer of yours?#~SetPrecision~1& ?
J42161217

@Jenny_mathy It fails the 0.25 test case.
alephalpha
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.