f (g (x)) diminui enquanto g (f (x)) aumenta

42

Para esse desafio, você precisa implementar duas funções, f e g , nos números inteiros, de modo que f ∘ g seja uma função estritamente decrescente enquanto g ∘ f seja uma função estritamente crescente. Em outras palavras, se você pegar dois inteiros a <b , então f (g (a))> f (g (b)) e g (f (a)) <g (f (b)) . Não há restrições para f e g individualmente, exceto que cada um deve mapear um número inteiro para outro número inteiro.

Por favor, inclua uma breve descrição de f e g e um argumento para isso que eles têm a propriedade necessária.

Crédito: Esse desafio foi inspirado por um problema no concurso romeno de mestre de matemática de 2011 (que pergunta a mesma coisa, mas com números reais, em vez de números inteiros). Se você realmente quer spoilers, agora sabe o que procurar.

Regras

  • A palavra "função" neste desafio deve ser tomada no sentido matemático de mapear um número inteiro para outro: você pode escrever dois programas ou duas funções e usar qualquer um dos métodos padrão de recebimento de entrada e saída, como de costume. Você pode usar representações de seqüência de caracteres de números inteiros em vez de variáveis ​​inteiras reais, mas os tipos de entrada e saída devem ser idênticos, para que as funções possam ser compostas sem a conversão manual de tipos entre eles. Lembre-se de que, conceitualmente, f e g ainda precisam ter funções em ℤ, então você não pode trapacear usando duas representações de cadeias diferentes do mesmo número ou algo assim.

  • Lembre-se de que as funções podem não ter nome , desde que o nome não seja necessário por si só ou por outra função que você definir. Se você nomear uma ou ambas as funções, poderá assumir que elas existem no mesmo programa, para que possam se referir uma à outra em sua implementação (por exemplo, def f(x): return -g(x)em Python).

  • As regras usuais de estouro de números inteiros se aplicam: sua solução deve ser capaz de trabalhar com números inteiros arbitrariamente grandes em uma versão hipotética (ou talvez real) do seu idioma, na qual todos os números inteiros são ilimitados por padrão, mas se o seu programa falhar na prática devido à implementação não suporta números inteiros tão grandes, que não invalida a solução.

  • Você pode usar qualquer linguagem de programação , mas observe que essas brechas são proibidas por padrão.

  • Como é , sua pontuação é a soma do número de bytes de ambas as funções e a resposta mais curta válida.

Martin Ender
fonte
As funções podem retornar uma string?
Matthew Roh
@SIGSEGV Eu diria que sim, mas apenas se eles também usarem uma string como entrada, para que possam ser compostos sem precisar inserir nenhuma conversão de tipo.
Martin Ender
Aww danado, tentei a conversão para string para tornar a outra função incapaz de editar ainda mais os resultados.
Matthew Roh
1
@Fatalize Correct. Cada um deve ser uma função do tipo ℤ → ℤ.
Martin Ender
1
@ Bijan tanto positivo quanto negativo.
Martin Ender

Respostas:

18

Python, 68 caracteres

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 mapeia números negativos para números ímpares e números positivos para números pares e números pares para números positivos e números ímpares para números negativos, com a magnitude da saída aumentando estritamente com a magnitude da entrada.

g faz o mesmo, exceto que mapeia números negativos para números pares e números positivos para números ímpares.

f maps g mapeia negativo → par → positivo e positivo → ímpar → negativo.
g ∘ f mapeia negativo → ímpar → negativo e positivo → par → positivo.

Portanto, f e g têm as propriedades desejadas.

user1502040
fonte
2
fe gpodem ser funções sem nome, para que você possa eliminar quatro bytes.
Martin Ender
Você pode definir (1-x%2*2)como uma variável para salvar alguns bytes.
OldBunny2800
Aqui está um código completo para você brincar. 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(); Você pode substituir ;por feeds de linha para facilitar a leitura.
Stéphane Gourichon
16

Python , 40 bytes

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

Experimente online! Algumas saídas são flutuantes que são iguais a números inteiros porque (-1)**(-3)fornecem um flutuador, por exemplo.

Baseado em idéias de Peter Taylor . A função fnega números ímpares e deixa os pares inalterados. A função gfaz o mesmo e aplica o mapa de comutação de paridade monotônico x -> 3*x + 1.

Desde então f(f(x)) = x, temos g(f(x)) = 3*f(f(x))+1 = 3*x+1aumentado.

Pois f(g(x)) = f(3*f(x)+1), a ideia é que exatamente um dos fflips internos e externos assine, diminuindo.

  • Para par x, f(x) = xmas f(3*x+1) = -3*x-1porque 3*x+1é estranho.
  • Por estranho x, f(x) = -xe f(-3*x+1) = -3*x+1porque -3*x+1é mesmo.

Agora, só precisamos que as entradas pares e ímpares se intercalem de maneira decrescente, o que vale porque -3*x±1está diminuindo, independentemente de como os sinais são escolhidos. É por isso que 3*é necessário.

Uma porta Haskell tem 25 bytes:

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

Experimente online!

xnor
fonte
Em Haskell, (^)é exponenciação de número inteiro.
precisa saber é o seguinte
1
@ user1502040 Não suporta expoentes negativos.
Xnor
1
Como você não está se chamando, gvocê pode salvar dois bytes, tornando-o sem nome.
Martin Ender
14

CJam (17 bytes)

Função f (nomeada Fporque o CJam permite apenas nomes em maiúsculas):

{W1$2b,#*}:F

Função g (anônima):

{F2*}

Demonstração online

Isso economiza um byte, contando com um detalhe de implementação do CJam, que é sem dúvida um bug: ao fazer conversões básicas, ele usa valor absoluto. 2b,portanto, fornece o número de bits no valor absoluto de seu argumento, então f nega precisamente aqueles números cujo valor absoluto possui um número ímpar de bits. g aplica f e depois dobra (alterando a paridade do número de bits).

Portanto, aplicar f e, em seguida, g deixa o sinal inalterado e dobra, mapeando xpara 2x. Aplicar ge ef muda o sinal exatamente uma vez e dobra, mapeando xpara -2x.

Peter Taylor
fonte
Bom, essa é exatamente a solução de referência fornecida na competição. (Eu suponho que você veio com ele de forma independente?)
Martin Ender
@ MartinEnder, eu já vi esse problema em algum lugar antes. Possivelmente em math.SE.
Peter Taylor
2

Pyth, 34 bytes

Esta é apenas uma tradução direta da minha resposta em Python.

*-1*2%Q2+*2*QQ<Q0
*-1*2%Q2+*2*QQ>Q0
user1502040
fonte