Mancha de broca alternada


12

Introdução

Esse desafio exige que você defina os zeros à direita de uma representação binária de números inteiros 010101…, isso é melhor explicado com um exemplo:

Dado o número inteiro 400, o primeiro passo é convertê-lo em binário:

110010000

Como podemos ver, o quinto bit é o menos significativo 1; portanto, a partir daí, substituímos os zeros inferiores por 0101:

110010101

Finalmente, convertemos isso de volta para decimal: 405

Desafio

Dado um retorno / saída inteiro positivo, o valor resultante correspondente do processo acima definido.

Regras

  • Essa sequência é definida apenas para números inteiros com pelo menos um 1bit, portanto a entrada sempre será ≥ 1
  • Você pode usar a entrada como uma sequência de caracteres, lista de dígitos (decimal)
  • Você não precisa lidar com entradas inválidas

Casos de teste

Aqui estão mais alguns casos de teste com as etapas intermediárias (você não precisa imprimi-las / devolvê-las):

In -> … -> … -> Out
1 -> 1 -> 1 -> 1
2 -> 10 -> 10 -> 2
3 -> 11 -> 11 -> 3
4 -> 100 -> 101 -> 5
24 -> 11000 -> 11010 -> 26
29 -> 11101 -> 11101 -> 29
32 -> 100000 -> 101010 -> 42
192 -> 11000000 -> 11010101 -> 213
400 -> 110010000 -> 110010101 -> 405
298 -> 100101010 -> 100101010 -> 298

Podemos assumir um número inteiro de 32 bits?
Arnauld

@Arnauld: Claro!
ბიმო

9
Alguma idéia de golfe: Se né a potência máxima de 2 que divide a entrada, a resposta é simplesmente #(input) + ceil((2^n - 2)/3)
JungHwan Min

Respostas:


12

Python 3 , 20 bytes

lambda n:(n&-n)//3+n

Experimente online!

Explicação

Tome 192como exemplo. Sua forma binária é 11000000e precisamos convertê-la para 11010101.

Observamos que precisamos adicionar 10101ao número. Esta é uma série geométrica ( 4^0 + 4^1 + 4^2), que tem uma forma fechada como (4^3-1)/(4-1). É o mesmo que 4^3//3onde //denota divisão inteira.

Se fosse 101010, ainda seria uma série geométrica ( 2×4^0 + 2×4^1 + 2×4^2), 2×4^3//3pelas razões acima.

Enfim, 4^3e 2×4^3seria apenas o bit menos significativo que obtemos por n&-n:

Percebemos que o complemento de né 00111111. Se adicionarmos um, ele se tornará 01000000e só se sobrepõe n=11000000ao dígito menos significativo. Observe que "complementar e adicionar um" é apenas negação.


6
@ Mr.Xcoder bom desportivismo
Leaky Nun

1
Possivelmente lambda n:(n&-n)//3+nfunciona também? Passa em todos os casos de teste de amostra , mas, de acordo com minha intuição, não deve ser válido, certo?
Sr. Xcoder

@ Mr.Xcoder é realmente válido.
Leaky Nun

1
Por que não usar o Python 2 para salvar um byte? TIO
FlipTack

4
@FlipTack Eu odeio python 2
Leaky Nun

8

Gelatina , 5 bytes

&N:3+

Experimente online!

Desta vez, um porto da abordagem de Leaky Nun (pelo menos eu o ajudei a jogar um pouco: P)

Geléia , 7 bytes

^N+4:6ạ

Experimente online!

Utiliza a abordagem fantástica de JungHwan Min , com a ajuda indireta de Martin Ender .


Dennis postou e excluiu uma solução de 5 bytes muito semelhante logo após a edição. Algo como &N:3|. Parabéns; você venceu o Dennis na geléia! (Mas não completamente fora-golfed.)
wizzwizz4

