이진 부분 문자열


17

BMO2 2009 의 네 번째 문제에서 영감을 얻었습니다 .

양의 정수 n 을 입력 또는 매개 변수로 지정하면 이진 표현이 n 의 이진 확장에서 블록으로 발생하는 양의 정수 수를 반환합니다 .

예를 들어, 이진의 13이 1101이고 하위 문자열이 있기 때문에 13-> 6 1101, 110, 101, 11, 10, 1입니다. 우리는 0으로 시작하는 이진수를 세지 않으며 0 자체를 세지 않습니다.

테스트 사례

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

다음 중 하나로 n 을 사용할 수 있습니다 .

  • 정수
  • 이진 표현에 대한 진실 / 거짓 값의 목록
  • 이진 표현을위한 문자열
  • 기본 10 문자열 (아무도 왜 이것을 할 지 모르겠지만)

코드를 가능한 짧게 만드십시오.


3
6이 아니라 63-> 5를 확인할 수 있습니까? Bin (63) =
111111-

관련. (하위 문자열 대신 하위 시퀀스를 사용하고 선행 0을 무시하지 않습니다.)
Martin Ender

1
@dylnan 오타. 결정된.
0WJYxW9FMN

@MartinEnder이 사이트에 머무르기에 충분하지 않습니까? 아니면 중복으로 삭제해야합니까? 나는 그것이 충분히 다르다고 생각하지만, 당신은 나보다 훨씬 잘 알고 있습니다.
0WJYxW9FMN

복제하지 않기위한 더 큰 차이점은 다른 문제에 대한 시간 제한입니다. 너는 괜찮아. (그냥 링크를 게시하여 서로의 사이드 바에 문제가 표시되었습니다.)
Martin Ender

답변:


7

파이썬 3, 54 50 바이트

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

4 바이트를 절약 한 Rod와 Jonathan Allan에게 감사합니다.


+1범위에서 범위로 이동할 수 있습니다bin(i)
Rod

1
실제로 우리는 항상n 자체를 계산 하고 항상 카운트 에서 제외 해야하기 때문에0 대신 항상 제외 n하고 항상 계산 0(bin (n) starts '0b...') 할 수 있으므로1, 4 바이트를 절약하기 위해 and를 +1완전히 하고 그대로 둘 수 있습니다. bin(i)
Jonathan Allan

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을 얻습니다. . 이 제품이 수행하는 첫 번째 일은 물론,의 문자열 걸릴 것입니다 N 2 ( N 자료 2 ). 여기에는 0 또는 1로 시작하는 중복 하위 문자열이 포함됩니다 .

그런 다음 하위 문자열 목록에서 각 값의 첫 번째 항목 만 유지하여 고유 한 하위 문자열을 가져옵니다.

그런 다음이 프로그램은 목록의 첫 번째 요소를 합한 다음 두 번째 요소, 세 번째, 네 번째 등을 합하며 목록 중 하나에 해당 요소 0가없는 것으로 가정합니다. 문제는 효과적으로 묻는 것입니다. 이 숫자는 1로 시작하는 고유 한 하위 문자열 이 몇 개입니까? . 계산할 첫 번째 요소는 모두이므로 1적절한 하위 문자열을 필터링하는 대신 간단히 합할 수 있습니다.

이제 위에서 설명한 합계 목록의 첫 번째 요소는 하위 문자열의 첫 번째 비트 수를 유지하므로 간단히 팝하고 마지막으로 반환합니다.


4

옥타브 , 62 61 바이트

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

온라인으로 사용해보십시오!

설명

input의 경우이 n코드 는 이진수 표현이 입력 이진 표현의 하위 문자열인지 확인 1하기 n위해 모든 숫자를 테스트합니다 .

@(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 바이트

입력을 이진 문자열로 가져옵니다.
헤더는 테스트하기 쉽도록 정수 입력을 2 진으로 변환합니다.

ŒCÙĀO

온라인으로 사용해보십시오!

설명

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

Awwhh ... 필터가 똑똑하다고 생각했습니다. bŒʒć}Ùg하지만 더 낫습니다.
Magic Octopus Urn


