Numeri di pollo McNugget


29

Descrizione

I numeri di Chicken McNugget sono numeri che possono essere espressi come una somma di 6, 9 o 20 - le dimensioni iniziali delle famose scatole di Chicken McNuggets vendute da McDonald's. In tale somma, un numero può essere presente più di una volta, così 6 + 6 = 12come un tale numero e il numero deve "contenere" almeno una delle dimensioni indicate. I primi numeri di Chicken McNugget sono:

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

Sfida

Il tuo compito è scrivere un programma o una funzione che, dato un numero intero positivo, determini se questo numero può essere espresso nel modo descritto, quindi è un tale numero di Chicken McNugget. Dovrebbe quindi generare un valore di verità o falsità in base alla sua decisione.

Casi test

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

Questo è , quindi vince la risposta più breve in byte e si applicano le scappatoie standard!


15
Va notato che "Tutti i numeri interi sono numeri McNugget tranne 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23, 25, 28, 31, 34, 37 e 43. " ( mathworld )
Leaky Nun,

1
Bene, allora prendiamolo come una sfida di compressione, ma grazie per la nota
racer290,

3
Qualcuno ha un link OEIS per questo ???
CraigR8806,

2
Cosa hai contro il pacchetto di pepite da 4 pezzi? mcdonalds.com/us/en-us/product/chicken-mcnuggets-4-piece.html
Dan Neely,

Risposte:


37

Python, 27 byte

lambda n:0x82492cb6dbf>>n&1

Provalo online!


11
Cos'è questo codice magico o_O è fantastico
HyperNeutrino,

È possibile rimuovere il ~perché è possibile scambiare gli output.
Leaky Nun,

1
Inoltre, 8953174650303ha la stessa identica lunghezza 0x82492cb6dbf(anche se meno leggibile).
Leaky Nun,

2
@HyperNeutrino il numero magico ha solo quei bit impostati che corrispondono a numeri che non sono numeri di Chicken McNugget. Guarda la sua rappresentazione binaria e sarà molto più chiaro.
David Z,

1
Peccato che non puoi facilmente usare questa stessa idea con la base 64
Jacob Garby,

29

Python 3 , 24 byte

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

Provalo online!

Spiegazione

Con 6e 9solo, si possono rendere divisibili tutti i numeri interi per i 3quali sono maggiori di3 , come si afferma nel commento di ovs alla sfida . Si presume che si possa anche fare 0. In conclusione, si può fare 0,6,9,12,15,....

Con un'istanza di 20, si può fare: 20,26,29,32,35,....

Con due casi di 20 , si può fare: 40,46,49,52,55,....

Tre casi non sono mai necessari, per 3 x 20 = 10 x 6 .


Si noti che i casi in cui non 20è necessario è anche divisibile per 3; i casi in cui uno 20è necessario lascia un resto di2 ; i casi in cui ne 20sono necessari due ne lasciano un residuo 1.

Il numero di 20necessari può quindi essere calcolato da (-n)%3. Quindi, facciamo n-(((-n)%3)*20)per rimuovere il numero di 20necessario dal numero. Quindi controlliamo che questo numero non sia negativo, ma non lo è 3.



@ Mr.Xcoder aggiornato.
Leaky Nun,

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

@ Zacharý grazie, aggiornato.
Leaky Nun,

1
Puoi rimuovere f=ora poiché non è ricorsivo.
notjagan,

8

Python 2 , 28 byte

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

Provalo online!


Usando alcune prove ed errori e mappando la prima parte dell'intervallo, ho una vaga idea di come funzioni. Tuttavia, vorrei sapere come hai trovato questa soluzione.
Leaky Nun,

@LeakyNun Divertente, ho pensato che questo fosse il metodo naturale e il tuo è stato il più intelligente :). Ho notato che i possibili valori di (n%3,n/20)dalla tua lista esclusi sono {(2, 0), (1, 0), (1, 1)}. Usare -n%3invece ha dato una disuguaglianza n/20>=(-n)%3. Da lì, ho cercato un po 'di tempo per invertire {3,23,43}3 mod 20 senza influire su 63,83, ... Ho scoperto che spostare l'endpoint di disuguaglianza per questi ha funzionato meglio.
xnor

Bene, il mio metodo prevede davvero di risolvere il problema, mentre il tuo metodo sta armeggiando con i valori nell'elenco escluso, quindi direi che il mio metodo è più naturale :)
Leaky Nun,

7

Gelatina , 11 byte

