Defina una función f tal que f (f (n)) = -n para todos los enteros distintos de cero n


43

Este desafío fue inspirado por un blog de programación que frecuente. Vea la publicación original aquí: Un rompecabezas de programación


Reto

Defina una función f:Q->Qtal que f(f(n)) = -npara todos los enteros distintos de cero n, y dónde Qestá el conjunto de números racionales.

Detalles

En el idioma que prefiera, defina una función o programa fque acepte como parámetro un número ny devuelva o genere un número f(n).

La entrada se puede proporcionar a través del mecanismo más natural para su idioma: argumento de función, lectura de STDIN, argumento de línea de comando, posición de pila, entrada de voz, signos de pandillas, etc.

La salida debe ser un valor de retorno de una función / programa o impreso en STDOUT.

Me gustaría restringir las respuestas a las funciones que no aprovechan el estado del programa o la memoria / datos globales que son visibles desde el exterior de la función f. Por ejemplo, mantener un contador fuera de feso cuenta cuántas veces fse llamó y simplemente hacer una negación basada en este conteo no es muy desafiante o interesante para nadie. Las decisiones fque se tomen deben basarse únicamente en datos dentro fdel alcance léxico.

Sin embargo, esta restricción es probablemente inapropiada para algunos lenguajes orientados a la pila u otros tipos de idiomas que no distinguen estos tipos de datos o ámbitos. Utiliza tu mejor criterio para seguir con el espíritu de este desafío.


Tanteo

Se aplican reglas comunes de golf de código: su puntaje es el número de bytes en su código fuente.

La respuesta mínima requiere que el dominio y el codominio fsean un subconjunto de los racionales Q. Si restringe su dominio y codominio fa los enteros Z, su puntaje es el límite del 90% del número de bytes en su código fuente.

Desempate

En caso de empate, se utilizará lo siguiente en orden:

  1. Poca cantidad de símbolos imprimibles que no sean espacios en blanco en su código fuente
  2. Fecha y hora más tempranas de envío de respuestas

Editar

No está obligado a admitir números de tamaño arbitrario. Interprete los conjuntos Zy los Qtipos de datos en el idioma elegido (normalmente, entero y coma flotante, respectivamente).

Si su solución se basa completamente en la estructura subyacente o el patrón de bits de un tipo de datos, describa sus limitaciones y cómo se está utilizando.


20
f (n) = i * n - matemática pura: P
Johannes Kuhn

8
@JohannesKuhn esta es la razón por la cual el dominio y el codominio están restringidos a los racionales
ardnew

¿Podría explicar qué f:Q->Qsignifica?
beary605

@ beary605 significa que fes una función que asigna miembros de Q(números racionales) a otros miembros (posiblemente los mismos) de Q. ver en.wikipedia.org/wiki/Function_(mathematics)#Notation
ardnew

77
Sabía que había visto esto recientemente, pero me llevó un tiempo recordar dónde. Una versión menos fuertemente especificada en StackOverflow se cerró recientemente. Más de 100 respuestas.
Peter Taylor

Respuestas:


12

J, 9 puntos (10 caracteres)

