Süper Katlanır Sayılar


10

Biz zaten bir katlama numarasını tanımladıktan burada .

Ama şimdi bir Süper Katlama Numarası tanımlayacağız. Süper Katlama numarası, yeterince katlandığında eninde iki güçten daha azına ulaşacak bir sayıdır. Katlama yöntemi katlama sayısı sorusundan biraz farklıdır.

Katlama algoritması aşağıdaki gibi gider:

  • İkili temsili alın

    örneğin 5882

    1011011111010
    
  • Üç bölüme döktüm. İlk yarı, son yarı ve orta basamak (tek sayıda basamak varsa)

    101101 1 111010
    
  • Orta basamak sıfırsa bu sayı katlanamaz

  • İkinci yarıyı tersine çevirin ve ilk yarıda üst üste bindik

    010111
    101101
    
  • Rakamları yerine ekleyin

    111212
    
  • Sonuçta herhangi bir 2s varsa, sayı katlanamaz, aksi takdirde yeni sayı katlama algoritmasının sonucudur.

Bir sayı, sürekli bir dizgiye katlanabiliyorsa Süper Katlama numarasıdır. (Tüm Katlanır numaralar da Süper Katlanır Numaralardır)

Göreviniz, bir sayı alan ve sayı bir Süper Katlama numarası ise doğruluk değeri veren bir kod yazmaktır, aksi takdirde yanlıştır. Programınızın boyutuna göre puanlandırılacaksınız.

Örnekler

5200

İkili biçime dönüştür:

1010001010000

İkiye bölmek:

101000 1 010000

Orta birdir, bu yüzden devam ediyoruz.

000010
101000

Ekledi:

101010

İkili yok, bu yüzden ikiye bölünmeye devam ediyoruz:

101 010

Kat:

010
101

111

