二进制栅栏


16

输入:

  • n范围内的整数2 <= n <= 10
  • 正整数列表

输出:

将整数转换为二进制表示形式(不带任何前导零),然后将它们全部连接在一起。
然后使用n围栏柱的数量确定构成“二进制围栏”的所有二进制子串。每个栅栏柱之间的空间(零)无关紧要(至少为1),但栅栏柱本身的宽度都应相等。
在这里,正则表达式的二进制子字符串应该与每个匹配n

n   Regex to match to be a 'binary fence'   Some examples

2   ^(1+)0+\1$                              101; 1100011; 1110111;
3   ^(1+)0+\10+\1$                          10101; 1000101; 110011011;
4   ^(1+)0+\10+\10+\1$                      1010101; 110110011011; 11110111100001111001111;
etc. etc. You get the point

n=4例子:

1010101
^ ^ ^ ^    All fence posts have a width of one 1
 ^ ^ ^     with one or more 0s in between them

110110011011
^^ ^^  ^^ ^^    All fence posts have a width of two 1s
  ^  ^^  ^      with one or more 0s in between them

11110111100001111001111
^^^^ ^^^^    ^^^^  ^^^^    All fence posts have a width of four 1s
    ^    ^^^^    ^^        with one or more 0s in between them

然后,我们输出使用匹配项“二进制围栏”的二进制数字的数字。

例:

输入:n=4L=[85,77,71]

这些整数连接在一起的二进制表示形式是:(
1010101 1001101 1000111注意:仅在示例中添加空格作为说明)。

