Substrings binárias

17

Inspirado pelo quarto problema da BMO2 2009 .

Dado um número inteiro positivo n como entrada ou parâmetro, retorne o número de números inteiros positivos cujas representações binárias ocorrem como blocos na expansão binária de n .

Por exemplo, 13 -> 6 porque 13 no binário é 1101 e possui substrings 1101, 110, 101, 11, 10, 1. Não contamos números binários que começam com zero e não contamos zero.

Casos de teste

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

Você pode aceitar n como qualquer um dos seguintes:

  • um inteiro
  • uma lista de valores verdadeiros / falsos para a representação binária
  • uma sequência para a representação binária
  • uma string de base 10 (embora eu não saiba por que alguém faria isso)

Faça seu código o mais curto possível.

0WJYxW9FMN
fonte
3
Você pode confirmar 63-> 5 e não 6? Bin (63) = 111111 -> seis
substratos
Relacionado. (Usa subsequências em vez de substrings e não desconsidera os zeros à esquerda).
Martin Ender
1
@dylnan Typo. Fixo.
0JJxW9FMN
@MartinEnder Isso é diferente o suficiente para permanecer neste site ou devo excluí-lo como duplicado? Eu acho que é suficientemente diferente, mas você sabe muito melhor do que eu.
0JJxW9FMN
@ J843136028 A maior diferença para não torná-lo uma duplicata é a restrição de tempo para o outro desafio. Você está bem. (Just postou o link, para que os desafios aparecem na barra lateral do outro.)
Martin Ender

Respostas:

7

Python 3, 54 50 bytes

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

Agradecemos a Rod e Jonathan Allan por salvar quatro bytes.

0WJYxW9FMN
fonte
Você pode mover +1do intervalo parabin(i)
Rod
1
Na verdade, uma vez que sempre contar nem si e devem sempre excluir 0da nossa contagem podemos vez sempre excluir ne sempre contar 0(Bin (n) começa '0b...'), portanto, podemos remover o 1,e +1inteiramente e licença bin(i)como é salvar quatro bytes Experimente online!
Jonathan Allan
5

Gelatina , 4 bytes

ẆQSḢ

Experimente online!

Recebe a entrada como lista de 0s e 1s.

Experimente online com números!

Explicação:

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

Prova de que funciona:

Este programa recebe um número de entrada, N . A primeira coisa que este produto faz é, é claro, pegar as substrings de N 2 ( N na base 2 ). Isso inclui substrings duplicados, começando com 0 ou 1 .

Depois disso, simplesmente pegamos as substrings exclusivas, mantendo apenas a primeira ocorrência de cada valor na lista de substring.

Então, este programa soma os primeiros elementos das listas, depois os segundos, depois o terceiro, quarto, etc. e se uma das listas não tiver esse elemento, 0será assumido. O que o desafio pede é efetivamente Quantas substrings únicas começando com 1 esse número tem em sua forma binária? . Como todo primeiro elemento a ser contado é 1, podemos simplesmente somar em vez de filtrar as substrings apropriadas.

Agora, o primeiro elemento da lista resultante do somatório descrito acima contém a contagem dos primeiros bits das substrings, então simplesmente pop e finalmente retornamos.

Erik, o Outgolfer
fonte
4

Oitava , 62 61 bytes

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

Experimente online!

Explicação

Para entrada n, o código testa todos os números de 1até npara ver se sua representação binária é uma substring da representação binária da entrada.

@(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
fonte
3

05AB1E , 5 bytes

Recebe a entrada como uma sequência binária.
O cabeçalho converte a entrada inteira em binário para facilitar o teste.

ŒCÙĀO

Experimente online!

Explicação

Œ        # push all substrings of input
 C       # convert to base-10 int
  Ù      # remove duplicates
   Ā     # truthify (convert non-zero elements to 1)
    O    # sum
Emigna
fonte
Awwhh ... eu pensei que meu filtro era inteligente. bŒʒć}Ùgmas não, isso é melhor.
Magic Octopus Urn
3

Perl 5 , 36 + 1 ( -p) = 37 bytes

/.*(.+?)(?{$k{0|$1}++})(?!)/;$_=%k-1

Experimente online!

Recebe entrada como uma sequência binária.

Xcali
fonte
2

PowerShell , 103 92 82 bytes

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

Experimente online!

Recebe a entrada como uma matriz de 1e 0(verdade e falsey no PowerShell). Faz um loop $s(ou seja, quantos elementos na matriz de entrada). Dentro do loop, fazemos o loop do número atual (salvo como $i) até $s.count. Cada loop interno, dividimos -joina matriz em uma string. Em seguida, sortcom a -ubandeira nique (que é mais curta do que selectcom a -ubandeira nique e não nos importamos se elas estão classificadas ou não), pegamos as que não começam e pegamos 0o total .count. Isso é deixado no pipeline e a produção está implícita.

AdmBorkBork
fonte
2

JavaScript (ES6), 55 bytes

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

Recebe entrada como uma sequência binária.

Aqui está uma triste tentativa de fazê-lo com números e funções recursivas:

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)

Abordagem antiga, 74 bytes

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

Também recebe entrada como uma sequência binária.

ETHproductions
fonte
1

Python 2 ,  118  81 bytes

Obrigado a @Rod por salvar 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})

Recebe entrada como uma sequência binária.

Experimente online!

