ビットランランダウン


43

整数を指定するとn > 0、バイナリ表現の、0または1そのバイナリ表現の最長連続シーケンスの長さが出力されます。

  • 6110バイナリで書かれています。最長のシーケンスは11なので、返す必要があります2
  • 16100004
  • 89311011111015
  • 13373711010001101000000110116
  • 111
  • 99655461001100000001111111010107


32ビットや64ビットのような整数のサイズの境界を想定できますか?
-xnor

@xnorはい、あなたは、intは32ビットで最大であると仮定することができます
アルノー

回答:


30

パイソン246の 45バイト

f=lambda n,k=1:`k`in bin(n^n/2)and-~f(n,k*10)

オンラインでお試しください!

使い方

排他的論理和によりN及びN / 2(割る2、本質的に最後のビットをオフチョップ)、新たな整数取得Mその解除ビットに隣接するビットに一致示すnは

たとえば、n = 1337371の場合、次のようになります。

n    = 1337371 = 101000110100000011011₂
n/2  =  668685 =  10100011010000001101₂
m    = 1989654 = 111100101110000010110₂

これにより、タスクの実行回数が減り、ゼロが最も長く実行されます。正の整数のバイナリ表現は常に1で始まるため、mのバイナリ表現に現れる最も長い10 *桁の文字列を見つけようとします。これは再帰的に実行できます。

k1として初期化します。fが実行されるたびに、最初にkの10 進表現がmのバイナリ表現に現れるかどうかをテストします。存在する場合、k10を掛けて、fを再度呼び出します。そうでない場合、右側のコードandは実行されず、Falseを返します。

これを行うには、まずを計算しbin(k)[3:]ます。この例でbin(k)'0b111100101110000010110'、を返し、0b1先頭のはで削除され[3:]ます。

これで、-~再帰呼び出しの前に、fが再帰的に呼び出されるたびにFalse / 0が増分されます。一旦10 {J} 1続くj個の反復0)のバイナリ表現に表示されていないK、にゼロの最長ランkは長有する1 - jは。以来、J - 1における連続するゼロkが示すJに隣接するビットに一致nは、所望の結果は、J我々はインクリメントし得るものであり、 / 0を合計j回。


2
これは本当に賢いです!
CraigR8806

1
うわー、それは賢いです。考えたこともありませんでした。
ハイパーニュートリノ

10の累乗を使用した素敵なトリックですが、Lでロングになりませんか?
-xnor

@xnor最終的には、それは単なるデータ型の制限です。C、JavaScript、およびPHPの回答にもこの問題があります。
デニス

本番環境で使用すると、これは深刻に維持できなくなります。要するに(ゲヘ)ゴルフが達成され、ホールインワン:)
JAK

17

Python 2、46バイト

f=lambda n,r=1:max(r,n and f(n/2,1+~-n/2%2*r))

オンラインで試す

とをn繰り返し取得することにより、逆に2進数を抽出n/2n%2ます。r最後の2桁が等しくない場合に0にリセットしてから1を加算することにより、現在の等しい桁の実行の長さを追跡します。

式は~-n/2%2、最後の2桁が等しいかどうかの指標であるすなわちn、前の数字を覚えるよりも短く一緒になって、最後の2桁を確認する0または3モジュロ4です。



9

Mathematica、38バイト