Según la respuesta de stackoverflow :

   (*-[*_1&^)

Primera idea (13 caracteres):

   ((-*)-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

Esto funciona para la entrada de enteros, pero produce una salida imaginaria para valores de coma flotante (la función debe producir una salida racional para una entrada racional de acuerdo con la especificación)
Volatilidad

55
@Volatility, la especificación es confusa, pero a medida que la leo permite restringir el dominio y el codominio a enteros.
Peter Taylor

¿Necesitas los paréntesis?
Cyoce

14

Python: 61 34 30 29 27 puntos

f: Q -> Q

en matemáticas:

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

en Python:

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

probado con

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

lógica detrás de esto:

Cuando tomas un número entero ny lo fpones, obtendrás x+0.5. Esto ya no es un entero, por lo que la siguiente aplicación será 0.5-(x+0.5)cuál es -x.

Créditos

Gracias a

  • Bakuriu por despojarlo de 61 caracteres a 34 caracteres.
  • Volatilidad para reducir aún más el tamaño del código a 30 caracteres.
  • copia para reducir el tamaño del código a 29 caracteres (y solucionar un posible problema de coma flotante).
  • Aditsu por mencionar una inconsistencia que vino con los cambios anteriores.

Notas

Primero pensé que esto estaría bien

f = lambda n: 1j*n

pero es f: N-> C y eso no está permitido: - /


1
Se puede reducir a: f=lambda x:x%1>0and(-x+x%1)or x+.1que tiene solo 34 caracteres de longitud.
Bakuriu

f=lambda x:[x+.1,x%1-x](x%1>0)es solo 30
Volatilidad

1
Una Char más corto: f=lambda x:[x+.5,.5-x][x%1>0]. Tenga en cuenta el uso de .5 en lugar de .1 para solucionar problemas de precisión
copie el

1
@AJMansfield 1.48 no es un número entero.
Martin Thoma

1
No, eso no significa eso. Si menciona eso, debería haber escrito "todos los números racionales". f:Q->Qsolo significa que f asigna un número racional a números racionales. Lo que hace mi definición de f.
Martin Thoma

11

C, 41 puntos (41 o 45 caracteres)

Funciona con 32 y 64 bits.

f : Z -> Z(excepto INT_MAX):

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

Si no tenemos que incluir 0podemos eliminar algunos caracteres (41 caracteres):

f : Z -> Z(excepto 0& INT_MAX):

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

Esta función funciona dividiendo todos los enteros en 4 grupos según su signo y paridad.

Entonces tenemos las 4 combinaciones diferentes:

+ even, + odd, - even, - odd

Como necesitamos cambiar el signo del número, pero no la paridad después de dos pasadas, obtenemos dos posibles secuencias diferentes:

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

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

En este ejemplo, he elegido el primero.

Primero necesitamos mapear todos los enteros positivos pares a enteros negativos impares. Hacemos esto cambiando el signo e incrementando el número (también puede optar por disminuir el número):

f1(n) = -n + 1

Luego necesitamos asignar todos los enteros negativos impares a los enteros negativos pares. Necesitamos asegurarnos de que f2(f1(n)) = -n:

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

Usando los mismos métodos encontramos f3y f4:

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

Para combinar estas funciones en una sola función, observamos que cada vez nque incluso cambiamos el signo de ny cada vez que nes positivo, incrementamos en uno y de lo contrario disminuimos en uno:

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

Esto puede reescribirse así como:

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

donde odd(n)regresa 1para números impares y -1para números pares.

Hay 4 soluciones en total:

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_MINsiempre se puede considerar un caso límite en las 4 funciones como -INT_MIN == INT_MIN=> f(f(INT_MIN)) = INT_MIN.


Esto es esencialmente lo mismo que mi respuesta GolfScript (excepto que se explica mejor). ¿Esto funciona para 0?
Ben Reich

@BenReich Como se indicó en la respuesta, no funciona para 0otros 3 números.
Tyilo

1
@Tylio Ya veo ahora. Tiene sentido. Parece que solo deberías tomar el Zbono si cubres 0, al menos.
Ben Reich

@BenReich eliminó el bono hasta que lo solucione.
Tyilo

9

Aquí está mi intento.

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

Ejemplo en vivo :

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

Los tipos de entrada pueden adaptarse arbitrariamente para satisfacer sus necesidades. Esta versión funciona para literales enteros de menor magnitud que 2 ^ 32-1.


2
El problema decía que f:Q->Qno f:Z->Z.
AJMansfield

@AJMansfield la sección de puntuación de la especificación estaba destinado a ofrecer puntos de bonificación para las funciones definidas f:Z->Z, lo siento por la redacción confusa
ardnew

66
El problema con esta respuesta es que parece definir dos funciones separadas, mientras que la especificación requiere que solo defina una. pero no me refiero a iniciar un debate semántico, sigue siendo una solución muy reflexiva
nuevo

@ardnew, oh tienes razón. Me señalaron esta objeción válida solo unos segundos antes de compartirla con el Lounge <C ++> en el chat SO. Me pregunto qué hace el compilador de esto (si no incluye las llamadas), pero mi ensamblaje apesta.
rubenvb

1
Creo que puedes eliminar el espacio enreturn -i
Cyoce

6

JavaScript, 18

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

Usando la nueva notación de flecha gorda (Firefox 22).

Otra versión (18):

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

Versión anterior (20):

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

Ejemplo:

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

10
Parece que JavaScript está evolucionando hacia CoffeeScript.
Peter Taylor

4

Mathematica 18

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

Aquí ⌊...⌋está la función de piso. Utiliza solo números racionales (no listas, números complejos, etc.)

f[10]
f[f[10]]

21/2

-10

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

-9/2

5 5


3

lenguaje ensamblador x86 (FASM). El argumento y el resultado están en registro eax.

Funciona correctamente para -2 ^ 30 <N <+ 2 ^ 30-1

Código ejecutable de 16 bytes.

        use32

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

Nitpicking sus números; 2E30 sería 2 * 10 ^ 30, no 2 ^ 30 como creo que quieres.
Nick T

@NickT Mi error. Fijo.
johnfound

Estoy bastante seguro de que se supone que debes contar los bytes en el código fuente.
nyuszika7h

3

Lisp común: 35 bytes

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

Esquema (y raqueta): 36 bytes

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

Ungolfed con comentarios y explicaciones:

(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

Para cualquier número xen [1,->]el ifse convertirá en la fracción 1/2que es un número exacto real en ambos idiomas.

La parte dividida se convertirá entonces en (/ 1/2 x)la fracción 1/(x*2)que siempre será inferior 1. Porque 1será 1/2, porque 2es 1/4, etc.

Para cualquier número por debajo de 1, ifse convertirá en la fracción -1/2, lo que hace que la función haga lo (/ -1/2 x)que es, -1/(2*x)pero como podemos esperar que el valor sea el resultado de la ejecución anterior, podemos sustituir x por 1 / (x * 2) haciendo una aplicación doble-1/((1/(x*2))*2) = -x

Por ejemplo, ya que se 1convierte en 1/2la segunda aplicación es(/ -1/2 1/2) ==> -1


¿Como funciona esto?
AJMansfield

@AJMansfield agregó alguna información. Solo pregunta si hay algo que no esté claro. Leer la sintaxis de LISP es como el griego si no lo has aprendido y lleva algunas semanas acostumbrarte.
Sylwester

3

C, 60 (⌈66 * .9⌉)

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

Aquí hay una versión sin condensar:

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

Este método funciona utilizando solo enteros, por lo que obtiene el bono de puntuación del 90%. Originalmente lo escribía en Java, pero me di cuenta de que este programa en particular podría beneficiarse de los operadores lógicos de estilo C.

Como no hay un número entero correspondiente a -INT_MIN, f(f(INT_MIN))devuelve en su INT_MINlugar.

El mapeo subyacente es algebraicamente bastante simple. La ejecución de la declaración x=f(x)reemplaza x con:

  • x+1, si xes positivo e impar
  • -x+1, si xes positivo e incluso
  • x-1, si xes negativo e impar
  • -x-1, si xes negativo e incluso

El resultado de cada caso se incluirá en el siguiente caso la próxima vez que se aplique la función a x.

Como puede ver, componer un caso con el siguiente caso produce -x.

El código es el resultado de una simplificación inteligente de la función para aprovechar la estructura de bits de los enteros complementarios de dos.


3

> <> , 21 + 3 = 24 bytes, 22 puntos

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

Use el intérprete oficial de Python y use la -vopción de línea de comando para ingresar la entrada, a un costo de 3 bytes.

Tengo la sensación de que esto podría ser mejor. Seguiré mirándolo e intentaré jugarlo.

Dada entrada n, el programa sale

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

donde (n>0)y (n<0)son booleanos. Esto es equivalente a la respuesta Python de gelatina

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

pero ><>no tiene un operador de exponenciación incorporado, por lo que utilizamos (1 - 2*(n%2))en lugar de (-1)**n.

Lo que sigue es la teoría matemática: lee si (y solo si) estás interesado:

Dado cualquier función f: Z -> Ztal que f(f(n)) = -npara todos nen Z, vemos inmediatamente que f(f(f(f(n)))) = n, o en otras palabras, f^4es la función identidad. En particular, fes invertible, y su función inversa es f^3. Por lo tanto fes una permutación de Z, y desde f^4 = Id, se sigue que cada órbita (o ciclo) de ftiene tamaño, ya sea 1, 2o 4.

A continuación, vemos eso f(0) = 0. Prueba: f(0) = f(-0) = f(f(f(0))) = -f(0)así f(0) = 0, como se desee. Por el contrario, supongamos que xestá en un ciclo de longitud 1o 2, entonces f(f(x)) = x. Entonces -x = xentonces x = 0.

Por flo tanto, se compone completamente de 4 ciclos, excepto el punto fijo (1 ciclo) en 0.

Además, cada 4-ciclo debe tener la forma (x, y, -x, -y), y mediante la rotación del ciclo alrededor podemos suponer que xy yson ambos positivos. Por el contrario, cada uno de esos productos de particiones de 4 ciclos de los enteros distintos de cero determina una elección de f.

Por lo tanto, cada elección de fcorresponde únicamente a un gráfico dirigido cuyos vértices son los enteros positivos, de modo que cada vértice incide exactamente en una flecha, ya sea entrando o saliendo. Más precisamente, en el gráfico subyacente no dirigido, cada vértice tiene un grado exacto 1. (Cada 4 ciclos (x y -x -y)con xy ypositivo corresponde a la flecha x --> y).

La función de esta respuesta (y varias otras respuestas aquí) se corresponde con el gráfico donde 1 --> 2, 3 --> 4y, en general 2k-1 --> 2k.

Tales gráficos están en biyección con secuencias infinitas de pares ordenados (a_n, p_n), donde cada a_nes un entero positivo y cada uno p_nes o bien 0o 1: dada una secuencia de (a_1, p_1), (a_2, p_2), (a_3, p_3), ..., en primer lugar par 1con 1 + a_1, y luego formar o bien la flecha 1 --> 1 + a_1o en la flecha 1 + a_1 --> 1en función de si p_1es 0o 1. Esencialmente, la flecha es un <signo o un >signo, dependiendo de la paridad de p_1.

A continuación, tome el entero positivo no emparejado más pequeño ky cuente desde k, exactamente los a_2pasos, SALTANDO cualquier número que ya esté emparejado con algo. Empareje kcon el resultado y establezca la dirección de la flecha según p_2lo anterior. Luego repite con (a_3, p_3), etc.

Cada flecha finalmente se determinará de esta manera, por lo que el proceso está bien definido. La función en esta respuesta corresponde a la secuencia (1,0), (1,0), (1,0), ..., ya que en el paso nel número entero más pequeño sin emparejar es 2n-1y no hay enteros más grandes que los que 2n-1se hayan emparejado con algo, por lo que obtenemos 2n-1 --> 2npara cada uno n(las flechas están orientadas de esta manera porque cada una p_nes igual 0).

La cardinalidad de este conjunto es (N*2)^N = N^N, que en el último párrafo de esta respuesta es igual 2^N, la cardinalidad de los números reales.


Las opciones de línea de comando son generalmente un byte cada una.
gato

@cat Vea la sección "Invocaciones especiales" en esta meta publicación .
Mathmandan

2

Para arreglar la respuesta J anterior (no tengo suficiente reputación para comentar sobre el original):

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

Simplemente reemplaza el _1&^con 1-~2*2|], que da el signo opuesto. Así que cambié el -a a +(que solo importa en la entrada de 1y _1).

Aquí están las pruebas:

   (*+[*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

Como puede ver, el dominio y el rango son de todos los números reales, pero solo funciona para enteros (incluido 0).

Explicación:

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

2

GolfScript ceiling(26*.9)=24

Golfscript solo maneja números enteros, así que aplique la Zbonificación por un total de 24 puntos:

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

El caso especial de 0 representa 8 caracteres. Ignorando 0, podemos tener una respuesta de 17 puntos:

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

Este código hace lo siguiente a un número entero xen la parte superior de la pila:

  • Si xes 0, déjelo 0en la pila y no aplique más reglas.
  • Si xes par, negar x.
  • Si xes positivo, agregue 1.
  • Si xes negativo, resta 1.

Esto conecta lógicamente conjuntos de 4 números en un ciclo, donde fatraviesa elementos del ciclo y las esquinas opuestas del ciclo son negativas entre sí. Cada entero es parte de exactamente 1 de estos ciclos, excepto 0, que está en mayúsculas especiales. Por ejemplo, para {-8, -7, 7, 8}:

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

Los únicos casos de prueba relevantes que se me ocurrieron fueron negativos impares, negativos pares, positivos impares, positivos pares 0, y luego presenté -1y 1dado que su proximidad 0puede haber causado problemas:

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

Estoy seguro de que el GolfScript real se puede mejorar un poco. ¡No parece que deba ocupar 26 caracteres! Me encantaría escuchar algunas sugerencias.


2

Java, solo por diversión

Aquí hay una implementación que realiza una biyección real entre ℤ y ℤ², que es una función extraña al mismo tiempo (g (-x) == -g (x)). Trata el elemento ℤ² correspondiente como un número complejo y lo multiplica por "i", luego lo convierte de nuevo a ℤ.

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

La función se ejecuta en 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);
            }
        }
    }
}