Sonuç 111(ondalık olarak 7'dir) bu yüzden bu bir Süper Katlama Numarasıdır.

Test Durumları

İlk 100 Süper Katlanır Numara:

[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
Yanılmadıkça, 3tekrar test senaryolarına nasıl girildi? Nasıl katlanabileceğini göremiyorum, çünkü ayrılıyor 1 1, hemen a 2. Yoksa sıfır kez katlamanın da önemli olduğunu mu söylüyorsunuz?
Geobits

@geobits 3'ün orada olması gerekiyordu. Bu kez kontrol ettim;). Üç 11, bu yüzden sadece sıfır dosyada olanlar alır
Ad Hoc Garf Hunter

Bu sorudaki bireysel katlamaların farklı bir yöntem kullanacağına dikkat çeken diğer katlama numarası sorusuna bağlantı verdikten hemen sonra, hemen üste yakın bir not koymaya değer olduğunu düşünüyorum.
Jonathan Allan

Yanıtlar:


9

İşte kod golf at ilk atış:

Python 3, 167 bayt

Girinti için sekmeler veya tek boşluklar kullanılıyorsa 167 bayt

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

Düzenleme: Aşağıdaki herkesin yardımı sayesinde, yukarıdaki kod 232 baytlık orijinal boyutundan küçültüldü!


1
PPCG'ye Hoşgeldiniz! Sen sonra boşluk kaldırarak bayt bir demet kaydedebilirsiniz :s ve dönen 0ve 1yerine Trueve False.
Steven H.

Teşekkürler Steven. Ayrıca, bayt uzunluğunu doğru saydığımdan% 100 emin değilim.
Kapocsi

1
232 bayt görüyorum . Bana bir saniye ver ve biraz daha golf oynamaya çalışabilirim.
Steven H.

Bunu ölçmek için kullandım: bytesizematters.com
Kapocsi

1
@Kapocsi, bytesizematters.com yeni satırları yanlış sayıyor. Mothereff.in , 5 basamak ve 5 yeni satır ile karşılaştırmak byteize aldım 14 değil 10 bayt ... onun 232.
Linus

5

Java 7, 202 bayt

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

Eski katlama işlevini tekrarlanabilir hale getirmek biraz çaba gerektirdi, ama işte burada. Dürüst olmak gerekirse günah gibi çirkin. Daha fazla golf oynayabileceğimi görmek için sabahları bir göz atmam gerekecek, çünkü şu anda bakmak için zar zor dayanabiliyorum.

Satır kesmeleri ile:

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 bayt

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

Çevrimiçi deneyin! veya belirli bir sayıya kadar süper katlama sayılarının bir listesini oluşturabilirsiniz .
Golf girişimleri görülebilir burada .


Kod aşağıdaki aşamalara ayrılır:

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: Bu sürüm aşağı yukarı De Morgan Yasası önceki sürümüne yaklaşım alır .

* Singletons üzerinde çalışan sorun, dilim sonra boş bir dize ile sıkışmış olmasıdır.

** İkili bir sayı süper katlanırsa, ayna görüntüsü (gerekirse önde 0'larla) olur. Bu, sağ yarıyı almak için bayt tasarrufu sağlar.


2

JavaScript, 149 bayt

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

Özyinelemeli bir işlevi tanımlar.

Açıklama:

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)(Ters dize dilim veya). Başarısızlık ve başarı durumlarını değiştirirseniz kullanabilirsiniz /0/.test(n)?f(...):1.
Neil

2

JavaScript (ES6), 113 109 108 bayt

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

Biçimlendirilmiş ve yorumlanmış

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

gösteri

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 bayt

İçin +1 içerir -p

STDIN'de numara verin

superfolding.pl:

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

1

Python 2, 151 bayt

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

Bir tamsayı alan nve 0veya döndüren çift ​​yinelemeli işlev 1.

rHem katlama sonucuna izin vermek hem de şu anda olup olmadığımızı bilmek için bir değişken korunur: bir tamsayı var (yalnızca ilk olarak); katlamaya çalışmak için yeni bir ikili dize (dış); veya katlanır (iç).

İlk geçişte Python 2'de nolan tamsayıdır, <''böylece özyineleme ikili bir dizeye döküm yaparak başlar.

Bir sonraki yürütme vardır r=''ve bu nedenle test {'1'}==set(n)sürekli bir 1s dizesini kontrol etmek için yürütülür (RHS, {n}bu noktayı daha sonra geçmemiz gerekebileceği gibi olamaz r=''ve nbu eşit olmayacak bir sözlük {'1'}, bir küme olduğunda boş olacaktır ).

Bu tatmin olmazsa, iç kuyruk kriterleri test edilir (gereksiz olsa bile): boş bir dize veya bir single n in'1'olduğunda True olarak değerlendirilirse , daha sonra katlanmış ikili dize yerleştirilerek yeni bir dış özyineleme başlatılır . ve içine . Bu işlev çağrısının sonucuna, daha sonra düzeltilecek bir sonraki bölüme (mantıksalın sağına ) düşmemesi için değişmez değer eklenir .n1rn''r2or

Bu bir doğruluk değeri değilse (sıfır olmayan tamsayılar Python'da doğrudur) dış kuyruk özyineleme ölçütleri aşağıdakiler için test edilir: n!=0orta 0ve dış iki karakter test edilen durumu hariç tutar 2, dize birleştirme ile toplanmaz '11'!=n[0]+n[-1]; Bu, her iki doğru çıkması halinde, dış bit gelen atılır nile n[1:-1], ve daha sonra bir 1eklenir rbaşka bir şekilde dış varsa 0gerçeğini kullanarak, bir '1'>'0'ile Python max(n[0],n[-1]).

Son olarak, 2her bir iç özyinelemenin eklenmesi ile düzeltilir %2.


0

PHP, 113 bayt

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

1argüman süper katlanır değilse hata (kod ) ile çıkar , 0başka kod . İle çalıştırın -r.
Giriş 0true değerini döndürür (kod 0).

Yıkmak

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 Bayt

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

Expanded

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

Gerçek değerler <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, 99848128, 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, 99848128, 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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.