Limpando o bit mais significativo de um número inteiro

29

Entrada

A entrada é um número inteiro positivo único n

Saída

A saída está ncom o bit mais significativo definido como 0.

Casos de teste

1 -> 0
2 -> 0
10 -> 2
16 -> 0
100 -> 36
267 -> 11
350 -> 94
500 -> 244

Por exemplo: 350em binário é 101011110. Definir o bit mais significativo (ou seja, o 1bit mais à esquerda ) para 0transformá-lo no 001011110equivalente ao número inteiro decimal 94, a saída. Este é o OEIS A053645 .

Marcus Andrews
fonte
19
Limpar o bit mais significativo a partir 10obviamente dá 0: D
clabacchio
@clabacchio Eu .. isso ... er ... o quê? (Nice one) #
11007 Baldrickk
12
Parece-me que os zeros são tão significativos quanto esses. Quando você diz "o bit mais significativo", significa "o bit mais significativo definido como um".
Michael Kay

Respostas:

12

C (gcc) , 49 44 40 39 bytes

i;f(n){for(i=1;n/i;i*=2);return n^i/2;}

Experimente online!

cleblanc
fonte
11
É possível substituir i<=ncom n/ipara -1 byte. Este não é o meu jogo de golfe, alguém tentou editá-lo em sua postagem, mas eu o revirei porque as edições de jogos de golfe não são aceitas de acordo com as regras da comunidade.
HyperNeutrino
11
@HyperNeutrino Vi e aprovei a edição agora. Não estava ciente dessa regra, mas é uma boa dica de golfe!
Cleblanc #
Ah ok. Sim, normalmente as pessoas devem postar comentários sobre dicas de golfe e o OP deve fazer as edições, mas se você aceitou, não é realmente um problema. :)
HyperNeutrino
9

05AB1E , 5 bytes

.²óo-

Experimente online!

Removendo o bit mais significativo de um número inteiro N é equivalente a encontrar a distância a partir de N para a maior potência inteira de 2 inferior ao N .

Assim, usei a fórmula N - 2 andar (log 2 N) :

  • - Logaritmo com base 2 .
  • ó - Pavimento para um número inteiro.
  • o- 2 elevado à potência do resultado acima.
  • - - Diferença.
Mr. Xcoder
fonte
11
b¦Ctambém funciona ... não é? Converta em binário, o MSB está sempre no índice 1, remova o MSB, converta novamente.
Urna Mágica do Polvo
2
@MagicOctopusUrn Não, isso está errado, falha 1!
Mr. Xcoder
8

Gelatina , 3 bytes

BḊḄ

Experimente online!

Explicação

BḊḄ  Main Link
B    Convert to binary
 Ḋ   Dequeue; remove the first element
  Ḅ  Convert from binary
HyperNeutrino
fonte
2
Não são e pontos de código de dois bytes? Isso mudaria o tamanho geral para 5 bytes.
Bartek Banachewicz
3
O @BartekBanachewicz Jelly usa sua própria página de códigos , onde esses caracteres têm apenas 1 byte.
precisa
11
Obrigado por perguntar e responder a isso, que me incomodou por um longo tempo!
precisa
8

C (gcc) - 59 bytes

main(i){scanf("%d",&i);return i&~(1<<31-__builtin_clz(i));}

Esta resposta do gcc usa apenas operações inteiras bit a bit e aritméticas. Não há logaritmos aqui! Pode ter problemas com uma entrada 0 e é totalmente não portátil.

É a minha primeira resposta neste site, então eu adoraria comentários e melhorias. Eu certamente me diverti aprendendo expressões bit a bit.

Charles Diploma
fonte
11
Bem-vindo ao PPCG, e ótima primeira resposta! Esperamos que você goste de participar de muitos outros desafios :-)
ETHproductions
Você não precisa de um programa completo com main, uma função é um envio válido . Mudar isso para uma função e receber entrada como argumento para a referida função economiza 18 bytes .
Steadybox 17/11
11
Você pode até escrever como uma macro para economizar mais dois bytes .
Steadybox 17/11
7

MATL , 8 6 bytes

B0T(XB

Experimente online!

Economizou dois bytes graças a Cinaski. A mudança para a indexação de atribuição em vez da indexação de referência foi 2 bytes mais curta :)

Explicação:

          % Grab input implicitly: 267
