Tarefa
Encontre o conjunto de números de modo que a representação binária contenha duas ou mais execuções 1
separadas por pelo menos uma 0
.
Por exemplo, para os números com 4 bits:
0 0000 (no ones)
1 0001 (only one run)
2 0010 (only one run)
3 0011 (only one run)
4 0100 (only one run)
5 0101 Valid
6 0110 (only one run)
7 0111 (only one run)
8 1000 (only one run)
9 1001 Valid
10 1010 Valid
11 1011 Valid
12 1100 (only one run)
13 1101 Valid
14 1110 (only one run)
15 1111 (only one run)
Entrada
Um número inteiro fornecido ao aplicativo por meio de alguma entrada no intervalo 3 .. 32
. Isso representa o número máximo de bits a serem contados.
A entrada de n
indica que os números precisam ser examinados.0 .. 2n-1
Saída
Uma lista delimitada (à sua escolha) de todos os números que atendem aos critérios. Os números devem ser apresentados em ordem numérica. Um delimitador à direita extra é aceitável. Os gabinetes de estrutura de dados (por exemplo, []
e similares) também são aceitáveis.
Exemplo
Input: 3
Output: 5
Input: 4
Output: 5, 9, 10, 11, 13
Input: 5
Output: 5, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29
Isso é código-golfe - a resposta com a menor quantidade de bytes ganha.
\n
delimitando e colocando um\n
na última linha, o,
delimitado com um,
final também deve ser aceitável. Atualizada.[1, 2, 3]
?Respostas:
Pitão, 12 bytes
Experimente online.
Idéia
A representação binária de qualquer número positivo sempre começa com uma sequência de 1 s, possivelmente seguido por outras, alternando pistas de 0 s e 1 s. Se houver pelo menos três execuções separadas, é garantido que duas delas sejam de 1 s.
Código
fonte
Python, 48
Eu tinha pensado muito nisso. Só precisamos verificar se a expansão binária contém
'01'
.Para que haja duas execuções de uma, a da direita deve ser precedida por a
0
. Se houver apenas uma corrida, não haverá líderes0
, e isso não acontecerá.Resposta antiga:
A representação binária do Python funciona muito bem aqui. Um número binário é escrito como
bin(9)=='0b10110'
. Divisão nos'0'
resultados em uma lista de0
, entre duas consecutivas0
e à direita de qualquer final0
b
seguida por um ou mais líderes1
que não estão liderandoAs duas primeiras categorias sempre existem, mas a última só existe se houver uma execução
1
que não contenha a liderança'1'
e, portanto, somente se houver mais de uma execução1
. Portanto, basta verificar se a lista contém mais do que2
elementos distintos.O Python 3.5 salva 2 caracteres descompactando
{*_}
no lugar deset(_)
.fonte
/01/
vez de/10+1/
. Eu aproveitei isso no Perl .Ruby,
444038 caracteresriscado 44 ainda é regular 44;
Uma função anônima (proc, na verdade) que pega um número inteiro e retorna uma matriz.
Usa a regex@histocrat ressalta que, se/10+1/
: a1
, pelo menos uma0
e depois outra1
.01
houver algum lugar na string, deve haver um1
lugar antes dela.fonte
/10+1/=~'%b'%x
. Além disso, você pode salvar um personagem usando um intervalo inclusivo (0..2**n
), pois2**n
nunca haverá várias execuções.=~
. Obrigado!/01/
funciona tão bem. Se houver um01
, deve haver um 1 à esquerda em algum lugar.Julia,
4341 bytesIsso cria uma função sem nome que aceita um número inteiro e retorna uma matriz. Ele usa o truque de regex dos histocratas (usado na resposta da maçaneta da porta), onde
01
só corresponderá se houver um 1 anterior.Ungolfed:
fonte
Matlab,
79 68 6459A idéia é interpretar o número binário como matriz de zeros e uns e calcular a diferença absoluta entre cada par de vizinhos. Se tivermos duas ou mais vezes a diferença de 1, obviamente teremos uma sequência de duas ou mais. Observe que isso só funciona se representarmos o número binário sem zeros à esquerda.
Versões antigas:
fonte
JavaScript (ES7),
8985726962 bytesCaramba, criar intervalos em JS não é fácil.
Talvez fosse mais curto com umNão, eu menti; na verdade é um pouco mais. Ah bem. Acho que vou ter que me contentar com 27 bytes salvos. (7 agradecimentos a Mwr247!)for
loop real .Funciona corretamente nas versões mais recentes do Firefox, mas provavelmente não em nenhum outro navegador. Experimente:
(Trecho extraído desta página )
Sugestões são bem-vindas!
fonte
.keys()
em vez de.fill()
ea
em vez dei
amarrar meu para 62:x=>[for(a of Array(1<<x).keys())if(/01/.test(a.toString(2)))a]
Haskell,
686153 bytesMelhoria de Damien
História:
Isso corrige o erro (Comutado == e = e quadrado em vez da potência de dois). E substitua true por 2> 1 e false por 1> 2. Também graças a salientar que 2 ^ x sempre falha. Obrigado a Thomas Kwa e nimi
Originalmente
Se tiver que ser programa completo,
fonte
1..(2^x-1)
que pode ser1.. (2^x)
porque 2 ^ x sempre falha.False
eTrue
com1>2
e1<2
. Não há necessidade de parênteses2^x-1
. (BTW: você tem um erro de digitação: deve ser4==1=True
).mod
4 == 1 = x> 4 | 2> 1 = g $ xdiv
2APL,
3427 bytesIsso cria uma função monádica sem nome que aceita um número inteiro à direita e retorna uma matriz.
Explicação:
Economizou 7 bytes graças a Dennis!
fonte
R,
5547 bytes(com alguma ajuda de @ Alex.A)
R não possui uma função integrada para exibir números convertidos de uma maneira conveniente, então estou usando
R.utils::intToBin
isso, enquanto todo o resto é basicamente apenas relatar o local da expressão de expressão regular correspondente e imprimir em STDOUT enquanto separado por um espaço.fonte
cat
é um espaço, então você pode omitir,sep=","
completamente, economizando 7 bytes.CJam, 14
3 bytes mais curtos, graças a Dennis. Experimente online
fonte
2be`,2>
.2be`2>
e2,#)
deve funcionar também. Além disso, o OP esclareceu que a saída pode ser impressa em forma de lista.JavaScript (ES6),
69686762 bytesHoje, descobri uma nova maneira mais curta de preencher matrizes dinamicamente sem o uso de preenchimento ou mapa. Doing
x=>[...Array(x).keys()]
retornará uma matriz do intervalo de 0 a x. Se você deseja definir seu próprio intervalo / valores, usex=>[...Array(x)].map((a,i)=>i)
, pois são apenas mais alguns bytes.fonte
Java,
214165155154 154148141110 bytesEsta submissão explora o fato de que uma representação de cadeia binária de um número em Java nunca possui um zero inicial. Se a cadeia "01" aparecer na representação binária de um número, isso deve marcar a segunda ocorrência do número "1".
Golfe:
Ungolfed:
Saída do programa (lembre-se, delimitadores à direita são aceitáveis):
fonte
int
para a variável do contador?long
é necessário um de 64 bits . Além disso, usando umint
seria realmente aumentar o tamanho do código devido à referência aInteger
classe wrapper que faz a análise de número. Penso que o lugar provável para economizar espaço seria a regex, mas meu teste mostrou que eu tenho que ter esquerda e à direita.*
Long
invólucroint
? (Bem não neste caso, mas geralmente?)int
será promovido paralong
quando usado como parâmetro comLong
. Neste caso, embora não exista realmente nenhuma maneira de usar umint
por causa do bit de sinal eInteger
seja maior queLong
. Ainda assim, encontrei algumas maneiras de extrair espaço extra de uma linguagem tão detalhada quanto o Java.new Long()
vez deLong.parseLong()
?C (gcc) ,
11199 bytesExperimente online!
12 bytes raspados de graças a @ceilingcat!
Ungolfed:
A função ffsl () fornece o índice do primeiro bit definido em um número inteiro longo. Então, passamos de
i = 1
2 ^ number_of_bits. Definimos o deslocamentox
para ai
direita até removermos todos os zero bits consecutivos na extremidade menos significativa. Então, mudamos para ax
direita até removermos todos os 1 bits consecutivos no final menos significativo. Se o resultado ainda for diferente de zero, encontramos uma correspondência.fonte
if (popcount(i ^ (i*2))>3)
e expandir popcount () para uma série de ANDs bit a bit e operações de deslocamento. Mas isso resultaria em um código bastante longo.JavaScript (ES6) 76
fonte
,,,,,5,,,,9,10,11,,13,,,,17,18,19,20,21,22,23,,25,26,27,,29,,
K5, 19 bytes
Isso opera de acordo com princípios semelhantes aos da solução de Dennis, mas com menos recursos internos para aproveitar.
Primeiro, gere uma série de tuplas x binárias (
+!x#2
) e, em seguida, para cada tupla, encontre todos os pontos em que um dígito não corresponde ao anterior, se tratarmos o -1º elemento da lista como 0 para essa finalidade (~0=':'
). Nossas soluções são onde duas é menor que a soma de cada contagem de execução. (&2<+/'
)Mostrar cada etapa intermediária é mais claro:
E todos juntos:
fonte
Pip, 13 + 1 = 14 bytes
Pega a entrada da linha de comando e usa o
-s
sinalizador para espaços entre os números de saída.Bem direto: crie
range(2**a)
e filtrelambda _: "01" in toBinary(_)
. Fiquei muito feliz em pensar na01
ideia de forma independente. Não são necessárias aspas01
porque ele digitaliza como um literal numérico (números e seqüências de caracteres são do mesmo tipo no Pip).fonte
Julia, 40 bytes
Isso usa uma abordagem um pouco diferente da outra solução Julia - em vez de fazer uma pesquisa por "01" na cadeia de bits, usa alguma matemática para determinar se o número satisfaz a condição.
i$i>>1
terá somente nos locais onde o dígito muda de zero para um ou de um para zero. Como tal, deve haver pelo menos três parai
alternar entre zero e uma vez o suficiente.count_ones
localiza o número de unidades efilter
remove as que não têm número suficiente.fonte
C ++,
197188141 bytesNota: isso foi escrito e testado usando o MSVC ++ 2013. Parece que o
#include
ing<iostream>
inclui todos os cabeçalhos C necessários para fazer esse trabalho. Parece também que o código não é mais verdadeiramente C ++, mas a compilação usando C ++ permite esse truque de cabeçalho que reduz o tamanho do código em comparação com a inclusão de vários cabeçalhos em C.Usar em
printf
vez decout
também salva alguns bytes.Golfe:
Ungolfed:
fonte
'\n'
vez de std :: endl (em geral), ou','
como qualquer separador é válido e um separador à direita é bom.strstr(c,"01")
.1<<atol(b[1])
devem ser1L<<atol(b[1])
, caso contrário, o resultado dessa expressão será um inteiro assinado de 32 bits, o que significa que o código será executado apenas até 2 ^ 30. O printf deve ser usado%ld
para imprimir números entre 2 ^ 31 e 2 ^ 32 corretamente.Perl 5,
5553494741 bytes5452484640 bytes, mais um para o-E
sinalizador em vez de-e
.Obrigado ao xnor pela dica sobre o uso do
/01/
invés de/10+1/
, que salvou dois bytes.Agradecemos a Dennis pelo conselho de usar, em
<>
vez de$ARGV[0]
, que salvou seis bytes.fonte
C,
8481 bytesIsso se baseia nos comentários que fiz em outra resposta C a esta pergunta sobre a possibilidade de usar operadores bit a bit simples. Ele funciona alternando todos os 0 bits à direita para 1 na instrução i | (i-1). Em seguida, alterna todos os 1 bits finais para 0 usando k & (k + 1). Isso resultará em zero se houver apenas uma execução de unidades e diferente de zero. Eu suponho que o comprimento seja de 64 bits, mas poderia corrigir isso às custas de três bytes usando int64_t.
Ungolfed
fonte
int64_t
é definido apenas se você#include<stdint.h>
. garantir a operação de 64 bits requer umlong long
tipo a um custo de 5 bytes.long i
para o%d
formato. Observe também que()
são supérfluos para os operadores&
e|
. Corrigir isso economiza 3 bytes!long i,j,k;main(){for(scanf("%ld",&j);++i<1L<<j;k&k+1&&printf("%ld ",i))k=i|i-1;}
Pitão,
201716 bytesDemonstração ao vivo.
fonte
"01"
. Exceto por 0, o repr binário. sempre começará com um 1.Python 2.7, 89 bytes
Eu acho que isso poderia ser um pouco de golfe.
fonte
0
na saída.print[i for i in range(2**input())if[n[:1]for n in bin(i)[2:].split("0")].count("1")-1]
é dois bytes mais curto. Mas com a correção0
seria o mesmo comprimento (89), se você usarrange(1,2**input())
.TI-BASIC,
343230 bytesPara uma calculadora da série TI-83 + / 84 +.
Para que um número contenha duas execuções de 1s, ele deve conter duas
10
s quando colocamos um zero à direita na representação binária.Em vez de gerar a representação binária e verificar a
10
, testamos pares de bits matematicamente usando o restante por 4 (int(4fPart(
), que fornecerá2
onde existe a10
. Porque nós não nos importamos com ordem,randIntNoRep(
é o maneira mais curta de gerar a lista de expoentes.Usamos
log(
para verificar o número de execuções:Se houver pelo menos 2 execuções, então
log(
é positivo e o número é exibido.Se houver uma execução, então
log(
será 0 e o número não será exibido.Se não houver execuções (o que acontece primeiro em X = 2 ^ Ans),
log(
lança um ERR: DOMAIN, parando a saída exatamente no ponto certo.Usamos
e^(Ans
como argumento final doFor(
loop - é sempre maior que2^Ans
, mase^(
é um único token, portanto, é um byte menor.Entrada / saída para N = 4:
Então a calculadora lança um erro; a tela de erro fica assim:
Quando 1 é pressionado, a tela inicial é exibida novamente:
As calculadoras da TI armazenam todos os números em um flutuador BCD com 14 dígitos de precisão, não um flutuador int ou binário. Portanto, divisões por potências de dois maiores que
2^14
podem não ser exatas. Embora tenha verificado que os números mais complicados3*2^30-1
e2^32-1
manipulados corretamente, não descartei a possibilidade de erros de arredondamento. No entanto, ficaria surpreso se houvesse erros para qualquer entrada.fonte
Matlab
(90)(70)execução
4
ans =
ans =
ans =
princípio
Qualquer número retirado do intervalo] f (n, l), f (n, l) + 2 ^ (l-1) [onde l> 1 verifica essa condição, portanto o resultado é resultado da negação desta série em termos de n.
x = 1
x = x + 1 =
01
,x = x + 2 ^ 0 =
11
,x = x + 1 =
001
,x = x + 2 ^ 1 =
011
,x = x + 2 ^ 0 =
111
,x = x + 1 =
0001
,x = x + 2 ^ 2 =
0011
,x = x + 2 ^ 1 =
0111
,x = x + 2 ^ 0 =
0111
,x = x + 1 =
1111
...Qual é o valor de x na equação x + 2 ^ x = 0?
Meu programa imprime o intervalo entre cada duas linhas (se existir)
depois de um período de luta, consegui encontrar uma representação matemática para esta série que é:
2 ^ l (0 + 1 + 2 ^ 1 + ... 2 ^ k) com l + k <n
= 2 ^ l (2 ^ k-1)
score = 90
fonte
C,
103102 bytesExpandindo (realmente contraindo) na entrada G.Sliepen, aproveitando a observação xnor sobre o
01
padrão na representação binária, mas usando apenas funções padrão e algumas correções.Versão não destruída:
O loop interno verifica
i
o padrão binário01
deslocando iterativamentex
para a direita, desde que tenha 3 bits restantes.printf
retorna o número de caracteres impressos; portanto, nunca0
, portanto, o teste do loop interno falha após oprintf
, evitando a necessidade de umabreak
declaração.C ++,
129128 bytesAdaptando a mesma idéia, a variante C ++ está aqui:
Tecnicamente, devo garantir
i
umalong long
operação de 64 bits e calcular até2^32
5 bytes extras, mas as plataformas modernas têm ints de 64 bits.fonte
JavaScript ES6, 60 bytes
Código
Experimente online!
Explicação
fonte
C (tipo de - compila com avisos no GCC) - 103
Isso não usa funções de biblioteca de qualquer tipo, exceto printf. Você pode ver, olhando para isso, que nenhum esforço foi poupado para torná-lo compatível com os padrões ou evitar UB.
Para torná-lo compatível, você precisará fazer várias coisas, incluindo stdio.h, o que seria contrário ao espírito de torná-lo o menor possível.
Se alguém tiver sugestões para torná-lo mais curto, entre em contato.
fonte
PowerShell, 80 bytes
fonte
Python, 44 bytes
Ok, isso provavelmente poderia ser mais curto, mas é o meu primeiro codegolf:
Pense que isso responde à pergunta, por favor, não vote abaixo se não, basta postar o que há de errado com isso abaixo.
fonte
input()
é o ideal) para obtern
e, em seguida, contar apenas2^n-1
, em vez de fazer um loop indefinidamente. Além disso, você pode usar 1 e 2 espaços para o aninhamento, em vez de 4 e 8, e usarmap
ou uma compreensão de lista provavelmente reduziria tremendamente o seu código.outra resposta diferente do matlab de boa pontuação.
Matlab
60(57)execução
ans =
>> ans(5)
ans =
1
exemplo:
0000111
é rejeitado porque ~ x =1111
, ~ x + 1 =00001
contém um dígito = 10100111
é aceito porque ~ x =1011
, ~ x + 1 =0111
contém muitos 1'sfonte