Chất nền nhị phân


17

Lấy cảm hứng từ vấn đề thứ tư từ BMO2 2009 .

Cho một số nguyên dương n là đầu vào hoặc một tham số, trả về số lượng số nguyên dương có biểu diễn nhị phân xảy ra dưới dạng các khối trong khai triển nhị phân của n .

Ví dụ: 13 -> 6 vì 13 trong nhị phân là 1101 và nó có các chuỗi con 1101, 110, 101, 11, 10, 1. Chúng tôi không tính số nhị phân bắt đầu bằng 0 và chúng tôi không đếm số không.

Các trường hợp thử nghiệm

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

Bạn có thể nhận n như bất kỳ điều nào sau đây:

  • một số nguyên
  • một danh sách các giá trị trung thực / giả cho biểu diễn nhị phân
  • một chuỗi cho biểu diễn nhị phân
  • một chuỗi cơ sở 10 (mặc dù tôi không chắc tại sao mọi người sẽ làm điều này)

Làm cho mã của bạn càng ngắn càng tốt.


3
Bạn có thể xác nhận 63-> 5 chứ không phải 6? Bin (63) = 111111 -> sáu chất nền khác nhau
dylnan

Liên quan. (Sử dụng các chuỗi con thay vì các chuỗi con và không bỏ qua các số 0 đứng đầu.)
Martin Ender

1
@dyl Nam Typo. Đã sửa.
0WJYxW9FMN

@MartinEnder Điều này có đủ khác để ở lại trang web này hay tôi sẽ xóa nó dưới dạng trùng lặp? Tôi nghĩ nó đủ khác biệt, nhưng bạn biết nhiều hơn tôi.
0WJYxW9FMN

@ J843136028 Sự khác biệt lớn hơn để không biến nó thành một bản sao là hạn chế thời gian cho thử thách khác. Bạn vẫn khỏe (Chỉ cần đăng liên kết, để các thách thức xuất hiện trong thanh bên của nhau.)
Martin Ender

Câu trả lời:


7

Python 3, 54 50 byte

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

Cảm ơn Rod và Jonathan Allan vì đã tiết kiệm bốn byte.


Bạn có thể di chuyển +1từ phạm vi sangbin(i)
Rod

1
Trong thực tế vì chúng ta luônn tự đếm và luôn loại trừ 0khỏi số đếm của mình, thay vào đó chúng ta luôn có thể loại trừ nvà luôn luôn đếm 0(bin (n) bắt đầu '0b...'), do đó chúng ta có thể xóa 1,+1hoàn toàn và để lại bin(i)như vậy để lưu bốn byte Hãy thử trực tuyến!
Jonathan Allan

5

Thạch , 4 byte

ẆQSḢ

Hãy thử trực tuyến!

Lấy đầu vào là danh sách của 0s và 1s.

Hãy thử trực tuyến với những con số!

Giải trình:

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

Bằng chứng nó hoạt động:

Chương trình này được một số đầu vào, N . Tất nhiên, điều đầu tiên mà sản phẩm này làm là lấy các chuỗi con của N 2 ( N ở cơ sở 2 ). Điều này bao gồm các chuỗi con trùng lặp bắt đầu bằng 0 hoặc 1 .

Sau đó, chúng ta chỉ cần lấy các chuỗi con duy nhất bằng cách chỉ giữ lần xuất hiện đầu tiên của mỗi giá trị trong danh sách chuỗi con.

Sau đó, chương trình này tổng hợp các phần tử đầu tiên của các danh sách lại với nhau, sau đó là các phần tử thứ hai, sau đó là phần thứ ba, thứ tư, v.v. và nếu một trong các danh sách không có phần tử nào như vậy 0được giả sử. Những gì thách thức yêu cầu là có hiệu quả Có bao nhiêu chuỗi con duy nhất bắt đầu bằng 1 con số này có ở dạng nhị phân của nó? . Vì mỗi phần tử đầu tiên được tính là 1, chúng ta có thể chỉ cần tính tổng thay vì lọc cho các chuỗi con thích hợp.

Bây giờ, phần tử đầu tiên của danh sách kết quả của phép tính tổng được mô tả ở trên chứa số bit đầu tiên của chuỗi con, vì vậy chúng ta chỉ cần bật và cuối cùng trả về nó.


