Universidad de Costa Rica
Escuela de Ciencias de la
Computación e Informática
Profesor Adolfo Di Mare
CI-1101
II Semestre 2012
[<=] [home] [<>] [\/] [=>]
CI-1101 Programación I

Tarea #3 [solución]

Comparación de vectores

      Complete la implementación del método Encajados.java para que funcione de acuerdo a su especificación. Note que el programa calcula correctamente la cantidad de valores que están en su posición exacta, pero no está el bloque de código que calcula cuántos están corridos.

      Además, incluya más datos de prueba para el métdodo elDelMedio(), pues los que tiene no son suficientes. Recuerde usar DrJava como platforma de desarrollo. También recuerde pulsar el botón [Test] para activar el programa usando pruebas tipo JUnit (es más complicado ejecutar el programa activando el botón "run"). Recuerde: agregue su algoritmo dentro del bloque marcado "{ *** RELLENE CON SU ALGORITMO *** }"... ¡No modifique ninguna otra parte del programa!

      Para esta tarea programada usted debe enviarme estos archivos:

  1. Encajados.java
  2. TestEncajados.java
  3. CARNET.docx
  4. CARNET.html
  5. CARNET.url

      En el documento CARNET.docx deben describir su experiencia de aprendizaje para completar esta tarea. Explique qué hizo, cómo lo hizo y por qué lo hizo. En especial, es importante que mencionen por qué escogieron las instrucciones que incluyeron y cuáles fueron las dificultades que enfrentaron. El archivo CARNET.html es copia de la página Internet en donde usted instaló la solución de su tarea programada. El archivo de enlace Internet CARNET.url contiene solo 2 renglones y sirve para abrir la página Internet en que está la documentación completa de su programa (para crearlo puede usar cualquier editor de texto).

[InternetShortcut]
URL=http://www.di-mare.com/adolfo/cursos/ci-1101.htm
ci-1101.url

Consulta:
Profe: Podría explicarme de una manera mas concreta qué tengo que hacer en esta tarea.
Respuesta:
  1. Hay que agregarle los ciclos anidados en donde está el cuadrado "RELLENE CON SU ALGORITMO".
  2. Hay que agregar pruebas tipo assertTrue() en testElDelMedio() para completar por lo menos 10 pruebas porque para el método elDelMedio() hay muy pocos datos de prueba.
  3. Las pruebas para testElDelMedio() no deben ser repetitivas y deben mostrar diferentes datos de entrada. Para eso pueden usar nuevos vectores además de los que aparecen en la implementación del método elDelMedio().

      Cuando el programa funcione, la barrita "Test Progress" del DrJava se pondrá toda verde .

      Entregue su tarea por correo electrónico, como lo hizo anteriormente.

/**
    @(#)Encajados.java 2009
    adolfo@di-mare.com
    Ejemplo de uso de vectores.

    @author Adolfo Di Mare <adolfo@di-mare.com>
*/

/** Contiene los métodos que realizan cada uno de los pasos del proceso. */
public class Encajados {

    /** Nombre el índice de "exactos" en el vector {@code res[]} */
    public static final int EXACTO  = 0;
    /** Nombre el índice de "corridos" en el vector {@code res[]} */
    public static final int CORRIDO = 1;

