Целое число является двоичным тяжелым, если его двоичное представление содержит больше 1
s, чем 0
s, игнорируя при этом ведущие нули. Например, 1 двоично-тяжелый, поскольку его двоичное представление просто 1
, однако 4 не двоично-тяжелый, как его двоичное представление 100
. В случае связи (например, 2 с двоичным представлением 10
) число не считается двоичным.
Учитывая положительное целое число в качестве входных данных, выведите истинное значение, если оно двоично-тяжелое, и ложное значение, если это не так.
Testcases
Формат: input -> binary -> output
1 -> 1 -> True
2 -> 10 -> False
4 -> 100 -> False
5 -> 101 -> True
60 -> 111100 -> True
316 -> 100111100 -> True
632 -> 1001111000 -> False
2147483647 -> 1111111111111111111111111111111 -> True
2147483648 -> 10000000000000000000000000000000 -> False
счет
Это код-гольф, поэтому побеждает меньше байтов на каждом языке
code-golf
number
decision-problem
binary
Skidsdev
источник
источник
Ответы:
Машинный код x86,
1514 байтЭто функция, использующая соглашение о вызовах __fastcall от Microsoft (первый и единственный параметр в ecx, возвращаемое значение в eax, вызываемый объект может закрывать edx), хотя ее можно легко изменить для других соглашений о вызовах, которые передают аргументы в регистрах.
Возвращает 255 как правдивую и 0 как ложную.
Он использует недокументированный (но широко поддерживаемый) код операции
salc
.Разборка ниже:
Попробуйте онлайн!
Спасибо Питеру Кордесу за предложение заменить
lzcnt
наbsr
.источник
popcnt
перед прокруткой вниз, чтобы посмотреть на ответы, но не думал о том,lzcnt
чтобы иметь дело только с существенными цифрами, как того требует вопрос.bsr
вместоlzcnt
(акаrep bsr
)? Вы должны использоватьsub
вместо,lea
так как это дает вам 32-lzcnt. (Или оставляет dst неизмененным для src = 0 на всем существующем оборудовании Intel и AMD. AMD даже документирует это поведение, но Intel говорит, что не определено ... Во всяком случае, OP сказал положительно , что исключает0
.)popcnt
иbsr
, но это было 17 байт. Я думал, что это было довольно хорошо по сравнению с первым ответом на вопрос, который я увидел , но этот хитрыйlea
трюк превосходит его. Я тоже посмотрел на сравнениеbsf
иpopcnt
. Но я не вижу, как это решение можно превзойти, даже принимая во внимание 1 байт, который вы могли бы сохранить, отбросивrep
префикс.salc
не эквивалентно , чтобыsetc al
: последний устанавливаетal
в 1 , если CF установлен, чтобы не 255.salc
равенsbb al, al
, но вы получаете экономию в 1 байт для его кодирования. Кстати, это будет документировано AMD, и это широко поддерживается Intel, с мнемоническим даже наступающим от карты от Intel P6 опкода. Так что это на самом деле довольно безопасно для использования. Кроме того, хорошее улучшение здесь, чтобы думать, чтобы использовать эту инструкцию! Это в основном то, что сделал мой первоначальный черновик, за исключением того, что (1) я использовал код x86-64, поэтомуinc
для кодирования было вдвое больше времени, и (2) я не думалsalc
, поэтому выполнял ту же работу в более длинный путь Жаль, что я могу проголосовать только один раз.Желе , 5 байт
Выдает непустой вывод (истинный) или пустой вывод (ложный).
Попробуйте онлайн!
Как это устроено
источник
Bo-S
, но я не мог найти 1-байтовый атом, который преобразовал бы положительное / не положительное в правдивое / ложное ...Æṃ
не существовало.Python 2 , 35 байт
Попробуйте онлайн!
Старый ответ, 38 байт
Выводы
0
как ложные и /-2
или-1
правдивыеПопробуйте онлайн!
источник
bin
причины этого решения проблемы?max
работы. В случае привязки max вернет первое значение в итерируемом, которое имеет максимальное значение. Этот код использует этот факт, чтобы убедиться, что 1 возвращается в случае связи, что фактически означает, что существует больше единиц, чем нулей, так как дополнительный ноль был добавленbin
. Это будет на самом деле неправильно, если написано таким образом, если бы не дополнительный ноль.cmp
возвращается,0
когда они оба равныОктава , 18 байт
TIO не работает, так как инструментарий связи не включен. Это можно проверить на Octave-Online .
Как это работает:
de2bi
преобразует десятичное число в двоичный числовой вектор, а не в строку, как этоdec2bin
делает.mode
возвращает наиболее частую цифру в векторе. По умолчанию это самый низкий уровень в случае ничьей.источник
JavaScript (ES6),
3634 байтаисточник
f=(n,x=0)=>n?f(n>>>1,x+=n%2-.5):x>0
для 35 байтов.n>>1
вместо того,n>>>1
чтобы сохранить байт, так как ввод никогда не бывает отрицательным.n/2|0
не лучше: /MATL , 3 байта
Попробуйте онлайн!
Я действительно не знаю MATL, я только заметил, что это
mode
может сработать в ответе Octave от alephalpha, и решил, что в MATL есть какой-то эквивалент.источник
Mathematica, 22 байта
Сохранено один байт благодаря @MartinEnder и @JungHwanMin .
источник
@@
.#>#2&@@#~DigitCount~2&
Брахилог , 6 байт
Попробуйте онлайн!
объяснение
Поскольку
ḃ
никогда не объединять свой вывод со списком цифр с ведущими нулями, мы знаем, что вхождения1
всегда будут первыми, а вхождения0
всегда будут вторыми послеọ
.источник
Python 3 ,
44(спасибо @ c-mcavoy) 40 байтПопробуйте онлайн!
источник
C (gcc) ,
51484140 байтПопробуйте онлайн!
источник
unsigned
n>>=1
наn/=2
. Я также думаю, что вы можете использовать~n
вместоn^-1
, что также должно позволить вам перейти&&
на&
n
, и не берите в голову изменение&&
на&
, я не думаю, что это будет работать. Но,*
похоже, это работает&&
Только для обработки беззнакового случая, но так как мне нужно обрабатывать только положительные целые числа, я могу удалить все это вместе. Хороший pouint о/=
том, что короче,>>=
хотя, спасибо!n&1?++i:--1
наi+=n%2*2-1
. Вы также можете избавиться от>0
этого, заявив, что вы получите ноль для тяжелого и ненулевой для не тяжелогоR ,
545351 байт-1 байт благодаря Max Lawnboy
читает со стандартного ввода; возвращает
TRUE
двоичные тяжелые числа.d
количество двоичных цифр;sum(n%/%2^(0:d)%%2
вычисляет сумму цифр (т. е. количество единиц).Попробуйте онлайн!
источник
log2(n)
вместо того,log(n,2)
чтобы сохранить 1 байтмашинный код x86_64,
232221 байтРазобрал:
Спасибо @Ruslan, @PeterCordes за
-1
байт!Попробуйте онлайн!
источник
8d 1f
вместо89 fb
?add eax, 2
+dec eax
, но ваши комментарии предполагают, что вы хотите увеличитьebx
, а неeax
.jnz Next
/add
/dec
(7 байтов) наlea -1(%rax, %rbx, 2), %eax
(4 байта), чтобы сделатьeax += 2*ebx - 1
(как в другом ответе машинного кода x86 ). Затем за пределами циклаneg %eax
(2 байта), прежде чем сдвинуть бит знака вниз. Чистая экономия 1 байта. Илиtest %eax,%eax
/setge %al
также будет работать, если ваше возвращаемое значение равноbool
илиint8_t
.lea -1(%rax,rbx,2)
а толькоlea -1(%eax,%eax,2)
и тратить байты таким образом ... В любом случае, вы оба были правы, я могу сохранить такой байт, как этот. Большое спасибо (взамен я изменюlea
это,mov
пока я в этом)!Perl 6 ,
3230 байтПроверь это
Проверь это
Expanded:
источник
Мудрый ,
4039 байтПопробуйте онлайн!
объяснение
источник
Хаскелл,
4134Если
n
это нечетно, возьмите,-1
если это четное, возьмите1
. Добавить рекурсивный вызов с помощьюn/2
и прекратить, еслиn = 0
. Если результат меньше, чем0
число является двоичным тяжелым.Попробуйте онлайн!
Редактировать: @ Ørjan Йохансен нашел несколько ярлыков и сохранил 7 байтов. Спасибо!
источник
mod n 2
может быть простоn
, и это меньше байта без аккумулятора. Попробуйте онлайн!Сетчатка ,
3734 байтаПопробуйте онлайн! Ссылка включает в себя меньшие тестовые случаи (более крупные, вероятно, не хватило бы памяти). Редактировать: 3 байта сохранены благодаря @MartinEnder. Объяснение: Первый этап преобразуется из десятичного в унарный, а следующие два этапа преобразуются из унарного в двоичный (это почти прямо из унарной арифметической страницы в вики Retina, за исключением того, что я использую
@
вместо0
). Третий этап ищет пары разнородных символов, которые могут быть как@1
или1@
, так и удаляет их, пока не останется ни одного. Последний этап затем проверяет оставшиеся 1 с.источник
${1}
может быть$+
. Или вы можете использовать!
вместо,0
а затем сократить01|10
до.\b.
.$+
ли правильно, когда шаблон содержит|
? Интересно, мог бы я использовать это раньше ...$+
это супер глупо и просто использует группу с наибольшим номером, независимо от того, использовалась она или нет. Это полезно только для игры в гольф, когда у вас более девяти групп или в ситуации, подобной той, что здесь, и я не знаю, почему я когда-либо использовал это в регулярных выражениях.R , 43 байта
Попробуйте онлайн!
источник
intToBits
Котлин , 50 байтов
Лямбда неявного типа
(Int) -> Boolean
. Версия 1.1 и выше только за счет использованияInt.toString(radix: Int)
.К сожалению, среда выполнения Kotlin в TIO выглядит как 1.0.x, так что вместо ссылки TIO здесь есть грустная собака:
источник
Pyth,
97 байтПопробуй это здесь.
-2 благодаря FryAmTheEggman .
источник
>ysJjQ2lJ
.B
!)R,
3937 байтЭто комбинация методов, используемых @MickyT и @Giuseppe, сохраняя еще несколько байтов.
sum(intToBits(x) > 0)
подсчитывает количество1
бит и2+log2(x)/2
составляет половину от общего количества бит при округлении в меньшую сторону. Нам не нужно округлять из-за поведения, когда два значения равны.источник
C # (.NET Core) ,
62, 49 байтовБез LINQ.
РЕДАКТИРОВАТЬ: дана с -13 байтовым гольфом, изменяющим время на рекурсивный для и возвращающим бул вместо целого числа.
Попробуйте онлайн!
источник
Регулярное выражение (ECMAScript),
857371 байтПопробуйте онлайн!
объяснение по Deadcode
Более ранняя 73-байтовая версия описана ниже.
^((?=(x*?)\2(\2{4})+$)\2|(?=(x*?)(\4\4xx)*$)(\4|\5(x*)\7\7(?=\4\7$)\B))+$
Из-за ограничений регулярного выражения ECMAScript эффективная тактика часто заключается в преобразовании числа на один шаг за раз, сохраняя при этом обязательное свойство неизменным на каждом этапе. Например, чтобы проверить идеальный квадрат или степень 2, уменьшите число в размерах, сохраняя при этом квадрат или степень 2 (соответственно) на каждом шаге.
Вот что делает это решение на каждом этапе:
1
1
1
10
01
01
Когда эти повторяющиеся шаги не могут идти дальше, конечным результатом будет либо непрерывная цепочка
1
битов, которая является тяжелой и указывает, что исходное число также было тяжелым, либо степень 2, что указывает на то, что исходное число не было тяжелым.И конечно, хотя эти шаги описаны выше в терминах типографских манипуляций над двоичным представлением числа, они фактически реализованы как унарная арифметика.
источник
\5
на одно отключены). Я изучил это, объяснил и прокомментировал это в своем ответе (потому что StackExchange не разрешает многострочные ответы).Регулярное выражение (ECMAScript), 183 байта
Это была еще одна интересная проблема, которую нужно решить с помощью регулярного выражения ECMA. «Очевидный» способ справиться с этим - подсчитать количество
1
битов и сравнить их с общим количеством битов. Но вы не можете напрямую сосчитать вещи в регулярном выражении ECMAScript - отсутствие постоянных обратных ссылок означает, что в цикле можно изменить только одно число, и на каждом шаге его можно только уменьшить.Этот унарный алгоритм работает следующим образом:
1
бит в наименее значимое положение, где есть0
бит. Каждый из этих шагов является вычитанием. В конце цикла оставшееся число (как оно будет представлено в двоичном виде) представляет собой строку1
s без0
s. Эти операции фактически выполняются в унарном порядке; это только концептуально, что они делаются в двоичном формате.1
s" с квадратным корнем, полученным ранее. Если квадратный корень нужно было округлить в меньшую сторону, используйте двойную версию. Это гарантирует, что «двоичная строка1
s» должна иметь более половины числа двоичных цифр, чем N, чтобы иметь место окончательное совпадение.Чтобы получить квадратный корень, используется вариант алгоритма умножения, кратко описанного в моем посте регулярных выражений чисел Рокко . Чтобы идентифицировать младший значащий
0
бит, используется алгоритм деления, кратко описанный в моем посте регулярных выражений факторных чисел . Это спойлеры . Так что не читайте дальше, если вы не хотите, чтобы какая-то продвинутая магия унарных регулярных выражений была испорчена для вас . Если вы действительно хотите сами разобраться в этой магии, я настоятельно рекомендую начать с решения некоторых проблем в списке последовательно рекомендованных проблем с помеченными спойлерами в этом предыдущем посте и попытаться найти математическое понимание самостоятельно.Без дальнейших церемоний, регулярное выражение:
^(?=.*?(?!(x(xx)+)\1*$)(x)*?(x(x*))(?=(\4*)\5+$)\4*$\6)(?=(((?=(x(x+)(?=\10$))*(x*))(?!.*$\11)(?=(x*)(?=(x\12)*$)(?=\11+$)\11\12+$)(?=.*?(?!(x(xx)+)\14*$)\13(x*))\16)*))\7\4(.*$\3|\4)
Попробуйте онлайн!
источник
Желе , 6 байт
Попробуйте онлайн!
источник
Bo-S
может использоваться для вычисления двоичного «веса» входных данных, к сожалению, самый короткий способ использования, который, по-видимому,Bo-S>0
...Ḷ
работает: PJ , 12 байт
J выполняет глаголы справа налево, поэтому давайте начнем с конца и продолжим путь к началу.
объяснение
источник
(#<2*+/)@#:
должен сохранить 1, если я что-то упустил.Юлия, 22 байта
источник
Октава , 26 байт
Попробуйте онлайн!
источник
mode(dec2bin(a)-48)
PHP , 44 байта
Попробуйте онлайн!
PHP , 48 байт
Попробуйте онлайн!
источник
Python 2 , 44 байта
Попробуйте онлайн!
Старый ответ, 47 байт
Это просто порт ответа C cleblanc . Это длиннее, чем другие ответы Python, но я решил, что это стоит опубликовать, поскольку это совершенно другой метод поиска ответа.
Попробуйте онлайн!
источник
C #, 82 байта
источник
n=>{var s=Convert.ToString(n,2);return s.Count(c=>c=='1')>s.Length/2;}
Convert
и включитьusing System.Linq;
(написано короче какnamespace System.Linq{}
). Хорошая идея просто не бреет достаточно, чтобы оправдать экономию в этом случае.