Max[Length/@Split[#~IntegerDigits~2]]&

または

Max[Tr/@(1^Split[#~IntegerDigits~2])]&

9

Python、53バイト

import re;lambda g:max(map(len,re.findall('1+|0+',bin(g))))

匿名のラムダ関数。



9

Ruby、41 40バイト

->b{("%b%b"%[b,~b]).scan(/1+/).max.size}

bまたはその逆の「1」の最長シーケンスを見つけます。

1バイトを節約してくれたmanatworkに感謝します。


2
他のバージョンについてはわかりませんが、2.3.1 %bではの間にスペースは必要ありません。
マナトワーク

そうです、負の2進数は「..」で始まります。ありがとう。
GB

7

JavaScript(ES6)、54バイト

f=(n,r=0,l=1,d=2)=>n?f(n>>1,d^n&1?1:++r,r>l?r:l,n&1):l

多くのビット操作を伴う再帰的ソリューション。n入力をr保存し、現在の実行lの長さを保存し、最長の実行の長さをd保存し、前の数字を保存します。

テストスニペット

f=(n,r=0,l=1,d=2)=>n?f(n>>1,d^n&1?1:++r,r>l?r:l,n&1):l

for(var i of [0,1,2,3,4,5,6,7,8,9,16,893,1337371]) console.log(`f(${i}): ${f(i)}`)


1
同じ考えが、より多くのビット演算を使用し、ボロー気軽に0に未定義のデフォルトの変換を利用:f=(x,b,n,m)=>x?f(x>>1,x&1,n=x&1^b||-~n,m>n?m:n):m
edc65

7

Ruby、51 44 43バイト

機能ソリューション。

@manatworkは魔法でできている

->s{('%b'%s).scan(/0+|1+/).map(&:size).max}

これは、連続した同一の数字または単に連続した0sをチェックしますか?
ngenisis

2
893の誤った結果
orlp

@orlpはもうありません!:D
バリューインク

1
私は、1番目と2番目のソリューションを組み合わせます->s{s.to_s(2).scan(/0+|1+/).map(&:size).max}
マナトワーク

6

Python 2、57バイト

a=lambda n:n and max((n&-n|~n&-~n).bit_length()-1,a(n/2))

再帰的なソリューション。ビットマジックの短い形式があります。


6

Perl、43バイト

#!perl -p
\@a[$a+=$_-1+($_>>=1)&1||-$a]while$_;$_=@a

シバングを1つとしてカウントすると、入力はstdinから取得されます。

オンラインでお試しください!


シバングは0バイトとしてカウントされます。
電卓

メタに関する @CalculatorFeline コンセンサス#!perl、ではなくゼロとしてカウントされること#!perl -pです。
プリモ

@CalculatorFeline:-pコスト1、Perlコマンドラインにとにかく引数(例:-eまたは-M5.010)があると仮定するpと、ハイフンの1つの直後に挿入できます。#!perl(不要なが)自由です。

知っておくといい。。
CalculatorFeline

5

ピップ、16バイト

同じ数字の実行を取得するためのより短い方法があるように思えます...

MX#*(TBa`1+|0+`)

入力をコマンドライン引数として受け取ります。オンラインでお試しください!

説明

     TBa          1st cmdline arg, To Binary
    (   `1+|0+`)  Find all matches of this regex
  #*              Map length operator to that list
MX                Get the maximum and autoprint it

5

Perl 6、36バイト

{(.base(2)~~m:g/1+|0+/)».chars.max}

説明:

{                                 }   # a lambda
  .base(2)                            # convert the argument to base 2
          ~~m:g/     /                # regex match, with global matching turned on
                1+|0+                 # match one or more 1, or one or more 0
 (                    )».chars        # replace each match by its length
                              .max    # take the maximum number

オンラインでお試しください


4

Haskell、79文字

maximum.map length.group.i

どこ

import Data.List
i 0=[]
i n=mod n 2:i(div n 2)

または、非ゴルフバージョンでは:

import Data.List
pcg :: Int -> Int
pcg = maximum . map length . group . intToBin

intToBin :: Int -> [Int]
intToBin 0 = []
intToBin n = n `mod` 2 : intToBin (n `div` 2)

説明:

intToBinintを2進数のリストに変換します(lsbが最初)。group[1, 1, 0, 0, 0, 1]なるような連続したシーケンスをグループ化します[[1, 1],[0, 0, 0],[1]]maximum . map length各内部リストの長さを計算し、最長の長さを返します。

編集:バイトを保存してくれた@xnorと@Laikoniに感謝


2
groupデフォルトではPreludeにないので、import Data.List使用する必要があります。
-xnor

1
以下の代わりにガードを使用できることに注意してくださいleti n|(q,r)<-n`quotRem`2=r:i qHaskellゴルフのヒントをご覧ください。quotRemすることができますdivModi 0=[]基本ケースとして使用できると思います。
xnor

1
divandをmod直接使用すると、さらに短くなりますi n=mod n 2:i(div n 2)
ライコニ

3

Pyth、7バイト

heSr8.B

バイナリ文字列でランレングスエンコードを実行し、最長のランが最後になるようにソートしてから、リストの最後の要素(最長のラン)の最初の要素(長さ)を取得します。

擬似コードで:

'  S     ' sorted(
'   r8   '   run_length_encode(
'     .BQ'     bin(input()) ))  \
'he      '   [-1][0]

3

J、21バイト

[:>./#:#;.1~1,2~:/\#:

オンラインでお試しください!

説明

[:>./#:#;.1~1,2~:/\#:  Input: integer n
                   #:  Binary digits of n
              2   \    For each continuous subarray of 2 digits
               ~:/       Reduce it using not-equals
            1,         Prepend a 1 to those results
     #:                Binary digits of n
        ;.1~           Cut the binary digits at each location with a 1
       #                 Get the length of each cut
[:>./                  Reduce those lengths using maximum and return

3

MATLAB 71バイト

m=1;a=diff(int8(dec2bin(a)));while(any(a==0)),m=m+1;a=diff(a);end;m

これは、整数変数「a」をバイナリint8配列に変換し、結果にゼロがなくなるまで結果を微分する必要がある回数をカウントします。

私はここでは新人です。この種の入力とワンライナーは、PCGルールで許可されていますか?


3
PPCGへようこそ!デフォルトでは、機能または完全なプログラム(コードスニペットではない)のみが受け入れられます。あなたのケースでの手段は、あなたが入力する必要があるということaa=input('');。また、いくつかのゴルフのアドバイス:の~a代わりにa==0。本当に必要int8ですか?)
ルイスメンドー

3

オクターブ、31バイト

@(n)max(runlength(+dec2bin(n)))

オンラインでお試しください!

説明

これは私のMATL回答の翻訳です。私の最初の計画は、異なるアプローチでした@(n)max(diff(find(diff([0 +dec2bin(n) 0]))))。しかし、Octaveにはrunlength機能があることがわかりました(これについては、先ほど知りました)。デフォルトでは、ランレングスの配列のみを出力するため、目的の結果はmaxその配列の結果になります。およびdec2binを含む文字配列(文字列)であるの出力は、数値入力を想定しているため、を使用して数値配列に変換する必要があります。'0''1'+runlength



3

Bash(+ coreutils、+ GNU grep)、 33、32バイト

編集:

  • マイナス1バイト(grep式の前後の引用符を削除)

ゴルフ

dc -e2o$1p|grep -Po 1+\|0+|wc -L

説明した

 #Convert to binary
 >dc -e2o893p
 1101111101

 #Place each continuous run of 1es or 0es on its own line
 >dc -e2o893p|grep -Po '1+|0+'
 11
 0
 11111
 0
 1

 #Output the length of the longest line
 >dc -e2o893p|grep -Po '1+|0+'|wc -L
 5

オンラインでお試しください!


私の知る限り、grepはbashの一部でもcoreutilsの一部でもありませんが、独自に維持および配布されます。dcについてはわかりませんが、GNUの世界では以前はスタンドアロンのツールでした。coreutilsの一部を形成する唯一のものはwcです。
モレアキ

@ Moreaki、grepはPOSIXであるため、シェルベースの回答は、すでに利用可能であることを意味します。dcはPOSIXではありませんが、ほとんどすべての* Nixシステムの標準部分であるため、通常、別個の依存関係としても言及されていません。
ツェッペリン

私はここで2つの異なる思考の列にいると思います:私のポイントは、grepがPOSIXであるかどうかではなく、私のポイントは、あなたの提出のタイトルがあなたのソリューションを動作させるためにbash + coreutilsが必要であることを示したことでしたこれは事実ではないようです。最初に読んだとき、この情報は私を混乱させました。macOSに付属のbashシェルでソリューションを試しても、機能しません。また、coreutilsをインストールしたかどうかは関係ありません。動作させるにはGNU grepが必要です。
モレアキ

@Moreaki、うん、私はGNUシステムを暗示している、+ coreutilsを言うとき、それは常にそうであるとは限らない。タイトルをより正確に更新しました。
ツェッペリン


2

C#、106バイト

n=>{int l=1,o=0,p=0;foreach(var c in System.Convert.ToString(n,2)){o=c!=p?1:o+1;l=o>l?o:l;p=c;}return l;};

フォーマット済みバージョン:

System.Func<int, int> f = n =>
{
    int l = 1, o = 0, p = 0;
    foreach (var c in System.Convert.ToString(n, 2))
    {
        o = c != p ? 1 : o + 1;

        l = o > l ? o : l;

        p = c;
    }

    return l;
};

そして、空白を削除して、118バイトのインデックスで文字列にアクセスする代替アプローチ:

System.Func<int, int> f2 = n =>
{
    var s = System.Convert.ToString(n, 2);

    int l = 1, c = 1, i = 0;

    for (; i < s.Length - 1; )
    {
        c = s[i] == s[++i] ? c + 1 : 1;
        l = l < c ? c : l;
    }

    return l;
};

2

Javascript、66バイト

x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.leng‌​th))

コードのmanatworkに感謝します。

説明

x.toString(2)

数値をバイナリ文字列に変換します。

split(/(0+|1+)/g)

異なる文字(0または1)ごとに分割します(この正規表現は空のスペースをキャプチャしますが、無視できます)

map(y=>y.length)

配列の各要素の長さを取得し、返された配列に入れます。

...

配列を引数のリストに変換します([1,2,3]-> 1,2,3)

Math.max()

引数から最大数を取得します。


1
インスピレーションをValue InkRubyソリューションに与えたことで、これはに変換できますx=>x.toString(2).split(/(0+|1+)/g).map(y=>y.length).sort().pop()。または同じ長さ:x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.length))
マナトワーク

3
ソート関数に述語を追加する必要があるかもしれませんsort((a,b)=>b-a)。デフォルトでは、ソート機能が置き10の間に12
ママファンロール

または、manatworkが示唆するように、Math.maxを使用できます。
ママファンロール

WTF、しかしそれらは数字です。JSお願いします。

2

ワンダー、27バイト

max.map#len.mstr`0+|1+`g.bn

使用法:

(max.map#len.mstr`0+|1+`g.bn)123

バイナリに変換し、0と1の各シーケンスに一致し、各一致の長さを取得し、最大値を取得します。


これは入力をバイナリに変換しますか?
ライコニ

ああ、その部分を見逃した。クイックフィックス:P
ママファンロール

2

バッチ、102バイト

@set/a"n=%1/2,d=%1%%2,r=1+(%3+0)*!(0%2^d),l=%4-(%4-r>>5)
@if not %n%==0 %0 %n% %d% %r% %l%
@echo %l%

@ edc65の回答のポート。%2.. %4は最初の呼び出しで空になるため、式がまだ機能するように式を記述する必要があります。最も一般的なケースは%3、私がとして書かなければならなかったケースです(%3+0)%2は8進数で同じ0またはのみであるため、より簡単です。ここで動作します。差し引くだけでいいので、さらに簡単になりました。比較するために使用されるとバッチのは、として比較演算子を持っていません。10%2%4(%4-r>>5)lrset/a


2

Dyalog APL、22 バイト

無名関数トレイン

⌈/∘(≢¨⊢⊂⍨1,2≠/⊢)2⊥⍣¯1

⌈/∘(...次の匿名関数トレインの結果の最大値...

≢¨  それぞれの集計

⊢⊂⍨ 引数のパーティション。パーティションは、次のものによって決定されます。

1, に追加されたもの

2≠/ ペアワイズ不等

 引数

) に適用されます

2⊥⍣¯1 from-base-2は負に1回適用されます(つまりto-base-2、1回)

 引数

TryAPLオンライン!


2

Japt、15バイト

2o!q¢ c ml n gJ

オンラインでテストしてください!または、すべてのテストケースを一度に検証します

使い方

                 // Implicit: U = input integer, J = -1
2o               // Create the range [0...2), or [0,1].
  ! ¢            // Map each item Z in this range to U.s(2)
   q             //                                        .q(Z).
                 // This returns the runs of 1's and 0's in the binary
                 // representation of U, respectively.
      c          // Flatten into a single list.
        ml       // Map each item Z to Z.length.
           n gJ  // Sort the result and grab the item at index -1, or the last item.
                 // This returns the largest element in the list.
                 // Implicit: output result of last expression

2

R、45 34バイト

max(rle(miscFuncs::bin(scan()))$l)

@rturnbullと@plannapusのおかげで愚かな誤解を修正しました。


おそらく私は何かが欠けていますが、入力は2進数ではなく整数であるはずではありませんか?そして、私たちは、だけでなく、0またはの最大実行を探していますか?10
-rturnbull

@plannapus私は正直に知りません。完全に仕様を逃したに違いない。修正されました。
ビリーウォブ

2

PowerShell78 74 73バイト

([regex]::Matches([convert]::ToString("$args",2),'0+|1+')|% Le*|sort)[-1]

オンラインでお試しください!

これらの.Netメソッド。

これは、正規表現を使用して1と0の連続したシーケンスを検索(および一致)し、結果の一致オブジェクトのLengthプロパティ(ForEach-Object1バイトを保存するために、既知のほとんどのパラメーターセットを使用する新しいパターン)を取得します。それらをソートし、最後のもの(最大のもの)を出力します。


1

J、27バイト

>./>#&.>((1,2~:/\[)<;.1])#:

マイルの答えに対するわずかに異なる(そして残念なことに長い)アプローチ。

使用法:

    >./>#&.>((1,2~:/\[)<;.1])#:893
5

説明

>./>#&.>((1,2~:/\[)<;.1])#:
                         #: Convert to base 2
        (               )   A fork
                       ]    Previous result
         (1,2~:/\[)         Find where each new sequence begins
                   <;.1     Cut the string of integers based on where each sequence begins and box them
    #&.>                    Count under open - open each box and count the items in it
>./>                        Open all the boxes and find the maximum value

私はこれが有効だとは思わない-それは関数ではなく、スニペットでもある。
コナーオブライエン

@ ConorO'Brienわかりました、後でもう一度見ます。
ガレス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.