    /** Detecta cuántos valores del vector {@code ADIVINA[]} están
        en su posición correcta o corrida en el vector {@code SECRETO[]}.
        <ul>
        <li> Retorna {@code true} cuando todos los valores de
             {@code ADIVINA[]} están es su correcta posición
             {@code SECRETO[]}. </li>
        <li> Calcula la cantidad de valores de {@code ADIVINA[]} que si
             están en su posición final y lo retorna en {@code res[0]==res[EXACTO]}. </li>
        <li> Calcula la cantidad de valores de {@code ADIVINA[]} que no
             están en su posición final y lo retorna en {@code res[1]==res[CORRIDO]}. </li>
        <li> "EXACTO" significa que {@code ADIVINA[i] == SECRETO[i]} </li>
        <li> "CORRIDO" significa que {@code ADIVINA[i] == SECRETO[j] && i != j} </li>
        <li> Los vectores no necesariamente tienen la misma cantidad de valores. </li>
        </ul>
    */
    public static boolean estanEncajados(
        int SECRETO[],
        int ADIVINA[],
        int res[]
    ) {
        int exactos=0, corridos=0; // inicializa contadores

        // calcula la longitud mínima
        int min = ( SECRETO.length < ADIVINA.length ? SECRETO.length : ADIVINA.length );

        // calcula cuáles valores de ADIVINA[] están en su sitio final
        for ( int i=0; i<min; ++i ) {
            if ( SECRETO[i] == ADIVINA[i] ) {
                exactos++;
            }
        }

        // calcula cuáles valores de ADIVINA[] están en algún sitio en SECRETO[]
        {    
            /******************************\
            *                              *
            *   RELLENE CON SU ALGORITMO   *
            *                              *
            \******************************/
        }
        res[EXACTO]  = exactos;  // Achará: no se vale pasar parámetros "int" por referencia
        res[CORRIDO] = corridos; // - "exactos" y "corridos" son identificadores significativos
        return ( (exactos == SECRETO.length) && (SECRETO.length == ADIVINA.length ) );
    }

    /** Retorna la cantidad de valores del vector {@code VEC[]} que son menores a {@code val}.
    */
    public static int porDebajo( int VEC[], int val ) {
        int tot = 0;
        for ( int i=0; i<VEC.length; ++i ) {
            if ( VEC[i] < val ) {
                tot++;
            }
        }
        return tot;
    }

    /** Retorna la cantidad de valores del vector {@code VEC[]} que son mayores a {@code val}.
    */
    public static int porEncima( int VEC[], int val ) {
        int tot = 0;
        for ( int i=0; i<VEC.length; ++i ) {
            if ( VEC[i] > val ) {
                tot++;
            }
        }
        return tot;
    }

    /** Retorna el índice del primer valor de {@code VEC[]} tiene tantos valores por encima como debajo.
      * <ul><li> Si tal valor no existe, retorna {@code VEC.length}. </li></ul>
    */
    public static int elDelMedio( int VEC[] ) {
        for ( int i=0; i<VEC.length; ++i ) {
            if ( porDebajo(VEC,VEC[i]) == porEncima(VEC,VEC[i]) ) {
                return i;
            }
        }
        return VEC.length;
    }
    /** Muestra que los parámetros escalares no se pasan por referencia.
      * <ul>
      * <li> Tanto P como Q conservan su valor original. </li>
      * <li> Lo que el método usa es una copia de P y otra de Q. </li> </ul>
    */
    public static void noIntercambia( int P, int Q ) {
       int temp = P;
       P = Q;
       Q = temp;
    }

}

// EOF: Encajados.java
/**
    @(#)TestEncajados.java 2009
    adolfo@di-mare.com
    Datos de prueba para {@code Encajados}.

    @author Adolfo Di Mare <adolfo@di-mare.com>
*/

import junit.framework.*;

/** Datos de prueba para la clase {@code Encajados}. */
public class TestEncajados extends TestCase {
    static int V1234567[] = { 1, 2, 3, 4, 5, 6, 7 };
    static int V0101010[] = { 0, 1, 0, 1, 0, 1, 0 };
    static int Vunos[]    = { 1, 1, 1, 1, 1, 1, 1 };

    static int A1111[]    = { 1, 1, 1, 1 };
    static int A0123[]    = { 0, 1, 2, 3 };
    static int A3210[]    = { 3, 2, 1, 0 };

    static int A10[]      = { 1, 0 };
    static int A01[]      = { 0, 1 };

    static int A990123[]  = { 9, 9, 0, 1, 2, 3 };

