Answers:
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 *数字字符串。这可以递归完成。
将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个在连续的零ķ指示Ĵ在匹配相邻比特Ñ,期望的结果是Ĵ,这就是我们通过递增得到假 / 0共j次。
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)}`)
f=(x,b,n,m)=>x?f(x>>1,x&1,n=x&1^b||-~n,m>n?m:n):m
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节省了字节
group
默认情况下不在Prelude中,则需要import Data.List
使用它。
let
:i n|(q,r)<-n`quotRem`2=r:i q
。请参阅我们的Haskell高尔夫球技巧。quotRem
可以divMod
。我认为您可以将其i 0=[]
用作基本案例。
div
和mod
直接使用的时间更短:i n=mod n 2:i(div n 2)
。
[:>./#:#;.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
编辑:
打高尔夫球
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
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;
};
x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.length))
感谢manatwork的代码。
x.toString(2)
将数字转换为二进制字符串。
split(/(0+|1+)/g)
分割每个不同的字符(0或1)(此正则表达式捕获空白,但可以忽略它们)
map(y=>y.length)
对于数组的每个元素,获取其长度并将其放入返回的数组中。
...
将数组转换为参数列表([1,2,3]-> 1,2,3)
Math.max()
从参数中获取最大的数字。
sort((a,b)=>b-a)
。默认情况下,排序功能10
位于1
和之间2
。
匿名功能火车
⌈/∘(≢¨⊢⊂⍨1,2≠/⊢)2⊥⍣¯1⊢
⌈/∘(
...以下匿名函数训练的最大结果...
≢¨
每个的理货
⊢⊂⍨
参数的分区,其中分区由
1,
一个前置
2≠/
的成对不等式
⊢
论点
)
应用于
2⊥⍣¯1
from-base-2应用了一次负数(即to-base-2,一次)
⊢
论点
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
([regex]::Matches([convert]::ToString("$args",2),'0+|1+')|% Le*|sort)[-1]
那些.Net方法。
这只是使用一个正则表达式来查找(并匹配)一和零的连续序列,然后采用结果匹配对象的Length
属性(我发现了一种新模式,该模式使用了一个鲜为人知的参数集ForEach-Object
,以节省1个字节),对它们进行排序,然后输出最后一个(最大)。
>./>#&.>((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