Usuwanie najbardziej znaczącego bitu z liczby całkowitej


29

Wkład

Dane wejściowe to pojedyncza dodatnia liczba całkowita n

Wydajność

Wyjście ma nnajbardziej znaczący bit ustawiony na 0.

Przypadki testowe

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

Na przykład: 350w pliku binarnym jest 101011110. Ustawienie jego najbardziej znaczącego bitu (tj. Bitu najbardziej z lewej strony 1), aby 0przekształcić go w 001011110ekwiwalent dziesiętnej liczby całkowitej 94, czyli wyjścia. To jest OEIS A053645 .


19
Usunięcie najważniejszego fragmentu z 10oczywiście daje 0: D
clabacchio

@clabacchio I .. it ... ee ... co? (fajny)
Baldrickk

12
Wydaje mi się, że zera są tak samo znaczące jak jedynki. Kiedy mówisz „najbardziej znaczący bit”, masz na myśli „najbardziej znaczący bit, który jest ustawiony na jeden”.
Michael Kay

Odpowiedzi:


12

C (gcc) , 49 44 40 39 bajtów

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

Wypróbuj online!


1
Można wymienić i<=nz n/ina -1 bajt. To nie jest mój golf. Ktoś inny próbował go edytować w swoim poście, ale wycofałem go, ponieważ zmiany postów do gry w golfa nie są akceptowane zgodnie z zasadami naszej społeczności.
HyperNeutrino,

1
@HyperNeutrino Właśnie widziałem i zatwierdziłem zmianę. Nie wiedziałem o tej zasadzie, ale to fajna wskazówka golfowa!
cleblanc

Ah, dobrze. Tak, zazwyczaj ludzie powinni publikować komentarze do wskazówek golfowych, a OP powinien wprowadzać zmiany, ale jeśli je zaakceptowałeś, nie jest to tak naprawdę duży problem. :)
HyperNeutrino,


9

05AB1E , 5 bajtów

.²óo-

Wypróbuj online!

Usunięcie najbardziej znaczącego bitu z liczb całkowitych n jest równoważna do znalezienia odległości od N do najwyższej mocy całkowitą od 2 niższej niż N .

Dlatego użyłem wzoru N - 2 piętro (log 2 N) :

  • - Logarytm z podstawą 2 .
  • ó - Piętro do liczby całkowitej.
  • o- 2 podniesione do potęgi wyniku powyżej.
  • - - Różnica.

1
b¦Cdziała również ... prawda? Konwertuj na binarny, MSB jest zawsze pod indeksem 1, usuń MSB, przekonwertuj z powrotem.
Magic Octopus Urn

2
@MagicOctopusUrn Nie, to źle, nie udaje się 1!
Pan Xcoder,


8

C (gcc) - 59 bajtów

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

Ta odpowiedź gcc używa tylko liczb całkowitych operacji bitowych i arytmetycznych. Brak logarytmów tutaj! Może mieć problemy z wejściem 0 i jest całkowicie nieprzenośny.

To moja pierwsza odpowiedź na tej stronie, więc chciałbym poznać opinie i ulepszenia. Na pewno dobrze się bawiłem, ucząc się wyrażeń bitowych.


1
Witamy w PPCG i świetna pierwsza odpowiedź! Mamy nadzieję, że spodoba ci się udział w wielu innych wyzwaniach :-)
ETHproductions

Nie potrzebujesz pełnego programu main, funkcja jest prawidłowym przesłaniem . Zmiana tego na funkcję i przyjęcie danych wejściowych jako argumentu dla tej funkcji pozwala zaoszczędzić 18 bajtów .
Steadybox

1
Możesz nawet napisać to jako makro, aby zaoszczędzić jeszcze dwa bajty .
Steadybox

7

MATL , 8 6 bajtów

B0T(XB

Wypróbuj online!

Zaoszczędził dwa bajty dzięki Cinaski. Przejście na indeksowanie przypisań zamiast indeksowania referencyjnego było o 2 bajty krótsze :)

Wyjaśnienie:

          % 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
Możesz użyć indeksowania referencyjnego (także dla 6 bajtów), jeśli użyłeś 4Lzamiast [2J]. Kolejna zabawa 6 bajtów: tZlcW-(działa tylko w MATLAB, nie w TIO / Octave)
Sanchises

6

Java (OpenJDK 8) , 23 bajty

n->n^n.highestOneBit(n)

Wypróbuj online!