Python 2 , 81 bytes

Graças a @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]})

Recebe entrada como uma sequência binária.

Experimente online!

Steadybox
fonte
Você pode aceitar uma string binária como entrada, também pode substituir set(...)por {...}e xrangecomrange
Rod
Você também pode mover o +1do intervalo para a fatia e mudar s.startswithpara o int(s,2) seguinte
Rod
1
Se você quer manter sua antiga abordagem, você também pode usar isso para o mesmo número de bytes
Rod
1

Gelatina , 5 bytes

ẆḄQṠS

Experimente online!

Recebe a entrada como uma lista de 1s e 0s. O rodapé no link aplica a função a cada um dos exemplos na postagem.

Jonathan Allan apontou que ẆḄQTLé uma alternativa de 5 bytes que usa o Tátomo que encontra os índices de todos os elementos da verdade.

Explicação

Tome bin (13) = 1101 como exemplo. Entrada é[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

Tomou a idéia "truthify" (assine neste caso) da resposta 05AB1E

dylnan
fonte
1
Você poderia realmente usar o átomo de Jelly's Truthy Indexes,, TcomẆḄQTL
Jonathan Allan
1

R , 88 bytes

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

Experimente online!

Recebe entrada como uma sequência binária.

usando mapply , gera uma matriz de todas as substrings da entrada. strtoiconverte-os como 2números inteiros base , e tomo a soma da conversão lógica ( !!) das entradas no resultado.

Giuseppe
fonte
1

Retina , 37 29 bytes

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

Experimente online!Eu apenas tive que experimentar o wmodificador do Retina 1.0 . Editar: salvou 8 bytes graças a @MartinEnder. Explicação:

.+
*

Converta de decimal para unário.

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

Converter de unário em binário, usando #para 0e_ for 1.

wp`_.*

Gere substrings que começam com 1, quero dizer _,. O wmodificador corresponde a todas as substrings, não apenas a mais longa em cada inicialização _, enquanto o pmodificador deduplica as correspondências. Finalmente, como esta é a última etapa, a contagem de correspondências é retornada implicitamente.

Neil
fonte
Você pode rolar os últimos três estágios em um usando o modificador q(ou p) além de w. Você também não precisa especificar Cexplicitamente, porque é o tipo de estágio padrão se houver apenas uma única fonte.
Martin Ender 23/01
@MartinEnder Obrigado, ainda estou acostumado a Mser o tipo de estágio padrão!
Neil
Bem, Cmeio que é o que Mcostumava ser. :)
Martin Ender
Eu sei por que é o padrão, está apenas se acostumando à mudança.
Neil
1

Pitão , 8 bytes

l #{vM.:

Experimente aqui!

Recebe entrada como uma sequência binária.

.:gera todas as substrings, vMavalia cada uma (ou seja, converte cada uma das binárias), {desduplica, <space>#filtra por identidade e lobtém o comprimento.

Mr. Xcoder
fonte
1

Wolfram Language (Mathematica) , 35 bytes

Contando subsequências únicas da representação binária que começam com uma, embora não tenha certeza de que esse código precise de uma explicação.

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

Experimente online!

Kelly Lowder
fonte
O que ___faz?
precisa saber é o seguinte
Correspondência de padrões, _ é um único item, __ é um ou mais, ___ é 0 ou mais.
precisa saber é o seguinte
0

Perl 6 , 47 bytes

->\n{+grep {n.base(2).contains(.base: 2)},1..n}

Experimente online!

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

Onde n é a entrada, b é a representação binária e l é uma lista de todas as substrings. A publicação pela primeira vez aqui, definitivamente precisa melhorar e fique à vontade para apontar quaisquer erros! Ligeiramente editado para facilitar a leitura.

Nihilish
fonte
Bem-vindo ao PPCG! No que diz respeito à inserção de novas linhas para facilitar a leitura, geralmente é preferível ter uma versão de pontuação que tenha exatamente a quantidade de bytes conforme escrita no cabeçalho e, em seguida, uma versão adicional não-jogada ou com menos golfe para facilitar a leitura.
Laikoni 22/01
@Laikoni Obrigado pelo alerta! Tenha em mente as postagens futuras!
Nihilish
String b=...,te int i=...,j,ksalvar caracteres para declarações repetidas do mesmo tipo. Seu código também não se qualificariam como uma entrada porque é um trecho, nem um programa completo nem um fragmento funcional, você tem que escrever seja uma função ou envolva o seu código na forma lambda
Unihedron
0

Anexo , 35 bytes

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

Experimente online!

Equivalentemente:

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

Explicação

Vou explicar a segunda versão, pois é mais fácil seguir (sendo explícito):

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

Entrada como String binária.
Deve haver uma maneira mais curta ..>.>

Explicação:

Experimente online.

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

Esta é uma função recursiva. Usamos a std::setpara contar valores, ignorando duplicatas. As duas chamadas recursivas mascaram os bits à esquerda ( f(n&i)) e à direita (f(n/2) ), eventualmente produzindo todas as substrings como números inteiros.

Observe que se você deseja chamá-lo novamente, sdeve ser limpo entre as chamadas.

Programa de teste

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

Resultados

./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
fonte
0

J , 15 bytes

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

Entrada é uma lista binária. Experimente online!

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

Perl 6 , 34 bytes

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

Teste-o

Expandido:

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