Курячі номери МакНуггет


29

Опис

Номери курчат МакНуггет - це числа, які можна виразити сумою 6, 9 або 20 - початкові розміри знаменитих коробок МакНуггетт, що продаються компанією McDonald's. У цій сумі число може виникати більше одного разу, тому 6 + 6 = 12таке число теж є, і число повинне "містити" принаймні один із згаданих розмірів. Перші курки МакНуггет:

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

Виклик

Ваше завдання полягає в тому, щоб написати програму або функцію, яка за заданим цілим числом визначає, чи можна це число виразити описаним способом, тому таке число Курячого МакНуггет. Тоді він повинен виводити напевне або хибне значення на основі свого рішення.

Тестові справи

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

Це , тому найкоротша відповідь у байтах виграє і застосовуються стандартні лазівки!


15
Слід зазначити, що "Усі цілі числа - це числа МакНуггет, крім 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23, 25, 28, 31, 34, 37 та 43. " ( mathworld )
Leaky Nun

1
Ну, тоді давайте
сприймемо

3
У когось для цього є посилання OEIS ???
CraigR8806

2
Що ти маєш проти 4-х частинного самородка? mcdonalds.com/us/en-us/product/chicken-mcnuggets-4-piece.html
Dan Neely

Відповіді:


37

Пітон, 27 байт

lambda n:0x82492cb6dbf>>n&1

Спробуйте в Інтернеті!


11
Що це за магічний код o_O, це дивовижно
HyperNeutrino

Ви можете видалити, ~оскільки ви можете поміняти місцями.
Leaky Nun

1
Також 8953174650303має точно таку ж довжину з 0x82492cb6dbf(хоча і менш читаною).
Leaky Nun

2
@HyperNeutrino магічне число має лише ті біти, які відповідають номерам, які не є номерами Курячого МакНуггет. Подивіться на його бінарне подання, і це буде набагато зрозуміліше.
David Z

1
Соромно, що ти не можеш легко використовувати цю саму ідею з базою 64
Jacob Garby

29

Python 3 , 24 байти

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

Спробуйте в Інтернеті!

Пояснення

За допомогою 6і 9лише вони можуть зробити всі цілі числа ділими на3 більші, ніж 3зазначено в коментарі ovs до виклику . Передбачається, що можна і зробити 0. На закінчення можна зробити0,6,9,12,15,... .

З одним екземпляром 20 можна зробити:20,26,29,32,35,... .

З двома примірниками 20 можна зробити:40,46,49,52,55,... .

Три екземпляри ніколи не потрібні 3 x 20 = 10 x 6 .


Зауважте, що випадки, коли немає 20необхідності, також поділяються на 3; випадки, коли 20потрібен один , залишають залишки 2; випадки, коли два20 потрібні , залишають залишок1 .

Отже, кількість 20необхідних може бути обчислена (-n)%3. Потім робимо, n-(((-n)%3)*20)щоб зняти потрібну кількість 20з числа. Потім ми перевіряємо, чи ця цифра є негативною, але ні 3.



@ Mr.Xcoder оновлено.
Leaky Nun

f=lambda n:n%3<1<n-2or n>20and f(n-20)це працює?
Zacharý

@ Zacharý спасибі, оновлено.
Лина монашка

1
Ви можете видалити f=зараз, оскільки це не рекурсивно.
notjagan

8

Python 2 , 28 байт

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

Спробуйте в Інтернеті!


Користуючись деякими пробними та помилковими помилками та відображаючи першу частину в діапазоні, я маю грубе уявлення про те, як це працює. Однак я хотів би знати, як ви придумали це рішення.
Leaky Nun

@LeakyNun Смішно, я думав, що це природний метод, і ваш розумний :). Я зазначив, що можливі значення (n%3,n/20)з вашого виключеного списку є {(2, 0), (1, 0), (1, 1)}. Використання-n%3 натомість дало нерівність n/20>=(-n)%3. Звідти я хотів деякий час повернути назад, {3,23,43}які є 3 моди 20, не впливаючи на 63,83, ... Я виявив зміщення кінцевої точки нерівності для цих найприємніших.
xnor

Ну, мій метод передбачає дійсно вирішити проблему, тоді як ваш метод співпадає зі значеннями у списку, що виключається, тому я б сказав, що мій метод є більш природним :)
Leaky Nun

7

Желе , 11 байт

ṗ3’æ.“©µÞ‘ċ

Спробуйте в Інтернеті!

Як це працює

ṗ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
Курка McNuggets ™ і желе! Ммммм !!!
CJ Dennis

@CJDennis Насправді це курка МакНугеттс © і Джеллі.
caird coinheringaahing

