Определите функцию f такую, что f (f (n)) = -n для всех ненулевых целых чисел n


43

Эта проблема была вдохновлена ​​программистским блогом, который я часто посещаю. Пожалуйста, смотрите оригинальный пост здесь: программирование головоломки


Вызов

Определите функцию так f:Q->Q, чтобы f(f(n)) = -nдля всех ненулевых целых чисел nи где Qбыло множество рациональных чисел.

Детали

На любом языке, который вы предпочитаете, определите одну функцию или программу, fкоторая принимает в качестве параметра один номер nи возвращает или выводит один номер f(n).

Ввод может быть осуществлен с помощью любого наиболее естественного для вашего языка механизма: аргумент функции, чтение из STDIN, аргумент командной строки, позиция стека, голосовой ввод, знаки банды и т. Д.

Выходные данные должны быть возвращаемым значением из функции / программы или распечатаны в STDOUT.

Я хотел бы ограничить ответы функциями, которые не используют состояние программы или глобальную память / данные, которые видны снаружи функции f. Например, сохранение счетчика вне fэтого подсчета подсчитывает, сколько раз fбыло вызвано, и просто делать отрицание на основе этого подсчета не очень сложно или интересно для всех. Принятие решений fдолжно опираться только на данные в fлексической области.

Однако это ограничение, вероятно, не подходит для некоторых языков, ориентированных на стек, или для других типов языков, которые не различают эти типы данных или области. Пожалуйста, используйте свое лучшее суждение, чтобы соответствовать духу этой задачи.


счет

Применяются общепринятые правила игры в гольф - ваш счет - это количество байтов в исходном коде.

Минимальный ответ требует, чтобы домен и кодомен fбыли подмножеством рациональных чисел Q. Если вы ограничите свой домен и кодомен fдо целых чисел Z, то ваш счет - это верхний предел 90% количества байтов в вашем исходном коде.

Баадур

В случае ничьей будет использовано следующее:

  1. Наименьшее количество печатаемых непробельных символов в вашем исходном коде
  2. Самая ранняя дата и время подачи ответа

редактировать

Вы не обязаны поддерживать номера произвольного размера. Пожалуйста, интерпретируйте наборы Zи Qтипы данных на выбранном вами языке (обычно целочисленные и с плавающей запятой соответственно).

Если ваше решение полностью основано на базовой структуре или битовой структуре типа данных, пожалуйста, опишите ее ограничения и способы ее использования.


20
f (n) = i * n - чистая математика: P
Йоханнес Кун

8
@JohannesKuhn, поэтому домен и кодомен ограничены рациональными значениями
ardnew

Не могли бы вы объяснить, что f:Q->Qзначит?
beary605

@ beary605 это означает, fчто это функция, отображающая членов Q(рациональных чисел) в другие члены (возможно, одинаковые) из Q. см. en.wikipedia.org/wiki/Function_(matmatics)#Notation
ardnew

7
Я знал, что видел это недавно, но потребовалось время, чтобы вспомнить, где. Менее плотно указанная версия на StackOverflow была недавно закрыта. Более 100 ответов.
Питер Тейлор

Ответы:


12

J, 9 баллов (10 символов)

