Очищення найбільш значущого біта від цілого числа


29

Вхідні дані

Вхід є єдиним натуральним числом n

Вихід

Вихід має nнайзначніший біт 0.

Випробування

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

Наприклад: 350у двійковій є 101011110. Встановлення його найбільш значущого біта (тобто крайнього лівого 1біта) 0перетворює його в 001011110який еквівалентний десятковому цілому числу 94. Це OEIS A053645 .


19
Очищення найбільш значущого шматочка від 10очевидно дає 0: D
clabacchio

@clabacchio я .. це ... е-е ... а? (приємний)
Балдрік

12
Мені здається, що нулі такі ж значні, як і нулі. Коли ви говорите "найзначніший біт", ви маєте на увазі "найзначніший біт, який встановлений на один".
Майкл Кей

Відповіді:


12

C (gcc) , 49 44 40 39 байт

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

Спробуйте в Інтернеті!


1
Ви можете замінити i<=nз n/iна -1 байт. Це не мій гольф, хтось інший намагався відредагувати його у вашій публікації, але я повернув його назад, оскільки редагування постів для гольфу не приймаються відповідно до правил нашої спільноти.
HyperNeutrino

1
@HyperNeutrino Я побачив і схвалив редагування саме зараз. Не знав цього правила, але це приємна порада з гольфу!
cleblanc

Ага гаразд. Так, зазвичай люди повинні публікувати коментарі щодо порад щодо гольфу, і ОП повинні внести зміни, але якщо ви це прийняли, це не дуже велика проблема. :)
HyperNeutrino


9

05AB1E , 5 байт

.²óo-

Спробуйте в Інтернеті!

Видалення найбільш значимий біт з цілих чисел N еквівалентно знаходженню відстані від N до найвищого цілій степені 2 нижче , ніж N .

Таким чином, я використав формулу N - 2 поверх (log 2 N) :

  • - Логарифм із основою 2 .
  • ó - Поверх до цілого числа.
  • o- 2 підняті до сили результату вище.
  • - - Різниця.

1
b¦Cтакож працює ... чи не так? Перетворити на бінарне, MSB завжди знаходиться в індексі 1, видалити MSB, перетворити назад.
Чарівний восьминога Урна

2
@MagicOctopusUrn Ні, що не так, не вдається 1!
Містер Xcoder

8

Желе , 3 байти

BḊḄ

Спробуйте в Інтернеті!

Пояснення

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

2
Не є і двобайтові кодові точки? Це змінило б загальний розмір до 5 байт.
Bartek Banachewicz

3
@BartekBanachewicz Jelly використовує власну кодову сторінку , де ці символи мають лише 1 байт.
steenbergh

1
Дякую за запитання та відповіді на це, що мене давно клопоче!
Укко

8

C (gcc) - 59 байт

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

Ця відповідь gcc використовує лише цілі побітові та арифметичні операції. Тут немає логарифмів! У нього можуть виникнути проблеми із входом 0, і він є абсолютно не портативним.

Це моя перша відповідь на цьому сайті, тому я хотів би отримати відгуки та вдосконалення. Я впевнено розважався з навчанням розрядних виразів.


1
Ласкаво просимо в PPCG, і чудова перша відповідь! Сподіваємося, вам сподобається брати участь у багатьох інших викликах :-)
ETHproductions

Вам не потрібна повна програма main, функція - це дійсне подання . Змінивши цю функцію та взявши введення в якості аргументу зазначеній функції, економиться 18 байт .
Steadybox

1
Ви навіть можете записати його як макрос, щоб зберегти ще два байти .
Steadybox

7

MATL , 8 6 байт

B0T(XB

Спробуйте в Інтернеті!

Збережено два байти завдяки Cinaski. Перехід на індексацію призначення замість опорної індексації був на 2 байти коротшим :)

Пояснення:

          % 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
Ви могли б використовувати еталонну індексацію (також для 6 байт), якщо використовували б, 4Lа не [2J]. Ще одне веселе 6 байт: tZlcW-(працює лише в MATLAB, не в TIO / Octave)
Sanchises

6

Java (OpenJDK 8) , 23 байти

n->n^n.highestOneBit(n)

