Otro pequeño reto

Este reto es más sencillo en cuanto a que no tienen que programar la función. Pueden intentar fácilmente con pseudocódigo en una hoja de papel. Por ello esta es una buena pregunta en entrevistas de trabajo.

Diseña una función f, que cumpla lo siguiente:

f(f(n)) == -n

para cualquier entero n. No se permite usar aritmética de números complejos.

Si lo logran resolver por su cuenta (y no buscando en goolge o siguiendo el enlace de la fuente) agreguen un comentario con su solución.

Fuente: Stackoverflow

15 comentarios en “Otro pequeño reto

  1. Esta es mi solucion… me ha llevado un tiempo pensarla pero asi como en el reto anterior me funciona. Trabaja con enteros relativamente grandes y con negativos.

    [java]
    public static int f(int n)
    {
    int retu = n ;
    int nConst = -99999; // constante puesta arbitrariamente

    if (n % nConst == 0)
    {
    retu = n / (nConst*-1);
    }
    else
    {
    retu = n * nConst;
    }
    return retu;
    }
    [/java]

    Me gusta

  2. Se me han ocurrido 2 posibilidades:

    1a f utiliza numeros complejos i multiplica el valor por i, al aplicarla 2 veces obtenemos el nº original cambiado de signo.

    2a Os lo pongo en pseudo python:
    [python]
    def f(n):
    if abs(n) < 0 :
    return -(1.0/n) if n != 0 else 0
    else
    return 1.0/n
    [/python]
    Esta segunda posibilidad no me acaba de convencer, por la posible falta de precisión al hacer la división.

    Me gusta

    • abs(n) nunca es menor que 0. Creo que estabas pensando en abs(n) < 1. Pero de ser así para el 1 no funciona (aunque uses <=). Para los demás funciona haciendo un lado la posible falta de precisión.

      Me gusta

      • Tienes razón, le habia estado dando vueltas ayer al tema y lo anoté, pero al escribir el comentario lo he hecho según lo recordaba y rápido… Con las consecuencias que comentas.
        En la versión que anoté usaba en la condición el 1 en lugar del 0, tambien controlaba cuando n era 0, pero no caí en el caso de 1

        Después he visto el articulo de stackoverflow y la solución con nºs complejos no resulta válida para lo que piden.

        Además viendo que el valor al que se debe aplicar la función debe ser un entero con signo de 32 bits, está claro que la división no es una opción.

        Me gusta

  3. va en lenguaje C, soportando numeros tan grandes como lo permita el tipo long:

    long efe(long n)
    {
      static long c = 0;
      if (c == 0)
        {
          c = n;
        }
      return n - c;
    }
    
    int main()
    {
      long n;
      scanf(&quot;%ld&quot;, &amp;amp;n);
      printf(&quot;%ldn&quot;, efe(efe(n)));
    }
    

    Me gusta

      • Si tienes razón… Aunque en el texto del problema no se pedía restricción alguna 😉 pensare en otra solución … Gracias!

        Me gusta

      • sale, gracias por no dejarme pensar en otra cosa… jajaja

        va en python, otra posibilidad:


        def efe(n):
        if type(n).__name__ == 'int':
        return n * 3.14
        else:
        return int(n / 3.14 * -1)

        Mi razonamiento es el siguiente…

        estuve pensando, por un lado, en no usar almacenamiento temporal.
        Y dandole vueltas llegue a la pregunta:

        ¿en matematicas hay una funcion tal que, al aplicarla dos veces seguidas (la segunda sobre el resultado de la primera) me pueda dar el negativo de la entrada?
        Y la verdad, no llegue a una respuesta <- desmienteme aqui por favor

        Asi que se me ocurrio que cualquier solucion a la que se pueda llegar en un lenguaje, tiene una de dos opciones:

        1) usar alguna especie de memoria en la primera corrida de forma que en la segunda se detecte esa situacion y se haga negativa la entrada y ya…

        2) usar (o abusar de) alguna caracteristica del lenguaje en particular que se use

        En cuanto a la opcion 2, estuve pensando si usar los overflows, o rotaciones de bits podria ayudar, y la verdad es que me canse un poco y opte por sacar rapido una solucion de tipo 1…

        en ultima instancia, toda solucion de tipo 1 necesita un tipo de memoria. En mi primer propuesta yo use una variable static, que por lo menos, considero que no necesita mucha 'memoria' en la funcion para recordar la primer corrida, simplemente funciona (y si funciona eh? pruebalo :))

        En este otro caso mi 'memoria' fue cambiar el tipo de dato de la entrada en la primer corrida, detectar eso en la segunda y regresar todo a entero y cambiarle el signo…

        Al final y al cabo, o se tiene una especie de 'recordatorio' en la funcion (que puede ser un static, una variable global, cambiar el tipo, usar el modulo con una constante arbitraria como lo hizo Silver, o lo que sea…) para que la segunda corrida lo detecte, o se abusa de alguna característica del lenguaje… <- de nuevo, desmientemen en esto, que solo fueron elucubraciones en mi viaje al trabajo 😉

        saludos!

        Me gusta

  4. Talvez este obviando algo importante porque problema me parece sospechosamente trivial.


    # La funcion f es de primera clase.
    sub f {
    -
    }

    print &f(sub{5}); # Imprime -5

    Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s