4

Octave , 62 61 byte

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

Hãy thử trực tuyến!

Giải trình

Đối với đầu vào n, mã kiểm tra tất cả các số từ 1để nxem liệu biểu diễn nhị phân của chúng có phải là chuỗi con của biểu diễn nhị phân của đầu vào không.

@(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 byte

Đưa đầu vào dưới dạng một chuỗi nhị phân.
Tiêu đề chuyển đổi đầu vào số nguyên thành nhị phân để dễ kiểm tra.

ŒCÙĀO

Hãy thử trực tuyến!

Giải trình

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

Awwhh ... Tôi nghĩ rằng bộ lọc của tôi là thông minh. bŒʒć}ÙgNhưng không, điều đó tốt hơn.
Bạch tuộc ma thuật Urn


2

PowerShell , 103 92 82 byte

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

Hãy thử trực tuyến!

Lấy đầu vào là một mảng 10(trung thực và falsey trong PowerShell). Vòng lặp thông qua $s(nghĩa là có bao nhiêu phần tử trong mảng đầu vào). Trong vòng lặp, chúng tôi lặp từ số hiện tại (được lưu dưới dạng $i) lên đến $s.count. Mỗi vòng lặp bên trong, chúng ta -joinmảng cắt thành một chuỗi. Sau đó, chúng tôi sortvới -ucờ nique (ngắn hơn so selectvới -ucờ nique và chúng tôi không quan tâm liệu chúng có được sắp xếp hay không), lấy những cái không bắt đầu 0và lấy tổng thể .count. Đó là còn lại trên đường ống và đầu ra là ẩn.


2

JavaScript (ES6), 55 byte

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

Đưa đầu vào dưới dạng một chuỗi nhị phân.

Đây là một nỗ lực đáng buồn khi thực hiện nó với các số và các hàm đệ quy:

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)

Cách tiếp cận cũ, 74 byte

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

Cũng lấy đầu vào là một chuỗi nhị phân.


1

Python 2 ,  118  81 byte

Cảm ơn @Rod đã lưu 37 byte!

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

Đưa đầu vào dưới dạng một chuỗi nhị phân.

Hãy thử trực tuyến!

Python 2 , 81 byte

Cảm ơn @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]})

Đưa đầu vào dưới dạng một chuỗi nhị phân.

Hãy thử trực tuyến!


Bạn có thể chấp nhận một chuỗi nhị phân làm đầu vào, bạn cũng có thể thay thế set(...)bằng {...}xrangebằngrange
Rod

Bạn cũng có thể di chuyển +1từ dãy để lát, và chuyển đổi s.startswithđể int(s,2) thích này
Rod

1
Nếu bạn muốn giữ cách tiếp cận cũ của mình, bạn cũng có thể sử dụng phương pháp này cho cùng một số byte
Rod

1

Thạch , 5 byte

ẆḄQṠS

Hãy thử trực tuyến!

Đưa đầu vào dưới dạng danh sách 1s và 0. Chân trang trong liên kết áp dụng chức năng cho từng ví dụ trong bài.

Jonathan Allan chỉ ra rằng đó ẆḄQTLlà 5 byte thay thế sử dụng Tnguyên tử tìm thấy các chỉ số của tất cả các yếu tố trung thực.

Giải trình