ṗ3’æ.“©µÞ‘ċ

Provalo online!

Come funziona

ṗ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 ™ e Jelly! Mmmm!!!
CJ Dennis,

@CJDennis In realtà sono Chicken McNuggets © e Jelly.
caird coinheringaahing il

@cairdcoinheringaahing In realtà sono Chicken McNuggets® e Jelly.
Dan,

5

Haskell , 36 byte

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

Provalo online!

Spiegazione

Questa soluzione è il più semplice possibile. La prima riga dichiara che per qualsiasi numero inferiore a 1 è un numero McNugget se n==0. Vale a dire che 0è un numero McNugget e tutti i numeri negativi non lo sono.

La seconda riga dichiara che per tutti gli altri numeri, nè un numero McNugget se meno una delle dimensioni del Nugget è un numero McNugget.

Questa è una ricerca ricorsiva piuttosto semplice.



3

Gelatina , 11 byte

_20$%3$¿o>3

Provalo online!

Risposta di Port of my Python , ma leggermente modificata: sottrai 20fino a divisibile per 3, quindi controlla se appartiene 0,6,9,...mappando 0l'input (usando or), quindi controlla se è maggiore di 3.

Gli unici tre numeri che producono 0dopo aver completato il primo passo sono 0, 20o 40, con il primo che è fuori dal dominio e il resto è maggiore di 3.


Non capisco come inserire l'input ..
racer290,

@ racer290 Argomento della riga di comando.
Erik the Outgolfer,

3

Mathematica, 53 byte

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

Forse puoi usare la FrobeniusSolvefunzione.
alephalpha,


3

Mathematica, 20 byte

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

Funzione anonima. Prende un numero come input e restituisce Trueo Falsecome output. Logica copiata dalla risposta di Leaky Nun , con qualche ulteriore abuso di Inequality.


3

x86-64 Codice macchina, 22 byte

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

I byte precedenti definiscono una funzione nel codice macchina x86 a 64 bit che determina se il valore di input è un numero Chicken McNugget. Il singolo parametro intero positivo viene passato nel ECXregistro, in base alla convenzione di chiamata Microsoft a 64 bit utilizzata su Windows. Il risultato è un valore booleano restituito nel EAXregistro.

Mnemonici di assemblaggio non golfati:

; 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

Ovviamente, ciò gioca pesantemente sulla soluzione di Anders Kaseorg in Python , in quanto si basa su un bit-field che rappresenta i valori che sono i numeri di Chicken McNugget. In particolare, ogni bit in questo campo che corrisponde a un numero Chicken McNugget valido è impostato su 1; tutti gli altri bit sono impostati su 0. (Questo considera 0 un numero Chicken McNugget valido, ma se non ti piace, la tua preferenza è una modifica a singolo bit di distanza.)

Iniziamo semplicemente caricando questo valore in un registro. Si tratta di un valore a 64 bit, che richiede già 8 byte per la codifica, inoltre abbiamo bisogno di un prefisso REX.W a un byte, quindi siamo davvero abbastanza spesi in termini di byte, ma questo è il cuore della soluzione, quindi Immagino ne valga la pena.

Spostiamo quindi il campo a destra in base al valore di input. * Infine, mascheriamo tutto tranne il bit di ordine più basso, e questo diventa il nostro risultato booleano.

Tuttavia, poiché non è possibile spostare più del numero di bit effettivamente presenti nel valore, questo funziona solo per input da 0 a 63. Per supportare valori di input più elevati, inseriamo un test nella parte superiore della funzione che si dirama verso la parte inferiore del valore di input è> = 64. L'unica cosa interessante di questo è il precarico della costante del campo di bit in RAX, quindi ramo fino all'istruzione che maschera il bit di ordine più basso, assicurando così di restituire sempre 1.

Provalo online!
(La chiamata della funzione C è annotata con un attributo che fa sì che GCC la chiami utilizzando la convenzione di chiamata Microsoft utilizzata dal mio codice assembly. Se TIO avesse fornito MSVC, ciò non sarebbe necessario.)

