防位翻转复合数字


26

有时,在编写程序时,出于某种原因(例如,密码学),您需要使用质数。我认为有时您也需要使用一个复合数字。有时,至少在PPCG上,您的程序必须能够处理任意更改。而且在方便地提出一个有趣的PPCG问题的情况下,也许甚至您使用的数字也必须能够抵御腐败……

定义

合数是一个整数≥4不是素数,即它是两个较小的整数大于1更大的产物抗性bitflip复合数被定义如下:它是其中复合正整数,如果你把它写如果是二进制格式,则位数应尽可能少,您可以更改该位数中的任何一位或两位,并且该数字仍然是合成的。

例如,考虑数字84。在二进制中,即1010100。以下是所有相差不超过2位的数字:

0000100 4 2×2
0010000 16 4×4
0010100 20 4×5
0010101 21 3×7
0010110 22 2×11
0011100 28 4×7
0110100 52 4×13
1000000 64 8×8
1000100 68 4×17
1000101 69 3×23
1000110 70 7×10
1001100 76 4×19
1010000 80 8×10
1010001 81 9×9
1010010 82 2×41
1010100 84 7×12
1010101 85 5×17
1010110 86 2×43
1010111 87 3×29
1011000 88 8×11
1011100 92 4×23
1011101 93 3×31
1011110 94 2×47
1100100 100 10×10
1110000 112 8×14
1110100 116 4×29
1110101 117 9×13
1110110 118 2×59
1111100 124 4×31

第一列是二进制数。第二列是十进制数字。如第三列所示,所有这些数字都是合成的。这样,84是抗位翻转的复合数。

任务

您必须编写以下三个程序或函数之一,以最适合您的语言的形式:

  • 一个程序或函数,将非负整数n作为输入,并输出前n个抗位翻转的复合数字。
  • 一个程序或函数,将非负整数n作为输入,并输出所有小于n的耐位翻转复合数字(或者,如果您愿意,小于或等于n,即如果bitflip,则可以选择是否在输出中包含n) -)。
  • 无需输入,并输出所有可抵抗位翻转的复合数字的程序或函数。(这必须使用一种能够在程序仍在运行时产生输出的输出机制,例如打印到stdout,惰性列表或生成器;您不能只计算整个列表然后进行打印。)

测试用例

这是前几个抗位翻转的复合数字:

84, 184, 246, 252, 324, 342, 424, 468, 588, 636, 664, 670, 712, 730, 934, 958

澄清说明

  • 只有您产生的数字才能抵抗位翻转。这不是使程序能够发现它们对位翻转的抵抗力。使用您喜欢的程序本身中的任何数字。
  • 您输出的数字不必抵抗“前导零”中的位翻转;想象一下,数字将以最小可能的位数进行存储,并且只有那些位数必须不受翻转的影响。但是,您输出的数字的前1位必须不受位翻转的影响。
  • 使用您喜欢的任何产生正确结果的算法;您在此处未获得效率方面的标记。
  • 如果可以证明确实有很多抗位翻转的复合数字,则a)取消了对输出格式的限制,并且b)允许对该列表进行硬编码(尽管可能比仅对其进行计算更为冗长)。该规则主要是为了完整性。我不认为这是有意义的。

胜利条件

这是,因此,通常,较短的更好。同样,程序的长度将以字节为单位。


“一个程序或函数,将非负整数n作为输入,并输出所有小于n的耐位翻转复合数字”- n如果n耐位翻转,我可以包括在内吗?(即使其“小于或等于n”?)
JungHwan Min


2
我喜欢您的规格通常如此清晰和透彻
Luis Mendo

在一开始谈论抗拒腐败的所有话题时,我认为这将是另一个几乎不可能实现的辐射硬化挑战……
ETHproductions 2017年

2
@ ais523看起来像是空程序。所有空程序的集合。
mbomb007 '17

Answers:


5

果冻 20岁?22 字节

BµJŒċ;0Ṭ^µḄµÆPoỊṀ¬
⁴Ç#

在线尝试!

产生前n个这样的数字。

