f (g (x)) diminuisce mentre aumenta g (f (x))


42

Per questa sfida è necessario implementare due funzioni, f e g , sugli interi, in modo tale che f ∘ g sia una funzione strettamente decrescente mentre g ∘ f sia una funzione strettamente crescente. In altre parole, se prendi due numeri interi a <b , allora f (g (a))> f (g (b)) e g (f (a)) <g (f (b)) . Non ci sono restrizioni sul f e g individualmente, salvo che essi devono ogni mappa un intero ad un altro numero intero.

Si prega di includere una breve descrizione di f e g e un argomento per il motivo per cui hanno la proprietà richiesta.

Ringraziamento: questa sfida è stata ispirata da un problema nel concorso di Master of Mathematics rumeno del 2011 (che chiede la stessa cosa ma sui numeri reali, anziché sui numeri interi). Se vuoi davvero spoiler, ora sai cosa cercare.

Regole

  • La parola "funzione" in questa sfida dovrebbe essere presa nel senso matematico di mappare un intero a un altro: puoi scrivere due programmi o due funzioni e usare uno dei metodi standard per ricevere input e fornire output, come al solito. È possibile utilizzare rappresentazioni di stringhe di numeri interi anziché variabili intere effettive, ma i tipi di input e output devono essere identici, in modo che le funzioni possano essere composte senza convertire manualmente i tipi tra. Ricordate che concettualmente, f e g ancora bisogno di essere funzioni ℤ, quindi non si può barare utilizzando due diverse rappresentazioni di stringa dello stesso numero o qualcosa di simile.

  • Ricorda che le funzioni possono essere senza nome , purché il loro nome non sia necessario da solo o da un'altra funzione definita. Se si nominano una o entrambe le funzioni, si può presumere che esistano nello stesso programma, in modo che possano fare riferimento l'uno all'altro nella loro implementazione (ad esempio def f(x): return -g(x)in Python).

  • Si applicano le solite regole di overflow dei numeri interi: la soluzione deve essere in grado di funzionare per numeri interi arbitrariamente grandi in una versione ipotetica (o forse reale) della lingua in cui tutti i numeri interi non sono associati per impostazione predefinita, ma se il programma non riesce in pratica a causa dell'implementazione non supportando numeri interi così grandi, ciò non invalida la soluzione.

  • È possibile utilizzare qualsiasi linguaggio di programmazione , ma si noti che queste scappatoie sono vietate per impostazione predefinita.

  • Questo è , quindi il tuo punteggio è la somma del numero di byte di entrambe le funzioni e vince la risposta valida più breve.


Le funzioni possono restituire una stringa?
Matthew Roh,

@SIGSEGV Direi di sì, ma solo se prendono anche una stringa come input, quindi possono essere composti senza dover inserire alcuna conversione di tipo.
Martin Ender,

Oh maledizione, ho provato la conversione in stringa per rendere l'altra funzione incapace di modificare ulteriormente i risultati.
Matthew Roh,

1
@Fatalize Correct. Ciascuno deve essere una funzione di tipo ℤ → ℤ.
Martin Ender,

1
@Bijan sia positivo che negativo.
Martin Ender,

Risposte:


18

Python, 68 caratteri

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 associa numeri negativi a numeri dispari e numeri positivi a numeri pari e numeri pari a numeri positivi e numeri dispari a numeri negativi, con la magnitudine di uscita che aumenta strettamente con la magnitudine di ingresso.

g fa lo stesso, tranne per il fatto che mappa numeri negativi su numeri pari e numeri positivi su numeri dispari.

f ∘ g mappa negativo → pari → positivo e positivo → dispari → negativo.
g ∘ f mappa negativo → dispari → negativo e positivo → pari → positivo.

Pertanto feg hanno le proprietà desiderate.


2
fe gpossono essere funzioni senza nome, quindi è possibile eliminare quattro byte.
Martin Ender,

È possibile definire (1-x%2*2)come variabile per salvare alcuni byte.
OldBunny2800,

Ecco un codice completo con cui giocare 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(); Puoi sostituirlo ;con linefeed per leggibilità.
Stéphane Gourichon,

16

Python , 40 byte

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

Provalo online! Alcuni output sono float uguali a numeri interi perché, (-1)**(-3)ad esempio, fornisce un float.

Basato su idee di Peter Taylor . La funzione fannulla i numeri dispari e lascia invariati anche i numeri. La funzione gfa lo stesso, quindi applica la mappa di cambio di parità monotona x -> 3*x + 1.

Da allora f(f(x)) = x, abbiamo in g(f(x)) = 3*f(f(x))+1 = 3*x+1aumento.

Perché f(g(x)) = f(3*f(x)+1), l'idea è che esattamente uno dei fsegni di ribaltamento interno ed esterno , facendolo diminuire.

  • Per pari x, f(x) = xma f(3*x+1) = -3*x-1perché 3*x+1è strano.
  • Per dispari x, f(x) = -xe f(-3*x+1) = -3*x+1perché -3*x+1è pari.

Ora abbiamo solo bisogno che gli input pari e dispari si alternino in modo decrescente, il che vale perché -3*x±1sta diminuendo indipendentemente da come vengono scelti i segni. Questo è il motivo per cui 3*è necessario.

Una porta Haskell è di 25 byte:

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

Provalo online!


In Haskell, (^)è esponenziazione intera.
user1502040

1
@ user1502040 Non può gestire esponenti negativi.
xnor

1
Dal momento che non ti stai chiamando gpuoi salvare due byte rendendolo senza nome.
Martin Ender,

14

CJam (17 byte)

Funzione f (denominata Fperché CJam consente solo nomi in maiuscolo):

{W1$2b,#*}:F

Funzione g (anonima):

{F2*}

Demo online

Ciò consente di risparmiare un byte facendo affidamento su un dettaglio di implementazione di CJam che è probabilmente un bug: quando fa conversioni di base usa un valore assoluto. 2b,quindi fornisce il numero di bit nel valore assoluto del suo argomento, quindi f nega precisamente quei numeri il cui valore assoluto ha un numero dispari di bit. g applica f e quindi raddoppia (modificando la parità del numero di bit).

Quindi l'applicazione di f e poi g lascia il segno invariato e doppio, mappando xa 2x. Applicando g e poi f cambia il segno esattamente una volta e raddoppia, mappando xa -2x.


Bene, questa è esattamente la soluzione di riferimento fornita dalla concorrenza. (Suppongo che tu l'abbia inventato indipendentemente?)
Martin Ender,

@MartinEnder, ho già visto questo problema da qualche parte. Forse su math.SE.
Peter Taylor,

2

Pyth, 34 byte

Questa è solo una traduzione diretta della mia risposta Python.

*-1*2%Q2+*2*QQ<Q0
*-1*2%Q2+*2*QQ>Q0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.