Przepraszamy, wbudowane: - /


Java z wbudowaną wersją, której nie mają niektóre inne popularne języki, takie jak .NET i Python ?! o.Ô +1 do tego. Miałem zamiar opublikować coś dłuższego bez wbudowanych elementów. Twój jest o 15 bajtów krótszy. XD
Kevin Cruijssen

@KevinCruijssen Coś podobnego n->n^1<<(int)Math.log2(n)będzie działać i prawdopodobnie będzie miało mniej niż 38 bajtów. To był mój drugi (jeszcze nie przetestowany) pomysł, jeśli ten highestOneBitnie działał odpowiednio. Z ciekawości, jakie było twoje rozwiązanie
Olivier Grégoire,

Mój był, n->n^1<<(int)(Math.log(n)/Math.log(2))ponieważ Math.log2nie istnieje w Javie. ; P Tylko Math.log, Math.log10i Math.loglpsą dostępne.
Kevin Cruijssen

2
Zamierzałem opublikować to samo, tylko minus zamiast xor. Pamiętam metodę z tego
JollyJoker

1
@KevinCruijssen Ups, Math.log2naprawdę nie istnieje ... Mój zły. Widzieć? highestOneBitIstnieje jedna niezła metoda ( ), ale nie ma innej ( Math.log2). Java jest dziwna ;-)
Olivier Grégoire

6

Łuska , 3 bajty

ḋtḋ

Wypróbuj online!

Wyjaśnienie:

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

Podobnie jak w rozwiązaniu Jelly, to wydaje się, że to rzeczywiście 5 bajtów, a nie 3.
Bartek Banachewicz

1
@BartekBanachewicz Podobnie jak Jelly, Husk używa własnej strony kodowej, więc w rzeczywistości są to 3 bajty: P
HyperNeutrino,

@BartekBanachewicz Zobacz tutaj stronę kodową: github.com/barbuz/Husk/wiki/Codepage
Laikoni


5

Python 2 , 27 bajtów

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

Wypróbuj online!

Wyjaśnienie

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

... Właśnie wtedy, gdy pracowałem nad matematyką bitową. : P
totalnie ludzki,

@totallyhuman heh przepraszam, ale cię pokonałem: P
HyperNeutrino

2**len(bin(n))/8można również przeliterować 1<<len(bin(n))-3, a wtedy będzie działać zarówno w 2, jak i 3 (nie zapisano / nie dodano żadnych bajtów).
Mego

@Mego Cool, dzięki za dodanie!
HyperNeutrino,

5

Python 3 , 30 bajtów

-8 bajtów dzięki Cairney Coheringaahing. Wpisałem to z pamięci. : o

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

Wypróbuj online!



Cóż, a) to by błąd na 1 , b) Jestem na tyle głupi, żeby o tym nie myśleć. Ale naprawiłem to z niewielką zmianą. Dzięki!
całkowicieludzki


To wciąż błędy na 1 .
całkowicieludzki

@cairdcoinheringaahing To była moja pierwotna odpowiedź , ale potem zdałem sobie sprawę, że ją zignorowałem na 1. Obejście kończy się dłużej niż prosta metoda XOR
FlipTack


4

JavaScript, 22 20 bajtów

Zaoszczędzono 2 bajty dzięki ovs

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

Wypróbuj online!

Inne podejście, 32 bajty

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

Wypróbuj online!


dlaczego miałbyś zrobić, .slice`1`^0kiedy .slice(1)^0miałby równie dobrze działać, haha
ETHprodukcje

@ETHproductions. Ten wygląda lepiej :)

4

J, 6 bajtów

}.&.#:

Dość proste.

Wyjaśnienie

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