PD ¡Feliz año nuevo!


Creo que el espacio en blanco es innecesario.
pppery

2

Python 3 - 38

Similar a la respuesta de @ alce, pero f(n) == n,. Funciona para todos los valores enteros.

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

2

Perl, 33 (sin espacios en blanco)

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

Editar:

  • $=.".1"acortado a "$=.1"(gracias ardnew).

Mates:

Mates

Sin golf:

# 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($_));

Ejemplos:

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

Solución robusta: los casos de prueba de punto flotante que demuestre no son necesarios según las especificaciones (¡deberían haber ofrecido puntos de bonificación por eso!). aquí está su mismo algoritmo con algunas limpiezas en 22 caracteres:sub f{yzxzzc?-$_:x.$_}
ardnew

1
@ardnew: Gracias. Pero no estoy de acuerdo con que su solución use el mismo algoritmo. El algoritmo nosub f{yzxzzc?-$_:x.$_} está libre de estado, usa un estado a través de la variable . Debido a esto, ya no es una función (en el sentido matemático), porque son posibles diferentes valores para el mismo valor de entrada dependiendo del estado (el clima contiene o no). Mi algoritmo no usa un estado. La información está codificada en el valor de salida. Los enteros se convierten en números reales mediante la suma . Y los números reales se convierten de nuevo a enteros con el signo cambiado. $_f$_x.1
Heiko Oberdiek

