二进制子串


17

受到BMO2 2009中第四个问题的启发。

给定正整数n作为输入或参数,请返回其整数表示形式作为正整数n的块形式出现的正整数的数量。

例如13-> 6,因为二进制中的13是1101并且它具有子字符串1101, 110, 101, 11, 10, 1。我们不计算以零开头的二进制数,本身也不计算零。

测试用例

13 -> 6
2008 -> 39
63 -> 6
65 -> 7
850 -> 24
459 -> 23
716 -> 22
425 -> 20
327 -> 16

您可以输入n作为以下任意一项:

  • 一个整数
  • 二进制表示形式的真假值列表
  • 二进制表示形式的字符串
  • 以10为基数的字符串(尽管我不确定为什么有人会这样做)

使您的代码越短越好。


3
您可以确认63-> 5而不是6吗?Bin(63)=
111111-

有关。(使用子序列代替子字符串,并且不忽略前导零。)
Martin Ender

1
@dylnan Typo。固定。
0WJYxW9FMN

@MartinEnder这是否足以保留在此站点上,还是应该将其重复删除?我认为这已经足够不同了,但是您比我知道的要多得多。
0WJYxW9FMN

@ J843136028不进行重复操作的最大区别是其他挑战的时间限制。你没事。(只是发布了链接,以便使挑战在彼此的侧边栏中显示出来。)
Martin Ender

Answers:


7

Python 3,54 50字节

lambda n:sum(bin(i)[2:]in bin(n)for i in range(n))

感谢Rod和Jonathan Allan节省了四个字节。


您可以将+1范围从bin(i)
Rod

1
事实上,因为我们总是指望n本身是永远排除0从我们的统计数据,我们可以改为一律排除n,总是计数0(BIN(N)开始'0b...'),因此我们可以删除1,,并+1完全和休假bin(i)为的是救四个字节的在线试试吧!
乔纳森·艾伦

5

果冻,4字节

ẆQSḢ

在线尝试!

将输入作为0s和1s的列表。

在线尝试使用数字!

说明:

ẆQSḢ Argument: B = list of bits, e.g. [1, 1, 0, 1]
Ẇ    Get B's non-empty sublists (i.e. [[1], [1], [0], [1], [1, 1], [1, 0], [0, 1], [1, 1, 0], [1, 0, 1], [1, 1, 0, 1]])
 Q   Keep first occurrences (i.e. [[1], [0], [1, 1], [1, 0], [0, 1], [1, 1, 0], [1, 0, 1], [1, 1, 0, 1]])
  S  Reduce by vectorized addition (i.e. [6, 4, 1, 1])
   Ḣ Pop first element (i.e. 6)

证明有效:

这个程序获取的输入数,Ñ。当然,此乘积的第一件事是采用N 2的子字符串(N2为底)。这包括以01开头的重复子字符串

之后,我们仅通过将每个值的第一次出现保留在子字符串列表中,就可以获取唯一的子字符串。

然后,此程序将列表的第一个元素加在一起,然后将第二个元素加在一起,然后将第三个,第四个元素加起来,如果列表中的一个不包含这样的元素,0则假定为该元素。挑战是如何有效地询问这个数字以二进制形式有多少个1开头的唯一子字符串。由于每个要计数的第一个元素都是1,所以我们可以简单地求和而不是对适当的子字符串进行过滤。

现在,上述求和结果列表的第一个元素包含子字符串的第一位的计数,因此我们简单地弹出并最终将其返回。


4

八度62 61字节

@(n)sum(arrayfun(@(t)any(strfind((g=@dec2bin)(n),g(t))),1:n))

在线尝试!

说明

对于input n,代码从测试所有数字1n以查看其二进制表示形式是否为输入的二进制表示形式的子字符串。

@(n)                                                          % Anonymous function of n
        arrayfun(                                      ,1:n)  % Map over range 1:n
                 @(t)                                         % Anonymous function of t
                         strfind(               ,    )        % Indices of ...
                                                 g(t)         % t as binary string ...
                                 (g=@dec2bin)(n)              % within n as binary string
                     any(                             )       % True if contains nonzero
    sum(                                                    ) % Sum of array

3

05AB1E,5个字节

将输入作为二进制字符串。
标头将整数输入转换为二进制以便于测试。

ŒCÙĀO

在线尝试!

说明

Œ        # push all substrings of input
 C       # convert to base-10 int
  Ù      # remove duplicates
   Ā     # truthify (convert non-zero elements to 1)
    O    # sum

