超级折叠号码


10

我们已经在这里定义了折号。

但是现在我们将定义一个超级折叠数。超级折叠数字是一个数字,如果折叠足够的次数,它将最终小于2的幂。折叠的方法与折叠数问题稍有不同。

折叠算法如下:

  • 以二进制表示

    例如5882

    1011011111010
    
  • 将其洒入三个分区。前半部分,后半部分和中间数字(如果它的位数为奇数)

    101101 1 111010
    
  • 如果中间数字为零,则该数字不能折叠

  • 反转后半部分并叠加在前半部分上

    010111
    101101
    
  • 将数字添加到位

    111212
    
  • 如果结果中有2,则不能折叠该数字,否则新数字是折叠算法的结果。

如果数字可以折叠为连续的一串,则该数字为超级折叠数字。(所有折号也是超级折号)

您的任务是编写一个接受数字的代码,如果该数字是“超级可折叠”数字,则输出一个真实值,否则为“伪造”。您将在程序的大小上得分。

例子

5200

转换为二进制:

1010001010000

分成两半:

101000 1 010000

中间是一个,因此我们继续叠加两半:

000010
101000

添加了它们:

101010

没有二分之一,所以我们继续分成两半:

101 010

折:

010
101

111

结果是111(十进制为7),所以这是一个超级折叠数。

测试用例

前100个超级折号是:

[1, 2, 3, 6, 7, 8, 10, 12, 15, 20, 22, 28, 31, 34, 38, 42, 48, 52, 56, 63, 74, 78, 90, 104, 108, 120, 127, 128, 130, 132, 142, 150, 160, 170, 178, 192, 204, 212, 232, 240, 255, 272, 274, 276, 286, 310, 336, 346, 370, 400, 412, 436, 472, 496, 511, 516, 518, 524, 542, 558, 580, 598, 614, 640, 642, 648, 666, 682, 704, 722, 738, 772, 796, 812, 852, 868, 896, 920, 936, 976, 992, 1023, 1060, 1062, 1068, 1086, 1134, 1188, 1206, 1254, 1312, 1314, 1320, 1338, 1386, 1440, 1458, 1506, 1572, 1596]

2
除非我弄错了,如何3再次潜入测试用例?我看不到如何折叠,因为它会拆分成1 1,立即给出一个2。还是您说将其折叠零次也很重要?
Geobits

@geobits 3应该在那里。我这次检查了;)。三是11,所以零文件中只有一个
Ad Hoc Garf Hunter

我认为在链接到另一个折号问题之后指出顶部的位置可能是值得的,该问题指出该问题中的单个折痕将使用不同的方法。
乔纳森·艾伦

Answers:


9

这是我第一次打代码高尔夫:

Python 3,167个字节

如果将制表符或单个空格用于缩进,则为167个字节

def f(n):
 B=bin(n)[2:];L=len(B);M=L//2
 if'1'*L==B:return 1
 S=str(int(B[:M])+int(B[:-M-1:-1]))
 return 0if(~L%2==0and'0'==B[M])or'2'in S else{S}=={'1'}or f(int(S,2))

编辑:由于下面每个人的帮助,以上代码已从232字节的原始大小减少了!


1
欢迎来到PPCG!您可以通过删除:s 后的空格并返回01代替Trueand 来节省一堆字节False
史蒂文H.

谢谢史蒂文。另外,我不确定100%是否正确计算了字节长度。
卡波西(Kapocsi)

1
我看到232个字节。给我一点时间,我可以尝试进一步打高尔夫球。
史蒂文H.


1
@ Kapocsi,bytesizematters.com认为换行错误。与mothereff.in相比,5位数字和5个换行符应该是10个字节,而不是我在字节大小上得到的14个字节……它是232。–
Linus

5

Java 7,202字节

boolean g(Integer a){byte[]b=a.toString(a,2).getBytes();int i=0,l=b.length,o=0,c,z=(a+1&a)==0?-1:1;for(;i<l/2&z>0;o+=o+c*2,z*=c>1|(l%2>0&b[l/2]<49)?0:1)c=b[i]+b[l-++i]-96;return z<0?1>0:z<1?0>1:g(o/2);}

为了使旧的折叠功能可重复使用,需要花费一些精力,但是确实如此。老实说这是罪恶的丑陋。我必须早上看一眼,看看我是否可以继续打高尔夫球,因为现在我几乎站不起来看看它。

带换行符:

boolean g(Integer a){
    byte[]b=a.toString(a,2).getBytes();
    int i=0,l=b.length,o=0,c,z=(a+1&a)==0?-1:1;
    for(;i<l/2&z>0;o+=o+c*2,z*=c>1|(l%2>0&b[l/2]<49)?0:1)
        c=b[i]+b[l-++i]-96;
    return z<0?1>0:z<1?0>1:g(o/2);
}

3

CJam47 44字节

ri2b{_W%.+__0e=)\_,1>\0-X+:*3<*&}{_,2/<}w2-!

在线尝试!生成直到给定数字的超级折叠数字列表在这里
可以看到打高尔夫球的尝试。