interesante: no se utilizan datos de estado en su implementación debido a la asignación inicial y no debido a alguna propiedad especial de $=?
ardnew

No me di cuenta de que también fallé mi propio requisito (que fse definirá Q->Q) con ese xchar. también $=.".1"se puede acortar a"$=.1"
ardnew

@ardnew: La propiedad especial de $=es que solo toma números enteros. El mismo se puede conseguir mediante el uso de una variable ordinaria: $a=int$_[0]. Pero eso cuesta tres bytes adicionales debido a la función int.
Heiko Oberdiek

2

Julia, 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

No es súper competitivo, pero es muy juliano, ya que depende del envío múltiple. Simplemente hace que sea Racional si es un Int, o un int con un signo menos si es cualquier otra cosa. Se podría objetar que se trata de 2 funciones, pero Julia considera que se trata de una función con dos métodos, y es equivalente a definir una función con una declaración if sobre el tipo de n.


No es lo que un matemático llamaría una función: en Julia 3==3//1regresa truepero f(3//1)==f(3)regresa false.
Omar

2

Candy , 20 18 bytes

Utiliza el truco 3 -> 4 -> -3 -> -4 -> 3.

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

Para invocarlo, use el modificador -i en el intérprete

Ejemplo de doble invocación:

$ 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