    /** Nombre el índice de "exactos" en el vector {@code res[]} */
    static final int EXACTO  = Encajados.EXACTO;
    /** Nombre el índice de "corridos" en el vector {@code res[]} */
    static final int CORRIDO = Encajados.CORRIDO;

    /** test -> {@code Encajados.estanEncajados()}. */
    public void testEncajados() {
        int res[] = { -1 , -2 };   assertTrue( res[EXACTO] == -1 && res[CORRIDO] == -2 );
        boolean encajados = false; assertTrue( ! encajados  );

        encajados = Encajados.estanEncajados(A0123,A0123, res);
    //  System.out.print( (A0123.length) + " " +(res[EXACTO]) + " " + (res[CORRIDO]) );
        assertTrue( encajados && (res[EXACTO] == 4) && (res[CORRIDO] == 0) );
        assertTrue( res[EXACTO] != -1 && res[CORRIDO] != -2 );
        assertTrue( res[CORRIDO] == 0 && res[EXACTO]  ==  4 );
        assertTrue( res[EXACTO] !=  0 && res[EXACTO]  !=  3 && res[EXACTO] != 5 );

        encajados = Encajados.estanEncajados(A0123,A3210, res);
        assertTrue( !encajados && (res[EXACTO] == 0) && (res[CORRIDO] == 4) );
        encajados = Encajados.estanEncajados(A3210,A0123, res);
        assertTrue( !encajados && (res[EXACTO] == 0) && (res[CORRIDO] == 4) );

        encajados = Encajados.estanEncajados(A0123,A1111, res);
        assertTrue( !encajados && (res[EXACTO] == 1) && (res[CORRIDO] == 3) );
        encajados = Encajados.estanEncajados(A1111,A0123, res);
        assertTrue( !encajados && (res[EXACTO] == 1) && (res[CORRIDO] == 3) );

        encajados = Encajados.estanEncajados(A10,A1111, res);
        assertTrue( !encajados && (res[EXACTO] == 1) && (res[CORRIDO] == 3) );
        encajados = Encajados.estanEncajados(A1111,A10, res);
        assertTrue( !encajados && (res[EXACTO] == 1) && (res[CORRIDO] == 3) );

        encajados = Encajados.estanEncajados(A0123,V1234567, res);
        assertTrue( !encajados && (res[EXACTO] == 0) && (res[CORRIDO] == 3) );
        encajados = Encajados.estanEncajados(V1234567,A0123, res);
        assertTrue( !encajados && (res[EXACTO] == 0) && (res[CORRIDO] == 3) );

        encajados = Encajados.estanEncajados(V1234567,A10, res);
        assertTrue( !encajados && (res[EXACTO] == 1) && (res[CORRIDO] == 0) );
        encajados = Encajados.estanEncajados(A10,V1234567, res);
        assertTrue( !encajados && (res[EXACTO] == 1) && (res[CORRIDO] == 0) );

        encajados = Encajados.estanEncajados(A1111,A1111, res);
        assertTrue( encajados && (res[EXACTO] == 4) && (res[CORRIDO] == 12) );
    };

    /** test -> {@code Encajados.porEncima()}. */
    public void testPorEncima() {
        assertTrue( Encajados.porEncima( V1234567, 0 ) == 7 );
        assertTrue( Encajados.porEncima( V1234567, 1 ) == 6 );
        assertTrue( Encajados.porEncima( V1234567, 2 ) == 5 );
        assertTrue( Encajados.porEncima( V1234567, 3 ) == 4 );
        assertTrue( Encajados.porEncima( V1234567, 4 ) == 3 );
        assertTrue( Encajados.porEncima( V1234567, 5 ) == 2 );
        assertTrue( Encajados.porEncima( V1234567, 6 ) == 1 );
        assertTrue( Encajados.porEncima( V1234567, 7 ) == 0 );
        assertTrue( Encajados.porEncima( V1234567, 8 ) == 0 );

        assertTrue( Encajados.porEncima( V0101010,-1 ) == 7 );
        assertTrue( Encajados.porEncima( V0101010, 0 ) == 3 );
        assertTrue( Encajados.porEncima( V0101010, 1 ) == 0 );
        assertTrue( Encajados.porEncima( V0101010, 2 ) == 0 );

        assertTrue( Encajados.porEncima( Vunos   , 0 ) == 7 );
        assertTrue( Encajados.porEncima( Vunos   , 1 ) == 0 );
        assertTrue( Encajados.porEncima( Vunos   , 2 ) == 0 );
    }