......我以为我的筛选器很聪明。bŒʒć}Ùg但不,那更好。
魔术章鱼缸


2

的PowerShell103 92 82字节

param($s)(($s|%{$i..$s.count|%{-join$s[$i..$_]};$i++}|sort -u)-notmatch'^0').count

在线尝试!

将输入作为1and 的数组0(在PowerShell中为true和false)。循环遍历$s(即,输入数组中有多少个元素)。在循环内,我们从当前数字(保存为$i)循环到$s.count。每个内部循环,我们-join将数组切片成一个字符串。然后sort,我们使用-unique标记(比select使用-unique标记短,并且我们不在乎它们是否已排序),将那些不以开头的标记0取为整数.count。剩下的就在管道上,输出是隐式的。


2

JavaScript(ES6),55个字节

f=(s,q="0b"+s)=>q&&s.includes((q--).toString(2))+f(s,q)

将输入作为二进制字符串。

这是使用数字和递归函数进行的不幸尝试:

f=(n,q=n)=>q&&(g=n=>n?n^q&(h=n=>n&&n|h(n>>1))(q)?g(n>>1):1:0)(n)+f(s,q-1)

旧方法,74字节

s=>(f=s=>+s?new Set([+s,...f(s.slice(1)),...f(s.slice(0,-1))]):[])(s).size

也将输入作为二进制字符串。


1

Python 2中 118个  81字节

感谢@Rod节省了37个字节!

lambda n:len({int(n[i:j+1],2)for i in range(len(n))for j in range(i,len(n))}-{0})

将输入作为二进制字符串。

在线尝试!

Python 2,81个字节

感谢@Rod!

lambda n:len({n[i:j+1]for i in range(len(n))for j in range(i,len(n))if'1'==n[i]})

将输入作为二进制字符串。

在线尝试!


您可以接受一个二进制字符串作为输入,也可以代替set(...){...},并xrangerange
罗德

您也可以移动+1从范围到切片,并切换s.startswithint(s,2) 喜欢这个

1
如果您想保留原来的方法,也可以将用于相同的字节数
Rod

1

果冻,5个字节

ẆḄQṠS

在线尝试!

将输入作为1和0的列表。链接中的页脚将功能应用于帖子中的每个示例。

乔纳森·艾伦(Jonathan Allan)指出,这ẆḄQTL是使用T原子来查找所有真实元素的索引。

说明

以bin(13)= 1101为例。输入为[1,1,0,1]

ẆḄQṠS
Ẇ       All contiguous sublists -> 1,1,0,1,11,10,01,110,101,1101 (each is represented as a list)
 Ḅ      From binary to decimal. Vectorizes to each element of the above list -> 1,1,0,1,3,2,1,6,5,13
  Q     Unique elements
   Ṡ    Sign. Positive nums -> 1 , 0 -> 0.
    S   Sum

05AB1E答案中采纳了“真实化”(在这种情况下签名)的想法


1
您实际上可以使用Jelly的Truthy Indexes原子T,以及ẆḄQTL
Jonathan Allan

1

R88 77字节

function(x)sum(!!unique(strtoi(mapply(substring,x,n<-1:nchar(x),list(n)),2)))

在线尝试!

将输入作为二进制字符串。

使用mapply,生成输入的所有子字符串的数组。strtoi将它们转换为基本2整数,然后!!将结果中各项的逻辑转换()求和。


1

视网膜37 29字节

.+
*
+`(_+)\1
$1#
#_
_
wp`_.*

在线尝试!我只需要尝试Retina 1.0的w修改器。编辑:由于@MartinEnder,节省了8个字节。说明:

.+
*

从十进制转换为一元。

+`(_+)\1
$1#
#_
_

使用#for 0和从一元转换为二进制_ for 1。

wp`_.*

生成首先子1,我的意思是,_。然后,w修饰符将匹配所有子字符串,而不仅仅是每次开始_时最长的子字符串,而p修饰符则将匹配项进行重复数据删除。最终,因为这是最后阶段,所以将隐式返回匹配计数。


您还可以使用q(或p)修饰符将最后三个阶段合并为一个阶段w。您也不需要C显式指定,因为如果仅剩一个源,它是默认的阶段类型。
Martin Ender '18

@MartinEnder谢谢,我仍然习惯于使用M默认的舞台类型!
尼尔

好吧,C有点过去了M。:)
Martin Ender

我知道为什么它是默认值,只是习惯了切换。
尼尔

1

Pyth,8个字节

l #{vM.:

在这里尝试!