B         % Convert to binary: [1 0 0 0 0 1 0 1 1]
 0T(      % Set the first value to 0: [0 0 0 0 0 1 0 1 1]
    XB    % Convert to decimal: 11
Stewie Griffin
fonte
11
Você poderia ter a indexação de referência utilizado (também para 6 bytes), se utilizou 4Lem vez de [2J]. Um outro divertimento 6 bytes: tZlcW-(só funciona em MATLAB, não em TIO / Octave)
Sanchises
6

Java (OpenJDK 8) , 23 bytes

n->n^n.highestOneBit(n)

Experimente online!

Desculpe, embutido: - /

Olivier Grégoire
fonte
Java com um build-in que outras linguagens populares como .NET e Python não possuem ?! o.Ô +1 a isso. Estava prestes a postar algo mais sem build-ins. O seu é 15 bytes mais curto. XD
Kevin Cruijssen 15/11
@KevinCruijssen Algo como n->n^1<<(int)Math.log2(n)vai funcionar e provavelmente é menor que 38 bytes. Foi a minha segunda ideia (ainda não testada), se a highestOneBitque não funcionou adequadamente. Por curiosidade, qual foi a sua solução
Olivier Grégoire
O meu era n->n^1<<(int)(Math.log(n)/Math.log(2))porque Math.log2não existe em Java. ; Apenas P Math.log, Math.log10e Math.loglpestão disponíveis.
Kevin Cruijssen
2
Eu ia postar o mesmo, apenas menos em vez de xor. Lembrou-se do método a partir deste
JollyJoker 16/17/17
11
@KevinCruijssen Opa, Math.log2não existe mesmo ... Meu mal. Vejo? Um bom método ( highestOneBit) existe, mas não outro ( Math.log2). Java é ;-) estranho
Olivier Grégoire
6

Casca , 3 bytes

ḋtḋ

Experimente online!

Explicação:

    -- implicit input, e.g. 350
  ḋ -- convert number to list of binary digits (TNum -> [TNum]): [1,0,1,0,1,1,1,1,0]
 t  -- remove first element: [0,1,0,1,1,1,1,0]
ḋ   -- convert list of binary digits to number ([TNum] -> TNum): 94
Laikoni
fonte
Da mesma forma que a solução Jelly, este parece que é realmente 5 bytes, não 3.
Bartek Banachewicz
11
@BartekBanachewicz mesma forma para Jelly, Husk utiliza a sua própria página de código, de modo que este é , na verdade, 3 bytes: P
HyperNeutrino
@BartekBanachewicz Veja aqui para a página de códigos: github.com/barbuz/Husk/wiki/Codepage
Laikoni
5

Python 2 , 27 bytes

lambda n:n-2**len(bin(n))/8

Experimente online!

Explicação

lambda n:n-2**len(bin(n))/8  # Lambda Function: takes `n` as an argument
lambda n:                    # Declaration of Lambda Function
              len(bin(n))    # Number of bits + 2
           2**               # 2 ** this ^
                         /8  # Divide by 8 because of the extra characters in the binary representation
         n-                  # Subtract this from the original
HyperNeutrino
fonte
... Apenas quando eu estava trabalhando a matemática bit a bit. : P
totallyhuman
@totallyhuman heh desculpe, mas bater-lhe a ele: P
HyperNeutrino
2**len(bin(n))/8também pode ser escrito 1<<len(bin(n))-3e, em seguida, funcionará em 2 e 3 (sem bytes salvos / adicionados).
Mego
@Mego Cool, obrigado pela adição!
HyperNeutrino
5

Python 3 , 30 bytes

-8 bytes graças a caird coinheringaahing. Eu digitei isso de memória. : o

lambda n:int('0'+bin(n)[3:],2)

Experimente online!

totalmente humano
fonte
Por que não lambda n:int(bin(n)[3:],2)?
caird coinheringaahing
Bem, a) isso seria um erro em 1 , b) sou burro o suficiente para não pensar nisso. Mas eu consertei isso com uma pequena alteração. Obrigado!
totallyhuman
Eu editei o código para que ele funciona, (e salva 4 bytes)
Caird coinheringaahing
Isso ainda erros em 1 .
totallyhuman
@cairdcoinheringaahing Essa foi a minha resposta original , mas depois percebi que errored em 1. A solução acaba por mais tempo do que um método simples XOR
FlipTack
4

Mathematica, 37 bytes