也许;0可以将其删除(没有它,我们将不检查数字本身是否为复合数字-所有bit-flips复合数字中是否有素数?)

请注意,这是足够进行测试not(any(is prime))所设定的位翻转数。我们还必须测试0不在集合中的那个。

这是因为0不是素数也不是复合数(1也是,但是请参阅下文)。

0一个反例可以看出需要检查的地方:

  • 1311362 17 +2 6)具有以下翻转位:

[0, 64, 65, 66, 68, 72, 80, 96, 192, 320, 576, 1088, 2112, 4160, 8256, 16448, 32832, 65600, 131072, 131073, 131074, 131076, 131080, 131088, 131104, 131136, 131137, 131138, 131139, 131140, 131141, 131142, 131144, 131145, 131146, 131148, 131152, 131153, 131154, 131156, 131160, 131168, 131169, 131170, 131172, 131176, 131184, 131200, 131264, 131265, 131266, 131268, 131272, 131280, 131296, 131328, 131392, 131393, 131394, 131396, 131400, 131408, 131424, 131520, 131584, 131648, 131649, 131650, 131652, 131656, 131664, 131680, 131776, 131904, 132096, 132160, 132161, 132162, 132164, 132168, 132176, 132192, 132288, 132416, 132672, 133120, 133184, 133185, 133186, 133188, 133192, 133200, 133216, 133312, 133440, 133696, 134208, 135168, 135232, 135233, 135234, 135236, 135240, 135248, 135264, 135360, 135488, 135744, 136256, 137280, 139264, 139328, 139329, 139330, 139332, 139336, 139344, 139360, 139456, 139584, 139840, 140352, 141376, 143424, 147456, 147520, 147521, 147522, 147524, 147528, 147536, 147552, 147648, 147776, 148032, 148544, 149568, 151616, 155712, 163840, 163904, 163905, 163906, 163908, 163912, 163920, 163936, 164032, 164160, 164416, 164928, 165952, 168000, 172096, 180288, 196608, 196672, 196673, 196674, 196676, 196680, 196688, 196704, 196800, 196928, 197184, 197696, 198720, 200768, 204864, 213056, 229440]

除了0复合以外,所有这些都不是0主要的。

1也是非素数和非复合物,可能会出现在集合中。但是,我们可以根据需要将其保留为复合形式:

  • 所有小于或等于3(如果要考虑的话)的输入总而言之0(实际上都是比输入少7)。

  • 1翻转一次,原始数必须是2 k +2 0的形式,如果大于3,即k> 1,则可以3通过翻转k位并设置1位来达到(2 1 +2 0 = 3)。

  • 要达到1两次翻转,原始数必须为2 k的形式,如果大于3我们可以2两次翻转达到的2数,则为素数。

就目前而言,代码使用“无关紧要”的原子,01一起处理两者

怎么样?

⁴Ç# - Main link: n
⁴   - 16
  # - count up from 16 finding the first n matches of
 Ç  -     last link (1) as a monad

BµJŒċ;0Ṭ^µḄµÆPoỊṀ¬ - Link 1, test a number: i
B                  - convert to a binary list
 µ                 - start a new monadic chain
  J                - range(length): [1,2,...,nBits]
   Œċ              - pairs with replacement: [[1,1],[1,2],...,[1,nBits],[2,2],[2,3],...,[2,nBits],...,[nBits-1,nBits]]
     ;0            - concatenate a zero
       Ṭ           - untruth (makes lists with ones at those indexes - the [1,1], [2,2], etc make the one-flips, the zero makes the no-flip, the rest make the two-flips)
        ^          - exclusive or with the binary list version of i (flip the bits)
         µ         - start a new monadic chain
          Ḅ        - un-binary (get the integer values of each of the flipped versions)
           µ       - start a new monadic chain
            ÆP     - is prime? (make a list of 1s for primes and 0 for non-primes)
               Ị   - is insignificant (abs(v)<=1)
              o    - logical or (now we have true for any primes, 0 or 1 - hence non-composites)
                Ṁ  - maximum (1 if any non-composite was found)
                 ¬ - not (1 if all were composite)

