Cancellazione del bit più significativo da un numero intero


29

Ingresso

L'input è un singolo intero positivo n

Produzione

L'output è ncon il bit più significativo impostato su 0.

Casi test

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

Ad esempio: 350in binario è 101011110. Impostando il suo bit più significativo (ovvero il 1bit più a sinistra ) per 0trasformarlo in 001011110quale è equivalente all'intero decimale 94, l'output. Questo è OEIS A053645 .


19
Chiarire il bit più significativo da 10ovviamente dà 0: D
clabacchio il

@clabacchio I .. it ... er ... wha? (bello)
Baldrickk,

12
Mi sembra che gli zero siano significativi quanto quelli. Quando dici "il bit più significativo" intendi "il bit più significativo impostato su uno".
Michael Kay,

Risposte:


12

C (gcc) , 49 44 40 39 byte

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

Provalo online!


1
È possibile sostituire i<=ncon n/iper -1 byte. Questo non è il mio golf, qualcun altro ha provato a modificarlo nel tuo post ma l'ho ripristinato perché le modifiche per i post sul golf non sono accettate in base alle nostre regole della community.
HyperNeutrino,

1
@HyperNeutrino Ho visto e approvato la modifica proprio ora. Non ero a conoscenza di quella regola ma è un bel consiglio per il golf!
Cleblanc,

Ah ok. Sì, in genere le persone dovrebbero pubblicare commenti per suggerimenti sul golf e OP dovrebbe apportare le modifiche, ma se lo hai accettato, non è un problema. :)
HyperNeutrino,


9

05AB1E , 5 byte

.²óo-

Provalo online!

Rimozione del bit più significativo da un numero intero N equivale a trovare la distanza dalla N alla massima potenza intera di 2 inferiore a N .

Quindi, ho usato la formula N - 2 piano (log 2 N) :

  • - Logaritmo con base 2 .
  • ó - Piano a un numero intero.
  • o- 2 elevato alla potenza del risultato sopra.
  • - - Differenza.

1
b¦Cfunziona anche ... no? Convertire in binario, MSB è sempre all'indice 1, rimuovere MSB, riconvertire.
Magic Octopus Urn,

2
@MagicOctopusUrn No che non va, fallisce 1!
Mr. Xcoder,

8

Gelatina , 3 byte

BḊḄ

Provalo online!

Spiegazione

BḊḄ  Main Link
B    Convert to binary
 Ḋ   Dequeue; remove the first element
  Ḅ  Convert from binary

2
Non sono e due byte codepoints? Ciò cambierebbe la dimensione complessiva in 5 byte.
Bartek Banachewicz,

3
@BartekBanachewicz Jelly usa la sua codepage , dove quei caratteri sono solo 1 byte.
steenbergh,

1
Grazie per avermelo chiesto e risposto, questo mi ha infastidito per molto tempo!
Ukko,

8

C (gcc) - 59 byte

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

Questa risposta gcc utilizza solo operazioni bit per bit e aritmetiche intere. Nessun logaritmo qui! Potrebbe avere problemi con un input pari a 0 ed è totalmente non portatile.

È la mia prima risposta su questo sito, quindi mi piacerebbe molto feedback e miglioramenti. Mi sono sicuramente divertito con l'apprendimento delle espressioni bit per bit.


1
Benvenuti in PPCG e ottima prima risposta! Speriamo che ti piacerà partecipare a molte altre sfide :-)
ETHproductions

Non è necessario un programma completo con main, una funzione è un invio valido . Modificandolo in una funzione e prendendo l'input come argomento per detta funzione si risparmiano 18 byte .
Steadybox,

1
Potresti anche scriverlo come macro per salvare altri due byte .
Steadybox,

7

MATL , 8 6 byte

B0T(XB

Provalo online!

Due byte salvati grazie a Cinaski. Il passaggio all'indicizzazione delle assegnazioni invece dell'indicizzazione di riferimento è stato più breve di 2 byte :)

Spiegazione:

          % 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

