スーパーフォールディングナンバー


10

ここではすでに折りたたみ数を定義しています

しかし、これからスーパーフォールディングナンバーを定義します。スーパーフォールディング数は、十分に折り畳まれると、最終的には2の累乗よりも1少ない数になります。フォールディングの方法は、フォールディング数の質問とは少し異なります。

フォールディングアルゴリズムは次のようになります。

  • バイナリ表現を取る

    例:5882

    1011011111010
    
  • 3つのパーティションにそれをこぼした。前半、後半、中桁(奇数桁の場合)

    101101 1 111010
    
  • 中央の数字がゼロの場合、この数値は折りたたむことができません

  • 後半を逆にして前半に重ね合わせる

    010111
    101101
    
  • 桁を追加します

    111212
    
  • 結果に2がある場合、数値は折りたたむことができません。それ以外の場合、新しい数値は折りたたみアルゴリズムの結果です。

連続した1つの文字列に折りたたむことができる場合、その番号はスーパーフォールディング番号です。(すべての折りたたみ番号もスーパー折りたたみ番号です)

あなたの仕事は、数値を取り込んで、その数値がスーパーフォールディング数であれば真の値を出力し、そうでなければ偽のコードを書くことです。プログラムの規模で採点されます。

5200

バイナリに変換:

1010001010000

半分に分割:

101000 1 010000

真ん中は1つなので、続けて半分を重ね合わせます。

000010
101000

それらを追加しました:

101010

2はないので、半分に分割し続けます。

101 010

折りたたみ:

010
101

111

結果は111(10進数で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。それとも、それをゼロ回折りたたむことも数えると言っていますか?
2016年

@geobits 3があるはずです。今回チェックしました;)3は11なので、ゼロファイルでは1にしか
到達

私は、この質問の個々のフォールドが異なる方法を使用することを指摘する他のフォールディングナンバーの質問にリンクした直後に、ノートをすぐ上に置く価値があると思います。
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の後のスペースを削除し、0andの1代わりにTrueand を返すことで、大量のバイトを節約できますFalse
Steven H.

スティーブンありがとう。また、バイト長を正しくカウントしたかどうかは100%わかりません。
カポクシ2016年

1
私は見ている232バイト。少しお待ちください。もう少しゴルフを試すことができます。
Steven H.

私はこれを測定に使用しました:bytesizematters.com
Kapocsi

1
@ Kapocsi、bytesizematters.comは改行を間違って数えます。mothereff.inと比較すると、5桁と5つの改行は、バイトサイズで取得した14ではなく、10バイトになるはずです。その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

編集:このバージョンは、多かれ少なかれ、前のバージョンへのドモルガンの法則のアプローチを採用しています。

*シングルトンで実行する場合の問題は、スライスの後に空の文字列が表示されることです。

** 2進数がスーパーフォールディングである場合、その鏡像(必要に応じて先頭に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
ニール

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

ideone

整数、を取り、n返す二重再帰関数0 or1です。

変数 rは、折りたたみの結果と、次のことを確認するために維持されます。整数がある(最初のみ)。折りたたむための新しいバイナリ文字列を持ちます(外側)。または折りたたまれています(内側)。

最初のパスで nはで、整数は<''Python 2にあるため、再帰はバイナリ文字列にキャストすることから始まります。

次の実行でr=''テスト{'1'}==set(n)が実行され、1sの連続文字列をチェックします(RHSは、{n}後でこのポイントを渡す必要がある場合があるのでr=''、空nのディクショナリ{'1'}、セットの場合は空になります)。

これは、(でも、不要な場合)のためにテストされ、内側尾の基準を満たしていない場合は、次の場合n in'1'Trueの場合に評価されますn空の文字列または単一である1新しい外再帰を置くことによって開始され、そこで、rその後、折り畳まれ、バイナリ文字列にすることにより、n''r2この関数呼び出しの結果にリテラルが追加され、or後で修正される次の部分(論理の右側)にフォールスルーしないようにします。

それが真の値ではない場合(Pythonではゼロ以外の整数はすべて真実です)、外側の尾の再帰基準がテストされます。n!=0中央の大文字と小文字の大文字と小文字の02つがテストさ2れ、文字列連結によって合計されません'11'!=n[0]+n[-1]。これらの両方が当てはまる場合、外側ビットから破棄されるnn[1:-1]、その後1に追加されr、さもなければ外側に存在する場合0、その事実を使用して、ある'1'>'0'とPythonで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引数がスーパーフォールディングでない場合はエラー(コード)で終了し、0それ以外の場合はコード。で実行し-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、3762、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、7374、7528、7624、7792、 7888、8032、8128、8191、8202、8206、8218、8232、8236、8248、8318、8382、8456、8460、8472、8542、8606、8714、8844、8814、8878、8968、9038、9102、9218、 9222、9234、9248、9252、9264、9334、9398、9742、9476、9498、9558、9622、9730、9760、9830、9894、99848128、8191、8202、8206、8218、8232、8236、8248、8318、8382、8456、8460、8472、8542、8606、8714、8844、8814、8878、8968、9038、9102、9218、9222、9234、 9248、9252、9264、9334、9398、9742、9476、9488、9558、9622、9730、9760、9830、9894、99848128、8191、8202、8206、8218、8232、8236、8248、8318、8382、8456、8460、8472、8542、8606、8714、8844、8814、8878、8968、9038、9102、9218、9222、9234、 9248、9252、9264、9334、9398、9742、9476、9488、9558、9622、9730、9760、9830、9894、9984

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.