鸡McNugget号码


29

描述

麦克唐纳鸡肉数字是可以表示为6、9或20之和的数字- 麦当劳出售的著名的麦克唐纳鸡肉盒子的初始尺寸。在该总和中,一个数字可能出现不止一次,6 + 6 = 12这样的数字也是如此,并且该数字必须“包含”至少一个上述大小。第一个Chicken McNugget编号为:

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

挑战

您的任务是编写一个程序或函数,给定一个正整数,该程序或函数将确定该数字是否可以所描述的方式表示,因此就是Chicken McNugget数。然后,它应根据其决定输出真实或虚假的值。

测试用例

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

这是,因此以字节为单位的最短答案将获胜,并且存在标准漏洞!


15
请注意,“所有整数都是McNugget编号,除了1,2,3,4,4,5,7,8,10,11,13,14,16,17,19,22,23,25,28,31, 34、37和43。” (mathworld
Leaky Nun

1
好吧,那么让我们将其作为压缩挑战,但是感谢您的注意
racer290 '17

3
有人为此有OEIS链接吗???
CraigR8806

2

Answers:


37

Python,27个字节

lambda n:0x82492cb6dbf>>n&1

在线尝试!


11
什么是神奇的代码o_O,这太神奇了
HyperNeutrino

您可以删除,~因为您可以交换输出。
Leaky Nun

1
同样,8953174650303具有与之完全相同的长度0x82492cb6dbf(尽管可读性较差)。
Leaky Nun

2
@HyperNeutrino魔术数字仅设置了与不是 Chicken McNugget数字的数字相对应的那些位。看一下它的二进制表示形式,它将更加清晰。
David Z

1
可惜您不能轻易地将基数
设为

29

Python 3,24字节

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

在线尝试!

说明

随着69孤独,一个可以让所有整数整除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ý谢谢,更新。
Leaky Nun

1
您可以删除f=now,因为它不是递归的。
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 mod 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
Chicken McNuggets™和果冻!嗯!
CJ丹尼斯

@CJDennis实际上是Chicken McNuggets©和Jelly。
caird coinheringaahing

@cairdcoinheringaahing实际上是ChickenMcNuggets®和Jelly。

5

Haskell,36个字节

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

在线尝试!

说明

该解决方案尽可能简单。第一行声明对于小于1的任何数字,如果为,则为McNugget数字n==0。也就是说,这是0McNugget数,而所有负数都不是。

第二行声明,对于所有其他数字,n如果减去任何块大小即为McNugget数字,则为McNugget数字。

这是一个非常简单的递归搜索。



3

果冻,11字节

_20$%3$¿o>3

在线尝试!

我的Python答案的端口号,但稍作修改:减去20直到可被整除3,然后0,6,9,...通过映射0到输入(使用or)检查它是否属于,然后检查它是否大于3

产生唯一的三个数字0在完成第一个步骤是020或者40,与所述第一个是出域,而其余的是大于3


我不知道如何输入输入内容
。– racer290

@ racer290命令行参数。
暴民埃里克(Erik the Outgolfer)

3

Mathematica,53个字节

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

也许您可以使用该FrobeniusSolve功能。
alephalpha



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遵循Windows上使用的Microsoft 64位调用约定,将单个正整数参数传递到寄存器中。结果是在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

显然,这与Anders Kaseorg在Python中的解决方案大不相同,因为它是基于一个位域的,该位域表示的是Chicken McNugget数字。具体而言,该字段中与有效的McNugget小鸡编号相对应的每个位都设置为1;所有其他位都设置为0。(这将0视为有效的Chicken McNugget数字,但如果您不喜欢它,则可以选择单个位进行修改。)

我们首先简单地将此值加载到寄存器中。它是一个64位的值,已经需要8个字节进行编码,而且我们需要一个1字节的REX.W前缀,因此在字节方面我们确实非常不省钱,但这是解决方案的核心,因此我想这是值得的。

然后,我们将字段右移输入值。*最后,我们屏蔽掉除了最低位以外的所有位,这成为我们的布尔结果。

但是,由于移位的位数不能超过该值的实际位数,因此仅适用于0-63之间的输入。为了支持更高的输入值,我们在该函数的顶部插入一个测试,该测试的顶部分支到输入值的底部是> =64。对此唯一有趣的是,我们在中预加载了位字段常量RAX,然后进行分支直到掩盖最低位的指令,从而确保我们总是返回1。

在线尝试!
(那里的C函数调用带有一个属性,该属性使GCC使用我的汇编代码使用的Microsoft调用约定对其进行调用。如果TIO提供了MSVC,则不需要这样做。)

__
*作为移位的替代方法,我们可以使用x86 BT指令,但是编码要长1个字节,因此没有优势。除非我们被迫使用不同的调用约定,该约定不能方便地在ECX寄存器中传递输入值。这将是一个问题,因为SHR 要求其源操作数CL用于动态移位计数。因此,不同的调用约定将要求我们MOV从传递给它的任何寄存器中编辑输入值ECX,这将花费2个字节。该BT指令可以将任何寄存器用作源操作数,而仅花费1个字节。因此,在那种情况下,这将是可取的。BT将相应位的值放入进位标志(CF)中,因此您将使用一条SETC指令在整数寄存器中获取该值,就像AL可以将其返回给调用方一样。


替代实现,23字节

这是使用模和乘法运算来确定输入值是否为Chicken McNugget数的替代实现。

它使用System V AMD64调用约定,该约定将输入值传递到EDI寄存器中。结果仍然是布尔值,在中返回EAX

但是请注意,与上面的代码不同,这是一个反向布尔值(为实现方便)。它返回false如果输入值是一个鸡McNugget号,或者true如果输入值是不是一个鸡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

这样做的丑陋之处在于需要通过顶部的“比较与分支”显式处理输入值> = 43。显然有这样做不需要分支,就像其他的方式凯尔德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:我不确定100AB是否在05AB1E代码页中允许使用不可打印的内容。在这种情况下,可能必须采用不同的编码,这会使某些字符每个计数为2个字节。在这种情况下,ŽBo21в可以选择+1个字节。
凯文·克鲁伊森

就像Kevin提到的那样,字符串中的3个字节都不在05ab1e代码页中,因此,如果不将整个程序计算在utf-8中就无法使用,这会使它更长。但是,您可以ŽGç₂в在进程中同时保存一个字节的同时使用代替字符串。
Emigna

凯文,去吧。很高兴看到不同的方法。Emigna,谢谢您的建议,我将进行更改
修订

2

JavaScript(ES6),69 64字节

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

否则输出falseChicken McNugget编号的输出true


我想至少一个“试一试”链接..
racer290

@ racer290添加。
darrylyeo

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

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

Python 2,51个字节

-1字节感谢@LeakyNun

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

在线尝试!页脚打印所有非McNugget数字


n%3只能是0或1或2,因此n%3==2等效于n%3>1
Leaky Nun


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字节

*由于@Jonasw节省了14个字节

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外,所有整数都是McNugget数字,37和43。” 来自@LeakyNun的评论


使用一个简单的数组将为.split保存字节...
Jonas Wilms

@Jonas数组是108个字节,分割后的字符串是73个字节
SuperStormer




1

加++,35字节

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

在线尝试!

看,没有while循环。或字符串。或清单。或实际上可以帮助节省字节的任何内容。但是主要是因为Add ++不知道这些是什么。

3个月后,我意识到这是无效的,并将其修复。不知何故,它打了13个字节。该函数接受一个参数,并测试该参数是否为Chicken McNugget数字。

怎么运行的

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个字节

=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)

或者,92个字节:

=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字节

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

退出,并1获得一个McNugget小鸡编号,0否则。

与管道一起运行-n在线尝试



0

Mathematica,59个字节

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

0

Javascript 37字节

取正整数,n并输出trueChicken McNugget数和false其他数字。

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

说明

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

此函数的递归令人讨厌,对于任何足够大的递归n,您都将超出调用堆栈限制。这是一个通过检查是否n大于最大非鸡McNugget数(43个字节[最大非鸡McNugget数的加分点?])来避免这些限制的版本:

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


0

JavaScript ES5,46个字节

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

显式布尔答案,50个字节:

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

笨拙,但是可以完成工作。返回false0针对每个非0、1、2、3、4、5、7、8、10、11、13、14、16、17、19、22、23、25、28、31、34的值,37或43,和true-11为一切。

显式解决方案返回truefalse仅返回。

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字节

可以的快速尝试: #(-> %(rem 20)(rem 9)(rem 6)(= 0))


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.