Rest[#~IntegerDigits~2]~FromDigits~2&

Experimente online!

J42161217
fonte
4

JavaScript, 22 20 bytes

Economizou 2 bytes graças a ovs

a=>a^1<<Math.log2(a)

Experimente online!

Outra abordagem, 32 bytes

a=>'0b'+a.toString`2`.slice`1`^0

Experimente online!


fonte
por que você faria .slice`1`^0quando .slice(1)^0iria funcionar tão bem, haha
ETHproductions
@ETHproductions. Este parece melhor :)
4

J, 6 bytes

}.&.#:

Bem simples.

Explicação

}.&.#:
    #:  convert to list of binary digits
  &.    apply right function, then left, then the inverse of right
}.      behead
Cole
fonte
Eu estava indo para postar isso :(
Cyoce 15/17/17
@Cyoce Me too ...
Adám
4

APL (Dyalog) , 10 bytes

Função de prefixo tácito.

212∘⊥⍣¯1

Experimente online!

2∘⊥... descodificar a partir da base-2 ...
 ... ⍣¯1 tempo um negativo (ou seja, codificam na base 2)

1↓ largar o primeiro bit

2⊥ decodificar da base-2

Adão
fonte
4

Ruby, 26 bytes

-7 bytes graças a Ventero. -2 bytes graças ao historicrat.

->n{/./=~'%b'%n;$'.to_i 2}
Mostrar nome
fonte
Você pode salvar alguns bytes apenas pulando o primeiro caractere e soltando parênteses redundantes:->n{n.to_s(2)[1..-1].to_i 2}
Ventero 14/11
->n{/./=~'%b'%n;$'.to_i 2}
histocrat
4

C (gcc), 38 bytes

Built-in gcc usado.

f(c){return c^1<<31-__builtin_clz(c);}
Colera Su
fonte
Substituir 31-por ~deve salvar dois bytes.
@ThePirateBay depende do hardware se a mudança está mascarada. No meu computador, ele produzirá 0. #
Colera Su
4

Montagem do BRAÇO, 46 43 bytes

(Você pode omitir o registro de destino ao adicionar quando for igual à fonte)

clz x1,x0
add x1,1
lsl x0,x1
lsr x0,x1
ret
Michael Dorgan
fonte
Que sabor da sintaxe de montagem do ARM é essa? Meu assembler GNU não entende shr/ shl/ rete quer algo como lsr/ lsl/ bx lr.
Ruslan
Provavelmente misturando sintaxe entre várias versões (ret é de aarch64), embora eu pensasse que o montador faria pseudo-op para você. Para os propósitos aqui, no entanto, o uso do lsl / lsr mais antigo e direto provavelmente está correto.
quer
O engraçado é que posso fazê-lo em menos uma operação, mas o tamanho do byte aumenta em 2. Ah, código golf.
precisa
3

Pitão, 5 bytes

a^2sl

Suíte de teste.

Explicação:

    l   Log base 2 of input.
   s    Cast ^ to integer (this is the position of the most significant bit.)
 ^2     Raise 2 to ^ (get the value of said bit)
a       Subtract ^ from input
Steven H.
fonte
3

Alice , 8 bytes

./-l
o@i

Experimente online!

Explicação

.   Duplicate an implicit zero at the bottom of the stack. Does nothing.
/   Switch to Ordinal mode, move SE.
i   Read all input as a string.
l   Convert to lower case (does nothing, because the input doesn't contain letters).
i   Try reading all input again, pushes an empty string.
/   Switch to Cardinal mode, move W.
.   Duplicate. Since we're in Cardinal mode, this tries to duplicate an integer.
    To get an integer, the empty string is discarded implicitly and the input is 
    converted to the integer value it represents. Therefore, at the end of this,
    we get two copies of the integer value that was input.
l   Clear lower bits. This sets all bits except the MSB to zero.
-   Subtract. By subtracting the MSB from the input, we set it to zero. We could
    also use XOR here.
/   Switch to Ordinal, move NW (and immediately reflect to SW).
o   Implicitly convert the result to a string and print it.
/   Switch to Ordinal, move S.
@   Terminate the program.
Martin Ender
fonte
3

Japonês , 6 bytes

^2p¢ÊÉ

Experimente online!

Explicação

^2p¢ÊÉ
   ¢     Get binary form of input
    Ê    Get length of that
     É   Subtract 1
 2p      Raise 2 to the power of that
^        XOR with the input

Se a entrada 1puder falhar: 4 bytes

¢Ån2

Experimente online!

Explicação : obtenha binário de entrada ( ¢), corte primeiro char ( Å), analise como binário novamente em um número ( n2).

Justin Mariner
fonte
3

APL (Dyalog Unicode) , 9 bytes

⊢-2*∘⌊2⍟⊢

Experimente online!

-1 byte graças a Adam

HyperNeutrino
fonte
Completamente correto, embora eu tivesse usado o TIO para gerar um modelo para mim. De qualquer forma, ⊢-2*∘⌊2⍟⊢salva um byte.
Adám 14/11/17
Fiquei triste que a APL não estivesse representada, e existe, quase perdida no pergaminho! Sinto falta da APL.
Cmd
@cmm APL está vivo e bem. Sinta-se à vontade para sair na sala de bate-papo APL do Stack Exchange .
Adám 15/11/17
3

CJam , 7 bytes

{2b()b}

Experimente online!

Explicação:

{     }  Block:         267
 2b      Binary:        [1 0 0 0 0 1 0 1 1]
   (     Pop:           [0 0 0 0 1 0 1 1] 1
    )    Increment:     [0 0 0 0 1 0 1 1] 2
     b   Base convert:  11

Reutilize o MSB (que é sempre 1) para evitar ter que excluí-lo; o equivalente sem esse truque seria {2b1>2b}ou {2b(;2b}.

Esolanging Fruit
fonte
3

Retina , 15 13 bytes

^(^1|\1\1)*1

Experimente online!

Entrada e saída em unário (o conjunto de testes inclui a conversão de e para decimal por conveniência).

Explicação

Isso é bastante fácil de fazer em unário. Tudo o que queremos fazer é excluir a maior potência de 2 da entrada. Podemos combinar uma potência de 2 com algumas referências avançadas. Na verdade, é mais fácil corresponder aos valores do formulário 2 n -1 , portanto, faremos isso e corresponderemos a 1 separadamente:

^(^1|\1\1)*1

O grupo 1corresponde a um single 1no início para iniciar as coisas ou corresponde ao dobro do que fez na última iteração. Então corresponde 1, então 2, então 4e assim por diante. Uma vez que estes são somados, estamos sempre com uma potência abaixo de 2, que corrigimos 1no final.

Devido ao avanço de linha à direita, a correspondência é simplesmente removida da entrada.

Martin Ender
fonte
3

R , 28 bytes

function(x)x-2^(log2(x)%/%1)

Experimente online!

Mais fácil calcular o bit mais significativo por 2 ^ floor(log2(x))meio de conversões básicas, que são bastante detalhadas em R

user2390246
fonte
3

PARI / GP, 18 bytes

n->n-2^logint(n,2)

Solução alternativa:

n->n-2^exponent(n)
Charles
fonte
O primeiro parece dar respostas erradas. Deveria ser n->n-2^logint(n,2)? O segundo não é suportado na minha versão do PARI / GP, nem na versão usada pelo tio.run . Essa é uma nova função?
Jeppe Stig Nielsen
@JeppeStigNielsen Ops, fixo - é isso que recebo ao enviar do meu telefone. Sim, o segundo é uma nova função.
Charles
@JeppeStigNielsen Acabei de verificar, exponentfoi adicionado 5 dias atrás, comparado a este desafio que foi adicionado ontem. :)
Charles
3

Haskell , 32 29 bytes

(!1)
x!y|2*y>x=x-y|z<-2*y=x!z

Experimente online!

-3 bytes graças a @Laikoni

Solução mais antiga, 32 bytes

f x=last[x-2^i|i<-[0..x],2^i<=x]

Experimente online!

user28667
fonte
11
Funções anônimas são permitidas; portanto, você não precisa f=da primeira variante. Além disso, z<-2*y=x!zeconomiza um byte: Experimente online!
Laikoni
3

Excel, 20 bytes

=A1-2^INT(LOG(A1,2))
IanM_Matrix1
fonte
Bem vindo ao site! :)
DJMcMayhem
3

Excel, 36 31 bytes

-5 bytes graças a @ IanM_Matrix1

=BIN2DEC(MID(DEC2BIN(A1),2,99))

Nada interessante.

Wernisch
fonte
Reduza o tamanho para 31 bytes, substituindo REPLACE por um MID: = BIN2DEC (MID (DEC2BIN (A1), 2,99)))
IanM_Matrix1