Это версия недавнего вызова. Является ли это число целым числом -2? с другим набором критериев, разработанных, чтобы подчеркнуть интересный характер проблемы и усложнить задачу. Я положил некоторые соображения в это здесь .
Задача, замечательно сформулированная Тоби в связанном вопросе:
Есть умные способы определить, является ли целое число точной степенью 2. Это больше не интересная проблема, поэтому давайте определим, является ли данное целое число точной степенью -2 . Например:
-2 => yes: (-2)¹ -1 => no 0 => no 1 => yes: (-2)⁰ 2 => no 3 => no 4 => yes: (-2)²
Правила:
- Целое число - 64 бита, со знаком, два дополнения. Это единственный тип данных, с которым вы можете работать.
- Вы можете использовать только следующие операции. Каждый из них считается одной операцией.
n << k
,n >> k
: Сдвиг влево / вправоn
поk
битам. Бит знака расширяется при сдвиге вправо.n >>> k
: Сдвиг вправо, но не удлиняется бит знака. 0 сдвинуты в.a & b
,a | b
,a ^ b
: Побитовое И, ИЛИ, исключающее ИЛИ .a + b
,a - b
,a * b
: Сложение, вычитание, умножение.~b
: Побитовый инвертирование-b
: Отрицание дополнения двух.a / b
,a % b
: Делить (целое частное, округляет до 0) и по модулю.- По модулю отрицательных чисел используются правила, указанные в C99 :
(a/b) * b + a%b
равныa
. Так5 % -3
есть2
и-5 % 3
есть-2
: 5 / 3
есть1
,5 % 3
есть2
, как 1 * 3 + 2 = 5.-5 / 3
есть-1
,-5 % 3
есть-2
, как -1 * 3 + -2 = -5.5 / -3
есть-1
,5 % -3
есть2
, как -1 * -3 + 2 = 5.-5 / -3
есть1
,-5 % -3
есть-2
, как 1 * -3 + -2 = -5.- Обратите внимание, что
//
оператор деления по полу в Python здесь не удовлетворяет свойству деления «в сторону 0», и%
оператор Python также не удовлетворяет требованиям.
- По модулю отрицательных чисел используются правила, указанные в C99 :
- Задания не считаются операцией. Как и в C, назначения оценки к значению левой стороны после выполнения задания:
a = (b = a + 5)
наборыb
дляa + 5
, то наборыa
кb
, и рассчитывает как одну операцию. - Сложные задания могут использоваться
a += b
средствамиa = a + b
и считаться одной операцией.
- Вы можете использовать целочисленные константы, они не считаются ничем.
- Скобки для указания порядка операций допустимы.
- Вы можете объявить функции. Объявления функций могут быть в любом удобном для вас стиле, но обратите внимание, что 64-битные целые числа являются единственным допустимым типом данных. Объявления функций не считаются операциями, но вызов функции считается одним. Кроме того, чтобы быть ясным: функции могут содержать несколько
return
операторов иreturn
допускаются с любой точки. Само поreturn
себе не считается операцией. - Вы можете объявить переменные бесплатно.
- Вы можете использовать
while
петли, но вы не можете использоватьif
илиfor
. Операторы, используемые вwhile
условии, засчитываются в ваш счет.while
Циклы выполняются до тех пор, пока их состояние оценивается как ненулевое значение («истинный» 0 в языках, которые имеют эту концепцию, не является допустимым результатом). С раннего возврата допускается, вы имеете право использовать ,break
а также - Переполнение / переполнение допускается, и фиксация значения не производится. Считается, что операция действительно произошла правильно, а затем была усечена до 64 бит.
Критерии оценки / выигрыша:
Ваш код должен выдавать значение, отличное от нуля, если на входе есть степень -2, и ноль в противном случае.
Это атомный код-гольф . Ваша оценка - это общее количество операций, присутствующих в вашем коде (как определено выше), а не общее количество операций, выполняемых во время выполнения. Следующий код:
function example (a, b) {
return a + ~b;
}
function ispowerofnegtwo (input) {
y = example(input, 9);
y = example(y, 42);
y = example(y, 98);
return y;
}
Содержит 5 операций: две в функции и три вызова функций.
Неважно, как вы представляете свой результат, используете все, что удобно на вашем языке, будь то в конечном итоге сохранение результата в переменной, возвращение его из функции или что-то еще.
Победителем становится должность, которая является явно корректной (предоставьте случайное или формальное доказательство, если необходимо) и имеет наименьший балл, как описано выше.
Бонус Очень Сложный Режим Challenge!
Чтобы получить шанс выиграть абсолютно ничего, кроме потенциальной способности произвести впечатление на людей на вечеринках, отправьте ответ без использования while
петель! Если их будет достаточно, я могу даже рассмотреть вопрос о разделении выигрышных групп на две категории (с петлями и без них).
Примечание. Если вы хотите предоставить решение на языке, который поддерживает только 32-разрядные целые числа, вы можете сделать это при условии, что вы достаточно обосновываете, что оно все равно будет правильным для 64-разрядных целых чисел в объяснении.
Также: некоторые специфичные для языка функции могут быть разрешены бесплатно, если они не обходят правила, но необходимы для того, чтобы заставить ваш язык вести себя в соответствии с вышеуказанными правилами . Например (я придумал), я разрешаю сравнение « не равно 0» в while
циклах применительно к условию в целом, как обходной путь для языка с «истинными» 0. Явные попытки воспользоваться этими вещами недопустимы - например, концепция «истинных» 0 или «неопределенных» значений не существует в приведенном выше наборе правил, поэтому на них нельзя полагаться.
источник
m ^= s
этого все еще впечатляет, и я думаю, что было бы вполне нормально сделать замену, чтобы улучшить ее еще больше.while
и ,break
но неif
?if (x) { ... }
эквивалентноwhile (x) { ... break; }
.break
и досрочное возвращение - достойная сожаления часть), и это длинная история и урок, извлеченный из правил для будущих вызовов. Всегда есть «бонусная» версия! :)if
иfor
не разрешено?int x=condition; while (x) { ... x=0; }
бесплатно, просто больше кода. То же самое с с-стилемfor
.Ответы:
C ++, 15 операций
Я понятия не имею, почему
while
допускаются петли, поскольку они разрушают весь вызов. Вот ответ без каких-либо:источник
while
петли уничтожают весь вызов ?while
всячески противоречит этому.n
или чего-то еще.uint64_t
потому что это единственный способ получить правильный сдвиг без расширения знака)Python 2 , 3 операции
Попробуйте онлайн!
Эти операции
>>
,&
,/
.Идея состоит в том, чтобы повторно делить на -2. Полномочия -2 цепи вплоть до 1:
-8 -> 4 -> -2 -> 1
. Если мы нажмем1
, примите. Если мы нажмем нечетное число, прежде чем нажать1
, отклонить. Нам также нужно отказаться0
, что навсегда уходит само собой.while n>>1:
Петель до тех пор ,n
пока 0 или 1. Когда цикл прерывается,n
сам по себе возвращается, и1
является выходом Truthy и0
Falsey один. Внутри цикла мы неоднократно отвергаем применениеn -> n/-2
и отклоняем любые нечетныеn
.Поскольку
/
всегда используется только для четных значений, его поведение округления никогда не вступает в игру. Таким образом, не имеет значения, что Python округляется иначе, чем спецификация.источник
while n&1
вместоif n&1
?if
.Ржавчина,
1412 операций (без петель)Требуется оптимизация (
-O
) или-C overflow-checks=no
включение вычитания с переполнением вместо паники.(Для уточнения:
!x
это побитовое НЕ здесь, а не логико-НЕ)Тестовые случаи:
Попробуйте онлайн!
Идея состоит в том, чтобы проверить, если | x | это степень 2 (используя
(y & (y - 1)) == 0
как обычно). Если x является степенью 2, то мы дополнительно проверяем (1), когдаx >= 0
, это также должно быть четной степенью 2, или (2), когдаx < 0
, это должно быть нечетной степенью 2. Мы проверяем это с помощью&
-ing "bad_power_of_two
"маскировать 0x… aaaa когдаx >= 0
(выдает 0 только когда это четная сила) или 0x… 5555 когдаx < 0
.источник
~((r | -r) >> 63)
трюк, чтобы закончить исправлять мой ответ.Haskell,
23 операцииОпределяет рекурсивную функцию
f(n)
. Используются следующие операции: вызов функции (f
), деление (div
), а также побитовое и (.&.
).Не содержит циклов из-за того, что в Haskell нет операторов цикла :-)
источник
f 0
,f 1
,f n ...
здесь , потому что они, по существу ,if
«S в маскировке, но опять же , я позволитьwhile
+break
и раноreturn
s, так что кажется справедливым. Хотя мне кажется, что мой набор правил непреднамеренно оставлен открытым для интерпретации, это хорошее решение.|
они особенно в воздухе. Тем не менее, это нарушает одно конкретное правило менее спорным способом: сравнение==
не допускается. Однако следует отметить, что если моя интерпретация этого кода является правильной, использование булевых здесь же появляется приемлемым, подставляя произвольные целые значения на их месте не появляется , чтобы изменить результаты, и они больше конечной формы представления.==
потому, что в Haskell нет другого способа разыграть изInt
toBool
или "Truthy". Является ли совпадение по шаблону и охранники нарушениемif
правила "нет s" - ваш звонок ;-)Python 3,
10 или 119 операцийВозвращает
5
за полномочия-2
, в0
противном случаеисточник
С, 5 операций
С, 10 операций, без петель
С, 1 операция
источник
Сборка, 1 операция
Использует огромную таблицу поиска, чтобы определить, является ли число степенью 2. Вы можете расширить это до 64 бит, но поиск компьютера для хранения такого количества данных останется в качестве упражнения для читателя :-P
источник
С, 31 операция
Live Demo
Моя идея проста: если это степень двойки, то, если ее журнал четен, то он должен быть положительным, в противном случае его журнал должен быть нечетным.
источник
С, 7 операций
или:
C, 13 операций без циклов как условия
Объяснение:
n&-n
дает самый низкий набор битn
.a
является отрицательным абсолютным значениемn/2
, обязательно отрицательным, потому что/2
предотвращает переполнение отрицания.a/x
равен нулю только в том случае, еслиa
является точной степенью двойки; в противном случае устанавливается по крайней мере еще один бит, и он больше, чемx
младший бит, что дает отрицательный результат.~(a/x >> 63)
затем выдает битовую маску, которая является единичными, еслиn
или-n
является степенью двойки, в противном случае - все нули.^s
применяется к маске, чтобы проверить знак,n
чтобы увидеть, если это сила-2
.источник
PHP, 3 операции
троичные и
if
не разрешены; так что давайте ругатьwhile
:$n>>1
: если число 0 или 1, возвращаемый номер$n&1
: если число нечетное, вернуть 0$n/-2
(+ приведение к int)источник
JavaScript ES6, 7 операций
Попробуйте онлайн!
объяснение
В то время как x! = 0 и x% 2 == 0 4 ops
x / x равен 1, при условии, что x не равен 0 (0/0 дает NaN, который оценивается как ложный)
& побитово, а
x & 1 ^ 1 равно 1 если х четный (х и 1) хор 1
Это форма деления, определяемая вопросом 1 оп
Хотя x! = 1 и x! = 0 1 op
Условие, необходимое для выхода, когда x == 0 или x == 1, так как эти два являются возвращаемыми значениями, и вход в бесконечный цикл не будет продуктивным. Теоретически это можно расширить для больших значений, увеличив шестнадцатеричное число. В настоящее время работает до ± 2 ^ 32-1
Установите x в 0 1 op
Хотя я мог бы использовать return 0 для 0 ops, я чувствовал, что любой цикл while, который прерывается другим оператором, слишком похож на обман.
возвращает x (1, если степень -2, 0 в противном случае)
источник