Zamierzałem opublikować to :(
Cyoce

@Cyoce Me too ...
Adám

4

APL (Dyalog) , 10 bajtów

Funkcja ukrytego przedrostka.

212∘⊥⍣¯1

Wypróbuj online!

2∘⊥... dekodowania z bazy-2 ...
 ... ⍣¯1 jednej negatywnej czasie (czyli kodowanie w bazie-2)

1↓ upuść pierwszy bit

2⊥ dekodować z base-2


4

Rubinowy, 26 bajtów

-7 Bajtów dzięki Ventero. -2 bajty dzięki historicrat.

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

Możesz zaoszczędzić kilka bajtów, po prostu pomijając pierwszy znak i upuszczając zbędne nawiasy:->n{n.to_s(2)[1..-1].to_i 2}
Ventero

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

4

C (gcc), 38 bajtów

Używany wbudowany gcc.

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

Zastąpienie 31-przez ~powinno zaoszczędzić dwa bajty.

@ThePirateBay zależy od sprzętu, czy zmiana jest maskowana. Na moim komputerze wyświetli 0.
Colera Su

4

Montaż ARM, 46 43 bajtów

(Można pominąć rejestr docelowy przy dodawaniu, gdy jest on taki sam jak źródłowy)

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

Jaki to smak składni zestawu ARM? Mój asembler GNU nie rozumie shr/ shl/ reti zamiast tego chce czegoś takiego jak lsr/ lsl/ bx lr.
Ruslan

Prawdopodobnie miksowanie składni w wielu wersjach (ret pochodzi z aarch64), choć myślałem, że asembler przygotuje je dla ciebie. Jednak w tym przypadku użycie starszego i bezpośredniego lsl / lsr jest prawdopodobnie poprawne.
Michael Dorgan

Zabawne, że mogę to zrobić w 1 operacji mniej, ale rozmiar bajtu wzrasta o 2. Ah kod golfa.
Michael Dorgan,

3

Pyth, 5 bajtów

a^2sl

Zestaw testowy.

Wyjaśnienie:

    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 bajtów

./-l
o@i

Wypróbuj online!

Wyjaśnienie

.   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 bajtów

^2p¢ÊÉ

Wypróbuj online!

Wyjaśnienie

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

Jeśli wprowadzanie 1może się nie powieść: 4 bajty

¢Ån2

Wypróbuj online!

Objaśnienie : pobierz wejściowy binarny ( ¢), odetnij pierwszy znak ( Å), przeanalizuj jako binarny powrót do liczby ( n2).




3

CJam , 7 bajtów

{2b()b}

Wypróbuj online!

Wyjaśnienie:

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

Ponownie użyj MSB (zawsze 1), aby uniknąć konieczności jego usunięcia; ekwiwalent bez tej sztuczki to {2b1>2b}lub {2b(;2b}.


3

Siatkówka , 15 13 bajtów

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

Wypróbuj online!

Wejściowe i wyjściowe w jednostkowym (zestaw testowy dla wygody zawiera konwersję zi na dziesiętny).

Wyjaśnienie

Jest to dość łatwe do zrobienia w pojedynkę. Wszystko, co chcemy zrobić, to usunąć największą moc 2 z wejścia. Możemy dopasować potęgę 2 z niektórymi referencjami. W rzeczywistości łatwiej jest dopasować wartości formularza 2 n -1 , więc zrobimy to i dopasujemy jeden 1 osobno:

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

Grupa 1albo dopasowuje jeden 1na początku, aby rozpocząć, albo dwukrotnie pasuje do tego, co zrobiła podczas ostatniej iteracji. Więc pasuje 1, wtedy 2, wtedy 4i tak dalej. Ponieważ sumy te się sumują, zawsze brakuje nam potęgi 2, którą naprawiamy 1na końcu.

Ze względu na końcowe podawanie linii dopasowanie jest po prostu usuwane z danych wejściowych.


3

R , 28 bajtów

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

Wypróbuj online!

Najłatwiej jest obliczyć najbardziej znaczący bit, 2 ^ floor(log2(x))zamiast przeprowadzać podstawowe konwersje, które są dość szczegółowe w R


3

PARI / GP, 18 bajtów

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

Alternatywne rozwiązanie:

n->n-2^exponent(n)

Pierwszy wydaje się dawać złe odpowiedzi. Powinno być n->n-2^logint(n,2)? Drugi nie jest obsługiwany w mojej wersji PARI / GP ani w wersji używanej przez tio.run . Czy to nowa funkcja?
Jeppe Stig Nielsen

@JeppeStigNielsen Ups, naprawione - to właśnie otrzymuję za przesłanie z mojego telefonu. Tak, drugi to nowa funkcja.
Charles

@JeppeStigNielsen, który właśnie sprawdziłem, exponentzostał dodany 5 dni temu, w porównaniu do tego wyzwania, które zostało dodane wczoraj. :)
Charles



3

Excel, 36 31 bajtów

-5 bajty dzięki @ IanM_Matrix1

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

Nic interesującego.


Zmniejsz rozmiar do 31 bajtów, zastępując REPLACE przez MID: = BIN2DEC (MID (DEC2BIN (A1), 2,99))
IanM_Matrix1
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.