    /** test -> {@code Encajados.porDebajo()}. */
    public void testPorDebajo() {
        assertTrue( Encajados.porDebajo( V1234567, 0 ) == 0 );
        assertTrue( Encajados.porDebajo( V1234567, 1 ) == 0 );
        assertTrue( Encajados.porDebajo( V1234567, 2 ) == 1 );
        assertTrue( Encajados.porDebajo( V1234567, 3 ) == 2 );
        assertTrue( Encajados.porDebajo( V1234567, 4 ) == 3 );
        assertTrue( Encajados.porDebajo( V1234567, 5 ) == 4 );
        assertTrue( Encajados.porDebajo( V1234567, 6 ) == 5 );
        assertTrue( Encajados.porDebajo( V1234567, 7 ) == 6 );
        assertTrue( Encajados.porDebajo( V1234567, 8 ) == 7 );

        assertTrue( Encajados.porDebajo( V0101010,-1 ) == 0 );
        assertTrue( Encajados.porDebajo( V0101010, 0 ) == 0 );
        assertTrue( Encajados.porDebajo( V0101010, 1 ) == 4 );
        assertTrue( Encajados.porDebajo( V0101010, 2 ) == 7 );

        assertTrue( Encajados.porDebajo( Vunos   , 0 ) == 0 );
        assertTrue( Encajados.porDebajo( Vunos   , 1 ) == 0 );
        assertTrue( Encajados.porDebajo( Vunos   , 2 ) == 7 );
    }
    
    /** test -> {@code Encajados.elDelMedio()}. */
    public void testElDelMedio() {
        assertTrue( Encajados.elDelMedio( V1234567 ) == 3 );
        assertTrue( V1234567[ Encajados.elDelMedio(V1234567) ] == 4 );
        assertTrue( Encajados.elDelMedio( V0101010 ) == V0101010.length );
    }

    /** Muestra que los argumentos {@code int} nunca son modificados. */
    public void testNoIntercambia() {
        int P=12, Q=13;
        Encajados.noIntercambia( P , Q );
        assertTrue( P == 12 && Q == 13  );
        assertTrue( P != 13 && Q != 12  );
    }
}

// EOF: TestEncajados.java

Consulta:
Profe: Porqué no me funciona el TestEncajados.java en Jeliot?
Respuesta:
Jeliot no puede ejecutar programas que se activan con el botón [Test] de JUnit (para eso hay que usar el DrJava). Aquí está una versión del programa que sí se puede ejecutar en Jeliot. Es importante recordar que el nombre del archivo TestEncajadosJeliot.java debe calzar con el nombre de la clase TestEncajadosJeliot que contiene al programa principal main().

/**
    @(#)TestEncajadosJeliot.java 2009
    adolfo@di-mare.com
    Programa de prueba para {@code Encajados}.

    @author Adolfo Di Mare <adolfo@di-mare.com>
*/

/** Datos de prueba para la clase {@code Encajados}. */
public class TestEncajadosJeliot {

    /** Nombre el índice de "exactos" en el vector {@code res[]} */
    public static final int EXACTO  = 0;
    /** Nombre el índice de "corridos" en el vector {@code res[]} */
    public static final int CORRIDO = 1;