1
Avresti potuto usare l'indicizzazione di riferimento (anche per 6 byte), se avessi usato 4Linvece di [2J]. Un altro divertente 6 byte: tZlcW-(funziona solo in MATLAB, non in TIO / Octave)
Sanchises

6

Java (OpenJDK 8) , 23 byte

n->n^n.highestOneBit(n)

Provalo online!

Siamo spiacenti, integrato: - /


Java con un build-in che altri linguaggi popolari come .NET e Python non hanno ?! o.Ô +1 a quello. Stava per pubblicare qualcosa di più a lungo senza build-in .. Il tuo è più corto di 15 byte. XD
Kevin Cruijssen,

@KevinCruijssen Qualcosa del genere n->n^1<<(int)Math.log2(n)funzionerà ed è probabilmente più breve di 38 byte. Era la mia seconda idea (ancora non testata), se highestOneBitquella non avesse funzionato in modo appropriato. Per curiosità, qual è stata la tua soluzione
Olivier Grégoire il

Il mio era n->n^1<<(int)(Math.log(n)/Math.log(2))perché Math.log2non esiste in Java. ; Solo P Math.log, Math.log10e Math.loglpsono disponibili.
Kevin Cruijssen,

2
Avevo intenzione di pubblicare lo stesso, solo meno invece di xor. Ricordato il metodo da questo
JollyJoker

1
@KevinCruijssen Oops, Math.log2non esiste davvero ... Mio male. Vedere? highestOneBitEsiste un metodo piacevole ( ) ma non un altro ( Math.log2). Java è strano ;-)
Olivier Grégoire il

6

Buccia , 3 byte

ḋtḋ

Provalo online!

Spiegazione:

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

Analogamente alla soluzione Jelly, sembra che in realtà sia 5 byte, non 3.
Bartek Banachewicz,

1
@BartekBanachewicz Analogamente a Jelly, Husk utilizza la propria tabella codici, quindi in realtà si tratta di 3 byte: P
HyperNeutrino

@BartekBanachewicz Vedi qui per la codepage: github.com/barbuz/Husk/wiki/Codepage
Laikoni


5

Python 2 , 27 byte

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

Provalo online!

Spiegazione

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

... Proprio mentre stavo lavorando la matematica bit per bit. : P
totalmente umano il

@totallyhuman eh scusa ma ti ho battuto: P
HyperNeutrino

2**len(bin(n))/8può anche essere scritto 1<<len(bin(n))-3e funzionerà sia in 2 che in 3 (nessun byte salvato / aggiunto).
Mego

@Mego Cool, grazie per l'aggiunta!
HyperNeutrino,

5

Python 3 , 30 byte

-8 byte grazie a cahing coinheringaahing. L'ho scritto a memoria. : o

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

Provalo online!



Bene, a) ciò errore su 1 , b) Sono abbastanza stupido da non pensarci. Ma l'ho risolto con un piccolo cambiamento. Grazie!
totalmente umano il

Ho modificato il codice in modo che funzioni (e salva 4 byte)
caird coinheringaahing

Che ancora errori su 1 .
totalmente umano il

@cairdcoinheringaahing Questa era la mia risposta originale , ma poi mi sono reso conto che non funzionava su 1. La soluzione alternativa finisce più a lungo di un semplice metodo XOR
FlipTack


4

JavaScript, 22 20 byte

Salvato 2 byte grazie a ovs

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

Provalo online!

Un altro approccio, 32 byte

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

Provalo online!


perché dovresti fare .slice`1`^0quando .slice(1)^0funzionerebbe altrettanto bene, haha
ETHproductions

@ETHproductions. Questo sembra migliore :)

4

J, 6 byte

}.&.#:

Abbastanza semplice.

Spiegazione

}.&.#:
    #:  convert to list of binary digits
  &.    apply right function, then left, then the inverse of right
}.      behead