@cairdcoinheringaahing Насправді це курка МакНуггетс® і Желе.
Ден

5

Haskell , 36 байт

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

Спробуйте в Інтернеті!

Пояснення

Це рішення є настільки ж простим, наскільки воно може отримати. Перший рядок оголошує, що для будь-якого числа менше 1 - це номер McNugget, якщо n==0. Тобто це 0число МакНуггет, і всі від’ємні числа не є.

Другий рядок оголошує, що для всіх інших чисел n- це номер McNugget, якщо його мінус будь-який розмір Nugget - це номер McNugget.

Це досить простий рекурсивний пошук.



3

Желе , 11 байт

_20$%3$¿o>3

Спробуйте в Інтернеті!

Порт моєї відповіді Python , але злегка модифікований: відніміть 20до ділення на 3, потім перевірте, чи належить він 0,6,9,..., відображаючи 0на вхід (за допомогоюor ), а потім перевірте, чи більший він від3 .

Тільки три цифри , які виробляють 0після завершення першого етапу є 0, 20або 40, з першим з яких з домену, а решта більше 3.


Я не розумію, як ввести вхід ..
racer290

Аргумент командного рядка @ racer290
Ерік Аутгольфер

3

Математика, 53 байти

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

Можливо, ви можете скористатися FrobeniusSolveфункцією.
алефальфа


3

Математика, 20 байт

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

Анонімна функція. Приймає число як вхід і повернення Trueабо Falseяк вихід. Логіка скопійована з відповіді Leaky Nun , з деякими додатковими зловживаннями Inequality.


3

x86-64 Машинний код, 22 байти

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

Вищеописані байти визначають функцію в 64-розрядному машинному коді x86, яка визначає, чи є вхідним значенням номер Chicken McNugget. Єдине додатне ціле число передається в ECXрегістр після 64-розрядного викликів Microsoft, який використовується в Windows. Результатом є булеве значення, повернене в EAXреєстр.

Невикольована збірна мнемоніка:

; 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

Очевидно, що це грає дуже сильно відмінне від рішення Андерса Касеорга в Python , оскільки воно засноване на бітовому полі, що представляє значення, які є числами Курячого МакНуггет. Зокрема, кожен біт у цьому полі, що відповідає дійсному номеру Chicken McNugget, встановлюється рівним 1; всі інші біти встановлені на 0. (Це вважає 0 дійсним номером курячого МакНуггетта, але якщо вам це не подобається, вашим уподобанням є одномовна модифікація.)

Ми починаємо, просто завантаживши це значення в регістр. Це 64-бітове значення, для кодування якого вже потрібно 8 байт, плюс нам потрібен однобайтовий префікс REX.W, тому ми насправді досить витрачаємо в плані байтів, але це суть рішення. Я здогадуюсь того варто.

Потім переміщуємо поле право на вхідне значення. * Нарешті, ми маскуємо всі, окрім бітів нижчого порядку, і це стає нашим булевим результатом.

Однак, оскільки ви не можете змістити на більшу кількість бітів, фактично значущих, це працює лише для входів від 0–63. Для підтримки більш високих вхідних значень ми вставляємо тест у верхній частині функції, яка розгалужується на нижню частину вхідного значення -> = 64. Єдине, що цікаво в цьому, - ми попередньо завантажуємо константу бітового поля RAX, а потім розгалужуємо вниз до інструкції, яка маскує біт нижнього порядку, забезпечуючи тим самим, що ми завжди повертаємо 1.

Спробуйте в Інтернеті!
(Виклик функції C там позначається атрибутом, який змушує GCC викликати його за допомогою правила виклику Microsoft, який використовує мій код складання. Якби TIO надав MSVC, це не було б необхідним.)

__
* В якості альтернативи зсуву ми могли б використовувати BTінструкцію x86 , але це на 1 байт довше, щоб кодувати, тому переваги немає. Якщо тільки нас не змусили використовувати інший режим виклику, який не зручно передавати вхідне значення в ECXрегістр. Це буде проблемою, оскільки SHR вимагає, щоб його вихідний операнд був CLдля динамічного підрахунку зсуву. Отже, інша умова виклику вимагає, щоб ми MOVредагували вхідне значення з того регістра, в який воно було передане ECX, що коштувало б нам 2 байти. BTКоманда може використовувати будь-який регістр в якості операнда - джерела, при вартості тільки 1 байт. Тож у цій ситуації було б краще.BTставить значення відповідного біта у прапор переносу (CF), тому ви використовуєтеSETCінструкція отримати це значення в ALцілому регістрі, як, щоб воно могло бути повернене абоненту.


Альтернативна реалізація, 23 байти

