Random IRC quote :      * madalenasbuenas se ha marchado (Quit: feliz dia de la raza canina)

Solución al reverseme! de Victor

Hola!,Ecuaciones

Ahora que alguien ya ha resuelto el reverseme! de Victor, enhorabuena a Tora y a Miguel : dice erg0t que eres una VM humana! ;-), aprovecho para postear mi solución, con código fuente incluido :-).

Lo primero era echar un vistazo al reverseme! de Victor y ver que perrerías nos había puesto, después de pasar su algoritmo a C, con un poquito de asm inline para ver el estado de la FPU 😉 , nos quedamos con algo como lo siguiente …

#include <stdio.h>
#include <math.h>

const float   _f_1 = 3.2e2;
const float   _f_2 = 5.96e2;
const float   _f_3 = 8.8804e4;
const double  _d_1 = 1.0e2;
const double  _d_2 = 4.0e2;
const double  _d_3 = 1.0;

int main (int argc, char **argv )
{
        double r,r1,r2;
        float  s1,s2;
        int   bdiverror  = 0;

        // get_right_values(&amp;s1,&amp;s2);

        printf("Trying values …  : %f-%fn",s1,s2);

        r  = ( ( s1 – _f_1 ) * (s1 – _f_1) ) / _d_1;
        r1 = ( ((s2 * s2)(_f_2 * s2)) + _f_3 ) / _d_2 ;     

        if ( (r + r1)  == _d_3)
        {

                        r2 = log(s1 / s2);             

                        // By default FP exceptions are not enabled so
                        // we just check FP status for divide error 🙂                

                        __asm
                        {
                                fld     r2
                                fdivr   _d_3
                                fnstsw  ax
                                test    ax, 4
                                jz      noerror
                                mov     bdiverror, 1

                                noerror:
                        }                      

                        // In order to raise a divide error (right password) we need r2 to be 0,                                               

        }

        if (bdiverror)
        {
                printf("Right!!n");
        }

        else
        {
                printf("Wrong!!n");
        }
}
 

Bien, parece que victor nos ha planteado un sistema formado por las siguientes ecuaciones :

a) ln(x/y) = 0;
b) ( ( ( x – _f_1 ) ^ 2 ) / _d_1 ) + ( ( y^2 – _f_2 * y + _f_3 ) / _d_2 ) = 1

De la primera ecuación podemos inferir lo siguiente :

ln(x/y) = 0 => (x/y) = 1 => x = y

Por lo tanto pasamos a sustituir todas las x por y en la segunda ecuación :

( (x – _f_1) ^2 ) / _d_1 ) + ( (x^2 – _f_2 * x + _f_3) /_d_2) = 1

Y desarrollamos :

_d_2 ( x^2 + _f_1^2 – 2 * _f_1 * x ) + _d_1 ( x^2 – _f_2 * x + _f_3 ) = _d_1 * _d_2
( _d_2 + _d_1 ) x^2 + ( – 2 * _f_1 * _d_2 – _d_1 * _f_2 ) * x + ( _d_2 * _f_1^2 + _d_1 * _f_3 – _d_1 * _d_2 )

Con esta expresión ya podemos escribir una pequeña función que resuelva la ecuación de segundo grado en dependencia de las constantes que ha puesto Victor :

void get_right_values (float *s1, float *s2)
{
        float a,b,c;

        // Usamos los valores obtenidos en el desarrollo :

        a = (float) (_d_2 + _d_1);
        b = (float) ( -2 * _f_1 * _d_2 – _d_1 * _f_2 );
        c = (float) ( _d_2 * _f_1 * _f_1 + _d_1 * _f_3 – _d_1 * _d_2 );

        // Calculamos una de las posibles raices de la ecuación.

        *s1 = ( -b – sqrtf(b*b – 4 * a * c) ) / (2*a);

        // El otro término debe ser igual

        *s2 = *s1;
}

Añadimos esta función al codigo revertido de Victor y ejecutamos nuestro programa …

Trying values … : 314.000000-314.000000
Right!!

Si probamos estos valores con el binario original de Victor también funcionan 😉 , el código
fuente de todo esto lo podeís encontrar aquí.

Gracias por el interesante reverseme! Victor, mira a ver si te curras otro 😀

Un saludo,

Mario

4 Comentarios para “Solución al reverseme! de Victor”

  1. Comment por Victor Manuel Alvarez | 07/25/07 at 7:48 am

    Enhorabuena por las soluciones! Y me alegro que les haya gustado, luego pensaré a ver si se me ocurre otro, manténganse en sintonía con 48bits 🙂

    Como detalle adicional, las dos soluciones al problema (una de ellas más teórica que práctica) son las coordenadas de los puntos en los que se cortan la recta y = x y una elipse. Si se fijan bien una de las ecuaciones que se tienen que cumplir tiene la forma de la ecuación de la elipse.

    Más info en: http://en.wikipedia.org/wiki/Ellipse

  2. Comment por Ruben | 07/25/07 at 10:28 am

    Otia, triunfada. Enhorabuena a Mario,Tora y Miguel por solucionarlo y a Víctor por el reverseme. Muy buen trabajo a todos!! Con vosotros la comunidad puede dormir tranquila 🙂

    Aunque para proximos retos deberíamos establecer unas reglas para publicar las soluciones ordenádamente tras un periodo razonable, se me ocurre por ejemplo que se envíen a un email o así. Sois mákinas, no me ha dado tiempo ni a mirarlo y ya con la solución publicada no tiene gracia ponerse 😀

    Además, así si alguien que no tiene acceso a postear en el blog también podría exponer su solución en algún formato mejor que en el de un comentario. A ver qué os parece.

  3. Comment por Miguel | 07/25/07 at 1:20 pm

    Buenos dias

    Totalmente de acuerdo con Ruben. Hemos sido un poco caoticos a la hora de hacer publicas las soluciones y con un poco mas de orden seguramente mas gente habria tenido la oportunidad de pasar un buen rato con el reverseme.
    Y felicidades para Tora y Mario por sus soluciones. En el caso de Mario yaque ha publicado el código, puedo decir que el programa-solución es mas directo y elegante que la versión que yo implemente, aunque como defensa dire que tengo pensado utilizar mi algoritmo de regula-falsi para otros menesteres :oD
    Y felicidades a Victor por su reverseme. Un trabajo cojonudo.
    Venga, un saludo!!!

  4. Comment por mballano | 07/25/07 at 1:38 pm

    Hola,

    Sip, estoy de acuerdo con Rubén, quizá podríamos hacer algo como lo siguiente:

    El que publica el reverseme da una direccion de correo y un tiempo, podría ser alrededor de una
    semana o similar, dependiendo de la dificultad del reto. Al cabo de ese tiempo, publica la
    solución oficial (o toma como oficial una de las que le han enviado ) y comenta el resto de las
    soluciones, cuales le han parecido mejor, peor y por qué, las subimos al repositorio de ficheros de
    48bits, dejando en el post un un enlace a cada una de ellas, para que cualquiera las pueda consultar.
    El resto lo podemos discutir en los propios comentarios del blog. ¿Qué os parece?, si preferís
    alguna otra alternativa o método comentad :-).

    Con respecto a la solución que puse, el método será mas elegante, pero yo quiero ver ese regula-falsi
    eh! ;-).

    Un saludo,

    Mario

    P.S: Creo que Victor ya está maquinando otra nueva prueba… x)

Se han cerrado los comentarios