Avevo intenzione di postare questo :(
Cyoce il

@Cyoce Me too ...
Adám,

4

APL (Dyalog) , 10 byte

Funzione prefisso tacita.

212∘⊥⍣¯1

Provalo online!

2∘⊥... decodifica da base-2 ...
 ... ⍣¯1 negativo una volta (ovvero codifica in base-2)

1↓ rilascia il primo bit

2⊥ decodifica da base-2


4

Ruby, 26 bytes

-7 Bytes thanks to Ventero. -2 Bytes thanks to historicrat.

->n{/./=~'%b'%n;$'.to_i 2}

You can save a few bytes by just skipping the first character and dropping redundant parentheses: ->n{n.to_s(2)[1..-1].to_i 2}
Ventero

->n{/./=~'%b'%n;$'.to_i 2}
histocrat

4

C (gcc), 38 bytes

Built-in in gcc used.

f(c){return c^1<<31-__builtin_clz(c);}

Replacing 31- with ~ should save two bytes.

@ThePirateBay it depends on hardware whether the shift is masked. On my computer, it will output 0.
Colera Su

4

ARM Assembly, 46 43 bytes

(You can omit destination register on add when same as source)

clz x1,x0
add x1,1
lsl x0,x1
lsr x0,x1
ret

What flavour of ARM assembly syntax is this? My GNU assembler doesn't understand shr/shl/ret and wants instead something like lsr/lsl/bx lr.
Ruslan

Probably mixing syntax across multiple versions (ret is from aarch64), though I thought that the assembler would pseudo op these for you. For purposes of here, though, using the older and direct lsl/lsr is probably correct.
Michael Dorgan

Funny thing, i can do it in 1 less operation, but I the byte size goes up by 2. Ah code golf.
Michael Dorgan

3

Pyth, 5 bytes

a^2sl

Test suite.

Explanation:

    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

3

Alice, 8 bytes

./-l
o@i

Try it online!

Explanation

.   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.

3

Japt, 6 bytes

^2p¢ÊÉ

Try it online!

Explanation

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

If input 1 can fail: 4 bytes

¢Ån2

Try it online!

Explanation: get input binary (¢), slice off first char (Å), parse as binary back to a number (n2).




3

CJam, 7 bytes

{2b()b}

Try it online!

Explanation:

{     }  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

Reuse the MSB (which is always 1) to avoid having to delete it; the equivalent without that trick would be {2b1>2b} or {2b(;2b}.


3

Retina, 15 13 bytes

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

Try it online!

Input and output in unary (the test suite includes conversion from and to decimal for convenience).

Explanation

This is quite easy to do in unary. All we want to do is delete the largest power of 2 from the input. We can match a power of 2 with some forward references. It's actually easier to match values of the form 2n-1, so we'll do that and match one 1 separately:

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

The group 1 either matches a single 1 at the beginning to kick things off, or it matches twice what it did on the last iteration. So it matches 1, then 2, then 4 and so on. Since these get added up, we're always one short of a power of 2, which we fix with the 1 at the end.

Due the trailing linefeed, the match is simply removed from the input.


3

R, 28 bytes

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

Try it online!

Easiest to calculate the most significant bit via 2 ^ floor(log2(x)) rather than carry out base conversions, which are quite verbose in R


3

PARI/GP, 18 bytes

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

Alternate solution:

n->n-2^exponent(n)

The first one seems to give wrong answers. Should it be n->n-2^logint(n,2)? The second one is not supported in my version of PARI/GP, nor in the version used by tio.run. Is that a new function?
Jeppe Stig Nielsen

@JeppeStigNielsen Oops, fixed -- that's what I get for submitting from my phone. Yes, the second one is a new function.
Charles

@JeppeStigNielsen I just checked, exponent was added 5 days ago, compared to this challenge which was added yesterday. :)
Charles



3

Excel, 36 31 bytes

-5 bytes thanks to @IanM_Matrix1

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

Nothing interesting.


Reduce the size to 31 bytes by replacing REPLACE with a MID: =BIN2DEC(MID(DEC2BIN(A1),2,99))
IanM_Matrix1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.