Forma larga:

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

Dyalog APL, 9 puntos

×-⍨⊢ׯ1*⊢

La fuente tiene una longitud de 9 bytes y califica para la bonificación (que no ayuda en absoluto). También utiliza la fórmula de la respuesta SO superior.




1

Java, 113 bytes

El enfoque es bastante simple. Terminó más bytes de lo que esperaba, pero tal vez se pueda reducir un poco.

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

Básicamente crea 4 "áreas" diferentes de x, utilizando el hecho de que Java felizmente deja que las variables se envuelvan. Tuve que hacer una conversión complicada para números negativos, que es la razón principal por la que esto terminó más grande de lo previsto.

Funciona para todas las x además de -2147483648.


1

Misma secuencia de números (3, 4, -3, -4, 3 ...) que la respuesta de golfscript, pero implementada en perl (42 caracteres después de que se elimine el espacio en blanco)

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

Más legible:

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

O incluso más legible:

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)
  }
}

Salida:

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

Lo anterior también funciona para los no enteros: ski @ anito: ~ / mysrc /.../ acme $ echo 1.1234 | perl -e 'sub f {($ _ [0]% 2? 1: -1) * $ _ [0] + ($ _ [0] <0? -1: 1)}; my $ x = <>; para (0..4) {print "$ _: $ x \ n"; $ x = f ($ x); } '0: 1.1234 1: 2.1234 2: -1.1234 3: -2.1234 4: 1.1234
skibrianski

