ตัวเลขการพับซุปเปอร์


10

เราได้กำหนดไว้แล้วจำนวนพับที่นี่

แต่ตอนนี้เรากำลังจะนิยาม Super Folding Number หมายเลข Super Folding เป็นจำนวนที่ถ้ามีเวลามากพอในที่สุดก็จะถึงหนึ่งน้อยกว่ากำลังสอง วิธีการพับนั้นแตกต่างจากคำถามหมายเลขการพับเล็กน้อย

อัลกอริธึมการพับมีดังนี้:

  • ทำหน้าที่เป็นตัวแทนไบนารี

    เช่น 5882

    1011011111010
    
  • แยกมันออกเป็นสามส่วน ครึ่งแรก, ครึ่งหลังและตัวเลขกลาง (ถ้ามีจำนวนหลักคี่)

    101101 1 111010
    
  • หากตัวเลขกลางเป็นศูนย์ตัวเลขนี้จะไม่สามารถถูกพับได้

  • ย้อนกลับครึ่งหลังและซ้อนทับในครึ่งแรก

    010111
    101101
    
  • เพิ่มตัวเลขในสถานที่

    111212
    
  • Iff มี 2s ใด ๆ ในผลลัพธ์ที่ไม่สามารถพับหมายเลขได้มิฉะนั้นหมายเลขใหม่คือผลลัพธ์ของอัลกอริธึมการพับ

ตัวเลขคือหมายเลข Super Folding หากสามารถพับเป็นสตริงต่อเนื่องได้ (ตัวเลขการพับทั้งหมดเป็นตัวเลขการพับอย่างมาก)

งานของคุณคือการเขียนรหัสที่ใช้ในจำนวนและส่งออกค่าความจริงถ้าตัวเลขเป็นจำนวน Super Folding และเป็นเท็จอย่างอื่น คุณจะได้คะแนนตามขนาดของโปรแกรมของคุณ

ตัวอย่าง

5200

แปลงเป็นไบนารี:

1010001010000

แบ่งครึ่ง:

101000 1 010000

ตรงกลางคืออันเดียวดังนั้นเราจะทำการเพิ่มจำนวนครึ่งต่อไป:

000010
101000

เพิ่มพวกเขา:

101010

ไม่มีสองครั้งเราจึงแยกครึ่งต่อไป:

101 010

พับ:

010
101

111

ผลลัพธ์ที่ได้คือ111(7 ในทศนิยม) ดังนั้นนี่จึงเป็น Super Folding Number

กรณีทดสอบ

100 อันดับแรกของ Super Folding คือ:

