Số siêu gấp


10

Chúng tôi đã xác định một số gấp ở đây .

Nhưng bây giờ chúng ta sẽ định nghĩa một Super Folding Number. Một số Super Folding là một số mà nếu gấp đủ số lần, cuối cùng nó sẽ đạt được một ít hơn một lũy thừa hai. Phương pháp gấp hơi khác so với câu hỏi số gấp.

Thuật toán gấp như sau:

  • Lấy biểu diễn nhị phân

    ví dụ 5882

    1011011111010
    
  • Đổ nó vào ba phân vùng. Nửa đầu, nửa cuối và chữ số giữa (nếu nó có số chữ số lẻ)

    101101 1 111010
    
  • Nếu chữ số giữa bằng 0, số này không thể được gấp lại

  • Đảo ngược nửa thứ hai và chồng lên trên nửa đầu

    010111
    101101
    
  • Thêm chữ số vào vị trí

    111212
    
  • Nếu có bất kỳ 2 giây nào trong kết quả thì số này không thể được gấp lại nếu không số mới là kết quả của thuật toán gấp.

Một số là một số Super Folding nếu nó có thể được gấp lại thành một chuỗi liên tục. (Tất cả các số gấp cũng là số siêu gấp)

Nhiệm vụ của bạn là viết mã nhận số và đưa ra giá trị trung thực nếu số đó là số Super Folding và giả mạo nếu không. Bạn sẽ được ghi vào kích thước của chương trình của bạn.

Ví dụ

5200

Chuyển đổi thành nhị phân:

1010001010000

Chia thành nửa:

101000 1 010000

Giữa là một vì vậy chúng tôi tiếp tục Siêu nhân một nửa:

000010
101000

Đã thêm chúng:

101010

Không có twos nên chúng tôi tiếp tục Chia làm đôi:

101 010

Gập lại:

010
101

111

Kết quả là 111(7 số thập phân) vì vậy đây là Số siêu gấp.

Các trường hợp thử nghiệm

100 số siêu gấp đầu tiên là:

[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
Trừ khi tôi nhầm, làm thế nào để 3lẻn vào các trường hợp thử nghiệm một lần nữa? Tôi không thể thấy làm thế nào nó có thể được gấp lại, vì nó tách ra 1 1, ngay lập tức đưa ra một 2. Hay bạn đang nói rằng gấp nó 0 lần cũng được tính?
Geobits 7/10/2016

@geobits 3 được cho là ở đó. Tôi đã kiểm tra lần này;). Ba là 11 vì vậy nó chỉ nhận được một trong các tệp không
Ad Hoc Garf Hunter

Tôi nghĩ rằng có thể đáng để đặt một ghi chú ngay gần đầu, ngay sau khi bạn liên kết đến câu hỏi số gấp khác chỉ ra rằng các nếp gấp riêng lẻ trong câu hỏi này sẽ sử dụng một phương pháp khác.
Jonathan Allan

Câu trả lời:


9

Đây là lần đầu tiên tôi bắn vào mã golf:

Python 3, 167 byte

167 byte nếu các tab hoặc khoảng trắng đơn được sử dụng để thụt lề

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

Chỉnh sửa: Nhờ sự giúp đỡ của mọi người bên dưới, mã ở trên đã được giảm từ kích thước ban đầu là 232 byte!


1
Chào mừng đến với PPCG! Bạn có thể lưu một loạt byte bằng cách xóa khoảng trắng sau :s, và quay lại 01thay vào đó TrueFalse.
Steven H.

Cảm ơn bạn Steven. Ngoài ra, tôi không chắc chắn 100% tôi đã đếm chính xác độ dài byte.
Kapocsi

1
Tôi đang thấy 232 byte. Hãy cho tôi một giây và tôi có thể cố gắng chơi golf xa hơn một chút.
Steven H.

Tôi đã sử dụng điều này để đo lường: byteizematters.com
Kapocsi

1
@Kapocsi, byteizematters.com đếm các dòng mới sai. So sánh với mẹeff.in , 5 chữ số và 5 dòng mới phải là 10 byte, không phải là 14 số tôi nhận được trên byteize ... đó là 232.
Linus

5

Java 7, 202 byte

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

Phải mất một chút nỗ lực để làm cho chức năng gấp cũ có thể được đệ quy, nhưng đây là. Thật là xấu xa như tội lỗi, thành thật mà nói. Tôi sẽ phải nhìn vào buổi sáng để xem liệu tôi có thể chơi gôn hơn nữa không, vì tôi hầu như không thể đứng nhìn nó ngay bây giờ.

Với ngắt dòng:

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

CJam , 47 44 byte

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

Hãy thử trực tuyến! hoặc tạo một danh sách các số siêu gấp đến một số đã cho.
Nỗ lực chơi gôn có thể được nhìn thấy ở đây .


Mã được chia thành các giai đoạn sau:

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

EDIT: Phiên bản này ít nhiều có cách tiếp cận Luật De Morgan so với phiên bản trước.

