f (g (x)) зменшується при збільшенні g (f (x))


42

Для цього завдання потрібно реалізувати дві функції, f і g , на цілі числа, таким чином, що f is g є строго зменшується функцією, тоді як g ∘ f - функція, що суворо зростає. Іншими словами, якщо взяти будь-які два цілі числа a <b , тоді f (g (a))> f (g (b)) і g (f (a)) <g (f (b)) . Немає обмежень на f і g окремо, за винятком того, що вони повинні відображати одне ціле число на інше ціле число.

Додайте короткий опис f і g та аргумент того, чому вони мають необхідну властивість.

Кредит: Цей виклик був натхнений проблемою на змаганнях з магістра математики в Румунії 2011 року (який задає те саме, але на реальні числа, а не на цілі числа). Якщо ви дійсно хочете спойлерів, тепер знаєте, що шукати.

Правила

  • Слово "функція" в цьому виклику слід сприймати в математичному сенсі відображення одного цілого числа на інше: ви можете або написати дві програми, або дві функції, і використовувати будь-який із стандартних методів отримання вводу та надання виводу, як зазвичай. Ви можете використовувати рядкові представлення цілих чисел замість фактичних цілих змінних, але типи введення та виведення повинні бути однаковими, щоб функції могли складатися без перетворення вручну типів між ними. Пам'ятайте, що концептуально f і g все ще повинні бути функціями на ℤ, тому ви не можете обманювати, використовуючи два різних рядкових представлення одного і того ж числа або щось подібне.

  • Пам'ятайте, що функції можуть бути безіменними , якщо їх ім'я не потрібне саме для себе або іншої функції, яку ви визначаєте. Якщо ви назвете одну або обидві функції, ви можете припустити, що вони існують в одній програмі, щоб вони могли посилатися один на одного при їх реалізації (наприклад, def f(x): return -g(x)в Python).

  • Застосовуються звичайні правила переповнення цілих чисел: ваше рішення повинне бути здатне працювати для довільно великих цілих чисел у гіпотетичній (або, можливо, реальній) версії вашої мови, в якій всі цілі числа за замовчуванням не пов'язані, але якщо ваша програма не працює на практиці через впровадження не підтримуючи великі цілі числа, це не може визнати недійсним рішення.

  • Ви можете використовувати будь-яку мову програмування , але зауважте, що ці лазівки за замовчуванням заборонені.

  • Це , тому ваш рахунок - це кількість байтів обох функцій і виграє найкоротший дійсний відповідь.


Чи можуть функції повернути рядок?
Меттью Рох

@SIGSEGV Я б сказав "так", але тільки якщо вони також беруть рядок як вхідний, тому вони можуть бути складені без необхідності вставляти перетворення будь-якого типу.
Мартін Ендер

Aww darnit, я спробував перетворити на рядок, щоб інші функції не змогли далі редагувати результати.
Меттью Рох

1
@ Фаталізувати правильно. Кожна повинна бути функцією типу ℤ → ℤ.
Мартін Ендер

1
@Bijan і позитивні, і негативні.
Мартін Ендер

Відповіді:


18

Пітон, 68 символів

f=lambda x:(1-x%2*2)*(2*x*x+(x<0))
g=lambda x:(1-x%2*2)*(2*x*x+(x>0))

f відображає від’ємні числа до непарних чисел та додатних чисел до парних чисел і парних чисел до додатних чи непарних чисел до від’ємних чисел, при цьому величина виходу суттєво зростає із вхідною величиною.

g робить те саме, за винятком того, що відображає від’ємні числа на парні числа та додатні числа на непарні числа.

f ∘ g відображає негативні → парні → позитивні та позитивні → непарні → негативні.
g ∘ f карти негативні → непарні → негативні та позитивні → парні → позитивні.

Тому f і g мають бажані властивості.


2
fі gможуть бути неназваними функціями, тому ви можете скинути чотири байти.
Мартін Ендер

Ви можете визначити (1-x%2*2)як змінну, щоб зберегти кілька байт.
OldBunny2800

Ось повний код, який можна пограти з import numpy as np; import matplotlib.pyplot as plt; xrange=np.arange(-3,4); f=lambda x:(1-x%2*2)*(2*x*x+(x<0)); g=lambda x:(1-x%2*2)*(2*x*x+(x>0)); plt.plot(xrange, map(f, xrange), 'ro'); plt.plot(xrange, map(g, xrange), 'go'); plt.plot(xrange, map(f, map(g, xrange)), 'b--'); plt.plot(xrange, map(g, map(f, xrange)), 'y--'); plt.show(); Ви можете замінити ;на канали ліній для зручності читання
Стефан Гурішон

16

Пітон , 40 байт

f=lambda x:x*(-1)**x
g=lambda x:3*f(x)+1

Спробуйте в Інтернеті! Деякі виходи - це поплавці, що дорівнюють цілим числам, тому що (-1)**(-3)дає float, наприклад.

Спираючись на ідеї Пітера Тейлора . Функція fзаперечує непарні числа і залишає парні без змін. Функція gробить те саме, після чого застосовує монотонну карту комутації парності x -> 3*x + 1.

Оскільки f(f(x)) = xми g(f(x)) = 3*f(f(x))+1 = 3*x+1збільшуємось.

Бо f(g(x)) = f(3*f(x)+1)ідея полягає в тому, що саме один із внутрішніх і зовнішніх fперевертає знак, завдяки чому він зменшується.

  • Навіть x, f(x) = xале f(3*x+1) = -3*x-1тому, що 3*x+1це дивно.
  • За непарні x, f(x) = -xі f(-3*x+1) = -3*x+1тому -3*x+1, що парні.

Нам зараз потрібні лише парні та непарні входи, які перемежовуються у зменшуваному вигляді, що має місце, оскільки -3*x±1зменшується незалежно від того, як обрані знаки. Ось чому 3*необхідне.

Порт Haskell - 25 байт:

f x=x*(-1)**x
g x=1+3*f x

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


У Хаскеллі - (^)це ціла експоненція.
user1502040

1
@ user1502040 Він не може обробляти негативні показники.
xnor

1
Оскільки ви не gназиваєте себе, ви можете зберегти два байти, зробивши його без імені.
Мартін Ендер

14

CJam (17 байт)

Функція f (названа Fтому, що CJam дозволяє лише великі регістри імен):

{W1$2b,#*}:F

Функція g (анонімне):

{F2*}

Демонстрація в Інтернеті

Це економить байт, спираючись на деталі реалізації CJam, що, можливо, є помилкою: при виконанні базових перетворень він використовує абсолютне значення. 2b,тому дає кількість бітів в абсолютному значенні свого аргументу, тому f заперечує саме ті числа, абсолютне значення яких має непарне число біт. g застосовується f, а потім подвоюється (змінюючи паритет кількості бітів).

Таким чином, застосовуючи f, а потім g залишає знак незмінним і подвоюється, відображаючись xна 2x. Застосовуючи g, а потім f змінює знак точно один раз і подвоюється, відображаючи xна -2x.


Приємно, саме це довідкове рішення, яке надається в конкурсі, звідки воно є. (Я припускаю, що ви придумали це самостійно?)
Мартін Ендер

@MartinEnder, я бачив цю проблему десь раніше. Можливо на математиці.SE.
Пітер Тейлор

2

Піт, 34 байт

Це лише прямий переклад моєї відповіді Python.

*-1*2%Q2+*2*QQ<Q0
*-1*2%Q2+*2*QQ>Q0
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.