На основании ответа stackoverflow :

   (*-[*_1&^)

Первая идея (13 символов):

   ((-*)-2&|*+:)

   ((-*)-2&|*+:) _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 0 1 2 3 4 5 6 7 8 9 10
_9 10 _7 8 _5 6 _3 4 _1 2 0 _2 1 _4 3 _6 5 _8 7 _10 9

   ((-*)-2&|*+:) _9 10 _7 8 _5 6 _3 4 _1 2 0 _2 1 _4 3 _6 5 _8 7 _10 9
10 9 8 7 6 5 4 3 2 1 0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _10

Это работает для целочисленного ввода, но производит мнимый вывод для значений с плавающей запятой (функция должна производить рациональный вывод для рационального ввода в соответствии со спецификацией)
Волатильность

5
@Volatility, спецификация сбивает с толку формулировку, но, как я ее прочел, она позволяет ограничить домен и кодомен до целых чисел.
Питер Тейлор

Вам нужны скобки?
Cyoce

14

Питон: 61 34 30 29 27 очков

f: Q -> Q

в математике:

       | 0.5-x   if x is in Q \ Z
f(x) = |
       | x+0.5   if x is in Z

в Python:

f=lambda x:.5+[x,-x][x%1>0]

проверено с

filter(lambda n: n[0] != -n[1], map(lambda n:(n,f(f(n))),range(0,50)))

логика за этим:

Когда вы возьмете целое число nи вставите его, fвы получите x+0.5. Это не является целым числом больше, так что следующая заявка будет 0.5-(x+0.5)что -x.

кредиты

Благодаря

  • Бакуриу за то, чтобы сократить его с 61 до 34 символов.
  • Волатильность для дальнейшего уменьшения размера кода до 30 символов.
  • копировать для уменьшения размера кода до 29 символов (и устранения потенциальной проблемы с плавающей запятой).
  • aditsu за упоминание несоответствия, которое пришло с изменениями выше.

Заметки

Сначала я думал, что это будет хорошо

f = lambda n: 1j*n

но это f: N-> C, и это не разрешено: - /


1
Может быть сокращен до: f=lambda x:x%1>0and(-x+x%1)or x+.1длиной всего 34 символа.
Бакуриу

f=lambda x:[x+.1,x%1-x](x%1>0)только 30 лет
волатильность

1
На один символ короче f=lambda x:[x+.5,.5-x][x%1>0]. Обратите внимание на использование .5 вместо .1, чтобы обойти проблемы точности
скопируйте

1
@AJMansfield 1.48 не является целым числом.
Мартин Тома

1
Нет, это не значит. Если он это сделал, он должен был написать «все рациональные числа». f:Q->Qозначает только то, что f отображает рациональное число в рациональные числа. Какое мое определение f делает.
Мартин Тома

11

C, 41 балл (41 или 45 символов)

Работает с использованием 32- и 64-разрядных.

f : Z -> Z(кроме INT_MAX):

f(n){return (abs(n)%2*2-1)*n+n?(-n<n)*2-1:0;}

Если нам не нужно включать, 0мы можем сбрить некоторые символы (41 символ):

f : Z -> Z(кроме 0& INT_MAX):

f(n){return (abs(n)%2*2-1)*n+(-n<n)*2-1;}

Эта функция работает путем деления всех целых чисел на 4 группы в зависимости от их знака и четности.

Итак, у нас есть 4 разные комбинации:

+ even, + odd, - even, - odd

Поскольку нам нужно поменять знак числа, а не четность после двух проходов, мы получаем две разные возможные последовательности:

  + even -> - odd -> - even -> + odd -\
^-------------------------------------/

  + even -> + odd -> - even -> - odd -\
^-------------------------------------/

В этом примере я выбрал первый.

Сначала нам нужно отобразить все четные положительные целые числа на нечетные отрицательные целые числа. Мы делаем это, изменяя знак и увеличивая число (вместо этого вы можете уменьшить число):

f1(n) = -n + 1

Затем нам нужно отобразить все нечетные отрицательные целые числа на четные отрицательные целые числа. Нам нужно убедиться, что f2(f1(n)) = -n:

f2(f1(n)) = -n
f2(-n + 1) = -n
f2(-n) = -n - 1
f2(n) = n - 1

Используя те же методы, мы находим f3и f4:

f3(n) = -n - 1
f4(n) =  n + 1

Чтобы объединить эти функции в одну функцию, мы видим, что каждый раз, когда nмы даже переключаем знак, nи каждый раз, когда nмы положительны, мы увеличиваем на единицу, а в противном случае мы уменьшаем на единицу:

f1(n) = -n + 1 (+ even)
f2(n) =  n - 1 (- odd)
f2(n) = -n - 1 (- even)
f4(n) =  n + 1 (+ odd)

Таким образом, это может быть переписано как:

f(n) = odd(n) * n + sign(n)

где odd(n)возвращает 1нечетные числа и -1четные числа.

Всего 4 решения:

f(n) = odd(n) * n + sign(n)  (edge cases: f(f(0))  -> -2, f(f(INT_MAX))   -> -8)
f(n) = even(n) * n - sign(n) (edge cases: f(f(0))  -> -2, f(f(INT_MIN+1)) -> -6)
f(n) = odd(n) * n - sign(n)  (edge cases: f(f(1))  -> -3, f(f(INT_MIN))   -> -5)
f(n) = even(n) * n + sign(n) (edge cases: f(f(-1)) -> -1, f(f(INT_MIN))   -> -5)

INT_MINвсегда может рассматриваться как крайний случай во всех 4 функциях как -INT_MIN == INT_MIN=> f(f(INT_MIN)) = INT_MIN.


По сути, это то же самое, что и мой ответ на GolfScript (за исключением объяснения лучше). Это работает для 0?
Бен Райх

@ BenReich Как указано в ответе, он не работает для 0и 3 других номеров.
Tyilo

1
@ Сейчас я вижу. Имеет смысл. Похоже, что вы должны брать Zбонус только если вы покрываете 0, по крайней мере.
Бен Райх

@BenReich Убрал бонус, пока я его не исправлю.
Tyilo

9

Вот мой путь.

long f(int i){return i;}
int f(long i){return -i;}

Живой пример :

int main()
{
  for(int i=-10; i<10; i=i+3)
    std::cout << f(f(i)) << "\n";
}

Типы ввода могут быть произвольно адаптированы к вашим потребностям. Эта версия работает для целочисленных литералов, которые меньше по величине, чем 2 ^ 32-1.


2
Проблема сказала f:Q->Q, нет f:Z->Z.
AJMansfield

@AJMansfield раздел оценки был предназначен для предложения бонусных баллов за определенные функции f:Z->Z, извините за запутанную формулировку
ardnew

6
проблема с этим ответом состоит в том, что он определяет две отдельные функции, в то время как спецификация требует, чтобы вы определили только одну. но я не хочу начинать дебаты по семантике, это все еще очень продуманное решение
ardnew

@ardnew, о, ты прав. Я получил указание на это действительное возражение всего за несколько секунд до того, как поделиться им с Lounge <C ++> в SO чате. Мне интересно, что компилятор делает из этого (если он не встроен в вызовы), но моя сборка - отстой.
rubenvb

1
Я думаю, что вы можете удалить пространство вreturn -i
Cyoce

6

JavaScript, 18

f=n=>n%1?.5-n:n+.5

Использование новой жирной стрелки (Firefox 22).

Другая версия (18):

f=n=>n%1?-.5/n:.5/n

Предыдущая версия (20):

f=n=>n-~~n?.5-n:n+.5

Пример:

> [-3,-2,-1,1,2,3].map(f).map(f)
[3, 2, 1, -1, -2, -3]

10
Похоже, JavaScript развивается в CoffeeScript.
Питер Тейлор

4

Mathematica 18

f=#+1/2-4#(#-⌊#⌋)&

Вот ⌊...⌋функция пола. Он использует только рациональные числа (не списки, комплексные числа и т. Д.)

f[10]
f[f[10]]

21/2

-10

f[-5]
f[f[-5]]

-9/2

5


3

ассемблер x86 (FASM). Аргумент и результат находятся в регистре eax.

Это работает правильно для -2 ^ 30 <N <+ 2 ^ 30-1

16 байт исполняемого кода.

        use32

f_n:
        lea     edx, [2*eax]
        xor     edx, eax
        btc     eax, 30
        shl     edx, 1
        jnc     .end
        neg     eax
.end:
        retn

Выбрав ваши номера; 2E30 будет 2 * 10 ^ 30, а не 2 ^ 30, как я думаю, вы хотите.
Ник Т

@NickT Моя ошибка. Исправлена.
johnfound

Я почти уверен, что вы должны считать байты в исходном коде.
nyuszika7h

3

Common Lisp: 35 байт

(defun f(x)(/(if(> 1 x)-1/2 1/2)x))

Схема (и ракетка): 36 байт

(define(f x)(/(if(> 1 x)-1/2 1/2)x))

Разгулялся с комментариями и объяснениями:

(define (f x)
  (/             ;; divide
     (if (> 1 x) ;; if x is below 1 
         -1/2    ;; then -1/2 (the fraction)
         1/2)    ;; else 1/2 (the fraction)
      x))        ;; gets divided with x

Для любого числа xв [1,->]число ifпревратится в дробь, 1/2которая является реальным точным числом на обоих языках.

Разделительная часть станет (/ 1/2 x)такой, 1/(x*2)какой станет дробь, которая всегда находится ниже 1. Для 1него будет 1/2, ибо 2это 1/4и т.д.

Для любого числа ниже 1 , то ifполучится в доле -1/2, что делает функцию делать (/ -1/2 x)что , -1/(2*x)но так как можно ожидать , что значение будет результат предыдущего запуска мы можем подставить е 1 / (х * 2) , что делает двойное применение-1/((1/(x*2))*2) = -x

Например, так как 1превращается во 1/2второе приложение(/ -1/2 1/2) ==> -1


Как это работает?
AJMansfield

@AJMansfield добавил немного информации. Просто спросите, есть ли что-то неясное. Чтение синтаксиса LISP похоже на греческое, если вы его не изучили, а привыкание занимает несколько недель.
Сильвестр

3

С 60 (⌈66 * .9⌉)

int f(int x){if(!x&1||!~x)return ~x;if(x<0)return x-1;return x+1;}

Вот безоговорочная версия:

int f(int x){
    if(!x&1 || !~x) return ~x;
    if(x<0) return x-1;
    return x+1;
}

Этот метод работает с использованием только целых чисел, поэтому он получает бонус в 90%. Первоначально я писал его на Java, но понял, что эта программа, в частности, может извлечь выгоду из логических операторов в стиле Си.

Поскольку нет целого числа, соответствующего -INT_MIN, вместо этого f(f(INT_MIN))возвращается INT_MIN.

Основное отображение алгебраически довольно просто. Выполнение оператора x=f(x)заменяет x на:

  • x+1, если xположительный и нечетный
  • -x+1, если xположительно и даже
  • x-1, если xотрицательный и нечетный
  • -x-1, если xотрицательно и даже

Результат каждого случая будет попадать в следующий случай при следующем применении функции к x.

Как видите, составление кейса с последующим кейсом дает -x.

Код является результатом некоторого умного упрощения функции, чтобы использовать в своих интересах битовую структуру целых чисел комплимента двух.


3

> <> , 21 + 3 = 24 байта, 22 балла

:0)$:0($:1$2%2*-*+-n;

Используйте официальный интерпретатор Python и используйте параметр -vкомандной строки для ввода ввода, стоимостью 3 байта.

У меня есть ощущение, что это может быть лучше - я буду продолжать смотреть на это и пытаться играть в гольф.

Учитывая ввод n, программа выводит

(n>0) - ((n<0) + n * (1 - 2*(n%2)))

где (n>0)и (n<0)есть логические значения. Это эквивалентно желатинскому ответу Python

(n>0) - (n<0) - n * (-1)**n

но ><>не имеет встроенного оператора возведения в степень, поэтому мы используем (1 - 2*(n%2))вместо (-1)**n.

Далее следует математическая теория - читайте, если (и только если) вы заинтересованы:

Для любой функции , f: Z -> Zтакие , что f(f(n)) = -nдля всех nин Z, мы видим сразу , что f(f(f(f(n)))) = n, или, другими словами, f^4это функция тождества. В частности, fобратим, а его обратная функция есть f^3. Таким образом , fперестановка Z, и так как f^4 = Id, то отсюда следует , что каждая орбита (или цикл) из fимеет размер либо 1, 2, или 4.

Далее мы видим это f(0) = 0. Доказательство: f(0) = f(-0) = f(f(f(0))) = -f(0)так f(0) = 0, по желанию. И наоборот, предположим, что xв цикле длины 1или 2, так f(f(x)) = x. Тогда -x = xтак x = 0.

Таким образом f, полностью состоит из 4 циклов, за исключением фиксированной точки (1 цикл) в 0.

Далее, каждый 4-цикл должен иметь форму (x, y, -x, -y), и, вращая цикл, мы можем предположить, что xи yоба положительны. Наоборот, каждое такое произведение 4-циклов, разделяющих ненулевые целые числа, определяет выбор f.

Таким образом, каждый выбор fоднозначно соответствует ориентированному графу, вершинами которого являются положительные целые числа, так что каждая вершина инцидентна ровно одной стрелке, входящей или выходящей. Точнее, в базовом неориентированном графе каждая вершина имеет степень точно 1. (Каждый 4-цикл (x y -x -y)с xи yположительными соответствует стрелке x --> y.)

Функция в этом ответе (и несколько других ответов здесь) соответствует графике , где 1 --> 2, 3 --> 4и в целом 2k-1 --> 2k.

Такие графики находятся во взаимно однозначном с бесконечными последовательностями упорядоченных пар (a_n, p_n), где каждый a_nпредставляет собой положительное целое число , и каждый p_nявляется либо 0или 1: дана последовательность (a_1, p_1), (a_2, p_2), (a_3, p_3), ..., мы первая пара 1с 1 + a_1, а затем формируют либо стрелку 1 --> 1 + a_1или стрелку в 1 + a_1 --> 1зависимости от того , p_1является 0или 1. По сути, стрелка является либо <знаком, либо >знаком, в зависимости от соотношения p_1.

Далее, возьмем наименьшее непарный целое положительное число k, и подсчитать от k, ровно a_2шагов, пропускаем любое число , которое уже в паре с чем - то. Сопряжение kс результатом, и установите направление стрелки в зависимости от того, p_2как указано выше. Затем повторите с (a_3, p_3)и т. Д.

Каждая стрелка в конечном итоге будет определена таким образом, поэтому процесс четко определен. Функция в этом ответе соответствует последовательности (1,0), (1,0), (1,0), ..., так как на шаге nнаименьшее непарное целое число равно целым 2n-1числам, а не целым, больше, чем 2n-1было спарено с чем-либо, поэтому мы получаем 2n-1 --> 2nдля каждого n(стрелки ориентированы таким образом, потому что каждый p_nравен 0).

Количество элементов этого множества (N*2)^N = N^N, которое по последнему абзацу этого ответа равно 2^Nколичеству вещественных чисел.


Параметры командной строки, как правило, каждый байт.
кошка

@cat См. раздел «Специальные вызовы» в этом мета-посте .
Матмандан

2

Чтобы исправить предыдущий ответ J (у меня недостаточно репутации, чтобы комментировать оригинал):

(*+[*1-~2*2|])

Он просто заменяет _1&^с 1-~2*2|], что дает противоположный знак. Поэтому я изменил на -a +(который имеет значение только для ввода 1и _1).