    /** Detecta cuántos valores del vector {@code ADIVINA[]} están
        en su posición correcta o corrida en el vector {@code SECRETO[]}.
        <ul>
        <li> Retorna {@code true} cuando todos los valores de
             {@code ADIVINA[]} están es su correcta posición
             {@code SECRETO[]}. </li>
        <li> Calcula la cantidad de valores de {@code ADIVINA[]} que si
             están en su posición final y lo retorna en {@code res[0]==res[EXACTO]}. </li>
        <li> Calcula la cantidad de valores de {@code ADIVINA[]} que no
             están en su posición final y lo retorna en {@code res[1]==res[CORRIDO]}. </li>
        <li> "EXACTO" significa que {@code ADIVINA[i] == SECRETO[i]} </li>
        <li> "CORRIDO" significa que {@code ADIVINA[i] == SECRETO[j] && i != j} </li>
        <li> Los vectores no necesariamente tienen la misma cantidad de valores. </li>
        </ul>
    */
    public static boolean estanEncajados(
        int SECRETO[],
        int ADIVINA[],
        int res[]
    ) {
        int exactos=0, corridos=0; // inicializa contadores

        // calcula la longitud mínima
        int min = ( SECRETO.length < ADIVINA.length ? SECRETO.length : ADIVINA.length );

        // calcula cuáles valores de ADIVINA[] están en su sitio final
        for ( int i=0; i<min; ++i ) {
            if ( SECRETO[i] == ADIVINA[i] ) {
                exactos++;
            }
        }

        // calcula cuáles valores de ADIVINA[] están en algún sitio en SECRETO[]
        {    
            /******************************\
            *                              *
            *   RELLENE CON SU ALGORITMO   *
            *                              *
            \******************************/ 
        }
        res[EXACTO]  = exactos;  // Achará: no se vale pasar parámetros "int" por referencia
        res[CORRIDO] = corridos; // - "exactos" y "corridos" son identificadores significativos
        return ( (exactos == SECRETO.length) && (SECRETO.length == ADIVINA.length ) );
    }

    /** Programa principal. */
    public static void main( String args[] ) {
        int res[] = { -1 , -2 };
        boolean encajados = false;

        if (true)  {
            int A3210[] = { 3, 2, 1, 0 };
            int A0123[] = { 0, 1, 2, 3 };
            encajados = estanEncajados(A0123,A3210, res);
            encajados = estanEncajados(A3210,A0123, res);
        }

        if (true) {
            int A0123[] = { 0, 1, 2, 3 };
            int A1111[] = { 1, 1, 1, 1 };
            encajados = estanEncajados(A0123,A1111, res);
            encajados = estanEncajados(A1111,A0123, res);
            encajados = estanEncajados(A1111,A1111, res);
        }

        if (false) {
            int A1111[] = { 1, 1, 1, 1 };
            int A10[]   = { 1, 0 };
            encajados = estanEncajados(A10,A1111, res);
            encajados = estanEncajados(A1111,A10, res);
        }

        if (false) {
            int A0123[]    = { 0, 1, 2, 3 };
            int V1234567[] = { 1, 2, 3, 4, 5, 6, 7 };
            encajados = estanEncajados(A0123,V1234567, res);
            encajados = estanEncajados(V1234567,A0123, res);
        }
        if (false) {
            int A10[]      = { 1, 0 };
            int V1234567[] = { 1, 2, 3, 4, 5, 6, 7 };
            encajados = estanEncajados(V1234567,A10, res);
            encajados = estanEncajados(A10,V1234567, res);
        }
        if (false)  {
            int A0123[] = { 0, 1, 2, 3 };
            encajados = estanEncajados(A0123,A0123, res);
        }

        // NOTA: active con (true) el ejemplo a visualizar
    }
}

// EOF: TestEncajadosJeliot.java

Soluciones

[mailto:] Adolfo Di Mare <adolfo@di-mare.com>.
Copyright © 2012
Derechos de autor reservados © 2012
[home] <> [/\]