1

Sed, 25 bytes.

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

Uso:

$ 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 caracteres

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

2
Esta no es una respuesta válida, ya que el dominio y el codominio de la función no deben ser complejos.
Wrzlprmft

oh, lo siento ... acabo de leer el título y no fui tan cuidadoso ... Veamos si puedo editar esto de alguna manera
bla

1

C ++ - 63 55.8

Así es como se ve el código:

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

No funciona en números enteros cuyo cuarto byte es igual a 0xB, ya que usa ese valor para realizar un seguimiento de los pases. De lo contrario, funciona en cualquier miembro de Z, incluido cero.


puedes explicar este? en la primera inspección, parece que mantiene un contador de llamadas fcon una variable estática. pero entonces, ¿cuál es el punto de la sqrt?
ardnew

Parece que he entendido mal la pregunta; pensé que una variable estática estaba bien ya que C ++ es un lenguaje orientado a la pila, pero arreglaré el código. De lo contrario, no tengo idea de por qué lo necesitaba, sqrtya que de todos modos se redondea con el tipo de conversión. Lo refactorizaré para que funcione sin la variable estática.
Darkgamma

No tengo idea de dónde obtuviste el 55.8, pero tu código actual tiene 62 bytes de longitud. Editar: No importa, no leí la pregunta correctamente.
nyuszika7h

La restricción de que el cuarto byte no puede ser igual a 0xB desafortunadamente hace que esta no sea una respuesta válida al desafío, lo que requiere que funcione en (al menos) todos los enteros.
pppery

1

Actualizado con la función suministrada por Synthetica (obviamente, quien debería obtener crédito por esto ahora)

Lenguaje: Python

Número de caracteres: 41 incluyendo espacios en blanco

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

Proporcione también el nombre del idioma que utilizó y proporcione también el recuento de caracteres.
ProgramFOX

Me gusta cómo esto también funciona con los no enteros. Bien hecho. :)
cjfaure

f=lambda x:-float(x) if str(x)==x else`x`es bastante más corto: 41 incluyendo espacios en blanco
ɐɔıʇǝɥʇuʎs

Gracias Synthetica, ¡ni siquiera sabía sobre el truco de backticks! : D
HolySquirrel

En enteros fdevuelve una cadena; La especificación dice que debe devolver un número racional.
Omar

1

Prólogo, 36 bytes

Código:

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

Explicado:

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

Ejemplo:

10*X.
X = 10.5

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


1

Mouse-2002 , 21 19 12 bytes

$A1%[1%_|1%]

Define una función A; llámalo como #A,#A,?;;(que esperará a que el usuario ingrese cualquier número). Alternativamente, llámelo como #A,#A,n;;donde nestá cualquier número.


1

Julia, 21

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

Luego

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

p // q es la notación literal de números racionales de julia.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.