* Vấn đề với việc chạy trên singletons là chúng ta bị kẹt với một chuỗi rỗng sau lát cắt.

** Nếu một số nhị phân là siêu gấp, hình ảnh phản chiếu của nó (với số 0 đứng đầu nếu cần) là. Điều này tiết kiệm một byte hơn lấy một nửa bên phải.


2

JavaScript, 149 byte

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``+"")

Xác định hàm đệ quy.

Giải trình:

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)(Hoặc cắt chuỗi đảo ngược). Tôi nghĩ rằng nếu bạn chuyển đổi các trường hợp thất bại và thành công thì bạn có thể sử dụng /0/.test(n)?f(...):1.
Neil

2

JavaScript (ES6), 113 109 108 byte

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

Định dạng và nhận xét

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

Bản giới thiệu

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 byte

Bao gồm +1 cho -p

Cho số trên STDIN

superfolding.pl:

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

1

Python 2, 151 byte

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

nhàn rỗi

Hàm đệ quy đôi có một số nguyên nvà trả về 0hoặc 1.

Một biến rđược duy trì để cho phép cả kết quả của việc gấp và để biết nếu chúng ta hiện tại: có một số nguyên (chỉ đầu tiên); có một chuỗi nhị phân mới để cố gắng gấp (bên ngoài); hoặc đang gấp (bên trong).

Trên pass đầu tiên nlà và số nguyên, nằm <''trong Python 2, vì vậy đệ quy bắt đầu bằng cách truyền vào chuỗi nhị phân.

Việc thực thi tiếp theo có r=''và do đó, kiểm tra {'1'}==set(n)được thực hiện để kiểm tra một chuỗi 1s liên tục (RHS không thể {n}vì chúng ta có thể cần phải vượt qua điểm này sau đó r=''và một khoảng trống nkhi đó sẽ là một từ điển không bằng nhau {'1'}, một tập hợp).

Nếu điều này không thỏa mãn, các tiêu chí đuôi bên trong được kiểm tra (ngay cả khi không cần thiết): if n in'1'sẽ đánh giá thành True khi nlà một chuỗi rỗng hoặc một chuỗi 1, sau đó một đệ quy bên ngoài mới được bắt đầu bằng cách đặt r, bằng cách gấp lại, chuỗi nhị phân vào n''vào r. Nghĩa đen 2được thêm vào kết quả của lệnh gọi hàm này để cho phép không rơi vào phần tiếp theo (bên phải của logic or) được sửa sau đó.

Nếu đó không phải là một giá trị trung thực (tất cả các số nguyên khác không là trung thực trong Python) thì các tiêu chí đệ quy đuôi bên ngoài được kiểm tra: n!=0loại trừ trường hợp có một ký tự ở giữa 0và hai ký tự bên ngoài được kiểm tra, chúng không được tính 2bằng phép nối chuỗi '11'!=n[0]+n[-1]; nếu những cả hai giữ đúng các bit bên ngoài được loại bỏ từ nvới n[1:-1], và sau đó một 1được thêm vào rnếu có một ở bên ngoài khác một 0là, sử dụng thực tế là '1'>'0'trong Python với max(n[0],n[-1]).

Cuối cùng, việc bổ sung 2tại mỗi đệ quy bên trong được sửa chữa với %2.


0

PHP, 113 byte

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

thoát với lỗi (mã 1) nếu đối số không phải là siêu gấp, mã 0khác. Chạy với -r.
Đầu vào 0sẽ trả về true (mã 0).

phá vỡ

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 byte

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

Mở rộng

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

Giá trị thực <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, 5186 5440, 5482, 5578, 5746, 5842, 5986, 6082, 6208, 6212, 6216, 6268, 6364, 6508, 6604. 7888, 8032, 8128, 8191, 8202, 8206, 8218, 8232, 8236, 8248, 8318, 8382, 8456, 8460, 8472, 8542, 8606, 8714, 8744, 8814, 8878, 8968, 9038, 9188 92222, 9234, 9248, 9252, 9264, 9334, 9398, 9472, 9476, 9488, 9558, 9622, 9730, 9760, 9830, 9894, 99848128, 8191, 8202, 8206, 8218, 8232, 8236, 8248, 8318, 8382, 8456, 8460, 8472, 8542, 8606, 8714, 8744, 8814, 8878, 8968, 9038, 9102, 9218, 938 9248, 9252, 9264, 9334, 9398, 9472, 9476, 9488, 9558, 9622, 9730, 9760, 9830, 9894, 99848128, 8191, 8202, 8206, 8218, 8232, 8236, 8248, 8318, 8382, 8456, 8460, 8472, 8542, 8606, 8714, 8744, 8814, 8878, 8968, 9038, 9102, 9218, 938 9248, 9252, 9264, 9334, 9398, 9472, 9476, 9488, 9558, 9622, 9730, 9760, 9830, 9894, 9984

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.