该代码分为以下几个阶段:

ri2b                e# get input in binary
{                   e# While fold is legal
 _W%.+_             e#   "fold" the whole number onto itself
 _0e=)\             e#   count zeros and add 1 (I)
 _,1>\              e#   size check, leave 0 if singleton (II)*
 0-X+:*3<           e#   product of 2s, leave 0 if too many (III)
 *&                 e#   (II AND III) AND parity of I
}{                  e# Do
 _,2/<              e#   slice opposite to the actual fold**
}w                  e# End while
2-!                 e# return 1 if "fold" ended in all 2s

编辑:此版本或多或少采用了先前版本的De Morgan法则

*在单例上运行的问题是,在切片之后,我们陷入了空字符串。

**如果二进制数是超级折叠的,则其镜像(如果需要,则以前导0表示)。这样比保留右半部分节省了一个字节。


2

JavaScript,149字节

f=(i,n=i.toString(2),l=n.length,m=l/2|0)=>/^1*$/.test(n)?1:/[^01]/.test(n)|!+n[m]&l?0:f(0,+n.slice(0,m)+ +n.slice(m+l%2).split``.reverse().join``+"")

定义一个递归函数。

说明:

f=(i                       //Defines the function: i is input
,n=i.toString(2)           //n is the current number
,l=n.length                //l is the length of the number,
,m=l/2|0)=>                //m is the index of the center character
/^1*$/.test(n)?1:          //returns 1 if the number is all ones
/[^01]/.test(n)            //returns 0 if the number has any chars other than 0 or 1
|!+n[m]&l?0:               //or if the middle char is 0
f(0,+n.slice(0,m)+ +n.slice(m+l%2).split``.reverse().join``+"")
                           //otherwise recurses using the first half of the number plus the second half

m=l>>1/2/.test(n)n.slice(l-m)(或切片反转字符串)。我认为,如果您切换失败案例和成功案例,则可以使用/0/.test(n)?f(...):1
尼尔,2016年

2

的JavaScript(ES6),113 109 108个字节

f=(n,[h,...r]=n.toString(2),b='')=>++n&-n-n?h?f(2,r,r[0]?b+(h- -r.pop()):+h?b:2):!isNaN(n=+('0b'+b))&&f(n):1

格式化和评论

f = (                               // given:
  n,                                // - n = integer to process
  [h, ...r] = n.toString(2),        // - h = highest bit, r = remaining low bits
  b = ''                            // - b = folded binary string
) =>                                //
  ++n & -n - n ?                    // if n is not of the form 2^N - 1:
    h ?                             //   if there's still at least one bit to process:
      f(                            //     do a recursive call with:
        2,                          //     - n = 2 to make the 2^N - 1 test fail
        r,                          //     - r = remaining bits
        r[0] ?                      //     - if there's at least one remaining low bit:
          b + (h - -r.pop())        //       append sum of highest bit + lowest bit to b
        : +h ? b : 2                //       else, h is the middle bit: let b unchanged
      )                             //       if it is set or force error if it's not
    : !isNaN(n = +('0b' + b)) &&    //   else, if b is a valid binary string:
      f(n)                          //     relaunch the entire process on it
  : 1                               // else: n is a super folding number -> success

演示版

f=(n,[h,...r]=n.toString(2),b='')=>++n&-n-n?h?f(2,r,r[0]?b+(h- -r.pop()):+h?b:2):!isNaN(n=+('0b'+b))&&f(n):1

// testing integers in [1 .. 99]
for(var i = 1; i < 100; i++) {
  f(i) && console.log(i);
}

// testing integers in [1500 .. 1599]
for(var i = 1500; i < 1600; i++) {
  f(i) && console.log(i);
}


2

Perl,71岁 70字节

包括+1的 -p

在STDIN上输入号码

superfolding.pl

#!/usr/bin/perl -p
$_=sprintf"%b",$_;s%.%/\G0$/?2:/.\B/g&&$&+chop%eg while/0/>/2/;$_=!$&

1

Python 2,151字节

f=lambda n,r=0:f(bin(n)[2:],'')if r<''else(r==''and{'1'}==set(n)or(n in'1'and f(r,'')+2)or n!='0'and'11'!=n[0]+n[-1]and f(n[1:-1],r+max(n[0],n[-1])))%2

异丁酮

一个双递归函数,该整数采用n,然后返回01

r保留一个变量以允许折叠结果并知道我们当前是否:具有整数(仅第一个);有一个新的二进制字符串尝试折叠(外部);或正在折叠(内部)。

在第一遍n是和整数,这是<''在Python 2中是这样,因此递归开始于转换为二进制字符串。

下一个执行有r='',因此{'1'}==set(n)执行测试以检查1s 的连续字符串(RHS不能是,{n}因为我们以后可能需要通过传递此点,r=''而RHS不能为空n,否则它将是一个不等于{'1'}set 的字典)。

如果不满足,则测试内部尾部标准(即使不是必需的):如果是空字符串或单个字符串,如果n in'1'将其评估为True,n1通过将r,然后折叠的二进制字符串放入,开始新的外部递归。n''进入r。将文字2添加到此函数调用的结果中,以防止掉落到or稍后要纠正的下一部分(逻辑的右边)。