Вот тесты:

   (*+[*1-~2*2|])6 3 _9 _8 1r2 _4.6 0 1 _1
7 _2 8 _9 1 7.28 0 2 _2
   (*+[*1-~2*2|])7 _2 8 _9 1 7.28 0 2 _2
_6 _3 9 8 0 _10.3568 0 _1 1

   NB. f^:2 = f@:f
   (*+[*1-~2*2|])^:(2)6 3 _9 _8 1r2 _4.6 0 1 _1
_6 _3 9 8 2 _5.0832 0 _1 1

Как видите, домен и диапазон имеют все действительные числа, но это работает только для целых чисел (включая 0).

Объяснение:

(   *     + [ *  1-~    2*     2|]    )
 signum n + n * pred (twice (n mod 2))

2

GolfScript ceiling(26*.9)=24

Golfscript обрабатывает только целые числа, поэтому примените Zбонус на общую сумму 24 балла:

.{..0>2*(\)2%!2*(@*+}{ }if

Особый случай 0 составляет 8 символов. Игнорируя 0, мы можем получить ответ из 17 пунктов:

..0>2*(\)2%!2*(@*+

Этот код выполняет следующие действия с целым числом xв верхней части стека:

  • Если x0, оставьте 0в стеке и больше не применяйте правила.
  • Если xчёт, отрицай x.
  • Если xположительно, добавьте 1.
  • Если xотрицательно, вычтите 1.

Это логически соединяет наборы из 4 чисел в цикле, где fобходы элементов цикла, а противоположные углы цикла являются отрицаниями друг друга. Каждое целое число является частью ровно 1 такого цикла, за исключением 0, которое имеет специальный регистр. Например, для {-8, -7, 7, 8}:

  • 7 f -> 8
  • 8 f -> -7
  • -7 f -> -8
  • -8 f -> 7

Единственные релевантные тестовые случаи, о которых я мог подумать, были отрицательный нечетный, отрицательный четный, положительный нечетный, положительный четный 0, а затем я добавил, -1и, 1поскольку их близость к, 0возможно, вызвала проблемы:

[-10 -5 -1 0 1 5 10]
{.{..0>2*(\)2%!2*(@*+}{ }if}:f;
{f f}%
-> [10,5,1,0,-1,-5,-10]

Я уверен, что настоящий GolfScript может быть несколько улучшен. Не похоже, что он должен занимать 26 символов! Хотелось бы услышать некоторые предложения.


2

Ява, просто для удовольствия

Вот реализация, которая выполняет фактическую биекцию между ℤ и ℤ², которая является одновременно нечетной функцией (g (-x) == -g (x)). Он обрабатывает соответствующий элемент as² как комплексное число и умножает его на «i», а затем преобразует обратно в ℤ.

f (x) = g⁻¹ (ig (x))
f (f (x)) = g⁻¹ (-g (x)) = - x

Функция работает в O (1).

public class Ffn {
    public static int f(int n) {
        if (n == 0) {
            return 0;
        }
        // adjust sign
        int s = n > 0 ? 1 : -1;
        int m = n * s;
        // calculate square "radius"
        int r = (int) (Math.sqrt(2 * m - 1) + 1) / 2;
        int q = r * 2;
        // starting point
        int x = r, y = r;
        int k = q * (r - 1) + 1;

        if (m - k < q) {
            // go left
            x -= m - k;
        }
        else {
            // go left
            x -= q;
            // go down
            y -= m - k - q;
        }

        // multiply by i
        int x2 = -y * s, y2 = x * s;
        // adjust sign
        s = y2 < x2 || y2 == x2 && x2 < 0 ? -1 : 1;
        x2 *= s;
        y2 *= s;

        if (y2 == r) {
            // go left
            k += r - x2;
        }
        else {
            // go left and down
            k += q + r - y2;
        }
        return k * s;
    }

    public static void main(final String... args) {
        for (int i = 0; i < 1000000; ++i) {
            if (f(f(i)) != -i || f(f(-i)) != i) {
                System.out.println(i);
            }
        }
    }
}

PS С новым годом!


Я считаю, что пробелы не нужны.
pppery

2

Питон 3 - 38

Похоже на ответ @ лося, но f(n) == n,. Работает для всех целочисленных значений.

f=lambda x:x*(isinstance(x,int)*2.0-1)

2

Perl, 33 (без пробелов)

sub f{($=)=@_;$=-$_[0]?-$=:"$=.1"}

Редактировать:

  • $=.".1"сокращено до "$=.1"(спасибо ardnew).

Математика:

математический

Ungolfed:

# script.pl
sub f {
  ($=) = @_;   # short for $= = int($_[0]); 
               # "int" is implicit in assignments to $=;
               # ($=) can be prepended by "local" to get
               # the function free of side effects.

  $= - $_[0] ? # short for $= != $_[0], check if input is integer
    -$=        # input is not an integer  
  : $= . ".1"  # input is integer
}  

# Testing
chomp;
$_ = sprintf "f(f($_)) = f(%s) = %s\n", f($_), f(f($_));

Примеры:

perl -p script.pl
7
f(f(7)) = f(7.1) = -7
2
f(f(2)) = f(2.1) = -2
0
f(f(0)) = f(0.1) = 0
-1
f(f(-1)) = f(-1.1) = 1
-10
f(f(-10)) = f(-10.1) = 10
-1.23
f(f(-1.23)) = f(1) = 1.1
3.4
f(f(3.4)) = f(-3) = -3.1
1.0
f(f(1.0)) = f(1.1) = -1

Надежное решение - демонстрационные тесты с плавающей запятой, которые вы демонстрировали, не требуются по спецификации (должны были предлагать бонусные баллы за это!). Вот ваш тот же алгоритм с несколькими очистками в 22 sub f{yzxzzc?-$_:x.$_}
символа

1
@ardnew: Спасибо. Но я не согласен, что ваше решение использует тот же алгоритм. Алгоритм sub f{yzxzzc?-$_:x.$_}является не состояние свободной, она использует состояние через переменную $_. Из-за этого fбольше не является функцией (в математическом смысле), поскольку возможны разные значения для одного и того же входного значения в зависимости от состояния (погода $_есть xили нет). Мой алгоритм не использует состояние, информация закодирована в выходном значении. Целые числа преобразуются в реальные числа путем добавления .1. И действительные числа конвертируются обратно в целые числа с переключенным знаком.
Хайко Обердик,

interesting- нет состояние данных не используется в вашей реализации из - за первоначального присвоения , а не из - за какого - то особого свойства $=?
ardnew

я не понимал, что я также не смог выполнить свое собственное требование (которое fбудет определено Q->Q) с этим xсимволом. также $=.".1"может быть сокращено до"$=.1"
ardnew

@ardnew: специальным свойством $=является то, что он принимает только целые числа. То же самое может быть достигнуто с помощью обычной переменной: $a=int$_[0]. Но это стоит три дополнительных байта из-за функции int.
Хейко Обердик,

2

Юлия, 26 лет

julia> f(n::Int)=n//1
f (generic function with 1 method)
julia> f(n)=int(-n)
f (generic function with 2 methods)
julia> f(f(4))
-4

Не супер конкурентоспособный, но очень юлианский, так как полагается на многократную отправку. Он просто делает Rational, если это Int, или int со знаком минус, если это что-то еще. Кто-то может возразить, что это 2 функции, но Джулия считает, что это одна функция с двумя методами, и это эквивалентно определению одной функции со статическим if для типа n.


Это не то, что математик назвал бы функцией: в Джулии 3==3//1возвращается, trueно f(3//1)==f(3)возвращается false.
Омар

2

Candy , 20 18 байтов

Использует трюк 3 -> 4 -> -3 -> -4 -> 3.

~A2%{|m}1A0>{+|-}.

Чтобы вызвать его, используйте ключ -i на интерпретаторе

Пример двойного вызова:

$ candy -i 7 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> 8
$ candy -i 8 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> -7
$ candy -i -7 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> -8
$ candy -i -8 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> 7

Длинная форма:

peekA
pushA
digit2
mod          # even/odd
if
else
  negate     # negate even numbers
endif
digit1
pushA
digit0
greater      # positive/negative
if
  add        # add two numbers from stack (original stack value, and delta)
else
  sub        # diff two numbers from stack (original stack value, and delta)
endif
retSub

2

Дьялог АПЛ, 9 очков

×-⍨⊢ׯ1*⊢

Длина источника составляет 9 байт, и он претендует на бонус (что совсем не помогает). Он также использует формулу из верхнего SO ответа.




1

Java, 113 байт

Подход довольно прост. В итоге получилось больше байтов, чем я ожидал, но, возможно, немного проиграл.

public class F{public static int f(int x){if(x<0)x+=-2147483647-++x;x+=1073741824;return x<0?-2147483647-++x:x;}

Он в основном создает 4 различных «области» x, используя тот факт, что Java успешно позволяет переменным оборачиваться. Мне пришлось сделать несколько хитрых преобразований для отрицательных чисел, и это главная причина, по которой это оказалось больше, чем предполагалось.

Работает для всех х, кроме -2147483648.


1

Та же последовательность чисел (3, 4, -3, -4, 3 ...), что и в ответе сценария гольфа, но реализована в perl (42 символа после пробела)

sub f{($_[0]%2?1:-1)*$_[0]+($_[0]<0?-1:1)}

Более разборчиво:

sub f { ($_[0] % 2 ? $_[0] : -$_[0] ) + ( $_[0] < 0 ? -1 : 1 ) }

Или даже более разборчиво:

sub f {
  my $n = shift;
  my $sign = $n >= 0 ? 1 : -1;
  # note that in perl $n % 2 is the same as int($n) % 2
  if( $n % 2 ) {
    # odd: add one to magnitude
    return $n + $sign
  } else {
    # even: subtract one from magnitude then invert
    return -($n - $sign)
  }
}

Выход:

ski@anito:~/mysrc/.../acme$ echo 3 | perl -e 'sub f{($_[0]%2?1:-1)*$_[0] + ($_[0]<0?-1:1)}; my $x = <>; for(0..10) { print "$_: $x\n"; $x = f($x); }'
0: 3
1: 4
2: -3
3: -4
4: 3
5: 4
6: -3
7: -4
8: 3
9: 4
10: -3

Вышеприведенное также работает для нецелых чисел: ski @ anito: ~ / mysrc /.../ acme $ echo 1.1234 | perl -e 'sub f {($ _ [0]% 2? 1: -1) * $ _ [0] + ($ _ [0] <0? -1: 1)}; мой $ x = <>; для (0..4) {print "$ _: $ x \ n"; $ x = f ($ x); } '0: 1.1234 1: 2.1234 2: -1.1234 3: -2.1234 4: 1.1234
скибрянски

1

Сед, 25 байт.

|sed s/0+/0-/|sed s/^/0+/

Использование:

$ echo 1.23 |sed s/0+/0-/|sed s/^/0+/
0+1.23
$ echo 0+1.23 |sed s/0+/0-/|sed s/^/0+/
0+0-1.23

1

Matlab, 26 символов

f=@(n) (n<0)-(n<0)-n*(-1)^n

2
Это неверный ответ, так как домен и кодомен функции не должны быть сложными.
Wrzlprmft

о, извини ... я просто прочитал заголовок и не был так осторожен ... посмотрим, смогу ли я отредактировать это немного
бла

1

С ++ - 63 55,8

Вот как выглядит код:

int f(int n){return (n&45056?n^45056:n|45056)*(n&45056?-1:1);}

Он не работает с целыми числами, чей четвертый байт равен 0xB, поскольку он использует это значение для отслеживания проходов. В противном случае работает на любом члене Z, включая ноль.


Вы можете объяснить это? при первом осмотре похоже, что вы ведете счетчик обращений к fстатической переменной. но тогда какой смысл sqrt?
ardnew

Я, кажется, неправильно понял вопрос; Я подумал, что статическая переменная была в порядке, поскольку C ++ является стек-ориентированным языком, но я исправлю код. В противном случае я понятия не имею, зачем мне это нужно, так sqrtкак оно все равно округляется при приведении типа. Я сделаю рефакторинг, чтобы он работал без статической переменной.
Darkgamma

Я понятия не имею, откуда вы взяли 55.8, но ваш текущий код длиной 62 байта. Изменить: не берите в голову, я не прочитал вопрос правильно.
nyuszika7h

Ограничение на то, что четвертый байт не может быть равен 0xB, к сожалению, делает это неверным ответом на вызов, который требует, чтобы он работал (по крайней мере) со всеми целыми числами.
pppery

1

Обновлен с помощью функции, поставляемой Synthetica (очевидно, тот, кто должен получить кредит на это сейчас)

Язык: Python

Количество символов: 41, включая пробелы

f=lambda x:-float(x) if str(x)==x else`x`

Пожалуйста, укажите также название языка, который вы использовали, а также количество символов.
ProgramFOX

Мне нравится, как это работает с нецелыми числами. Отлично сработано. :)
cjfaure

f=lambda x:-float(x) if str(x)==x else`x`немного короче: 41, включая пробелы
ɐɔıʇǝɥʇuʎs

Спасибо, Синтетика, я даже не знала о трюке с обратным ходом! : D
HolySquirrel

По целым числам fвозвращает строку; спецификация говорит, что она должна возвращать рациональное число.
Омар

1

Пролог, 36 байт

Код:

X*Y:-X//1=:=X,Y is 0.5+X;Y is 0.5-X.

Разъяснение:

Dyadic predicate which converts integers to floats and floats back to negated integers.

Пример:

10*X.
X = 10.5

10*Y,Y*X.
X = -10,
Y = 10.5


1

Мышь-2002 , 21 19 12 байт

$A1%[1%_|1%]

Определяет функцию A; Назовите его как #A,#A,?;;(который будет ждать, пока пользователь введет любой номер). В качестве альтернативы, позвоните, как #A,#A,n;;где- nнибудь номер.


1

Юлия, 21 год

f(x)=(1-2(1>x>-1))/2x

затем

julia> f(f(12//1))
-12//1

p // q - буквенное обозначение Юлии рациональных чисел.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.