位运行减少


43

给定一个整数n > 0,以01以其二进制表示形式输出最长连续序列的长度。

例子

  • 6110二进制写;最长的序列是11,所以我们应该返回2
  • 16→交通10000→交通4
  • 893→交通1101111101→交通5
  • 1337371→交通101000110100000011011→交通6
  • 1→交通1→交通1
  • 9965546→交通100110000000111111101010→交通7


我们可以假设整数大小的任何界限吗,例如32位或64位?
xnor

@xnor是,您可以假定int最大为32位
Arnaud

Answers:


30

Python 2中46个 45字节

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

在线尝试!

这个怎么运作

通过对nn / 2进行异或运算(除以最后一位除以2所得的整数),我们得到一个新的整数m,该整数的未设置位指示匹配n中的相邻位。

例如,如果n = 1337371,则我们具有以下内容。

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

这减少了寻找最长零位的任务。由于正整数的二进制表示形式始终以1开头,因此我们将尝试查找出现在m的二进制表示形式中的最长10 *数字字符串。这可以递归完成。

k初始化为1。每次执行f时,我们首先测试k的十进制表示形式是否出现在m的二进制表示形式中。如果确实如此,我们乘ķ10和呼叫˚F一次。如果没有,and则不会执行右边的代码,并且我们返回False

为此,我们首先计算bin(k)[3:]。在我们的示例中,bin(k)return '0b111100101110000010110',而0b1开头的则被删除[3:]

现在,-~递归调用之前,每次递归调用f时,一次递增False / 0。一旦10 {Ĵ} 1接着Ĵ的重复0)不会出现在的二进制表示ķ,零的最长运行ķ具有长度的J - 1。由于的J - 1个在连续的零ķ指示Ĵ在匹配相邻比特Ñ,期望的结果是Ĵ,这就是我们通过递增得到 / 0j次。


2
这真的很聪明!
CraigR8806

1
哇,那很聪明。从来没有想过。
HyperNeutrino

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通过反复取n/2和,从反方向提取二进制数字n%2r如果最后两位数字不相等,则将当前游程的位数重置为0来跟踪当前游程的长度,然后加1。

该表达式~-n/2%2指示最后两位数字是否相等,即n0或3模4。一起检查最后两位数字比记住前一位要短。


14

05AB1E,6个字节

b.¡€gM

在线尝试!

说明

b       # convert to binary
 .¡     # split at difference
   €g   # map length on each
     M  # take max

2
哈!最后!对的用法,我可以停止强迫自己尝试使用它。
Magic Octopus Urn

@carusocomputing:可以肯定,我已经在几个答案中使用了它。
Emigna

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

匿名lambda函数。


9

果冻,6字节

BŒgL€Ṁ

在线尝试!

这个怎么运作

BŒgL€Ṁ  Main link. Argument: n

B       Binary; convert n to base 2.
 Œg     Group adjacent, identical elements.
   L€   Map length over the groups.
     Ṁ  Take the maximum.

9

Ruby,41个 40字节

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

在b或其倒数中找到最长的'1'序列。

感谢manatwork节省了1个字节。


2
不确定其他版本,但在2.3.1中不需要在之间留空格%b
manatwork

您是对的,负二进制数以“ ..”开头。谢谢。
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
相同的想法,但是使用更多的位操作并利用undefined到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
我将结合第一和​​第二解决方案:->s{s.to_s(2).scan(/0+|1+/).map(&:size).max}
manatwork

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

将shebang视为一个,输入来自stdin。

在线尝试!


Shebangs计为0字节。
CalculatorFeline

关于meta的 @CalculatorFeline 共识#!perl计数为零,而不是#!perl -p
primo

@CalculatorFeline:-p成本为1,假设您的Perl命令行无论如何都会有一个参数(例如-e-M5.010),因此您可以p在连字符之一后插入a。的#!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)

说明:

intToBin将int转换为二进制数字列表(首先是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 q。请参阅我们的Haskell高尔夫球技巧quotRem可以divMod。我认为您可以将其i 0=[]用作基本案例。
xnor

1
divmod直接使用的时间更短:i n=mod n 2:i(div n 2)
Laikoni '01

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

在线尝试!


AFAIK,尽管grep由其自己维护和分发,但既不构成bash也不构成coreutils的一部分。不确定dc,但它曾经是GNU世界中的独立工具。wc是coreutils的唯一组成部分。
Moreaki '17

@ Moreaki,grep是POSIX,因此任何基于shell的答案都意味着它已经可用。dc不是POSIX,而是几乎所有* Nix系统的标准部分,因此通常也不会将其作为单独的依赖项提及。
Zeppelin

我认为我们在这里有两种不同的思路:我的观点不是grep是否为POSIX,我的观点是,您提交给我的标题表明,需要bash + coreutils来使您的解决方案起作用,而似乎并非如此。当我第一次阅读它时,这些信息使我感到困惑。如果您在macOS随附的bash shell上尝试解决方案,它将无法正常工作;是否安装coreutils都没有关系;您需要GNU grep才能使其正常工作。
Moreaki

@Moreaki,是的,当我说+ coreutils时,我只是暗示GNU系统,但并非总是如此。我已经更新了标题以更精确。
Zeppelin

2

Brachylog,9个字节

$b@b:lotl

在线尝试!

说明

$b          List of binary digits of the input
  @b        Runs of consecutive identical digits in that list
    :lo     Order those runs by length
       tl   Output is the length of the last one

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

3
我认为您可能必须在sort函数中添加谓词sort((a,b)=>b-a)。默认情况下,排序功能10位于1和之间2
Mama Fun Roll

或者您也可以按照操作建议使用Math.max。
Mama Fun Roll '01

WTF,但它们是数字。JS请。

2

不可思议,27个字节

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

用法:

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

转换为二进制,匹配每个0和1的序列,获取每个匹配的长度,并获取最大值。


这会将输入转换为二进制吗?
Laikoni

哦,我错过了那部分。快速解决方案: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更容易些,因为它只能是01,八进制相同,所以0%2在这里工作。%4事实证明它甚至更容易,因为我只需要从中减去。(%4-r>>5)用于进行比较lr因为Batch set/a没有比较运算符。


2

Dyalog APL,22 字节

匿名功能火车

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

⌈/∘(...以下匿名函数训练的最大结果...

≢¨  每个的理货

⊢⊂⍨ 参数的分区,其中分区由

1, 一个前置

2≠/ 的成对不等式

 论点

) 应用于

2⊥⍣¯1 from-base-2应用了一次负数(即to-base-2,一次)

 论点

在线尝试APL!


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而造成的愚蠢误解。


也许我缺少了一些东西,但是输入不应该是整数,而不是二进制数吗?我们正在寻找0或的最大运行次数1,而不仅仅是0,对吧?
rturnbull

@plannapus我不诚实。必须完全错过规格。立即修复。
Billywob

2

PowerShell78 74 73字节

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

在线尝试!

那些.Net方法。

这只是使用一个正则表达式来查找(并匹配)一和零的连续序列,然后采用结果匹配对象的Length属性(我发现了一种新模式,该模式使用了一个鲜为人知的参数集ForEach-Object,以节省1个字节),对它们进行排序,然后输出最后一个(最大)。


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

我认为这不是有效的-它不是功能,因此代码段也是如此。
Conor O'Brien

@ ConorO'Brien好的,我稍后再看。
Gareth
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.