Objetivo
Dado um número inteiro não negativo, crie uma função que retorne a posição inicial do número dos maiores 1s consecutivos no valor binário desse número.
Quando receber uma entrada 0
, retorne 0
.
Se o número tiver várias faixas de igual comprimento, você deverá retornar a posição da última faixa.
Entrada
Um número inteiro maior ou igual a 0.
Saída
Um número inteiro calculado como explicado abaixo.
Regras
- Isso é código-golfe, então o código mais curto em bytes em cada idioma vence.
- As brechas padrão são proibidas.
Exemplos e casos de teste
Exemplo 1
- Sua função passa o número inteiro 142
- 142 é igual a 10001110 em binário
- A sequência mais longa é "111" (uma sequência de três)
- A sequência começa na posição 2 ^ 1
- Sua função retorna 1 como resultado
Exemplo 2
- Sua função passa o número inteiro 48
- 48 é igual a 110000 em binário
- A sequência mais longa é "11" (uma sequência de duas)
- A sequência começa na posição 2 ^ 4
- Sua função retorna 4 como resultado
Exemplo 3
- Sua função é passada o número inteiro 750
- 750 é igual a 1011101110 em binário
- A sequência mais longa é "111" (uma sequência de três)
- Como existem duas faixas de igual comprimento, retornamos a sequência posterior.
- A sequência posterior começa na posição 2 ^ 5
- Sua função retorna 5 como resultado
0
. Esse é um caso de teste importante.Respostas:
Geléia ,
108 bytesExperimente online!
Como funciona
fonte
JavaScript (ES6),
41403634 bytesGuardado 4 bytes graças a @ThePirateBay
Casos de teste
Mostrar snippet de código
Quão?
Caso geral x> 0
Recursivamente, E a entrada x com x / 2, que reduz progressivamente os padrões de bits consecutivos, até que apenas o bit mais à direita da sequência permaneça. Mantemos uma cópia do último valor diferente de zero e determinamos a posição do seu bit mais significativo arredondando seu logaritmo de base 2 para o piso.
Abaixo estão as etapas que realizamos para x = 750 ( 1011101110 em binário).
Caixa de borda x = 0
O caso especial
x = 0
leva imediatamente aMath.log2(0) | 0
. O logaritmo de0
avalia para-Infinity
e o OR binário bit a bit força uma coerção a um número inteiro de 32 bits. Em conformidade com a especificação da operação abstrata ToInt32 , isso fornece o esperado0
:fonte
0
, que faz parte do intervalo de entrada.Math.log2(k)|0
vez de31-Math.clz32(k)
? Ou eu estou esquecendo de alguma coisa?Math.log2(k)|0
é realmente mais curto e mais simples para o caso especialx=0
. Obrigado. :)código de máquina x86, 14 bytes
Usar o algoritmo de @ Arnauld
x &= x>>1
e tomar a posição de bit mais alta da etapa anteriorx
se torna0
.É possível chamar de C / C ++ com assinatura
unsigned longest_set(unsigned edi);
no ABI x System- x86-64. Os mesmos bytes de código de máquina decodificarão da mesma maneira no modo de 32 bits, mas as convenções de chamada padrão de 32 bits não colocam o primeiro argumentoedi
. (Alterar o registro de entrada paraecx
ouedx
para Windows_fastcall
/_vectorcall
ougcc -mregparm
pode ser feito sem quebrar nada.)As
BSR
instruções do x86 (Bit Scan Reverse) são perfeitas para isso, fornecendo o índice de bits diretamente, em vez de contar zeros à esquerda. (bsr
não produz 0 diretamente para a entrada = 0 como32-lzcnt(x)
faria, mas precisamos de bsr = 31-lzcnt para entradas diferentes de zero, portantolzcnt
que nem salve as instruções, muito menos a contagem de bytes. Zerar o eax antes que o loop funcione devido absr
' s comportamento semioficial de deixar o destino inalterado quando a entrada é zero.)Isso seria ainda mais curto se pudéssemos retornar a posição MSB da execução mais longa. Nesse caso,
lea ecx, [rdi+rdi]
(3 bytes) copiaria + shift para a esquerda em vez demov
+shr
(4 bytes).Vejo este link TIO para um chamador asm que não
exit(longest_set(argc-1));
Testando com um loop de shell:
fonte
Geléia ,
191711 bytesExperimente online!
-6 (!) Bytes graças às fortes observações de @ Dennis
Como funciona
fonte
0
, que estão no intervalo de entrada.ȯ-µ...
B
sempre retorna uma matriz que começa com 1 ,BUṪMṪ’×Ṡ
pode se tornarṪBL’
. Além disso, você não precisa doḞ
eḟ0
salva um byte¹Ðf
.Python 2 , 45 bytes
Experimente online!
Economizou muitos bytes graças a Dennis! (Os heads-up em
len(bin(...))-3
vez demath.frexp
)Agradecemos ao @xnor por encontrar um bug, que felizmente era facilmente corrigível!
fonte
x=3
, acho que porque oand/or
errado curto-circuito quando a função retorna 0.Perl 6 ,
4535 bytesEsta versão altamente aprimorada é cortesia de @nwellnhof.
Experimente online!
fonte
:g
para obter todas as correspondências. Com o operador smart-match, eu poderia jogar até 40 bytes:{sort(.base(2).flip~~m:g/1+/).tail.from}
{.msb+1-(.base(2)~~m:g/1+/).max.to}
:g
e não descobri como posso usar o advérbio com o operador smartmatch. Além disso, o.msb
método é bastante útil aqui e eu não sabia disso antes.Python 2 ,
8978 bytesExperimente online!
EDIT: Economizou 11 bytes graças ao Sr. Xcoder.
fonte
05AB1E ,
141211 bytesExperimente online! ou execute casos de teste .
Explicação
fonte
J ,
1817 bytesExperimente online!
Explicação
fonte
x
díade são todas 0 e 1, o que isso significa? Um número base 2 possui dígitos0
e1
, portanto, um1
número base possui dígitos ...0
? então o que1
significa nesse contexto? E é sempre um0
número base0
?x #. y
primeiro calcula ew =: */\. }. x , 1
depois retorna+/ w * y
#.
, já que você conta com detalhes de implementação internos e não com a API pública?C # (.NET Core) ,
6460 bytesExperimente online!
Versão do CA # de da resposta @ Arnauld
Agradecimentos
4 bytes salvos graças a Kevin Cruijssen.
C # (.NET Core) ,
131123 + 18 = 141 bytesExperimente online!
+18 bytes para
using System.Linq;
Agradecimentos
8 bytes salvos graças a Grzegorz Puławski.
Degolfed
C # (.NET Core) ,
164161 bytesExperimente online!
Um não
Linq
solução, que tenho certeza de que poderia ser melhorada, embora nada seja imediatamente aparente.Degolfed
fonte
r
na primeira resposta: tio.run/##dY9RS8MwFIWfza/...T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Casca , 12 bytes
Experimente online!
Explicação
fonte
Geléia ,
14 13 1211 bytesUm link monádico que recebe e retorna números inteiros não negativos.
Experimente online! ou veja a suíte de testes .
Quão?
fonte
ŒrṪP
nos prefixos.Geléia , 19 bytes
Experimente online!
Obrigado a Jonathan Allan por salvar
46 bytes!Eu trabalhei muito para simplesmente abandonar isso, embora seja um pouco longo. Eu realmente queria adicionar uma solução que procure literalmente a substring mais longa do
1
s na representação binária ...Explicação
fonte
BŒgḄṀB
em vezBwÇɓÇL+ɓBL_‘
Kotlin , 77 bytes
Embelezado
Teste
fonte
Haskell ,
101989675 bytesExperimente online! Uso:
snd.maximum.(`zip`[0..]).c $ 142
rendimentos1
.Explicação:
c
converte a entrada em binário e, ao mesmo tempo, conta o comprimento das faixas de uma, coletando os resultados em uma lista.r<-c$div n 2
recursivamente calcula o restanter
desta lista, enquantosum[r!!0+1|mod n 2>0]:r
adiciona o comprimento atual da sequência ar
. A compreensão da lista verifica semod n 2>0
, ou seja, se o dígito binário atual é um e, nesse caso, pega o comprimento da sequência anterior (o primeiro elemento der
) e adiciona uma. Caso contrário, a compreensão da lista estará vazia esum[]
renderá0
. Para a entrada de exemplo,c 142
gera a lista[0,3,2,1,0,0,0,1,0]
.(`zip`[0..])
adiciona a posição a cada elemento da lista anterior como o segundo componente de uma tupla. Para o exemplo que isso dá[(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)]
.maximum
encontra a tupla lexicograficamente máxima nesta lista, ou seja, os comprimentos das faixas são considerados primeiro como o primeiro componente e, no caso de um empate, o segundo componente, ou seja, o índice maior, decide. Isso gera(3,1)
no exemplo esnd
retorna o segundo componente da tupla.fonte
Python 2 ou 3 , 58 bytes
Experimente online!
fonte
C (gcc) ,
8180 bytesExperimente online!
C (gcc) , 43 bytes
Versão CA da resposta de @ Arnauld
Experimente online!
fonte
n<1?0:log2(n)
vez de(k=log2(n))<0?0:k
MS SQL Server,
437426407398 bytesSQL Fiddle
Tenho certeza de que poderia remover quebras de linha, etc., mas isso é tão compacto quanto eu queria:
Aqui está uma versão mais legível:
O verdadeiro truque é que, até onde pude encontrar, não há funcionalidade SQL nativa para converter um número de decimal em binário. Como resultado, tive que codificar a conversão para binário manualmente, para poder compará-la como uma sequência, um caractere de cada vez, até encontrar o número certo.
Tenho certeza de que há uma maneira melhor de fazer isso, mas não vi uma resposta (n) SQL, então achei que a lançaria lá.
fonte
APL (Dyalog Unicode) , 22 caracteres = 53 bytes
Requer
⎕IO←0
qual é o padrão em muitos sistemas.Experimente online!
⎕
solicitação de entrada⊢
rendimento que (separa¯1
de⎕
)2⊥⍣¯1
converter para base-2, usando quantas posições forem necessáriasb←
armazenar comob
(para b inary)⌽
marcha ré(
…)
Marque as posições iniciais do seguinte:⊆⍨b
partição automáticab
(ou seja, as 1 faixas deb
)↑
mix (faça a lista de listas em matriz, preenchendo com zeros)∨⌿
redução OR vertical (produz a maior sequência)⍸
índices de posições iniciais⌽
marcha ré⊃
escolha o primeiro (produz zero se não houver nenhum disponível)fonte
MATL , 15 bytes
Experimente online!
Usa a metade e a idéia AND. A
k
só é necessário para torná-lo terminar de1
- por algum motivo, 1 e 0,5 devolve 1, fazendo com que num ciclo infinito.(solução alternativa:
BtnwY'tYswb*&X>)-
convertendo para codificação binária e de duração)fonte
Planilhas Google, 94 bytes
Não, não é muito bonito. Seria muito bom poder armazenar
Dec2Bin(A1)
como uma variável para referência.Ponto principal: como o Excel, a
Dec2Bin
função tem um valor máximo de entrada de511
. Qualquer coisa maior que isso retorna um erro, como mostrado abaixo.fonte
R, 117 bytes
fonte
rev
, useReduce(...,T,T)
para acumular da direita (alternandox,y
na definição da função). Em seguida, use,1+max(z)-which.max(z)
pois o resultado é um pouco diferente. Use em"if"
vez de"ifelse"
já que não precisamos da vetorização; aae se você usar emany(z)
vez de!sum(z)
soltar um byte.Excel VBA,
5444 bytes-10 Bytes graças a @EngineerToast
Função de janela imediata VBE anônima que leva a entrada do intervalo
[A1]
e sai para a janela imediata VBEfonte
C1
ainda estar lá, em vez deA1
, acho que você pode gerar osInstr
resultados diretamente com um pouco de distorção para a correção da entrada zero:?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0)
(46 bytes). Verdadeiro = -1 porque ... VBA.>0
na[A1]
notaçãoAPL (Dyalog Classic) ,
2421 bytesExperimente online!
fonte
Pitão , 17 bytes
Esta é uma função recursiva. O link inclui
y
para chamar a função na entrada fornecida.Verifique todos os casos de teste.
Pitão , 20 bytes
Verifique todos os casos de teste.
fonte
R, 66 bytes
Explicação:
fonte
a$l
vez dea[[1]]
e ema$v
vez dea[[2]]
salvar alguns bytes :), bem como em>0
vez de==1
.Python 2 , 41 bytes
Experimente online!
Baseado nesta solução pelo Sr. Xcoder .
fonte
Javascript, 54 caracteres
i.toString(2)
obtém a sequência binária do número inteiro..split(0)
obtém cada parte sequencial em um elemento da matriz..sort().reverse()
nos dá o maior valor como primeiro.[0].length
nos dá a duração desse primeiro valor.fonte
the starting position of number of largest consecutive 1's
Perl 5, 45 + 1 (-p)
Se você escrever isso na linha de comando da maioria dos shells, talvez seja necessário digitar isso como:
A dança das aspas no final é apenas para obter perl see a
'
, que de outra forma seria consumido pela casca.fonte
Retina ,
5243 bytesConverta em binário e substitua pelo comprimento da sequência maior de unidades.
Experimente online - todos os casos de teste
Economizou 9 bytes graças a Martin.
fonte
$+
para${1}
. Mas você pode economizar ainda mais substituindo a última etapa com um monte de estágios como este: tio.run/##K0otycxL/K/...${1}
foi copiado do seu tutorial no Github.