Спробуйте в Інтернеті!

Вибачте, вбудований: - /


Java зі вбудованою версією, яку не мають деякі інші популярні мови, такі як .NET і Python ?! o.Ô +1 до цього. Збирався розмістити щось довше без вбудованих програм. У вас на 15 байт коротше. XD
Кевін Круїйсен

@KevinCruijssen Щось подібне n->n^1<<(int)Math.log2(n)буде працювати і, ймовірно, коротше 38 байт. Це була моя друга (ще не перевірена) ідея, якщо highestOneBitодна не працювала належним чином. З цікавості, яке було ваше рішення
Олів'є Грегоар

Моє було n->n^1<<(int)(Math.log(n)/Math.log(2))тому, Math.log2що на Java не існує. ; P тільки Math.log, Math.log10і Math.loglpдоступні.
Kevin Cruijssen

2
Я збирався розмістити той самий, лише мінус замість xor. Згадав метод з цього
приводу

1
@KevinCruijssen На жаль, Math.log2не існує насправді ... Моє погано. Побачити? Є один приємний метод ( highestOneBit), але не інший ( Math.log2). Ява дивна ;-)
Олів'є Григоар

6

Лушпиння , 3 байти

ḋtḋ

Спробуйте в Інтернеті!

Пояснення:

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

Подібно до рішення Jelly, це здається, що насправді це 5 байт, а не 3.
Bartek Banachewicz

1
@BartekBanachewicz Подібно желе, лушпиння використовує свою власну кодову, так що це на самому справі 3 байта: P
HyperNeutrino

@BartekBanachewicz Дивіться тут для кодування: github.com/barbuz/Husk/wiki/Codepage
Laikoni


5

Python 2 , 27 байт

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

Спробуйте в Інтернеті!

Пояснення

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

... Тільки тоді, коли я працював з побітною математикою. : P
повністюлюдський

@totallyhuman heh вибачте, але побили вас до цього: P
HyperNeutrino

2**len(bin(n))/8також може бути написано 1<<len(bin(n))-3, і тоді вона буде працювати як у 2, так і в 3 (жодних байтів не збережено / додано).
Мего

@ Mego Cool, дякую за додаток!
HyperNeutrino

5

Python 3 , 30 байт

-8 байт завдяки співпраці у співтоваристві. Я набрав це з пам'яті. : o

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

Спробуйте в Інтернеті!



Ну, а) це помилка на 1 , б) я досить німий, щоб не думати про це. Але я це виправив незначною зміною. Спасибі!
повністюлюдський

Я відредагував код, щоб він працював, (і економить 4 байти)
caird coinheringaahing

Це все-таки помилки на 1 .
повністюлюдський

@cairdcoinheringaahing Це була моя оригінальна відповідь , але потім я зрозумів, що вона помилилася 1. Вирішення питання закінчується довше, ніж простий метод XOR
FlipTack



4

J, 6 байт

}.&.#:

Досить просто.

Пояснення

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