将输入作为二进制字符串。

.:生成所有子字符串,vM对每个子字符串求值(即,将每个子字符串从二进制转换),{重复数据删除,<space>#按身份过滤并l获取长度。





0

Java,232字节

String b=toBin(n);
l.add(b);
for(int i=1;i<b.length();i++){
for(int j=0;j<=b.length()-i;j++){
String t="";
if((""+b.charAt(j)).equals("0"))continue;
for(int k=0;k<i;k++){
t+=""+b.charAt(j+k);
}
if(!l.contains(t))l.add(t);
}
}
return l.size();

其中n是输入,b是二进制表示,l是所有子串的列表。第一次在这里发布,肯定需要改进,并随时指出任何错误!略作编辑以提高可读性。


欢迎来到PPCG!关于插入换行符以提高可读性,通常最好使用一个评分版本,该版本具有与标头中写入的字节数完全相同的值,然后再添加一个非高尔夫版本或非高尔夫版本,以提高可读性。
Laikoni '18

@Laikoni感谢您的注意!请记住以后的帖子!
Nihilish

String b=...,tint i=...,j,k保存字符以用于相同类型的重复声明。您的代码也没有资格作为条目,因为它只是一个代码段,既不是完整的程序也不是功能片段,因此您必须编写函数或以lambda形式包装代码
Unihedron

0

附件,35字节

`-&1@`#@Unique@(UnBin=>Subsets@Bin)

在线尝试!

等效地:

{#Unique[UnBin=>Subsets[Bin[_]]]-1}

说明

我将解释第二个版本,因为它比较容易理解(显式):

{#Unique[UnBin=>Subsets[Bin[_]]]-1}
{                                 }   lambda: _ = first argument
                        Bin[_]        convert to binary
                Subsets[      ]       all subsets of input
         UnBin=>                      map UnBin over these subsets
  Unique[                      ]      remove all duplicates
 #                              -1    size - 1 (since subsets is improper)


0

爪哇8,160个 159 158字节

import java.util.*;b->{Set s=new HashSet();for(int l=b.length(),i=0,j;i<l;i++)for(j=l-i;j>0;s.add(new Long(b.substring(i,i+j--))))s.add(0L);return~-s.size();}

输入为二进制字符串。
必须有更短的方法..>。>

说明:

在线尝试。

import java.util.*;          // Required import for Set and HashSet
b->{                         // Method with String as parameter and integer as return-type
  Set s=new HashSet();       //  Create a Set
  for(int l=b.length(),      //  Set `l` to the length of the binary-String
      i=0,j;i<l;i++)         //  Loop from 0 up to `l` (exclusive)
    for(j=l-i;j>0;           //   Inner loop from `l-i` down to `0` (exclusive)
      s.add(new Long(b.substring(i,i+j--))))
                             //    Add every substring converted to number to the Set
      s.add(0L);             //    Add 0 to the Set
  return~-s.size();}         //  Return the amount of items in the Set minus 1 (for the 0)

0

C ++,110个字节

#include<set>
std::set<int>s;int f(int n){for(int i=1;i<n;i+=i+1)f(n&i);return n?s.insert(n),f(n/2):s.size();}

这是一个递归函数。我们使用a std::set来计数值,忽略重复项。这两个递归调用掩盖了左侧(f(n&i))和右侧(f(n/2))的位,最终将所有子字符串生成为整数。

请注意,如果要再次调用,s必须在两次调用之间清除。

测试程序

#include <cstdlib>
#include <iostream>

int main(int, char **argv)
{
    while (*++argv) {
        auto const n = std::atoi(*argv);
        s={};
        std::cout << n << " -> " << f(n) << std::endl;
    }
}

结果

./153846 13 2008 63 65 850 459 716 425 327
13 -> 6
2008 -> 39
63 -> 6
65 -> 7
850 -> 24
459 -> 23
716 -> 22
425 -> 20
327 -> 16


0

J,15个字节

#.\\.#@=@-.&,0:

输入是一个二进制列表。在线尝试!

#.\\.               Convert every substring to decimal
         -.&,0:     Flatten and remove the 0s.        
     #@=            How many unique elements?

0

Perl 6,34个字节

{+unique ~«(.base(2)~~m:ex/1.*/)}

测试一下

展开:

{
  +                                # turn into Numeric (number of elements)
   unique                          # use only the unique ones
          ~«(                      # turn into strings
             .base(2)              # the input in base 2
                     ~~
                       m:ex/1.*/   # :exhaustive match substrings
                                )
}
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.