İkili Alt Dizeler


17

BMO2 2009'dan gelen dördüncü problemden esinlenmiştir .

Girdi veya parametre olarak pozitif bir tamsayı n verildiğinde , ikili gösterimleri n'nin ikili genişlemesinde bloklar olarak oluşan pozitif tamsayıların sayısını döndürür .

Örneğin, 13 -> 6, çünkü ikili dosyadaki 13, 1101'dir ve alt dizeleri vardır 1101, 110, 101, 11, 10, 1. Sıfır ile başlayan ikili sayıları saymıyoruz ve sıfırın kendisini saymıyoruz.

Test Durumları

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

Sen de alabilir n Aşağıdakilerden herhangi biri olarak:

  • Bir tam sayı
  • ikili gösterim için doğruluk / falsy değerlerinin bir listesi
  • ikili gösterim için bir dize
  • bir temel 10 dize (neden kimse bunu yapacak emin değilim)

Kodunuzu mümkün olduğunca kısa yapın.


3
6 değil, 63-> 5'i onaylayabilir misiniz?
Depo

İlişkili. (Alt dizeler yerine alt diziler kullanır ve baştaki sıfırları dikkate almaz.)
Martin Ender

1
@dylnan Typo. Sabit.
0WJYxW9FMN

@MartinEnder Bu sitede kalacak kadar farklı mı yoksa kopya olarak silmeli miyim? Bence bu yeterince farklı, ama benden çok daha iyi biliyorsun.
0WJYxW9FMN

J843136028 Yinelenmemesi için en büyük fark, diğer zorluklarla ilgili zaman kısıtlamasıdır. İyisin. (Bağlantıyı yeni yayınladım, böylece zorluklar birbirlerinin kenar çubuğunda ortaya çıktı.)
Martin Ender

Yanıtlar:


7

Python 3, 54 50 bayt

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

Rod ve Jonathan Allan'a dört bayt kazandıkları için teşekkürler.


+1Aralıktanbin(i)
Rod

1
Aslında biz bu yana her zaman saymak nkendisini ve üzeresiniz her zaman dışlamak 0yerine hep hariç tutabilirsiniz bizim sayısından nve her zaman saymak 0(bin (n) başlar '0b...'), dolayısıyla biz kaldırabilir 1,ve +1tamamen ve bırakın bin(i)dört bayt kurtarmaktır olarak çevrimiçi deneyin!
Jonathan Allan

5

Jöle , 4 bayt

ẆQSḢ

Çevrimiçi deneyin!

Girişi 0s ve 1s listesi olarak alır .

Sayılarla çevrimiçi deneyin!

Açıklama:

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

Çalıştığının kanıtı:

Bu program, bir giriş numarası alır , N . Bu ürün, ilk yaptığı şey, tabii ki substrings alır, bir N 2 ( N tabanında 2 ). Bu, 0 veya 1 ile başlayan yinelenen alt dizeleri içerir .

Bundan sonra, alt dize listesindeki her değerin yalnızca ilk oluşumunu tutarak benzersiz alt dizeleri alırız.

Daha sonra, bu program listelerin ilk elemanlarını bir araya getirir, daha sonra ikinci elemanlar, daha sonra üçüncü, dördüncü, vb 0. Bu meydan okuma ne kadar etkili bir şekilde sorulur ? Bu sayı 1 ile başlayan kaç tane benzersiz alt dize ikili biçimde var? . Sayılacak her ilk öğe 1uygun olduğundan, uygun alt dizeleri filtrelemek yerine toplayabiliriz.

Şimdi, yukarıda açıklanan toplam listesinin ilk öğesi, alt dizelerin ilk bitlerinin sayısını tutar, bu yüzden basitçe açılır ve son olarak döndürürüz.


4

Oktav , 62 61 bayt

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

Çevrimiçi deneyin!

açıklama

Giriş niçin kod , ikili gösterimlerinin girişin ikili gösteriminin bir alt dizisi olup olmadığını görmek 1için nile arasındaki tüm sayıları test eder.

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

Girdiyi ikili dize olarak alır.
Başlık, test kolaylığı için tamsayı girişini ikilik biçime dönüştürür.

ŒCÙĀO

Çevrimiçi deneyin!

açıklama

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

Awwhh ... Filtremin akıllı olduğunu düşündüm. bŒʒć}Ùgama hayır, bu daha iyi.
Sihirli Ahtapot Urn


2

PowerShell , 103 92 82 bayt

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

Çevrimiçi deneyin!

Bir dizisi olarak giriş alır 1ve 0(PowerShell truthy ve Falsey). İçine girer $s(yani, giriş dizisindeki kaç öğe). Döngünün içinde, geçerli sayıdan (olarak kaydedildi $i) şu noktaya kadar döngü yaparız $s.count. Her iç döngü, biz -joindizi bir dize dilim. Sonra sortbirlikte -u(daha kısadır nique bayrağı selectile -unique bayrağı ve biz onlar sıralanmış olup olmamanıza umurumda değil), ile başlamak olmayanları almak 0ve genel alır .count. Boru hattında kalan ve çıktı örtük.


2

JavaScript (ES6), 55 bayt

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

Girdiyi ikili dize olarak alır.

Sayılar ve özyinelemeli işlevlerle yapmaya üzücü bir girişim:

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)

Eski yaklaşım, 74 bayt

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

Ayrıca girişi ikili bir dize olarak alır.


1

Python 2 ,  118  81 bayt

37 bayt kaydettiği için @Rod'a teşekkürler!

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

