Цыпленок МакНуггет Числа


29

Описание

Числа Chicken McNugget - это числа, которые можно выразить в виде суммы 6, 9 или 20 - начальных размеров известных коробок Chicken McNuggets, продаваемых 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 )
Монахиня

1
Хорошо, тогда давайте возьмем это как проблему сжатия, но спасибо за примечание
racer290

3
У кого-нибудь есть ссылка OEIS для этого ???
CraigR8806

2
Что ты имеешь против 4-х частей самородка? mcdonalds.com/us/en-us/product/chicken-mcnuggets-4-piece.html
Дэн Нили,

Ответы:


37

Python, 27 байт

lambda n:0x82492cb6dbf>>n&1

Попробуйте онлайн!


11
Что это за волшебный код o_O это удивительно
HyperNeutrino

Вы можете удалить, ~потому что вы можете поменять местами выходы.
Утренняя монахиня

1
Кроме того, 8953174650303имеет точно такую ​​же длину с 0x82492cb6dbf(хотя и менее читабельным).
Утренняя монахиня

2
@HyperNeutrino у магического числа есть только те биты, которые соответствуют числам, которые не являются числами Цыпленка МакНуггет. Посмотрите на его двоичное представление, и оно будет намного понятнее.
Дэвид З

1
Жаль, что вы не можете легко использовать эту же идею с базой 64
Джейкоб Гарби

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 обновлен.
Утренняя монахиня

f=lambda n:n%3<1<n-2or n>20and f(n-20)это работает?
Захари

@ Zacharý спасибо, обновлено.
Утренняя монахиня

1
Вы можете удалить f=сейчас, так как это не рекурсивно.
Notjagan

8

Python 2 , 28 байт

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

Попробуйте онлайн!


Используя некоторые методы проб и ошибок и сопоставляя первую часть с диапазоном, у меня есть приблизительное представление о том, как это работает. Тем не менее, я хотел бы знать, как вы пришли к этому решению.
Утренняя монахиня

@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
Цыпленок МакНуггетс ™ и Желе! Мммм !!!
CJ Деннис

@CJDennis На самом деле это Куриные МакНаггетс © и Джелли.
Кэрд coinheringaahing

@cairdcoinheringaahing На самом деле это Куриные МакНуггетс® и Желе.
Дан

5

Haskell , 36 байт

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

Попробуйте онлайн!

объяснение

Это решение настолько простое, насколько это возможно. Первая строка объявляет, что для любого числа меньше 1 это число МакНуггет, если n==0. То есть это0 это число МакНуггет, а все отрицательные числа - нет.

Вторая строка объявляет, что для всех других чисел, n это число МакНуггет, если оно минус любой из размеров Наггетта, это число МакНуггет.

Это довольно простой рекурсивный поиск.



3

Желе , 11 байт

_20$%3$¿o>3

Попробуйте онлайн!

Порт моего ответа на Python , но немного измененный: вычитайте 20до деления на 3, затем проверяйте, принадлежит ли он 0,6,9,..., сопоставляя 0с входом (используя or), и затем проверяйте, больше ли он, чем3 .

Единственные три числа, которые появляются 0после завершения первого шага 0, это 20, или 40, если первый находится вне домена, а остальные больше чем 3.


Я не понимаю, как ввести ввод ..
racer290

@ racer290 Аргумент командной строки.
Эрик Outgolfer



3

Mathematica, 20 байтов

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

Анонимная функция. Принимает число как ввод и возвращает Trueили Falseкак вывод. Логика скопирована из ответа Лики Нун , с некоторыми дополнительными злоупотреблениями 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, которая определяет, является ли входное значение числом Чикен МакНуггет. Один положительный целочисленный параметр передается в 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 является действительным числом Chicken McNugget, но если вам это не нравится, ваши предпочтения - это однобитная модификация.)

Мы начинаем с простой загрузки этого значения в регистр. Это 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 байта

Вот альтернативная реализация, которая использует операции по модулю и умножению, чтобы определить, является ли входное значение числом Чикен МакНуггет.

Он использует соглашение о вызовах System V AMD64 , которое передает входное значение в 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 с помощью функции сравнения и ветвления вверху. Очевидно, есть другие способы сделать это, которые не требуют ветвления, например алгоритм caird coinheringaahing , но для кодирования потребуется намного больше байтов, так что это не является разумным решением. Я полагаю, что мне, вероятно, не хватает некоторого хитрого трюка, который сделал бы эту работу более элегантной и занимал бы меньше байтов, чем решение на основе битового поля выше (поскольку кодирование самого битового поля занимает так много байтов), но я изучил это для некоторое время и до сих пор не вижу этого.

Ну ладно, попробуйте в любом случае онлайн !


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ç₂ввместо строки при одновременном сохранении байта в процессе.
Эминья

Кевин, дерзай. Было бы неплохо увидеть разные подходы. Эминья, спасибо за предложение, я внесу изменения
ред.

2

JavaScript (ES6), 69 64 байта

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

Выходные данные falseдля чисел Chicken McNugget, в trueпротивном случае.


I'd like at least a "try it" link..
racer290

@racer290 Added.
darrylyeo

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

2

Java, 21 57 24 bytes

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

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

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

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.