f(g(x))减小而g(f(x))增大


42

为此,您需要在整数上实现两个函数fg,使得f∘g是严格减少的函数,而g∘f是严格增加的函数。换句话说,如果取任意两个整数a <b,则f(g(a))> f(g(b))g(f(a))<g(f(b))fg分别没有限制,只不过它们必须分别将一个整数映射到另一个整数。

请提供对fg的简短描述,以及有关为什么它们具有必需属性的参数。

信用:这项挑战的灵感来自2011年罗马尼亚数学硕士竞赛中的一个问题(该问题提出了相同的问题,但用实数而不是整数)。如果您真的想要破坏者,那么现在您知道要搜索什么。

规则

  • 应该从将一个整数映射到另一个整数的数学意义上来理解此挑战中的“函数”一词:您可以编写两个程序或两个函数,并像往常一样使用接收和提供输出的任何标准方法。您可以使用整数的字符串表示形式来代替实际的整数变量,但是输入和输出的类型应该相同,以便可以在不手动转换类型的情况下组成函数。请记住,从概念上讲,fg仍需要是ℤ上的函数,因此您不能通过使用相同数字或类似形式的两个不同的字符串表示形式作弊。

  • 请记住,函数可以是未命名的,只要它们本身或您定义的另一个函数不需要它们的名称即可。如果您确实命名了这两个功能中的一个或两个,则可以假定它们存在于同一程序中,因此它们在实现中可以相互引用(例如,def f(x): return -g(x)在Python中)。

  • 通常的整数溢出规则适用:您的解决方案必须能够在语言的假设(或实际)版本中使用任意大整数,默认情况下,所有整数都是无界的,但是如果您的程序由于实现而在实践中失败不支持大整数,这不会使解决方案无效。

  • 您可以使用任何编程语言,但是请注意,默认情况下,这些漏洞是禁止的。

  • 这是,因此您的得分是两个函数的字节数之和与最短有效答案的总和。


函数可以返回字符串吗?
马修·罗

@SIGSEGV我会说是的,但前提是它们也必须使用字符串作为输入,因此可以在不插入任何类型转换的情况下进行组合。
Martin Ender'4

Aww darnit,我尝试将其转换为字符串,以使其他函数无法进一步编辑结果。
马修·卢

1
@致命的正确。每个函数都必须是ℤ→ℤ类型的函数。
Martin Ender'4

1
@Bijan正面和负面。
Martin Ender

Answers:


18

Python,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可以是未命名的函数,因此可以删除四个字节。
Martin Ender

您可以定义(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

Python,40个字节

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

在线尝试!一些输出是等于整数的浮点数,因为(-1)**(-3)给出了一个浮点数。

基于Peter Taylor的观点。该函数取反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翻转符号之一,使其减小。

  • 对于连xf(x) = xf(3*x+1) = -3*x-1由于3*x+1是奇数。
  • 对于奇数xf(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

在线尝试!


在Haskell中,(^)是整数幂。
user1502040

1
@ user1502040它不能处理负指数。
xnor

1
由于您不自称g,因此可以通过将其命名为未命名来节省两个字节。
Martin Ender

14

CJam(17个字节)

函数f(F之所以命名,是因为CJam仅允许使用大写名称):

{W1$2b,#*}:F

函数g(匿名):

{F2*}

在线演示

通过依赖CJam的实现细节可以节省一个字节,这可以说是一个错误:在进行基本转换时,它使用绝对值。2b,因此,给出其参数绝对值中的位数,因此精确地求出那些绝对值具有奇数位数的数字。g应用f,然后加倍(更改位数的奇偶校验)。

因此,先应用f然后使用g,使符号保持不变并加倍,映射x2x。依次应用g和f,则将符号更改一次,然后翻倍,映射x-2x


很好,这正是本场比赛中提供的参考解决方案。(我想您是单独提出的吗?)
Martin Ender

@MartinEnder,我以前在某个地方见过这个问题。可能在math.SE上。
彼得·泰勒

2

Pyth,34个字节

这只是我的Python答案的直接翻译。

*-1*2%Q2+*2*QQ<Q0
*-1*2%Q2+*2*QQ>Q0
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.