Girdiyi ikili dize olarak alır.

Çevrimiçi deneyin!

Python 2 , 81 bayt

@ Rod sayesinde!

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

Girdiyi ikili dize olarak alır.

Çevrimiçi deneyin!


Girdi olarak bir ikili dize kabul edebilir, ayrıca yerini alabilir set(...)ile {...}ve xrangeilerange
Rod

Ayrıca taşıyabilirsiniz +1dilim aralığından ve geçiş s.startswithiçin int(s,2) bu gibi
Çubuk

1
Eski yaklaşım tutmak istiyorsanız, siz de kullanabilirsiniz bu aynı bayt sayısı için
Çubuk

1

Jöle , 5 bayt

ẆḄQṠS

Çevrimiçi deneyin!

Girişi 1s ve 0s listesi olarak alır. Bağlantıdaki altbilgi, işlevi gönderideki örneklerin her birine uygular.

Jonathan Allan ẆḄQTL, bunun Ttüm doğru unsurların indekslerini bulan atomu kullanan 5 baytlık bir alternatif olduğuna dikkat çekti .

açıklama

Örnek olarak bin (13) = 1101'i ele alalım. Girdi[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

Dan (bu durumda işareti) "truthify" fikrini aldı 05AB1E cevap


1
Aslında, Jelly Truthy Endeksleri atom kullanabilirsiniz TileẆḄQTL
Jonathan Allan

1

R , 88 77 bayt

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

Çevrimiçi deneyin!

Girdiyi ikili dize olarak alır.

using mapply, girdinin tüm alt dizelerinden oluşan bir dizi oluşturur. strtoibunları temel 2tamsayılar olarak dönüştürür ve sonuçtaki !!girdilerin mantıksal dönüşümünün ( ) toplamını alırım .


1

Retina , 37 29 bayt

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

Çevrimiçi deneyin! Sadece Retina 1.0'ın wdeğiştiricisini denemek zorunda kaldım . Düzenleme: @MartinEnder sayesinde 8 bayt kaydedildi. Açıklama:

.+
*

Ondalıktan tekliye dönüştürme.

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

#For için 0ve kullanarak, tekli ikiliden dönüştürün _.

wp`_.*

1Demek istediğim, ile başlayan alt dizeler oluşturun _. wDeğiştirici sonra tüm alt dizeleri, her başlangıç değil sadece uzun eşleşmesine _ederken, pdeğiştirici tekilleştirir maçlar. Son olarak bu son aşama olduğu için maç sayısı dolaylı olarak iade edilir.


Ek olarak q(veya p) değiştiriciyi kullanarak son üç aşamayı bire yuvarlayabilirsiniz w. Ayrıca Caçıkça belirtmeniz de gerekmez , çünkü yalnızca tek bir kaynak kaldıysa varsayılan sahne türüdür.
Martin Ender

@MartinEnder Teşekkürler, hala Mvarsayılan sahne türü olmaya alışkınım !
Neil

Eh, Cbiraz ne Molurdu. :)
Martin Ender

Neden varsayılan olduğunu biliyorum, sadece geçiş yapmaya alışıyor.
Neil

1

Pyth , 8 bayt

l #{vM.:

Burada deneyin!

Girdiyi ikili dize olarak alır.

.:tüm alt dizeleri oluşturur, vMher birini değerlendirir (yani her ikiliden dönüştürür), {yinelenenleri kaldırır, <space>#kimliğe göre filtreler ve luzunluğu alır.





0

Java, 232 bayt

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 girdi olduğunda, b ikili gösterimdir ve l tüm alt dizelerin listesidir. Burada ilk kez gönderme, kesinlikle geliştirmek gerekir ve herhangi bir hata işaret çekinmeyin! Okunabilirlik için hafifçe düzenlenmiştir.


PPCG'ye Hoşgeldiniz! Okunabilirlik için yeni satırlar eklemenize gelince, genellikle başlıkta yazıldığı gibi tam olarak bayt miktarına sahip bir puanlama sürümüne ve daha sonra okunabilirlik için ek bir golf edilmemiş veya daha az golfçü versiyona sahip olmak tercih edilir.
Laikoni

@Laikoni Head-up için teşekkürler! Gelecek gönderiler için aklınızda bulundurun!
Nihilish

String b=...,tve int i=...,j,kaynı türden tekrarlanan bildirimler için grafikleri kaydetmek. Kodunuz ayrıca bir snippet, ne tam bir program ne de fonksiyonel bir parça olduğu için bir giriş olarak nitelendirilmez, ya bir işlev yazmanız ya da kodunuzu lambda biçiminde sarmanız gerekir
Unihedron

0

Ataşesi , 35 bayt

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

Çevrimiçi deneyin!

eşdeğer bir:

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

açıklama

(Açık olmak) takip etmek daha kolay olduğu için, ikinci sürümü açıklayacağım:

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

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

Binary-String olarak girin.
Daha kısa bir yol olmalı ..>.>

Açıklama:

Çevrimiçi deneyin.

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 bayt

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

Bu özyinelemeli bir işlevdir. std::setYinelenen değerleri yok sayarak değerleri saymak için a kullanırız . İki özyinelemeli arama maskesi bitlerini soldan ( f(n&i)) ve sağdan (f(n/2) ) sonunda tüm alt dizeleri tamsayı olarak üretir.

Tekrar aramak isterseniz, saramalar arasında silinmesi gerektiğini unutmayın.

Test programı

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

Sonuçlar

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

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

Girdi ikili bir listedir. Çevrimiçi deneyin!

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.