Binäre Teilzeichenfolgen

17

Inspiriert vom vierten Problem von BMO2 2009 .

Geben Sie bei einer positiven Ganzzahl n als Eingabe oder einem Parameter die Anzahl der positiven Ganzzahlen zurück, deren binäre Darstellungen als Blöcke in der binären Erweiterung von n auftreten .

Beispiel: 13 -> 6, da 13 in der Binärdatei 1101 ist und Teilzeichenfolgen enthält 1101, 110, 101, 11, 10, 1. Wir zählen keine Binärzahlen, die mit Null beginnen, und wir zählen selbst keine Null.

Testfälle

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

Sie können n wie folgt aufnehmen:

  • eine ganze Zahl
  • eine Liste von Wahrheits- / Falschwerten für die Binärdarstellung
  • ein String für die Binärdarstellung
  • eine Base-10-Saite (obwohl ich nicht sicher bin, warum das jemand tun würde)

Machen Sie Ihren Code so kurz wie möglich.

0WJYxW9FMN
quelle
3
Kannst du 63-> 5 und nicht 6 bestätigen? Bin (63) = 111111 -> sechs verschiedene Nicht-Null-
Teilzeichenfolgen
Verbunden. (Verwendet Teilfolgen anstelle von Teilfolgen und ignoriert führende Nullen nicht.)
Martin Ender
1
@ Dylnan Typo. Fest.
0WJYxW9FMN
@MartinEnder Ist das anders genug, um auf dieser Site zu bleiben, oder soll ich es als Duplikat löschen? Ich denke, es ist ausreichend anders, aber Sie wissen viel besser als ich.
0WJYxW9FMN
@ J843136028 Der größere Unterschied, warum kein Duplikat erstellt wird, ist die zeitliche Beschränkung für die andere Herausforderung. Du bist in Ordnung. (Habe gerade den Link gepostet, damit die Herausforderungen in der Seitenleiste des anderen auftauchen.)
Martin Ender

Antworten:

7

Python 3, 54 50 Bytes

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

Vielen Dank an Rod und Jonathan Allan für das Speichern von vier Bytes.

0WJYxW9FMN
quelle
Sie können die +1aus dem Bereich zu bewegenbin(i)
Rod
1
In der Tat , da wir immer zählen nselbst und sind immer ausschließen 0unserer Zählung können wir stattdessen immer ausschließen nund immer zählen 0(bin (n) beginnt '0b...'), daher können wir das entfernen 1,und +1ganz und verlassen bin(i)als vier Bytes speichern Online ausprobieren!
Jonathan Allan
5

Gelee , 4 Bytes

ẆQSḢ

Probieren Sie es online!

Übernimmt die Eingabe als Liste von 0s und 1s.

Probieren Sie es online mit Zahlen!

Erläuterung:

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

Beweis, dass es funktioniert:

Dieses Programm wird eine Eingangsnummer, N . Das erste, was dieses Produkt tut, ist natürlich, die Teilzeichenfolgen von N 2 ( N in Basis 2 ) zu nehmen. Dies schließt doppelte Teilzeichenfolgen ein, die mit 0 oder 1 beginnen .

Danach nehmen wir einfach die eindeutigen Teilzeichenfolgen, indem wir nur das erste Vorkommen jedes Werts in der Teilzeichenfolgenliste beibehalten.

Dann summiert dieses Programm die ersten Elemente der Listen zusammen, dann die zweiten Elemente, dann die dritten, vierten usw., und wenn eine der Listen kein solches Element aufweist, 0wird angenommen. Die eigentliche Herausforderung lautet: Wie viele eindeutige Teilzeichenfolgen, die mit 1 beginnen, hat diese Zahl in ihrer binären Form? . Da jedes erste Element, das gezählt werden soll 1, einfach summiert werden kann, anstatt nach geeigneten Teilzeichenfolgen zu filtern.

Nun enthält das erste Element der resultierenden Liste der oben beschriebenen Summierung die Anzahl der ersten Bits der Teilzeichenfolgen, sodass wir sie einfach einfügen und schließlich zurückgeben.

Erik der Outgolfer
quelle
4

Oktave , 62 61 Bytes

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

Probieren Sie es online!

Erläuterung

Bei der Eingabe nprüft der Code alle Zahlen von 1bis, num festzustellen, ob ihre Binärdarstellung eine Teilzeichenfolge der Binärdarstellung der Eingabe ist.