输入中是否包含最多相差2位的所有数字?如果是这样,它将无论如何检查输入本身的复合性。
JungHwan Min

不,这就是为什么;0-存在的原因- Œċ使用索引(J)替换所有无序对,因此对于84,它具有7位,即28(包括对单个位翻转的[1,1]之类的(来自“带有替换”部分),而不是29(加上无变化)
乔纳森·艾伦

如果我们知道不存在素数,使得所有的位翻转表亲都是复合的,则可以将其删除;但我不确定这个事实。
乔纳森·艾伦,

5

Brachylog32 38字节

2<≜.¬(ḃ↰₂↰₂~ḃ≜{ṗ|ℕ<2}∧)
k~k|tgT∧?k↰:Tc

在线尝试!

这是一个函数/谓词↰₀,返回生成所有此类数字的生成器。(TIO链接仅显示第一个数字,因此可以观察到。不过,在本地运行它会产生更多的结果。)

现在已更新为可以正确处理两个介于0或1(既不是素数也不是合成数)的位翻转中的数字。

说明

Helper谓词 ↰₂(返回一个等于输入的列表,除了一个元素外)

k~k|tgT∧?k↰:Tc
   |            Either:
 ~k               the output is produced by appending an arbitrary element
k                 to the input minus its last element
                Or:
        ?k        take the input minus its last element,
          ↰       call this predicate recursively on that,
      T    :Tc    then append
     g            the singleton list consisting of
    t             the last element of the input

如果有一种比较简单的递归方法,我会喜欢的,但是我不确定还没有。规范中有一些看起来不错的功能,但是被标记为未实现。

主程序 ↰₀

2<≜.¬(ḃ↰₂↰₂~ḃ≜{ṗ|ℕ<2}∧)
2<≜                      For each integer greater than 2
   .                     generate it if
    ¬(                )  it does not have the following property:
      ḃ                  converting it to binary,
       ↰₂↰₂              running the helper predicate twice,
           ~ḃ            and converting back to decimal
             ≜           does not allow us to find a specific value
              {     }    that is:
               ṗ           prime;
                |        or:
                 ℕ<2       nonnegative and less than 2
                     ∧   (disable an unwanted implicit constraint)

4

JavaScript(ES6),96个字节

一个完整的程序,提示您输入匹配整数的数量,并使用逐一显示它们alert()

for(i=prompt(n=2);i;n+=2)(g=b=>b>n?alert(n,i--):(C=(n,x=n)=>n%--x?C(n,x):x>1)(n^b|1)&&g(b*2))(1)

除非您的浏览器设置为使用尾部调用优化,否则由于递归溢出最终会中断。

下面是一个非递归版本(102字节)。

for(i=prompt(n=2);i;n+=2){for(c=b=1;b<n;b*=2,c&=C)for(C=k=2,x=n^b|1;k<x;k++)C|=!(x%k);c&&alert(n,i--)}

假设条件

该算法基于所有抗位翻转的复合数均为偶数的假设。这导致了一个相当重要的简化:我们没有翻转每个可能的位对,而是仅翻转了位#0和另一个(或根本没有其他位),并检查所有结果数字是否是合成的。

但是,我无法找到任何明显的证据来证明实际上不存在耐位翻转的奇数。对于小数(我检查到1,000,000)从来就不是这种情况,而且随着位数的增加,发现一个数的可能性似乎正在降低(但这基本上只是我的直觉)。


3

果冻20 17字节

BJŒċṬUḄ^;⁸ÆḍṂỊµÐḟ

在线尝试!

怎么运行的

BJŒċṬUḄ^;⁸ÆḍṂỊµÐḟ  Main link. Argument: n

              µ    Combine all links to the left into a chain.
               Ðḟ  Filter-false; keep only integers k from [1, ..., n] for which
                   the chain returns 0.
B                    Convert k to binary.
 J                   Get the indices of all digits.
  Œċ                 Take all combination of two indices, with replacement.
    Ṭ                Untruth; map each index pair [i, j] to the Boolean array of
                     length j that has 1's at (and only at) indices i and j.
     U               Upend; reverse each Boolean array.
      Ḅ              Unbinary; convert each array from base 2 to integer.
       ^             XOR the resulting numbers with k.
        ;⁸           Append k to the resulting list.
          Æḍ         Count the number of proper divisors of each result.
            Ṃ        Take the minimum.
             Ị       Insignificant; test if the minimum is 0 or 1.

1
现在,我想知道它对我的意思是,即使没有可用的解释(通过阅读源代码),我也弄清楚了它是如何工作的。我在Jelly遇到了这个问题,但是并没有走得太远(即我有一个可行的解决方案-这是生成测试用例列表的原因-但显然太冗长了)。我所缺少的是一种技巧:首先生成不超过2位的数字表,然后对其进行XOR运算。

3

Python 2,113字节

r=range
lambda N:[n for n in r(1,N)if 1-any((bin(k).count('1')<3)*all((n^k)%q for q in r(2,n^k))for k in r(n+1))]

(第二行是一个未命名的函数,该函数返回一个列表,列出所有小于该函数输入的抗位翻转复合数字。)

该语法all(u%q for q in range(2,u))Trueu等于素数或小于或等于时求和2,否则将等于False。(True如果u小于或等于,则是空虚的2。)

换句话说,all(u%q for q in range(2,u))等于0且仅当u是复合时。

如果函数的输入小于2,则函数将返回一个空列表(根据需要)。因此,假设输入N至少是2,并假设1 <= n < N。对于每一个k0通过n(含),该代码将检查是否n异或同k是复合物,并且它也检查是否k有至多两个1的在其二进制表示。如果n^k是合成的,或者如果k有两个以上1的整数,则它将移至的下一个值k。如果通过这种方式获得了kfrom的所有值,那么它将包括在列表中。0nn

在另一方面,如果有一个值k与最多两个1的这样n^k是不是复合,然后n不包括在列表中。


2

Perl 6的87 85个字节

{grep {!grep {$_%all 2..^$_},($_ X+^grep {.base(2)~~m:g/1/ <3},^(2+<.log(2)))},2..$_}

返回所有小于或等于输入数字的数字。

怎么运行的

对于从2到输入的每个数字n,它执行以下操作:

  1. ^(2 + <.log(2))

    生成位长度与n相同或更短的所有非负整数。

  2. grep {.base(2)~~ m:g / 1 / <3},

    从该列表中过滤少于三位的数字(使用正则表达式)。

  3. $ _ X + ^

    XOR的ñ每个这些数字的,产生的所有有效的“突变” ñ

  4. !grep {$ _%all 2 .. ^ $ _}

    如果所有突变都不是非复合的,则仅让n成为输出列表的一部分(通过将每个突变x取2到x -1 之间的数字的全结进行模检验)。


2

Mathematica,115个字节

@MartinEnder节省了1 4字节

Cases[4~Range~#,x_/;And@@CompositeQ[Fold[#+##&]/@Select[{0,1}~Tuples~BitLength@x,Tr@Abs[#-x~IntegerDigits~2]<3&]]]&

(* or *)

(s=Select)[4~Range~#,xAnd@@CompositeQ[Fold[#+##&]/@s[{0,1}~Tuples~BitLength@x,Tr@Abs[#-x~IntegerDigits~2]<3&]]]&

非常低效,因为它会生成所有最大为2 ^ ceil(lg(n))的数字。

第二个代码使用U + F4A1(Function功能)


1

Floroid95个 109字节

Bj:[n KnIw(j)Fp(Cao(hm("".y(k)))Mhm("".y(k))>1KkIcd("10"*Z(hi(n)),Z(hi(n)))FT(a!=b Ka,bIq(hi(n),"".y(k)))<3)]

返回不超过bitflip的数字的列表input - 1。同时处理前锋情况(0和1)。

Floroid是我的一门古老语言,我只使用过几次。暂时没有接触过它,因此程序的大小。

转换为以下Python代码,我认为可以通过递归减少。

lambda j:[n for n in  range(j) if  all( not  functions.isPrime( functions.fromBinStr("".join(k))) and  functions.fromBinStr("".join(k))>1for k in  functions.combinations_with_replacement("10"*len( functions.pureBin(n)),len( functions.pureBin(n))) if sum (a!=b for a,b in  zip( functions.pureBin(n),"".join(k)))<3)]

此处使用的每个功能都是在Floroid中预定义的。该页面包含所有功能及其定义。


请注意:有些数字(0和1)不是素数,但也不是合成的。因此,必须纠正一些解决方案。我怀疑这也会。

@ ais523我实际上读到了这件事。是否有任何已知的测试用例?无论如何,我会修复我的,因为它(可能)也很容易出现,谢谢!
Yytsi'2

@TuukaX:131136具有0作为唯一的非复合值,可以通过两个bitflips来达到(并且0不是素数)。感谢JonathanAllan找到了它。

1

MATL30 28 27 26字节

:GBnW:qtB!s3<)!Z~tZpw~+a~f

在线尝试!

输出所有直至(包括)n的耐位翻转复合数字。使用来自两个Jelly解决方案的想法-仅将0视为有问题的非质数;并首先生成距离为2的数字列表,然后进行异或运算。

替代解决方案,通过循环(30字节):

:"@BnW:qt@Z~B!s3<)Zp1M~ha~?@D]

输出所有直至(包括)n的耐位翻转复合数字。


0

CJam34 33字节

ri{_2b,,2\f#_m*::|0+f^:mp:+!},2>p

计算所有严格小于n的抗位翻转复合材料。

像乔纳森·艾伦(Jonathan Allan)一样,我不确定是否真的需要检查0个bitflips。如果事实证明没有质数的所有位翻转都导致合成数,则0+可以将其删除。

在线尝试!

说明

ri                                 Take an integer from input (n)
  {                                Filter out all numbers in the range 0...n-1 for which
                                    the following block is false
   _                                 Duplicate the number
    2b,                              Convert to binary, get the length
       ,                             Range from 0 to length-1
        2\f#                         Map each number in that range as a power of 2
                                      results in all powers of 2 less than or equal to n
            _m*                      Cartesian product with itself
               ::|                   Reduce each Cartesian pair with btiwse OR
                                      results in all numbers that have 1-2 1 bits in binary
                  0+                 Add 0 to that list
                    f^               Bitwise XOR the number we're checking with each of these
                                      This computes all the bitflips
                      :mp            Map each result to 0 if it's prime, 1 if it's composite
                         :+!         Take the sum of the list, check if it's 0
                                      If it is, then none of the results were prime
                            },     (end of filter block)
                              2>   Discard the first 2 numbers, since 0 and 1 always pass
                                p  Print the list nicely

0

MATL,29个字节

感谢乔纳森·艾伦的更正。

q:Q"@BtnFTZ^=~!s3<fqt2>)Zp~?@

这需要许多Ñ并输出所有耐bitflip-合数高达Ñ

怎么运行的

在MATL在线上尝试一下!

q:Q       % Input n implicitly. Push range [2 3 ... n]
"         % For each k in [2 3 ... n]
  @       %   Push k
  B       %   Convert to binary. Gives a row vector of zeros and ones, say v
  tn      %   Duplicate. Number of elements, say m
  FT      %   Push [0 1]
  Z^      %   Cartesian power of [0 1] raised to m. This gives a matrix,
          %   where each row is a binary number of length m
  =~      %   Compare with v, with broadcast
  !s      %   Sum of each row. Gives a row vector. This is the number of
          %   bit flips
  3<      %   True for numbers that are less than 3 bit flips away from k
  fq      %   Find their indices and subtract 1 to convert to decimal form.
          %   This gives a vector of numbers that are less than 3 bit flips
          %   away from k
  t2>)    %   Remove 0 or 1
  Zp~     %   Test each entry for non-primeness
?         % If all entries are true
  @       %   Push k
          % End (implicit)
          % Display stack (implicit)

@JonathanAllan现在解决了。再次感谢!
路易斯·门多
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.