__
* In alternativa a un turno, avremmo potuto usare l' BTistruzione x86 , ma è 1 byte più lungo da codificare, quindi nessun vantaggio. A meno che non fossimo costretti a utilizzare una convenzione di chiamata diversa che non passasse convenientemente il valore di input nel ECXregistro. Questo sarebbe un problema perché SHR richiede che il suo operando di origine sia CLper un conteggio di turni dinamico. Pertanto, una convenzione di chiamata diversa richiederebbe di modificare MOVil valore di input da qualsiasi registro in cui è stato passato ECX, il che ci costerebbe 2 byte. L' BTistruzione può utilizzare qualsiasi registro come operando di origine, al costo di solo 1 byte. Quindi, in quella situazione, sarebbe preferibile.BT inserisce il valore del bit corrispondente nel flag carry (CF), quindi useresti aSETCistruzioni per ottenere quel valore in un registro intero come in ALmodo che possa essere restituito al chiamante.


Implementazione alternativa, 23 byte

Ecco un'implementazione alternativa che utilizza le operazioni di modulo e moltiplicazione per determinare se il valore di input è un numero Chicken McNugget.

Utilizza la convenzione di chiamata AMD64 di System V , che passa il valore di input nel EDIregistro. Il risultato è ancora un booleano, restituito EAX.

Si noti, tuttavia, che a differenza del codice sopra, questo è un valore booleano inverso (per comodità di implementazione). Restituisce falsese il valore di input è un numero Chicken McNugget o truese il valore di input non è un numero 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

La cosa brutta di questo è la necessità di gestire esplicitamente i valori di input> = 43 mediante un confronto e un ramo in alto. Esistono ovviamente altri modi per farlo che non richiedono il branching, come l'algoritmo caher coinheringaahing , ma questo richiederebbe molti più byte per codificare, quindi non è una soluzione ragionevole. Immagino che probabilmente mi sto perdendo qualche trucco bit-twiddling che renderebbe questo lavoro più elegante ed essere meno byte rispetto alla soluzione basata su bitfield sopra (poiché la codifica del bitfield stesso richiede così tanti byte), ma ho studiato questo per un po 'e ancora non riesco a vederlo.

Oh bene, provalo comunque online !


3

05AB1E, 17 16 byte

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

Provalo online!

Spiegazione

  Ž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
Hai collegamenti TIO duplicati.
Incarnazione dell'ignoranza il

1
Bella risposta. Benvenuti in PPCG e nel mondo di 05AB1E. :) Una cosa da golf è di utilizzare per la stringa (ci sono buitins per le stringhe 1, 2, e 3-char, essendo ', e rispettivamente). Ho la sensazione che più si possa giocare a golf, magari usando un approccio diverso, ma a prescindere da questa è una bella prima risposta. +1 da me.
Kevin Cruijssen,

1
Era davvero corretto. Abbiamo trovato un 12-byter utilizzando l'incorporato Åœ: … ÇIÅœåPOĀ. È un approccio completamente diverso, quindi se vuoi che lo pubblichi come una risposta separata piuttosto che una tua golf, fammi sapere. PS: Non sono sicuro al 100% se gli non stampabili sono ammessi nella tabella codici 05AB1E . In quel caso ŽBo21вpotrebbe essere necessario avere una codifica diversa, il che farebbe in modo che alcuni caratteri contino come 2 byte ciascuno. In tal caso, potrebbe essere un'alternativa a +1 byte.
Kevin Cruijssen,

Come menziona Kevin, nessuno dei 3 byte nella stringa si trova nella tabella codici 05ab1e e quindi non può essere utilizzato senza contare l'intero programma in utf-8 che lo renderebbe molto più lungo. È possibile tuttavia utilizzare al ŽGç₂вposto della stringa e contemporaneamente salvare un byte nel processo.
Emigna il

Kevin, provaci. Sarebbe bello vedere approcci diversi. Emigna, grazie per il tuo suggerimento, farò il cambio
rev

2

JavaScript (ES6), 69 64 byte

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

Output falseper i numeri di Chicken McNugget, truealtrimenti.


Vorrei almeno un link "provalo" ..
racer290,

@ racer290 Aggiunto.
darrylyeo,

n=>~'ABCDEFHIKLNOQRTWXZ]`cfl'.search(String.fromCharCode(n+65))per 63 byte
Oki,

2

Java, 21 57 24 byte

Provalo online!

golfed:

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

Ungolfed:

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);
  }
}

Il risultato è errato per 26 = 20 + 6.
Leaky Nun,

@LeakyNun Algorithm era troppo ingenuo. Ho dovuto andare con il piano B che ha aggiunto alcuni byte, ma sembra produrre risultati corretti per tutto il tempo ora. Avrei dovuto ripetere tutti i valori anziché iniziare a fare affidamento sui casi di test nella domanda.


1
24 byte (vedi sopra)
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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.