@(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
Luis Mendo
quelle
3

05AB1E , 5 Bytes

Übernimmt die Eingabe als binäre Zeichenfolge.
Der Header konvertiert Ganzzahleingaben in Binärwerte, um das Testen zu vereinfachen.

ŒCÙĀO

Probieren Sie es online!

Erläuterung

Œ        # push all substrings of input
 C       # convert to base-10 int
  Ù      # remove duplicates
   Ā     # truthify (convert non-zero elements to 1)
    O    # sum
Emigna
quelle
Awwhh ... ich dachte mein Filter wäre schlau. bŒʒć}Ùgaber nein, das ist besser.
Magic Octopus Urn
2

PowerShell , 103 92 82 Byte

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

Probieren Sie es online!

Nimmt Eingaben als Array von 1und 0(wahr und falsch in PowerShell). Durchläuft $s(dh wie viele Elemente im Eingabearray). Innerhalb der Schleife durchlaufen wir die Schleife von der aktuellen Nummer (gespeichert unter $i) bis $s.count. In jeder inneren Schleife -joinschneiden wir das Array in eine Zeichenfolge. Wir dann sortmit der -uNique-Flagge (die kürzer ist als selectmit der -uNique-Flagge und es ist uns egal, ob sie sortiert sind oder nicht), nehmen diejenigen, die nicht anfangen 0, und nehmen den Overall .count. Das bleibt in der Pipeline und die Ausgabe ist implizit.

AdmBorkBork
quelle
2

JavaScript (ES6), 55 Byte

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

Übernimmt die Eingabe als binäre Zeichenfolge.

Hier ist ein trauriger Versuch, dies mit Zahlen und rekursiven Funktionen zu tun:

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)

Alter Ansatz, 74 Bytes

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

Nimmt auch Eingaben als Binärstring an.

ETHproductions
quelle
1

Python 2 ,  118  81 Bytes

Vielen Dank an @Rod für das Speichern von 37 Bytes!

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

Übernimmt die Eingabe als binäre Zeichenfolge.

Probieren Sie es online!

Python 2 , 81 Bytes

Vielen Dank an @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]})

Übernimmt die Eingabe als binäre Zeichenfolge.

Probieren Sie es online!

Steadybox
quelle
Sie können eine binäre Zeichenfolge als Eingabe akzeptieren, können Sie auch ersetzen set(...)mit {...}und xrangemitrange
Rod
Sie können auch die Bewegung +1aus dem Bereich der Scheibe, und schalten Sie die wie dieses.startswithint(s,2)
Rod
1
Wenn Sie Ihren alten Konzept behalten möchten, können Sie auch diese für die gleiche Byteanzahl
Rod
1

Gelee , 5 Bytes

ẆḄQṠS

Probieren Sie es online!

Nimmt die Eingabe als Liste von Einsen und Nullen. Die Fußzeile im Link wendet die Funktion auf jedes der Beispiele im Beitrag an.

Jonathan Allan wies darauf hin, dass ẆḄQTLes sich um eine 5-Byte-Alternative handelt, die das TAtom verwendet , das die Indizes aller wahrheitsgemäßen Elemente findet.

Erläuterung