[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

ฉันคิดว่ามันอาจจะคุ้มค่าที่จะจดบันทึกไว้ใกล้ด้านบนหลังจากคุณเชื่อมโยงไปยังคำถามหมายเลขการพับอื่นที่ชี้ให้เห็นว่าการพับแต่ละครั้งในคำถามนี้จะใช้วิธีการอื่น
Jonathan Allan

คำตอบ:


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, และกลับมา0และ1แทนและTrue False
Steven H.

ขอบคุณสตีเว่น นอกจากนี้ฉันไม่แน่ใจ 100% ว่าฉันนับความยาวของไบต์อย่างถูกต้อง
Kapocsi

1
ฉันเห็น232ไบต์ ให้เวลาฉันสักครู่และฉันจะพยายามตีกอล์ฟให้ไกลขึ้น
Steven H.

ฉันใช้สิ่งนี้เพื่อวัด: bytesizematters.com
Kapocsi

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

CJam , 47 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ไปยังรุ่นก่อนหน้า

* ปัญหาที่เกิดขึ้นกับการทำงานบน singletons คือเราติดกับสตริงว่างหลังจากชิ้น

** หากเลขฐานสองคือซูเปอร์พับภาพสะท้อนของกระจก (ที่มี 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ผมคิดว่าถ้าคุณเปลี่ยนความล้มเหลวและความสำเร็จกรณีแล้วคุณสามารถใช้
Neil

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



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

ideone

ฟังก์ชั่นทวีคูณ recursive ซึ่งจะเป็นจำนวนเต็มnและผลตอบแทนหรือ01

ตัวแปรrถูกเก็บรักษาไว้เพื่ออนุญาตให้ทั้งผลลัพธ์ของการพับและเพื่อทราบว่าขณะนี้เรา: มีจำนวนเต็ม (แรกเท่านั้น); มีสตริงไบนารีใหม่เพื่อพยายามพับ (ด้านนอก); หรือพับ (ด้านใน)

ในรอบแรกnคือและจำนวนเต็มซึ่งอยู่<''ใน Python 2 ดังนั้นการสอบถามซ้ำจึงเริ่มต้นด้วยการส่งไปยังสตริงไบนารี

การประมวลผลครั้งถัดไปมีr=''และดำเนินการทดสอบ{'1'}==set(n)เพื่อตรวจสอบสตริงต่อเนื่องของ1s (RHS ไม่สามารถทำได้{n}เนื่องจากเราอาจต้องผ่านจุดนี้ในภายหลังด้วยr=''และว่างเปล่าnเมื่อนั้นจะเป็นพจนานุกรมที่ไม่เท่ากับ{'1'}ชุด)

หากสิ่งนี้ไม่เป็นไปตามเกณฑ์หางด้านในจะถูกทดสอบสำหรับ (แม้ว่าไม่จำเป็น): หากn in'1'จะประเมินเป็น True เมื่อnเป็นสตริงว่างหรือเดี่ยว1ดังนั้นคร่าวๆการเรียกซ้ำภายนอกใหม่จะเริ่มต้นโดยการวางrโดยสตริงสตริงไบนารีที่พับแล้วnและเข้าไปใน'' rตัวอักษร2ถูกเพิ่มเข้ากับผลลัพธ์ของการเรียกฟังก์ชันนี้เพื่อให้ไม่ตกไปที่ส่วนถัดไป (ทางด้านขวาของตรรกะor) ที่ถูกแก้ไขในภายหลัง

หากที่ไม่ใช่ค่า truthy (ทั้งหมดไม่ใช่ศูนย์จำนวนเต็มมี truthy ในหลาม) เกณฑ์ recursion หางด้านนอกจะถูกทดสอบการ: n!=0ไม่รวมกรณีที่มีตรงกลาง0และด้านนอกตัวละครทั้งสองจะมีการทดสอบพวกเขาไม่ได้รวมไป2โดย concatenation สตริง'11'!=n[0]+n[-1]; ถ้าทั้งสองถือเป็นจริงบิตนอกจะถูกยกเลิกจากnด้วยn[1:-1]และจากนั้น1ถูกผนวกเข้ากับrถ้ามีคนที่อยู่ข้างนอกอย่างอื่น0จะใช้ความจริงที่ว่าในหลามกับ'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) หากอาร์กิวเมนต์ไม่ได้เป็น super-fold รหัส0อื่น -rทำงานด้วย
อินพุต0จะส่งคืนจริง (รหัส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]));

ค่าจริง <10,000

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, 1320, 1338, 1386, 1440, 1458, 1506, 1572, 1596 1644, 1716, 1764, 1824, 1848, 1896, 1968, 2016, 2047, 2050, 2054, 2058, 2064, 2068, 2072, 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, 3080, 3132, 3264, 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, 4922, 4966, 5062, 5246, 5246, 5440, 5482, 5578, 5746, 5842, 5986, 6082, 6208, 6212, 6216, 6268, 6364, 6508, 6604, 6720, 6772, 6868, 7012, 7108, 7232, 7288, 7288, 7288, 7888, 8032, 8128, 8191, 8202, 8206, 8218, 8232, 8224, 8248, 8318, 8382, 8456, 8460, 8472, 8542, 8146, 8714, 8878, 8878, 8898 9222, 9234, 9248, 9252, 9264, 9334, 9398, 9472, 9476, 9488, 9558, 9655, 9730, 9760, 9830, 9894, 99848128, 8191, 8202, 8206, 8218, 8232, 8236, 8248, 8318, 8382, 8456, 8606, 8460, 8472, 8542, 8606, 8714, 8744, 8878, 8968, 9068, 9689, 9182 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, 8606, 8460, 8472, 8542, 8606, 8714, 8744, 8878, 8968, 9068, 9689, 9182 9248, 9252, 9264, 9334, 9398, 9472, 9476, 9488, 9558, 9622, 9730, 9760, 9830, 9894, 9984

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.