Ось альтернативна реалізація, яка використовує операції по модулю та множення, щоб визначити, чи є вхідним значенням номер Chicken McNugget.

Він використовує System V AMD64 convention , що передає вхідне значення в EDIрегістр. Результат все ще булевий, повернувся EAX.

Зауважте, що на відміну від вищевказаного коду, це зворотний булевий (для зручності реалізації). Він повертається, falseякщо вхідним значенням є номер курячого Макнаггетта, або trueякщо вхідне значення не є номером Курячого МакНуггет.

                    ; 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

Неприємно в цьому полягає в необхідності чітко обробляти вхідні значення> = 43 шляхом порівняння та розгалуження вгорі. Очевидно, існують й інші способи цього, які не потребують розгалуження, як алгоритм канадського коінхерінгахінга , але для кодування знадобиться набагато більше байтів, тому це не є розумним рішенням. Я думаю, що я, мабуть, пропускаю якийсь тріпоткий трюк, який би зробив цю роботу більш елегантною і матиме менше байтів, ніж рішення, що базується на бітфілді (оскільки кодування бітфілда займає стільки байтів), але я вивчив це для деякий час, і досі його не бачу.

Ну добре, спробуйте все- таки в Інтернеті !


3

05AB1E, 17 16 байт

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

Спробуйте в Інтернеті!

Пояснення

  Ž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
У вас є повторювані посилання TIO.
Втілення Невідомості

1
Гарна відповідь. Ласкаво просимо до PPCG та світу 05AB1E. :) Єдине , що гольф є використання для рядка (є buitins для 1-, 2- і 3-символьних рядків, будучи ', і відповідно). У мене є відчуття, що більше можна пограти в гольф, можливо, використовуючи інший підхід, але незалежно від цього є приємною першою відповіддю. +1 від мене.
Кевін Круїссен

1
Дійсно було правильно. Знайдено 12-byter шляхом використання вбудованого Åœ: … ÇIÅœåPOĀ. Це зовсім інший підхід, тому, якщо ви хочете, щоб я опублікував це як окрему відповідь, а не ваш гольф, дайте мені знати. PS: Я не впевнений на 100%, чи дозволені недруковані матеріали на кодовій сторінці 05AB1E . У цьому випадку може знадобитися інше кодування, що призведе до того, що деякі символи замість цього будуть рахувати по 2 байти. У такому випадку це ŽBo21вможе бути альтернативою +1 ​​байту.
Кевін Круїссен

Як згадує Кевін, жоден з 3-х байтів у рядку не знаходиться в кодовій сторінці 05ab1e, і тому його не можна використовувати без підрахунку всієї програми у utf-8, що зробить її набагато довше. Однак ви можете використовувати ŽGç₂взамість рядка, одночасно зберігаючи байт у процесі.
Емінья

Кевін, піди на це. Було б непогано бачити різні підходи. Емінья, дякую за вашу пропозицію, я зроблю зміни
rev

2

JavaScript (ES6), 69 64 байт

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

Виходи falseдля номерів курки МакНуггет, trueінакше.


Я хотів би хоча б посилання "спробувати"
racer290

@ racer290 Додано
darrylyeo

n=>~'ABCDEFHIKLNOQRTWXZ]`cfl'.search(String.fromCharCode(n+65))за 63 байти
Окі

2

Java, 21 57 24 байти

Спробуйте в Інтернеті!

Гольф:

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

Безголовки:

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

Результат неправильний 26 = 20 + 6.
Leaky Nun

@LeakyNun Алгоритм був надто наївним. Мені довелося піти з планом B, який додав кілька байтів, але, здається, весь час дає правильні результати. Я повинен був би повторити всі значення для початку, а не покладатися на тестові випадки у питанні.


1
24 байти (див. Вище)
Leaky Nun

1
@LeakyNun дякую! У мене ще багато чого, щоб дізнатися про гольф.



1

Haskell, 64 56 байт

Я не робив жодних хитрощів, але дивлячись на інші відповіді, можливо, імпортувати Bitsмодуль та використовувати ці методи, можливо, буде коротше . Цей підхід перевіряється набагато прямо.

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

1
Кількість байтів - 66ні 64. Але ви можете зберегти багато дужок і поставити x/=0охорону, щоб зберегти кілька байт, дивіться тут .
ბიმო

1

Javascript, 92 78 72 байти

* збережено 14 байт завдяки @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])

Використовує той факт, що "Усі цілі числа - це числа МакНуггет, крім 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 22, 23, 25, 28, 31, 34 , 37 та 43. " з коментаря @ LeakyNun


використання простого масиву дозволить зберегти байти для .split ...
Jonas Wilms

Масив @Jonas складає 108 байт, розділений рядок - 73 байти
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

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.