如果那不是一个真值(Python中所有非零整数都是真),则测试外部尾递归条件:n!=0排除带有中间0字符的情况和测试外部两个字符的情况,它们不2通过字符串连接求和'11'!=n[0]+n[-1];如果这些都成立,则使用nwith 丢弃外部位n[1:-1],然后在外部添加a ,否则将a 1附加到后面,使用在Python中with 的事实。r0'1'>'0'max(n[0],n[-1])

最后,使用2校正每个内部递归的相加%2


0

PHP,113字节

for($n=$argv[1];$n!=$c;$n=($a=$n>>.5+$e)|($b=$n&$c=(1<<$e/=2)-1))if($a&$b||($e=1+log($n,2))&!(1&$n>>$e/2))die(1);

1如果参数不是超级折叠,则退出并返回错误(code ),0否则返回code 。用运行-r
输入0将返回true(代码0)。

分解

for($n=$argv[1];            
    $n!=$c;                 // loop while $n is != mask
                            // (first iteration: $c is null)
    $n=                     // add left half and right half to new number
        ($a=$n>>.5+$e)      // 7. $a=left half
        |
        ($b=$n&             // 6. $b=right half
            $c=(1<<$e/=2)-1 // 5. $c=mask for right half
        )
)
    if($a&$b                // 1. if any bit is set in both halves
                            // (first iteration: $a and $b are null -> no bits set)
        ||                  // or
        ($e=1+log($n,2))    // 2. get length of number
        &
        !(1&$n>>$e/2)       // 3. if the middle bit is not set -> 1
                            // 4. tests bit 0 in length --> and if length is odd
    )
    die(1);                 // -- exit with error

0

PHP,197字节

function f($b){if(!$b)return;if(!strpos($b,"0"))return 1;for($n="",$i=0;$i<($l=strlen($b))>>1;)$n.=$b[$i]+$b[$l-++$i];if($l%2&&!$b[$i]||strstr($n,"2"))return;return f($n);}echo f(decbin($argv[1]));

展开式

function f($b){
    if(!$b)return; # remove 0
    if(!strpos($b,"0"))return 1; # say okay alternative preg_match("#^1+$#",$b)
    for($n="",$i=0;$i<($l=strlen($b))>>1;)$n.=$b[$i]+$b[$l-++$i]; #add first half and second reverse
    if($l%2&&!$b[$i]||strstr($n,"2"))return; #if middle == zero or in new string is a 2 then it's not a number that we search
    return f($n); #recursive beginning
}
echo f(decbin($argv[1]));

真实值<10000

1,2,3,6,7,8,10,12,15,20,22,28,31,34,38,42,48,52,56,63,74,78,90,104,108, 120、127、128、130、132、142、150、160、170、178、192、204、212、232、240、255、272、274、276、286、310、336、346、370、400, 412、436、472、496、511、516、518、524、542、558、580、598、614、640、642、648、666、682、704、722、738、772、796、812、852, 868、896、920、936、976、992、1023、1060、1062、1068、1086、1134、1188、1206、1254、1312、1314、1320、1338、1386、1440、1458、1506、1572、1596, 1644、1716、1764、1824、1848、1896、1968、2016、2047、2050、2054、2058、2064、2068、2072、2110、2142、2176、2180、2184、2222、2254、2306、2320、2358, 2390、2432、2470、2502、2562、2576、2618、2650、2688、2730、2762、2866、2898、2978、3010、3072、3076、3080、3132、3164、3244、3276、3328、3380、3412, 3492、3524、3584、3640、3672、3752、3784、3888、3920、4000、4032,4095、4162、4166、4170、4176、4180、4184、4222、4318、4416、4420、4424、4462、4558、4674、4688、4726、4822、4928、4966、5062、5186、5200、5242、5338, 5440、5482、5578、5746、5842、5986、6082、6208、6212、6216、6268、6364、6508、6604、6720、6772、6868、7012、7108、7232、7288、7384、7528、7624、7792, 7888,8032,8128,8191,8202,8206,8218,8232,8236,8248,8318,8382,8456,8460,8472,8542,8606,8714,8744,8814,8878,8968,9038,9102,9218, 9222、9234、9248、9252、9264、9334、9398、9472、9476、9488、9558、9622、9730、9760、9830、9894、9984、9894、9894、99848128、8191、8202、8206、8218、8232、8236、8248、8318、8382、8456、8460、8452、8542、8606、8714、8744、8814、8868、8986、9038、9102、9218、9222、9234, 9248、9252、9264、9334、9398、9472、9476、9498、9558、9622、9730、9760、9830、9894、9984、9984、99848128、8191、8202、8206、8218、8232、8236、8248、8318、8382、8456、8460、8452、8542、8606、8714、8744、8814、8868、8986、9038、9102、9218、9222、9234, 9248、9252、9264、9334、9398、9472、9476、9498、9558、9622、9730、9760、9830、9894、9984、9984、9984

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.