задача
Учитывая положительное целое число n
, выведите, n+1
если n
нечетное, и выведите, n-1
если n
является четным.
вход
Целое положительное число. Вы можете предположить, что целое число находится в пределах возможностей обработки языка.
Выход
Целое положительное число, указанное выше.
Testcases
input output
1 2
2 1
3 4
4 3
5 6
6 5
7 8
8 7
313 314
314 313
счет
Это код-гольф , поэтому выигрывает самый короткий ответ в байтах.
Применяются стандартные лазейки .
Ответы:
C, 20 байтов
Попробуйте онлайн .
источник
Stack Cats , 3 + 3 (
-n
) = 6 байтПопробуйте онлайн!
Требуется
-n
флаг для работы с числовым вводом и выводом.объяснение
Stack Cats, как правило, далека от конкуренции из-за своего ограниченного набора команд (все из которых являются инъекциями, и большинство из которых являются инволюциями) и потому что каждая программа должна иметь зеркальную симметрию. Однако одна из инволюций состоит в переключении младшего значащего бита числа, и мы можем сместить значение с помощью унарного отрицания, которое также существует. К счастью, это дает нам симметричную программу, поэтому нам не нужно беспокоиться ни о чем другом:
Ввод и вывод неявны в начале и конце программы, потому что ввод и вывод не являются обратимой операцией, поэтому они не могут быть командами.
источник
perl -nle 'stuff'
на 2 символа большеperl -e 'stuff'
, поэтому он рассчитывает еще на 2 символа ». Так(space)-n
что на 3 байта больше, чем без флага.-e "code"
а затем вставлять дополнительные флаги передe
, например-pe "code"
. Тогда-p
флаг равен только одному байту. Однако у Stack Cats такого-e
аргумента нет, поэтому вам всегда нужно добавлять полное<sp>-n
значение в команду, и, следовательно, это три байта.Сборка x86, 9 байт (для конкурирующей записи)
Каждый, кто пытается решить эту проблему на языках высокого уровня, упускает истинное удовольствие от манипулирования необработанными битами. Есть так много тонких вариантов способов сделать это, это безумие - и очень интересно думать. Вот несколько решений, которые я разработал на 32-битном языке ассемблера x86.
Заранее извиняюсь, что это не типичный код-гольф-ответ. Я собираюсь много рассказать о мыслительном процессе итеративной оптимизации (для размера). Надеюсь, это интересно и познавательно для широкой аудитории, но если вы тип TL; DR, я не буду обижаться, если вы пропустите до конца.
Очевидное и эффективное решение состоит в том, чтобы проверить, является ли значение нечетным или четным (что можно эффективно сделать, посмотрев на младший значащий бит), и затем выбрать между n + 1 или n-1 соответственно. Предполагая, что входные данные передаются в качестве параметра в
ECX
регистр, а результат возвращается вEAX
регистр, мы получаем следующую функцию:(13 байт)
Но для целей кода-гольфа эти
LEA
инструкции не очень хороши, поскольку для их кодирования требуется 3 байта. ПростоеDEC
замечаниеECX
будет намного короче (всего один байт), но это влияет на флаги, поэтому мы должны быть немного хитрыми в том, как мы размещаем код. Мы можем сделать декремент первый , и четное / нечетное тест второго , но тогда мы должны инвертировать результат нечетного / даже тест.Кроме того, мы можем изменить инструкцию условного перемещения на ветвь, что может сделать код более медленным (в зависимости от того, насколько предсказуема ветвь - если входные данные чередуются между нечетным и четным, ветвь будет медленнее; если есть шаблон, это будет быстрее), что сэкономит нам еще один байт.
Фактически, с этой ревизией вся операция может быть выполнена на месте, используя только один регистр. Это замечательно, если вы где-то вставляете этот код (и, скорее всего, так и будет, так как он очень короткий).
(встроенный: 7 байтов; как функция: 10 байтов)
Но что, если вы захотите сделать это функцией? Ни одно стандартное соглашение о вызовах не использует тот же регистр для передачи параметров, как и для возвращаемого значения, поэтому вам нужно добавить
MOV
инструкцию register-register в начало или конец функции. Это практически не влияет на скорость, но добавляет 2 байта. (RET
Инструкция также добавляет байт, и есть некоторые накладные расходы, связанные с необходимостью выполнения и возврата из вызова функции, что означает, что это один из примеров, когда встраивание дает выигрыш как в скорости, так и в размере, а не просто в классической скорости -for-space trade.) Во всем, написанном как функция, этот код увеличивается до 10 байтов.Что еще мы можем сделать в 10 байтов? Если мы вообще заботимся о производительности (по крайней мере, о предсказуемой производительности), было бы неплохо избавиться от этой ветви. Вот решение без разветвлений с одинаковым размером в байтах. Основная предпосылка проста: мы используем побитовый XOR, чтобы перевернуть последний бит, преобразовав нечетное значение в четное, и наоборот. Но есть один недостаток - для нечетных входов, который дает нам n-1 , в то время как для четных входов он дает нам n + 1 - точно противоположное тому, что мы хотим. Итак, чтобы исправить это, мы выполняем операцию с отрицательным значением, эффективно переворачивая знак.
(встроенный: 7 байтов; как функция: 10 байтов)
Довольно гладкий; трудно понять, как это можно улучшить. Однако, одна вещь бросается в глаза: эти две 2-байтовые
NEG
инструкции. Честно говоря, два байта кажутся слишком большими, чтобы закодировать простое отрицание, но это набор инструкций, с которым мы должны работать. Есть ли обходные пути? Конечно! Если мыXOR
-2, мы можем заменить второеNEG
действие наINC
rement:(встроенный: 6 байтов; как функция: 9 байтов)
Еще одна странность набора команд x86 - это многоцелевая
LEA
команда , которая может перемещать регистр-регистр, добавлять регистр-регистр, смещать на константу и масштабировать все в одной инструкции!(10 байт)
AND
Инструкция какTEST
инструкции мы использовали ранее, в том , как сделать побитовую И и установить флаги соответственно, но наAND
самом деле обновляет назначение операнда. ЗатемLEA
инструкция масштабирует это на 2, добавляет исходное входное значение и уменьшает на 1. Если входное значение было нечетным, это вычитает из него 1 (2 × 0 - 1 = -1); если входное значение было четным, это добавляет 1 (2 × 1 - 1 = 1) к нему.Это очень быстрый и эффективный способ написания кода, так как большая часть выполнения может быть выполнена во внешнем интерфейсе, но это не дает нам больших затрат в виде байтов, поскольку для кодирования комплекса требуется очень много
LEA
инструкция. Эта версия также не подходит для встраивания, поскольку требует сохранения исходного входного значения в качестве вводаLEA
инструкции. Так что с этой последней попыткой оптимизации мы на самом деле пошли назад, предполагая, что пора остановиться.Таким образом, для последней конкурирующей записи у нас есть 9-байтовая функция, которая принимает входное значение в
ECX
регистре (полустандартное соглашение о вызовах на основе регистров в 32-битной x86) и возвращает результат вEAX
регистр (как в случае с все соглашения о вызовах x86):Готов к сборке с MASM; позвонить из C как:
источник
dec eax; xor eax, 1; inc eax
работать и сохранить еще один байт?Желе , 3 байта
Попробуйте онлайн!
псевдокод:
abs((-1)**n - n)
источник
-1
.Python3,
2018 байтДовольно просто Сначала мы вычисляем n-1 и решаем, добавлять ли 2 к нему или нет.
Если n чётно -> n mod 2 будет 0, таким образом, мы добавим 2 * 0 к n-1 , что приведет к n-1 .
Если n нечетно -> n mod 2 будет 1, таким образом, мы добавим 2 * 1 к n-1 , что приведет к n + 1 .
Я предпочитаю объяснение, которое я сделал с MS paint & touchpad для ноутбука ...
источник
Python, 16 байт
Попробуйте онлайн!
источник
"x+-012~|&^()*/%"
.-(1^-x)
.MATL , 7 байт
Это позволяет избежать любых арифметических операций. Попробуйте онлайн!
объяснение
Рассмотрим ввод
4
в качестве примера.источник
Braingolf v0.1 ,
1110 байтПопробуйте онлайн! (Второй аргумент - код Брейнгольфа, третий аргумент - ввод)
Сохранил байт благодаря Нейлу
Первый в истории конкурирующий ответ Braingolf: D
Объяснение:
Braingolf v0.2 , 9 байт [не конкурирует]
Попробуйте онлайн! (Второй аргумент - код Брейнгольфа, третий аргумент - ввод)
См. Выше для объяснения. Единственное различие заключается в Braingolf v0.2, поведение диадических операторов по умолчанию и функция
,
модификатора обращены в обратную сторону, что означает, что две запятые в ответе v0.1 больше не нужны.Однако v0.2 был выпущен после испытания, так что этот не конкурирующий
источник
.1<2,%?+:-
я то, что думаю?-
как она будет правильно выполнять операцию, и в этом случае она будет иметь ту же длину, что и мой ответ<
чтобы повернуть1
ниже входа, так что это было бы в правильном месте уже.-
стека, выглядит следующим образом:[n,1]
операторы braingolf обращаются вспять, поэтому он будет выполнять1 - n
, что приведет-(n-1)
к желаемому результату простоn-1
Cubix ,
109 байтовПопробуйте онлайн
объяснение
Сетевая версия
Выполненные символы
источник
Python, 68 байт
В духе уникального подхода. На следующем графике показана функция (с фиолетовыми точками, представляющими первые 10 случаев). Теоретически должно быть возможно построить решение этого вопроса на основе большинства (всех?) Периодических функций (например, sin, tan, sec). Фактически, замена cos на sec в коде должна работать.
источник
PHP, 15 байт
источник
;
требуется ли, и пытался использовать.php
файл, а также эхом напрямую в php (php7 cli.) Каждый раз, когда мне говорят, что$argn
это неопределенная переменная.F
флагом и конвейеромecho 42 | php -F script.php
.Javascript,
1712 байтДругой подход,
украдено10 байтиз ответа C (сссшхх)источник
x=>x-(-1)**x
|0
? Оба решения выглядят так, как будто они должны автоматически преобразовывать строки в числа. (Для первого решения, если вы хотите избежать десятичных дробей, используйте<input type=number>
.)JavaScript (ES6),
14131210 байтПопытайся
Оригинал, 12 байт
источник
Python, 20 байт
n%2or-1
вернет 1, если он нечетный, но если он четный,n%2
имеет значение «false» (0), поэтому вместо него возвращается -1. Затем мы просто добавляем это кn
.Предыдущее решение, 23 байта
n%2
вычисляет остаток от деленияn
на 2. Если оно четное, возвращается 0, а элемент 0 в этом списке равенn-1
. Если это нечетно, это возвращает 1, и элемент 1 в этом списке естьn+1
.источник
lambda n:[n-1,n+1][n%2]
Сетчатка , 21 байт
Попробуйте онлайн! Мой первый ответ Retina с двумя знаками перевода строки! Объяснение: Первые две строки преобразуются из десятичной в унарную. Третья и четвертая строки вычитают две из четных чисел. Последняя строка конвертируется обратно в десятичную, но тоже добавляет одну.
источник
05AB1E , 4 байта
Попробуйте онлайн!
источник
Èi>ë<
это так мило;_;
.Cubix , 11 байт
Попробуйте онлайн!
объяснение
Сетевая версия:
Символы выполняются в следующем порядке:
источник
Brain-Flak , 36 байт
Попробуйте онлайн!
Лично я очень доволен этим ответом, потому что он намного короче, чем я бы назвал традиционным методом решения этой проблемы.
объяснение
Первый бит кода
преобразует стек от просто
n
кТогда, пока вершина стека не равна нулю, мы уменьшаем его и переворачиваем знак числа под ним
Мы удаляем ноль и добавляем два оставшихся числа
источник
Mathematica,
2219 байтовСохранено 3 байта благодаря Грегу Мартину!
Предыдущий ответ, 22 байта
Пояснение (для предыдущего ответа)
Mathematica имеет приятную особенность, заключающуюся в том, что такие операции, как арифметика, автоматически пронизывают списки.
В этом случае мы берем
Mod[#,2]
0 или 1, но нам нужно добавить 1, потому что списки Mathematica индексируются 1. Если это даже , это выходит на 1, поэтому#-1
возвращается. Если это нечетно , получается 2, поэтому#+1
возвращается.источник
[[0]]
возможности:#-1[-1][[#~Mod~2]]&
.Мудрый , 8 байт
Попробуйте онлайн!
объяснение
Если бы все было наоборот (уменьшить, если нечетное, увеличить, если четное), это было бы довольно легко сделать.
Мы бы просто перевернули последний бит.
Исправление здесь состоит в том, что мы переворачиваем последний бит, в то время как отрицательный. Отрицательные числа равны 1 от отрицания чисел,
~
так что это создает смещение, решающее проблему.Таким образом, мы просто вынимаем программу и оборачиваем ее
-
.источник
Java 8,
1610 байтJava 7,
3428 байтСкучные порты удивительного C-ответа @feersum .
Попробуй это здесь.
Старые ответы:
Java 8, 16 байт
Java 7, 34 байта
Объяснение (старого ответа Java 7):
Попробуй это здесь.
Ответ выше - более короткий вариант
int c(int n){return n%2<1?n-1:n+1;}
избавления от места.источник
Japt , 6 байт
Попробуйте онлайн!
источник
Python, 20 байт
источник
Befunge 93 , 18 байт
Я еще не закончил игру в гольф (я надеюсь).
источник
kv
(или,jv
если оно строго 1 или 0) вместо#v_
. Кроме того, если вы используете « Попробовать онлайн» (и я рекомендую его), вы можете завершить программу другой&
(хотя это займет 60 секунд), так что вы можете избавиться от@
первой строки, если будете ее использовать. Вот полный список команд для Befunge-98 , хотя не все они могут быть правильно реализованы в TIO, как, например,&
завершение программы вместо обращения к EOF.Рубин, 12 байт
источник
R, 17 байт
где
n=scan()
принимает значение цифры.источник
-(-1)^n
а не+(-1)^n
так как мы должны вернуться,n-1
еслиn
дажеCasio-Basic, 27 байтов
26 байт для функции, +1 для ввода
n
в поле параметров.источник
C, 29 байт
источник
Желе , 4 байта
Попробуйте онлайн!
источник
Пакетный, 20 байтов
Самостоятельно заново открыл алгоритм @ feersum, честно!
источник