2

PowerShell , 103 92 82 바이트

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

온라인으로 사용해보십시오!

입력을 1and 의 배열로 0가져옵니다 (PowerShell에서 진실하고 거짓). 루프를 통해 $s(즉, 입력 배열의 요소 수) 현재 번호에서 루프, 우리 루프 내부에서 (로 저장 $i까지) $s.count. 각각의 내부 루프 -join는 배열 슬라이스를 문자열로 만듭니다. 우리는 다음 sort-u(보다 짧은 nique 플래그 select-unique 플래그와 우리는 그들이 분류 여부를하든 상관하지 않습니다)로 시작하지 않는 사람들을 0, 그리고 전체를 취할 .count. 그것은 파이프 라인에 남아 있으며 출력은 암시 적입니다.


2

자바 스크립트 (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

파이썬 2 ,  118  81 바이트

37 바이트를 절약 한 @Rod에게 감사드립니다!

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

입력을 이진 문자열로 가져옵니다.

온라인으로 사용해보십시오!

파이썬 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(...)있고 다음 {...}xrange같이 바꿀 수도 있습니다range
Rod

+1범위에서 슬라이스로 범위를 이동하고 이와 같이 전환 할 s.startswith수 있습니다int(s,2)
Rod

1
예전의 접근 방식을 유지 하려면 동일한 바이트 수로 이를 사용할 수도 있습니다
Rod

1

젤리 , 5 바이트

ẆḄQṠS

온라인으로 사용해보십시오!

1과 0의 목록으로 입력을받습니다. 링크의 바닥 글은 게시물의 각 예제에 기능을 적용합니다.

Jonathan Allan ẆḄQTL은 5 바이트 대안을 사용하여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 답변 에서 "truthify"(이 경우 서명) 아이디어를 얻었습니다.


1
실제로, 젤리의 Truthy 인덱스 원자를 사용할 수 T와 함께,ẆḄQTL
조나단 앨런

1

R , 88 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_1을 사용하여 단항에서 이진으로 변환 합니다.

wp`_.*

로 시작하는 문자열을 생성 1, 내 말은 _. w수정은 모든 문자열, 각각의 시작에서뿐만 아니라 긴 하나와 일치 _그동안, p수정 중복 제거 성냥. 마지막으로 이것이 마지막 단계이므로 일치 횟수가 암시 적으로 반환됩니다.


q(또는 p) 수정자를 사용하여 마지막 세 단계를 하나로 롤업 할 수 있습니다 w. C소스가 하나 밖에없는 경우 기본 스테이지 유형이므로 명시 적 으로 지정할 필요가 없습니다 .
Martin Ender

@MartinEnder 고마워요, 저는 여전히 M기본 스테이지 유형에 익숙 합니다!
Neil

글쎄, 예전의 C것이 었습니다 M. :)
Martin Ender

왜 이것이 기본값인지 알고 있으며 전환에 익숙해졌습니다.
Neil

1

Pyth , 8 바이트

l #{vM.:

여기 사용해보십시오!

입력을 이진 문자열로 가져옵니다.

.:모든 하위 문자열을 생성하고, vM각각을 평가하고 (즉, 각각을 이진에서 변환) {중복 제거 <space>#하고 ID별로 필터링 l하고 길이를 가져옵니다.





0

자바, 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

@Laikoni 헤드 업 주셔서 감사합니다! 향후 게시물을 염두에 두십시오!
Nihilish

String b=...,tint i=...,j,k같은 유형의 반복 선언에 대한 문자를 저장합니다. 코드는 또한 스 니펫이거나 전체 프로그램이나 기능적 조각이 아니기 때문에 항목으로 적합하지 않습니다. 함수를 작성하거나 코드를 람다 형식으로 감싸 야합니다
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();}

재귀 함수입니다. 우리는 std::set중복을 무시하고 값을 계산 하기 위해 a 를 사용합니다 . 두 개의 재귀 호출은 왼쪽 ( 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

펄 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
                                )
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.