@ wizzwizz4 Eu realmente não fiz muito, além de sugerir um pequeno golfe para a abordagem de Leaky e depois transportá-lo. Mas eh :-)
Mr. Xcoder

Esta é a primeira resposta Jelly somente em ASCII que eu já vi.
MD XF

6

Wolfram Language (Mathematica) , 36 28 26 24 bytes

-8 bytes graças a @MartinEnder e -2 bytes graças a @ Mr.Xcoder

#+⌊(#~BitAnd~-#)/3⌋&

Experimente online!

Precisamos apenas encontrar o número de zeros à direita na entrada e encontrar o número com 0s e s alternados 1com comprimento um menor que isso e adicioná-lo à entrada.

Então, 400 -> 11001000 -> 110010000 + 0000 -> 110010101 + 101 -> 405

A fórmula explícita para o nnúmero com 1s e s alternados 0foi dada em A000975 no OEIS. Podemos usar o nnúmero th, já que dois números diferentes não podem ter o mesmo comprimento em binário e ter dígitos alternados.


1
2^#~IntegerExponent~2é(BitXor[#,#-1]+1)/2
Martin Ender

@MartinEnder wow! E então eu posso apenas combinar as frações para reduzir mais bytes #
307 JungHwan Min

1
24 bytes . Você pode usar em seu #+⌊(#~BitAnd~-#)/3⌋&lugar.
Sr. Xcoder

@ Mr.Xcoder editou :) #
11136 JungHwan Min

5

J , 19 18 bytes