Nehmen Sie als Beispiel bin (13) = 1101. Eingabe ist[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

Hat die Idee "wahrheitsgemäß" (in diesem Fall unterschreiben) aus der 05AB1E-Antwort übernommen

dylnan
quelle
1
Sie könnten tatsächlich Jelly's Truthy Indexes Atom verwenden T, mitẆḄQTL
Jonathan Allan
1

R , 88 77 Bytes

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

Probieren Sie es online!

Übernimmt die Eingabe als binäre Zeichenfolge.

using mapplygeneriert ein Array aller Teilzeichenfolgen der Eingabe. strtoikonvertiert sie als Basis- 2Ganzzahlen und ich nehme die Summe der logischen Konvertierung ( !!) der Einträge im Ergebnis.

Giuseppe
quelle
1

Retina , 37 29 Bytes

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

Probieren Sie es online! Ich musste nur den wModifikator von Retina 1.0 ausprobieren . Bearbeiten: 8 Bytes dank @MartinEnder gespeichert. Erläuterung:

.+
*

Konvertiert von dezimal zu unär.

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

Konvertieren Sie von unär nach binär mit #for 0und _for 1.

wp`_.*

Erzeugen Sie Teilstrings, die mit 1, ich meine, beginnen _. Der wModifikator stimmt dann mit allen Teilzeichenfolgen überein, nicht nur mit der längsten bei jedem Start _, während der pModifikator die Übereinstimmungen dedupliziert. Da dies die letzte Stufe ist, wird die Anzahl der Übereinstimmungen implizit zurückgegeben.

Neil
quelle
Sie können die letzten drei Stufen zu einer zusammenfassen, indem Sie zusätzlich den Modifikator q(oder p) verwenden w. Sie müssen auch nicht Cexplizit angeben , da dies der Standardphasentyp ist, wenn nur noch eine einzige Quelle vorhanden ist.
Martin Ender
@MartinEnder Danke, ich bin es immer noch gewohnt M, der Standard- Bühnentyp zu sein!
Neil
Nun, Cirgendwie war es das, was Mfrüher war. :)
Martin Ender
Ich weiß, warum es die Standardeinstellung ist, es ist nur daran gewöhnt, zu wechseln.
Neil
1

Pyth , 8 Bytes

l #{vM.:

Probieren Sie es hier aus!

Übernimmt die Eingabe als binäre Zeichenfolge.

.:generiert alle Teilstrings, vMwertet jeden aus ( dh konvertiert jeden aus dem Binären), {dedupliziert, <space>#filtert nach Identität und lerhält die Länge.

Mr. Xcoder
quelle
1

Wolfram Language (Mathematica) , 35 Byte

Das Zählen eindeutiger Teilsequenzen der Binärdarstellung, die mit einer beginnen, obwohl ich nicht sicher bin, ob dieser Code überhaupt eine Erklärung benötigt.

Union@Subsequences@#~Count~{1,___}&

Probieren Sie es online!

Kelly Lowder
quelle
Was macht ___das?
FrownyFrog
Mustererkennung, _ ist ein einzelnes Element, __ ist eines oder mehrere, ___ ist 0 oder mehr.
Kelly Lowder
0

Java, 232 Bytes

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

Dabei ist n die Eingabe, b die Binärdarstellung und l eine Liste aller Teilzeichenfolgen. Zum ersten Mal hier posten, müssen auf jeden Fall verbessert werden, und zögern Sie nicht, auf Fehler hinzuweisen! Zur besseren Lesbarkeit leicht bearbeitet.

Nihilish
quelle
Willkommen bei PPCG! In Bezug auf das Einfügen von Zeilenumbrüchen aus Gründen der Lesbarkeit wird in der Regel eine Scoring-Version bevorzugt, die genau die im Header angegebene Anzahl von Bytes enthält, und anschließend eine zusätzliche ungolfed oder weniger golfed-Version, um die Lesbarkeit zu gewährleisten.
Laikoni
@Laikoni Danke für das Heads-up! Wird für zukünftige Beiträge im Hinterkopf behalten!
Nihilish
String b=...,tund int i=...,j,kZeichen für wiederholte Deklarationen desselben Typs zu speichern. Ihr Code würde sich auch nicht als Eintrag qualifizieren, da es sich um ein Snippet handelt, weder um ein vollständiges Programm noch um ein funktionales Fragment. Sie müssen entweder eine Funktion schreiben oder Ihren Code in die Lambda-Form
einschließen
0

Attache , 35 Bytes

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

Probieren Sie es online!

Äquivalent:

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

Erläuterung

Ich werde die zweite Version erklären, da es einfacher ist zu folgen (explizit zu sein):

{#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)
Conor O'Brien
quelle
0

Java 8, 160 159 158 Bytes

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

Eingabe als Binärstring.
Es muss einen kürzeren Weg geben ..>.>

Erläuterung:

Probieren Sie es online aus.

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)
Kevin Cruijssen
quelle
0

C ++, 110 Bytes

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

Dies ist eine rekursive Funktion. Wir verwenden a, std::setum Werte zu zählen, wobei Duplikate ignoriert werden. Die beiden rekursiven Aufrufe maskieren Bits links ( f(n&i)) und rechts ( f(n/2)) und erzeugen schließlich alle Teilzeichenfolgen als Ganzzahlen.

Beachten Sie, dass, wenn Sie es erneut anrufen möchten, szwischen den Anrufen gelöscht werden muss.

Testprogramm

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

Ergebnisse

./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
Toby Speight
quelle
0

J , 15 Bytes

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

Die Eingabe ist eine Binärliste. Probieren Sie es online!

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

Perl 6 , 34 Bytes

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

Probier es aus

Erweitert:

{
  +                                # 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
                                )
}
Brad Gilbert b2gills
quelle