由于n=4,我们将寻找与regex匹配的子字符串(1+)0+\10+\10+\1,在这种情况下,我们可以找到两个:(
1010101在position (1010101) 1001101 1000111);和11001101100011(在位置101010(1 1001101 100011)1

第一个二进制围栏仅使用来自的二进制数字85,第二个二进制围栏使用来自所有三个整数的二进制数字。因此,在这种情况下的输出将是:
[[85],[85,77,71]]

挑战规则:

  • 尽管在上面的示例中也提到了这一点,但最后一句话很重要:我们输出在“ binary fence”子字符串中使用二进制数字的数字。
  • I / O是灵活的。输入可以是整数的列表/数组/流,空格/逗号/换行符分隔的字符串等。输出可以是2D整数列表,单个定界的字符串,字符串列表,打印到STDOUT的换行符等。由您自己决定,但请说明您在答案中使用的内容。
  • 列表本身的输出顺序无关紧要,但是每个内部列表的输出当然与输入列表的顺序相同。因此,在上面的示例中,[[85,77,71],[85]]也是有效的输出,但[[85],[77,85,71]]不是。
  • 正如您可能已经从示例(85)中注意到的那样,可以多次使用二进制数字。
  • 正则表达式应完全匹配子字符串。因此,110101或者010101从来都不是有效的“二进制围栏”(10101不过是iff n=3)。
  • 输出列表中的项目不是唯一的,只有“二进制围栏”的二进制位置是唯一的。如果可以使用相同的整数创建多个“二进制围栏”,我们将它们多次添加到输出列表中。
    例如:n=2L=[109, 45](binary 1101101 101101)可以形成这些“ binary fence”子字符串:11011(at position (11011)01 101101); 101(在位置1(101)101 101101);11011(在位置110(1101 1)01101);101(在位置1101(101) 101101);11011(在位置110110(1 1011)01);101(在位置1101101 (101)101);101(在位置1101101 101(101)),因此输出将为[[109],[109],[109,45],[109],[109,45],[45],[45]]
    另一个示例:n=2L=[8127](binary 1111110111111)可以形成这些“ binary fence”子字符串:1111110111111(at position (1111110111111));11111011111(在位置1(11111011111)1);111101111(在位置11(111101111)11);1110111(在位置111(1110111)111);11011(在位置1111(11011)1111);101(在位置11111(101)11111),因此输出将为[[8127],[8127],[8127],[8127],[8127],[8127]]
  • 如果没有有效的输出是可能的,你可以返回一个空列表或其他某种falsey输出(nullfalse,抛出一个错误,等等。同样,你的电话)。

通用规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您使用非代码高尔夫球语言发布答案。尝试针对“任何”编程语言提出尽可能简短的答案。
  • 标准规则适用于您的答案,因此您可以使用STDIN / STDOUT,具有正确参数的函数/方法和返回类型的完整程序。你的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接(即TIO)。
  • 另外,强烈建议为您的答案添加说明。

测试用例:

Input:                       Output
                             (the binary below the output are added as clarification,
                             where the parenthesis indicate the substring matching the regex):

4, [85,77,71]                [[85],[85,77,71]]
                             (1010101) 1001101 1000111; 101010(1 1001101 100011)1

2, [109,45]                  [[109],[109],[109,45],[109],[109,45],[45],[45]]
                             (11011)01 101101; 1(101)101 101101; 110(1101 1)01101; 1101(101) 101101; 110110(1 1011)01; 1101101 (101)101; 1101101 101(101)

3, [990,1,3,3023,15,21]      [[990,1,3,3023],[990,1,3,3023],[1,3,3023],[21]]
                             (1111011110 1 11 1)01111001111 1111 10101; 11110(11110 1 11 101111)001111 1111 10101; 1111011110 (1 11 101111001111) 1111 10101; 1111011110 1 11 101111001111 1111 (10101)

2, [1,2,3,4,5,6,7,8,9,10]    [[1,2,3],[2,3],[4,5],[5],[5,6,7],[6,7],[6,7],[8,9],[9],[10]]
                             (1 10 11) 100 101 110 111 1000 1001 1010; 1 (10 1)1 100 101 110 111 1000 1001 1010; 1 10 11 (100 1)01 110 111 1000 1001 1010; 1 10 11 100 (101) 110 111 1000 1001 1010; 1 10 11 100 10(1 110 111) 1000 1001 1010; 1 10 11 100 101 (110 11)1 1000 1001 1010; 1 10 11 100 101 1(10 1)11 1000 1001 1010; 1 10 11 100 101 110 111 (1000 1)001 1010; 1 10 11 100 101 110 111 1000 (1001) 1010; 1 10 11 100 101 110 111 1000 1001 (101)0

3, [1,2,3,4,5,6,7,8,9,10]    [[4,5],[8,9]]
                             1 10 11 (100 101 )110 111 1000 1001 1010; 1 10 11 100 101 110 111 (1000 1001) 1010

10, [1,2,3,4,5,6,7,8,9,10]   []
                             No binary fences are possible for this input

6, [445873,2075]             [[445873,2075],[445873,2075],[445873,2075]]
                             (1101100110110110001 1)00000011011; 110(1100110110110001 100000011)011; 1101100(110110110001 100000011011)

2, [8127]                    [[8127],[8127],[8127],[8127],[8127],[8127]]
                             (1111110111111); 1(11111011111)1; 11(111101111)11; 111(1110111)111; 1111(11011)1111; 11111(101)11111

2, [10,10]                   [[10],[10,10],[10]]
                             (101)0 1010; 10(10 1)010; 1010 (101)0

4, [10,10,10]                [[10,10],[10,10,10],[10,10]]
                             (1010 101)0 1010; 10(10 1010 1)010; 1010 (1010 101)0

啊,糟糕,您刚上课就发布了此信息!
Quintec '18

是不是[1,2,3]有效的测试用例4?我看到了篱笆(1 10 11)
TFeld

1
好的,我想这次我做对了。我没有足够仔细地阅读示例的最后一句话。(由于这是非常重要的一个,也许在示例中不应提及。)
Arnauld

1
@Arnauld现在已将示例的最后一句话添加为第一条规则。我希望这一点更加明显。
凯文·克鲁伊森

3
我建议添加一个测试用例,其中相同的整数在列表中多次出现,例如2, [10, 10][[10],[10,10],[10]]如果我正确地理解了挑战,应该会导致这种情况
。y

Answers:


5

外壳,33字节

ṠṘmȯF-mȯ#öΛΛ=⁰Fzż+C2gQṁḋmëhohttIQ

在线尝试!

通过所有测试用例。这是一个艰巨的挑战,我的解决方案感到有些困惑。

说明

程序循环遍历输入的片段,并重复每一次包含正则表达式匹配项的次数。我们只想计算与切片中每个数字的二进制扩展重叠的那些匹配。这似乎很困难,但是对那些不使用第一个数字的匹配进行计数更容易:只需删除该数字并计算所有匹配。为了获得良好的匹配,我们计算所有匹配,然后减去不使用第一个数字的匹配数和不使用最后一个数字的匹配数。不使用两者的匹配项将被计算两次,因此我们必须将其重新添加以得到正确的结果。

计算切片中的匹配数是串联二进制扩展并遍历结果切片的问题。由于Husk不支持正则表达式,因此我们使用列表操作来识别匹配项。该函数g将切片拆分为相等的相邻元素的组。然后,我们必须验证以下内容:

  1. 第一组是1组。
  2. 组数是奇数。
  3. 1组的数量等于第一个输入n
  4. 1组的长度相等。

首先,我们将各组成对。如果1和2成立,则每对的第一组为1组,最后一对为单身。然后,我们通过逐个组件地对它们进行压缩来减少对的列表。这意味着1组和0组分别添加。加法会保留溢出的元素,因此加法[1,1,1][1,1]给出[2,2,1]。压缩不是这样,因此如果最后一对是单身,则0组的按分量求和将从结果中消失。最后,我们检查结果中的所有数字是否等于n

ṠṘm(...)Q  First input is explicit, say 3, second is implicit.
        Q  List of slices.
  m(...)   Map this function (which counts good matches) over the slices
ṠṘ         and replicate each by the corresponding number.

F-m(...)mëhohttI  Count good matches. Argument is a slice, say [6,2,5].
         ë        Define a list of 4 functions:
          h        remove first element,
           oht     remove first and last element,
              t    remove last element,
               I   identity.
        m         Apply each: [[2,5],[2],[6,2],[6,2,5]]
  m(...)          Map function (which counts all matches): [0,0,1,2]
F-                Reduce by subtraction: 1
                  In Husk, - has reversed arguments, so this computes
                  M(x) - (M(tx) - (M(htx) - M(hx)))
                  where M means number of matches.

#(...)Qṁḋ  Count all matches. Argument is a slice.
       ṁ   Map and concatenate
        ḋ  binary expansions.
      Q    List of slices.
#(...)     Count number of truthy results of function (which recognizes a match).

ΛΛ=⁰Fzż+C2g  Recognize a match. Argument is list of bits, say [1,1,0,1,1,0,0,0,1,1].
          g  Group elements: [[1,1],[0],[1,1],[0,0,0],[1,1]]
        C2   Cut into pairs: [[[1,1],[0]],[[1,1],[0,0,0]],[[1,1]]]
    F        Reduce by
     z       zip (discarding extraneous elements) with
      ż      zip (preserving extraneous elements) with
       +     addition: [[3,3]]
Λ            For all lists
 Λ           all elements
  =⁰         are equal to first input.

7

Perl 6的114个 112 110 107 106 104字节

->\n,\L{L[map {[...] flat(^L Zxx(L>>.msb X+1))[.from,.to-1]},L.fmt('%b','')~~m:ov/(1+)<{"0+$0"x n-1}>/]}

在线尝试!

说明

->\n,\L{  # Anonymous block taking arguments n and L
 L[       # Return elements of L
   map {  # Map matches to ranges
    [...] # Create range from start/end pair
          # Map indices into binary string to indices into L
          flat(     # Flatten
               ^L   # indices into L
               Zxx  # repeated times
               (L>>.msb X+1)  # length of each binary representation
          )
          # Lookup start/end pair in map above
          [.from,.to-1]
   },
   L.fmt('%b','')  # Join binary representations
   ~~              # Regex match
   m:ov/(1+)<{"0+$0"x n-1}>/  # Find overlapping matches
 ]
}

4

JavaScript的(ES6),187个 184 177 173字节

将输入作为(n)(list)。返回数组的数组。

n=>a=>(g=p=>(m=s.slice(p).match(`(1+)(0+\\1){${n-1}}`))?[a.filter((_,i)=>-~b[i-1]<p+m[0].length&b[i]>=p,p-=~m.index),...g(p)]:[])(s=[],b=a.map(n=>(s+=n.toString(2)).length))

在线尝试!

怎么样?

sbs

s = [], b = a.map(n => (s += n.toString(2)).length)

例:

                      (0)     7     13
                       v      v     v
a = [109, 45] --> s = "1101101101101" --> b = [7, 13]
                       \_____/\____/
                         109    45

我们使用以下模板来生成匹配二进制围栏的正则表达式:

`(1+)(0+\\1){${n-1}}`

sp

m = s.slice(p).match(`(1+)(0+\\1){${n-1}}`)

我们从开始p=0并根据先前匹配的位置在每次迭代时对其进行更新。

s一世bs

a.filter((_, i) => -~b[i - 1] < p + m[0].length & b[i] >= p, p -= ~m.index)

3

Python 2中271 246 223 214 208 202个 200 195字节

lambda n,l,R=range,L=len:sum([next(([l[i:j+1]]for j in R(i,L(l))if re.match('(1+)'+r'(0+\1)'*~-n,('{:b}'*(1+j-i)).format(*l[i:])[o:])),[])for i in R(L(l))for o in R(L(bin(l[i]))-2)],[])
import re

在线尝试!


1

Python 2,182字节

lambda n,L,b='{:b}'.format:[zip(*set([t
for t in enumerate(L)for _ in b(t[1])][slice(*m.span(1))]))[1]for
m in re.finditer('(?=((1+)'+r'[0]+\2'*~-n+'))',''.join(map(b,L)))]
import re

在线尝试!


对于任何n大于2的输入,这似乎都会产生错误。此外,即使输入n=2了错误的测试用例结果也是如此n=2, L=[10,10]。其他的测试用例也可以n=2工作。
凯文·克鲁伊森

哦,我明白了为什么失败了[10,10];让我看看修复该问题的成本是多少……
Lynn

1
@KevinCruijssen我修复了两个问题(以22字节为代价,哦!)
Lynn

0

05AB1E38 36 字节

Œvyy¨D¦y¦)bJεŒεγ0KDËsgIQyнyθP}}OÆFy,