+(2|-.i.@#.-.)&.#:

Experimente online!

Explicação Rápida

Esta é uma resposta antiga, mas é muito semelhante à atual, mas conta os zeros à direita de maneira diferente. Veja os comentários para um link explicando como funciona.

+(2|i.@i.&1@|.)&.#:
                 #:  Convert to binary list
       i.&1@|.       Index of last 1 from right
            |.         Reverse
       i.&1            Index of first 1
    i.               Range [0, index of last 1 from right)
  2|                 That range mod 2
               &.    Convert back to decimal number
+                    Add to the input

Outras respostas:

Resposta anterior (19 bytes).

+(2|i.@i.&1@|.)&.#:

Mais do que deveria, porque \vai da direita para a esquerda.

+(2|#*-.#.-.)\&.(|.@#:)

1
18 bytes+(2|-.i.@#.-.)&.#:
milhas

@miles mente explicando o que está acontecendo com a conversão de base lá? Acho que tem algo a ver com os zeros, mas não tenho certeza.
cole

#.~ conta o número de verdades finais , então o que precisamos é #.~ -. #:contar o número de zeros finais
milhas

@miles Ah! Isso é muito, muito inteligente.
cole

4

Julia 0,6 , 12 bytes

!n=n|n&-n÷3

Experimente online!


Parece um método eficiente. Você pode explicar a precedência do operador? Por exemplo, não sei dizer se foi avaliado como ((!n=(n|n))&-n)/3, ou !n=(((n|n)&(-n))/3)etc.
MD XF -

Em Julia, os operadores bit a bit têm as mesmas precedências que suas contrapartes aritméticas, assim |é +e &é como *. Portanto, n|n&-n÷3é analisado como n | ((n&-n) ÷3).
Dennis

3

JavaScript (ES6), 40 39 bytes

Recebe a entrada como um número inteiro de 32 bits.

n=>n|((n&=-n)&(m=0xAAAAAAAA)?m:m/2)&--n

Casos de teste


2

05AB1E , 13 8 5 bytes

Economizou 5 bytes graças à fórmula pura do Sr. Xcoder e JungHwan Min
Economizou outros 3 graças ao Sr. Xcoder

(&3÷+

Experimente online!

Explicação

(      # negate input
 &     # AND with input
  3÷   # integer divide by 3
    +  # add to input

1
Talvez valha a pena mencionar que a portabilidade da resposta do Mathematica fornece 8 bytes
Mr. Xcoder

@ Mr.Xcoder: Ooh, essa é uma fórmula interessante.
Emigna

1
05ab1e tem AND bit a bit? Nesse caso, (<bitwise and here>3÷+deve funcionar para ~ 5 bytes.
Sr. Xcoder

2

R , 71 58 bytes

graças ao NofP por -6 bytes

function(n){n=n%/%(x=2^(0:31))%%2
n[!cumsum(n)]=1:0
n%*%x}

Experimente online!

Assume que a entrada é um número inteiro de 32 bits. R só assinou números inteiros de 32 bits (convertidos para doublequando um número inteiro excede) de qualquer maneira e nenhuma entrada de 64 bits ou não assinada.


Você pode converter o which.max(n):1-1que !cumsum(n)para obter uma solução de 65 bytes
NofP

@NofP thanks! Essa é uma ótima ideia.
21717 Giuseppe

2

brainfuck , 120 bytes

>+<[[>-]++>[[>]>]<[>+>]<[<]>-]>[-<+>[-<[<]<]>]>[>]<[>+<[->+<]<[->+<]<]>>[<]+>[-[-<[->+<<+>]>[-<+>]]<[->++<]<[->+<]>>>]<<

Experimente Online!

Inicia com o valor na célula atual e termina na célula com o valor de saída. Obviamente, não funcionará em números acima de 255, já que esse é o limite de células para um típico ataque cerebral, mas funcionará se você assumir um tamanho infinito de células.


1

PowerShell , 168 bytes

param($n)$a=($c=[convert])::ToString($n,2);if(($x=[regex]::Match($a,'0+$').index)-gt0){$c::ToInt32(-join($a[0..($x-1)]+($a[$x..$a.length]|%{(0,1)[$i++%2]})),2)}else{$n}

Experimente online!

Ai. A conversão de / para fatias binárias e de array não é realmente o ponto forte do PowerShell.

Recebe a entrada $ncomo um número. Nós imediatamente convertque a base binária 2e armazenar isso em $a. Em seguida, temos uma construção if / else. A cláusula if testa se um regex Matchcontra 1 ou mais 0s no final da string ( '0+$') tem indexum local maior que 0(isto é, o início da string binária). Se isso acontecer, temos algo para trabalhar, elseapenas fornecemos o número.

Dentro do if, dividimos os xprimeiros dígitos e os concatenamos +com os dígitos restantes. No entanto, para os dígitos restantes, passamos por eles e selecionamos um 0ou 1a ser produzido, usando $i++%2para escolher. Isso nos dá o 010101...padrão em vez de 0s no final. Nós, então -join, $cvoltamos a formar uma string e a revertemos para uma Int32base 2.

Em qualquer das situações, o número é deixado no pipeline e a saída é implícita.


1

APL + WIN, 43 bytes

p←+/^\⌽~n←((⌊1+2⍟n)⍴2)⊤n←⎕⋄2⊥((-p)↓n),p⍴0 1

Solicita entrada de tela









1

JavaScript ES6, 13 bytes

n=>(n&-n)/3|n

f = 
n=>(n&-n)/3|n
;
console.log (f(8));
console.log (f(243));
console.log (f(1048576));
console.log (f(33554432));




0

Gelatina , 13 bytes

BŒgṪµ2Ḷṁ×CḄ+³

Experimente online!

Explicação

Tome 24 como exemplo de entrada.

BŒgṪµ2Ḷṁ×CḄ+³
B                Binary representation of the input → 11000
 Œg              Group runs of equal length → [[1,1],[0,0,0]]
   Ṫ             Tail → [0,0,0]
    µ            New monadic link
     2Ḷ          [0,1] constant
       ṁ         Mold [0,1] to the shape of [0,0,0] → [0,1,0]
        ×        Multiply [0,1,0] by...
         C       1-[0,0,0]. If last bit(s) of the original input are 1 this will add nothing to the original input
          Ḅ      Convert to decimal from binary → 2
           +³    Add this with the original input → 26
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.