Я збирався опублікувати це :(
Cyoce

@Cyoce Me too ...
17:52

4

APL (Dyalog) , 10 байт

Мовчазна префіксальна функція.

212∘⊥⍣¯1

Спробуйте в Інтернеті!

2∘⊥... розшифровує з бази-2 ...
 ... ⍣¯1 негативний момент один (тобто закодувати в базі-2)

1↓ киньте перший шматочок

2⊥ декодування з бази-2


4

Рубін, 26 байт

-7 байт завдяки Вентеро. -2 байти завдяки Historrat.

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

Ви можете зберегти кілька байтів, просто пропустивши перший символ і скинувши зайві дужки:->n{n.to_s(2)[1..-1].to_i 2}
Вентеро

->n{/./=~'%b'%n;$'.to_i 2}
гістократ

4

C (gcc), 38 байт

Використовуваний вбудований gcc.

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

Якщо замінити 31-на, ~слід зберегти два байти.

@ThePirateBay від апаратури залежить, чи зрушення маскується. На моєму комп’ютері він видасть 0.
Colera Su

4

Збірка АРМ, 46 43 байт

(Ви можете опустити реєстр призначення при додаванні, коли такий же, як джерело)

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

Який аромат синтаксису збірки ARM це? Мій асемблер GNU не розуміє shr/ shl/ retі хоче натомість щось подібне lsr/ lsl/ bx lr.
Руслан

Можливо, змішування синтаксису в декількох версіях (ret є від aarch64), хоча я думав, що асемблер буде псевдо-оп для вас. Для цілей тут, мабуть, використання старшого та прямого lsl / lsr, ймовірно, правильне.
Майкл Дорган

Смішна річ, я можу це зробити за 1 меншу операцію, але я розмір байта збільшується на 2. Ах гольф-код.
Майкл Дорган


3

Аліса , 8 байт

./-l
o@i

Спробуйте в Інтернеті!

Пояснення

.   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 байт

^2p¢ÊÉ

Спробуйте в Інтернеті!

Пояснення

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

Якщо введення 1не може: 4 байти

¢Ån2

Спробуйте в Інтернеті!

Пояснення : отримати вхідний бінарний ( ¢), відрізати перший char ( Å), проаналізувати як двійковий назад до числа ( n2).



3

APL (Dyalog Unicode) , 9 байт

⊢-2*∘⌊2⍟⊢

Спробуйте в Інтернеті!

-1 байт завдяки Адамові


Цілком правильно, хоча я б використовував TIO для створення шаблону для мене. У будь-якому випадку, ⊢-2*∘⌊2⍟⊢економить байт.
Adám

Мені було сумно, що APL не була представлена, і є, майже загублена в сувій! Я сумую за APL.
смм

@cmm APL живий і здоровий. Не соромтеся спілкуватися в чаті Stack Exchange APL .
Адам

3

CJam , 7 байт

{2b()b}

Спробуйте в Інтернеті!

Пояснення:

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

Використовуйте повторно MSB (який завжди 1), щоб уникнути необхідності його видалення; еквівалент без цього фокусу був би {2b1>2b}або {2b(;2b}.


3

Сітківка , 15 13 байт

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

Спробуйте в Інтернеті!

Введення та виведення не одинаково (тестовий набір включає перетворення з та в десяткові для зручності).

Пояснення

Це зробити досить просто в одинарному режимі. Все, що ми хочемо зробити, - це видалити найбільшу потужність 2 із входу. Ми можемо порівняти потужність 2 з деякими прямими посиланнями. Насправді простіше зіставити значення форми 2 n -1 , тому ми зробимо це і порівняємо один 1 окремо:

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

Група 1або 1на початку поєднується з синглом, щоб розпочати щось, або вдвічі збігається з тим, що було зроблено в останній ітерації. Так воно співпадає 1, потім 2, потім 4і так далі. Оскільки вони додаються, у нас завжди не вистачає потужності 2, яку ми фіксуємо 1в кінці.

У зв'язку із зворотним подачею лінії, сірник просто видаляється із вхідних даних.



3

PARI / GP, 18 байт

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

Альтернативне рішення:

n->n-2^exponent(n)

Перший, здається, дає неправильні відповіді. Чи має бути n->n-2^logint(n,2)? Другий не підтримується ні в моїй версії PARI / GP, ні у версії, яку використовує tio.run . Це нова функція?
Jeppe Stig Nielsen

@JeppeStigNielsen На жаль, виправлено - ось що я отримую за надсилання зі свого телефону. Так, друга - нова функція.
Чарльз

@JeppeStigNielsen Я щойно перевірив, exponentбув доданий 5 днів тому, порівняно з цим викликом, який було додано вчора. :)
Чарльз

3

Haskell , 32 29 байт

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

Спробуйте в Інтернеті!

-3 байти завдяки @Laikoni

Старіше рішення, 32 байти

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

Спробуйте в Інтернеті!


1
Анонімні функції дозволені, тому вам не потрібно f=в першому варіанті. Додатково z<-2*y=x!zекономить байт: Спробуйте це в Інтернеті!
Лайконі


3

Excel, 36 31 байт

-5 байт завдяки @ IanM_Matrix1

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

Нічого цікавого.


Зменшіть розмір до 31 байта, замінивши ЗАМЕНИТИ на MID: = BIN2DEC (MID (DEC2BIN (A1), 2,99))
IanM_Matrix1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.