受到@Zgarb的Husk答案的启发。

输出列表,以换行符分隔。

在线尝试验证所有测试用例

说明:

Œ            # Get the sublists of the (implicit) input-list
 v           # Loop `y` over each sublist:
  y          #  Push `y`
  y¨         #  Push `y` with the last item removed
  D¦         #  Push `y` with the first and last items removed
  y¦         #  Push `y` with the first item removed
  )          #  Wrap all four into a list
   b         #  Get the binary-string of each integer
    J        #  Join each inner list together
     ε       #  Map each converted binary-string to:
      Œ      #   Get all substrings of the binary-string
      ε      #   Map each binary substring to:
       γ     #    Split it into chunks of equal adjacent digits
       0K    #    Remove all chunks consisting of 0s
       DË    #    Check if all chunks consisting of 1s are the same
       sgIQ  #    Check if the amount of chunks of 1s is equal to the second input-integer
       yн    #    Check if the substring starts with a 1
       yθ    #    Check if the substring end with a 1
       P     #    Check if all four checks above are truthy for this substring
             #    (1 if truthy; 0 if falsey)
     }}      #  Close both maps
       O     #  Take the sum of each inner list
        Æ    #  Reduce the list of sums by subtraction
         F   #  Loop that many times:
          y, #   And print the current sublist `y` with a trailing newline
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.