Lấy bin (13) = 1101 làm ví dụ. Đầu vào là[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

Lấy ý tưởng "trung thực" (đăng nhập trong trường hợp này) từ câu trả lời 05AB1E


1
Bạn thực sự có thể sử dụng nguyên tử Jelly's Truthy Indexes T, vớiẆḄQTL
Jonathan Allan

1

R , 88 77 byte

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

Hãy thử trực tuyến!

Đưa đầu vào dưới dạng một chuỗi nhị phân.

bằng cách sử dụng mapply, tạo ra một mảng của tất cả các chuỗi con của đầu vào. strtoichuyển đổi chúng dưới dạng 2số nguyên cơ sở và tôi lấy tổng số chuyển đổi logic ( !!) của các mục trong kết quả.


1

Võng mạc , 37 29 byte

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

Hãy thử trực tuyến! Tôi vừa phải dùng thử công cụ wsửa đổi của Retina 1.0 . Chỉnh sửa: Đã lưu 8 byte nhờ @MartinEnder. Giải trình:

.+
*

Chuyển đổi từ số thập phân sang đơn nguyên.

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

Chuyển đổi từ unary sang nhị phân, sử dụng #cho 0_cho 1.

wp`_.*

Tạo các chuỗi con bắt đầu bằng 1, ý tôi là , _. Công cụ wsửa đổi sau đó khớp với tất cả các chuỗi con, không chỉ là chuỗi dài nhất ở mỗi lần khởi động _, trong khi công cụ psửa đổi lặp lại các kết quả khớp. Cuối cùng, vì đây là giai đoạn cuối cùng, số lượng các trận đấu được ngầm trả lại.


Bạn có thể cuộn ba giai đoạn cuối cùng thành một bằng cách sử dụng công cụ sửa đổi q(hoặc p) ngoài w. Bạn cũng không cần chỉ định Crõ ràng, vì đó là loại giai đoạn mặc định nếu chỉ còn một nguồn duy nhất.
Martin Ender

@MartinEnder Cảm ơn, tôi vẫn quen dùng Mloại sân khấu mặc định!
Neil

Vâng, Ckinda là những gì đã Mtừng. :)
Martin Ender

Tôi biết tại sao nó là mặc định, nó chỉ quen với việc chuyển đổi.
Neil

1

Bình thường , 8 byte

l #{vM.:

Hãy thử nó ở đây!

Đưa đầu vào dưới dạng một chuỗi nhị phân.

.:tạo ra tất cả các chuỗi con, vMđánh giá từng chuỗi (nghĩa là nó chuyển đổi từng chuỗi từ nhị phân), {lặp lại, <space>#lọc theo danh tính và llấy độ dài.





0

Java, 232 byte

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

Trong đó n là đầu vào, b là biểu diễn nhị phân và l là danh sách tất cả các chuỗi con. Lần đầu tiên đăng ở đây, chắc chắn cần phải cải thiện, và cảm thấy tự do để chỉ ra bất kỳ sai lầm! Hơi chỉnh sửa để dễ đọc.


Chào mừng đến với PPCG! Về việc bạn chèn các dòng mới để dễ đọc, thường nên có một phiên bản tính điểm có chính xác số lượng byte như được viết trong tiêu đề, và sau đó là một phiên bản không được bổ sung hoặc ít chơi gôn hơn để dễ đọc.
Laikoni

@Laikoni Cảm ơn bạn đã ủng hộ! Sẽ ghi nhớ cho bài viết trong tương lai!
Nihilish

String b=...,tint i=...,j,kđể lưu ký tự cho các khai báo lặp lại cùng loại. Mã của bạn cũng sẽ không đủ điều kiện làm mục nhập vì đó là đoạn mã, không phải là chương trình đầy đủ cũng không phải là đoạn chức năng, bạn phải viết một hàm hoặc bọc mã của mình ở dạng lambda
Unihedron

0

Tùy viên , 35 byte

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

Hãy thử trực tuyến!

Tương đương:

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

Giải trình

Tôi sẽ giải thích phiên bản thứ hai, vì nó dễ theo dõi hơn (rõ ràng):

{#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

Java 8, 160 159 158 byte

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();}

Nhập dưới dạng chuỗi nhị phân.
Phải có một cách ngắn hơn ..>.>

Giải trình:

Hãy thử trực tuyến.

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 byte

#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();}

Đây là một hàm đệ quy. Chúng tôi sử dụng a std::setđể đếm các giá trị, bỏ qua các bản sao. Hai cuộc gọi đệ quy mặt nạ bit bên trái ( f(n&i)) và bên phải ( f(n/2)), cuối cùng tạo ra tất cả các chuỗi con dưới dạng số nguyên.

Lưu ý rằng nếu bạn muốn gọi lại, sphải xóa giữa các cuộc gọi.

Chương trình kiểm tra

#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;
    }
}

Các kết quả

./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 byte

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

Đầu vào là một danh sách nhị phân. Hãy thử trực tuyến!

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

0

Perl 6 , 34 byte

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

Kiểm tra nó

Mở rộng:

{
  +                                # 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
                                )
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.