Ejercicios (sin formularios) - if ... elseif ... else ... (0) - Soluciones

En esta página se muestran una parte de las soluciones de los ejercicios if .. elseif ... else ... (0), concretamente el fragmento PHP, sin el principio ni el final de la página que se pueden dejar en fragmentos HTML.

Si lo prefiere, puede descargar unas posibles soluciones completas de estos ejercicios.

if ... elseif ... else ... (0) 1 - Par e impar (aviso final único)

Por tratarse del primer ejercicio, se ofrecen aquí más soluciones de las habituales, para ilustrar las diferentes maneras de enfocar un problema. La manera de presentarlas aquí es empezar por la solución menos "eficiente" e ir señalando cómo podemos mejorarla, pero en general para llegar al programa más "eficiente" no hace falta pasar antes por todos los anteriores. Lo que sí es aconsejable al programar es pensar siempre si hay diferentes maneras de enfocar los problemas y elegir la solución más eficiente en cada caso. El criterio de eficiencia no es absoluto, podemos encontrar soluciones más compactas (programas más cortos), soluciones más fáciles de entender (este criterio depende obviamente del nivel de conocimientos y experiencia del programador), soluciones más rápidas (porque requieren menos cálculos) o soluciones más fáciles de extender a situaciones más generales.

En todas las soluciones, el principio del programa debe mostrar los dados obtenidos. Esa parte común a todas las soluciones es la siguiente:

<?php
$dado1 = rand(1, 6);
$dado2 = rand(1, 6);

print "  <p>\n";
print "    Queremos sacar un valor par:\n";
print "    <img src=\"img/$dado1.svg\" alt=\"$dado1\" width=\"100\" height=\"100\" class=\"v-medio\">\n";
print "  </p>\n";
print "\n";

print "  <p>\n";
print "    Queremos sacar un valor impar:\n";
print "    <img src=\"img/$dado2.svg\" alt=\"$dado2\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
print "  </p>\n";
print "\n";

La parte del programa que puede enfocarse de varias maneras es la que escribe el mensaje final "¡Lo hemos conseguido!" o "!No lo hemos conseguido!".

  1. La solución más "ingenua" consistiría en comprobar todas las 36 posibles combinaciones de los valores de los dados mediante 36 estructuras if ... y mostrar en cada caso el mensaje correspondiente. El problema de este enfoque es que el programa resultante es muy largo, tan largo que ni siquiera se muestra la solución completa, aunque es fácil imaginar el resto.
    <?php
    if ($dado1 == 1 && $dado2 == 1) {   // Si sacamos 1 en el primer dado y 1 en el segundo ...
        print "  <p>¡No lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 == 1 && $dado2 == 2) {   // Si sacamos 1 en el primer dado y 2 en el segundo ...
        print "  <p>¡No lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 == 1 && $dado2 == 3) {   // Si sacamos 1 en el primer dado y 3 en el segundo ...
        print "  <p>¡No lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 == 1 && $dado2 == 4) {   // Si sacamos 1 en el primer dado y 4 en el segundo ...
        print "  <p>¡No lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 == 1 && $dado2 == 5) {   // Si sacamos 1 en el primer dado y 5 en el segundo ...
        print "  <p>¡No lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 == 1 && $dado2 == 6) {   // Si sacamos 1 en el primer dado y 6 en el segundo ...
        print "  <p>¡No lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 == 2 && $dado2 == 1) {   // Si sacamos 2 en el primer dado y 1 en el segundo ...
        print "  <p>¡Lo hemos conseguido!</p>\n";
    }
    
    // El programa continuaría con el resto de combinaciones posibles
    
  2. Lo primero de lo que nos podemos dar cuenta es de que no hace comprobar cada posible valor numérico de los dados puesto que lo importante es que el dado sea par e impar. La paridad se puede comprobar mediante el resto de la división entre 2 (que da 0 si el valor es par y 1 si es impar). Eso nos permite reducir el problema a cuatro estructuras if ....
    <?php
    if ($dado1 % 2 == 0 && $dado2 % 2 == 0) {       // Si el primer dado es par y el segundo dado es par
        print "  <p>!No lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 % 2 == 0 && $dado2 % 2 == 1) {       // Si el primer dado es par y el segundo dado es impar
        print "  <p>¡Lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 % 2 == 1 && $dado2 % 2 == 0) {       // Si el primer dado es impar y el segundo dado es par
        print "  <p>!No lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 % 2 == 1 && $dado2 % 2 == 1) {       // Si el primer dado es impar y el segundo dado es impar
        print "  <p>!No lo hemos conseguido!</p>\n";
    }
    
  3. Lo siguiente de lo que nos podemos dar cuenta es de que en realidad lo importante es el mensaje que se muestra. De las cuatro comprobaciones de la solución anterior en tres de ellas se muestra el mismo mensaje. El mensaje "¡Lo hemos conseguido!"" sólo se muestra cuando el primer dado es par y cuando el segundo es impar, mientras que el mensaje "!No lo hemos conseguido!" se muestra cuando el primer dado es para O cuando el segundo dado es impar. En vez de cuatro estructuras if ... podríamos haber utilizado solamente dos.
    <?php
    if ($dado1 % 2 == 0 && $dado2 % 2 == 1) {       // Si el primer dado es par Y el segundo dado es impar
        print "  <p>¡Lo hemos conseguido!</p>\n";
    }
    
    if ($dado1 % 2 == 1 || $dado2 % 2 == 0) {       // Si el primer dado es impar O el segundo dado es par
        print "  <p>!No lo hemos conseguido!</p>\n";
    }
    
  4. Por último, nos podemos dar cuenta de que las dos condiciones del programa anterior son excluyentes: o se cumple una o se cumpla la otra. Por tanto, podemos utilizar simplemente una estructura if ... else .... Lógicamente, podríamos escribir dos programas, según qué condición queramos comprobar primero:
    • El mensaje "¡Lo hemos conseguido!" debe mostrarse cuando el primer dado sea par y el segundo impar.
      <?php
      if ($dado1 % 2 == 0 && $dado2 % 2 == 1) {       // Si el primer dado es par Y el segundo dado es par
          print "  <p>¡Lo hemos conseguido!</p>\n";
      } else {                                        // En el resto de los casos
          print "  <p>!No lo hemos conseguido!</p>\n";
      }
      
    • El mensaje "¡No lo hemos conseguido!" debe mostrarse cuando el primer dado sea impar o el segundo par.
      <?php
      if ($dado1 % 2 == 1 || $dado2 % 2 == 0) {       // Si el primer dado es impar O el segundo dado es par
          print "  <p>!No lo hemos conseguido!</p>\n";
      } else {                                        // En el resto de los casos
          print "  <p>¡Lo hemos conseguido!</p>\n";
      }
      

if ... elseif ... else ... (0) 2 - Par e impar (avisos finales)

Dependiendo del resultado obtenido se muestran distintos mensajes:

<?php
$dado1 = rand(1, 6);

print "  <p>\n";
print "    Queremos sacar un valor par:\n";
print "    <img src=\"img/$dado1.svg\" alt=\"$dado1\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
print "  </p>\n";
print "\n";

$dado2 = rand(1, 6);
print "  <p>\n";
print "    Queremos sacar un valor impar:\n";
print "    <img src=\"img/$dado2.svg\" alt=\"$dado2\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
print "  </p>\n";
print "\n";

if ($dado1 % 2 == 1) {
    print "  <p>¡No hemos conseguido el dado par!</p>\n";
}

if ($dado2 % 2 == 0) {
    print "  <p>¡No hemos conseguido el dado impar!</p>\n";
}

if ($dado1 % 2 == 0 && $dado2 % 2 == 1) {
    print "  <p>!Lo hemos conseguido!</p>\n";
}

if ... elseif ... else ... (0) 3 - Par e impar (avisos inmediatos)

Este programa es prácticamente idéntico al anterior. La única diferencia es que, en su caso, el mensaje "¡No hemos conseguido el dado par!" se muestra después de mostrar el primer dado.

<?php
$dado1 = rand(1, 6);
$dado2 = rand(1, 6);

print "  <p>\n";
print "    Queremos sacar un valor par:\n";
print "    <img src=\"img/$dado1.svg\" alt=\"$dado1\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
print "  </p>\n";
print "\n";

if ($dado1 % 2 == 1) {
    print "  <p>¡No hemos conseguido el dado par!</p>\n";
}

print "  <p>\n";
print "    Queremos sacar un valor impar:\n";
print "    <img src=\"img/$dado2.svg\" alt=\"$dado2\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
print "  </p>\n";
print "\n";

if ($dado2 % 2 == 0) {
    print "  <p>¡No hemos conseguido el dado impar!</p>\n";
}

if ($dado1 % 2 == 0 && $dado2 % 2 == 1) {
    print "  <p>!Lo hemos conseguido!</p>\n";
}

if ... elseif ... else ... (0) 4 - Par e impar - (aviso inmediato)

En este ejercicio, sólo mostramos el segundo dado si el primer dado es par, es decir, las instrucciones que muestran el segundo dado se encontrarán en el bloque else ..., así como la estructura if ... else ... que muestra el mensaje correspondiente al segundo dado.

<?php
$dado1 = rand(1, 6);

print "  <p>\n";
print "    Queremos sacar un valor par:\n";
print "    <img src=\"img/$dado1.svg\" alt=\"$dado1\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
print "  </p>\n";
print "\n";

if ($dado1 % 2 == 1) {
    print "  <p>¡No lo hemos conseguido!</p>\n";
} else {
    $dado2 = rand(1, 6);

    print "  <p>\n";
    print "    Queremos sacar un valor impar:\n";
    print "    <img src=\"img/$dado2.svg\" alt=\"$dado2\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
    print "  </p>\n";
    print "\n";

    if ($dado2 % 2 == 0) {
        print "  <p>¡No lo hemos conseguido!</p>\n";
    } else {
        print "  <p>!Lo hemos conseguido!</p>\n";
    }
}

En las condiciones de la solución anterior comprobamos si los dados no tienen la paridad deseada. Si hubiéramos comprobado si los dados tienen la paridad deseada, los bloques de instrucciones simplemente se intercambiarían. Un criterio para elegir una opción u otra es la legibilidad del programa. En ese sentido, la primera solución sería preferible porque se reconoce más fácilmente la estructura if ... else ... correspondiente al primer dado ya que el bloque de instrucciones del if ... es más corto. En el caso del segundo dado, ese criterio no llevaría a preferir una forma u otra.

<?php
$dado1 = rand(1, 6);

print "  <p>\n";
print "    Queremos sacar un valor par:\n";
print "    <img src=\"img/$dado1.svg\" alt=\"$dado1\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
print "  </p>\n";
print "\n";

if ($dado1 % 2 == 0) {
    $dado2 = rand(1, 6);
    print "  <p>\n";
    print "    Queremos sacar un valor impar:\n";
    print "    <img src=\"img/$dado2.svg\" alt=\"$dado2\" width=\"140\" height=\"100\" class=\"v-medio\">\n";
    print "  </p>\n";
    print "\n";

    if ($dado2 % 2 == 1) {
        print "  <p>!Lo hemos conseguido!</p>\n";
    } else {
        print "  <p>¡No lo hemos conseguido!</p>\n";
    }
} else {
    print "  <p>¡No lo hemos conseguido!</p>\n";
}

if ... elseif ... else ... (0) 5 - Años bisiestos

Este programa es un ejemplo clásico de situación en que unos casos son un caso especial de otros casos. Concretamente, los años que son múltiplos de 400, también lo son 100 (y de 4). Y los años que son múltiplos de 100, también lo son de 4. Esto se puede aprovechar para simplificar las expresiones lógicas si utilizamos una estructura if ...

  1. Una primera solución sería escribir una estructura if ... para cada uno de los casos (no múltiplos de 4, múltiplo de 4 pero no de 100, múltiplo de 100 pero no de 400, múltiplo de 400). El orden de las comprobaciones es indiferente.
    <?php
    $year = rand(1582, 2100);
    
    if ($year % 4 != 0) {
        print "  <p>$year no es un año bisiesto porque no es múltiplo de 4.</p>\n";
    }
    
    if ($year % 4 == 0 && $year % 100 != 0) {
        print "  <p>$year es un año bisiesto porque es múltiplo de 4 pero no de 100.</p>\n";
    }
    
    if ($year % 100 == 0 && $year % 400 != 0) {
        print "  <p>$year no es un año bisiesto porque es múltiplo de 100 pero no de 400.</p>\n";
    }
    
    if ($year % 400 == 0) {
        print "  <p>$year es un año bisiesto porque es múltiplo de 400.</p>\n";
    }
    
  2. Como las cuatro condiciones son mutuamente excluyentes, se puede utilizar una estructura if ... elseif ... else .... Como antes, el orden de las comprobaciones es indiferente, aunque en este caso hemos escrito las condiciones del caso más "especial" (múltiplos de 400) al más general (no múltiplos de 4).
    <?php
    $year = rand(1582, 2100);
    
    if ($year % 400 == 0) {
        print "  <p>$year es un año bisiesto porque es múltiplo de 400.</p>\n";
    } elseif ($year % 100 == 0 && $year % 400 != 0) {
        print "  <p>$year no es un año bisiesto porque es múltiplo de 100 pero no de 400.</p>\n";
    } elseif ($year % 4 == 0 && $year % 100 != 0) {
        print "  <p>$year es un año bisiesto porque es múltiplo de 4 pero no de 100.</p>\n";
    } else {
        print "  <p>$year no es un año bisiesto porque no es múltiplo de 4.</p>\n";
    }
    
  3. Si nos fijamos en las condiciones, podemos observar que la segunda condición incluye la comprobación de no ser múltiplo de 400 ($year % 400 != 0) que en este caso resulta innecesaria porque la primera condición es precisamente la de ser múltiplo de 400 ($year % 400 == 0). Pero si el programa llega a evaluar la segunda condición es porque no se ha cumplido la primera, es decir, que si el programa llega a evaluar la segunda condición ya sabemos que el año no es múltiplo de 400 (si lo fuera hubiera ejecutado el primer bloque y no hubiera llegado a la primera condición). Por tanto no es necesario comprobar que el año no sea múltiplo de 400.

    El mismo razonamiento se puede hacer con la tercera condición que incluye la comprobación de que no se múltiplo de 100, cuando la segunda condición es precisamente la de ser múltiplo de 100. Es decir, no sería comprobar que el año no sea múltiplo de 100.

    Por tanto, podemos simplificar el programa hasta dejarlo así:

      <?php
    $year = rand(1582, 2100);
    
    if ($year % 400 == 0) {
        print "  <p>$year es un año bisiesto porque es múltiplo de 400.</p>\n";
    } elseif ($year % 100 == 0) {
        print "  <p>$year no es un año bisiesto porque es múltiplo de 100 pero no de 400.</p>\n";
    } elseif ($year % 4 == 0) {
        print "  <p>$year es un año bisiesto porque es múltiplo de 4 pero no de 100.</p>\n";
    } else {
        print "  <p>$year no es un año bisiesto porque no es múltiplo de 4.</p>\n";
    }
      

    Es muy importante señalar que en este programa ya no podemos cambiar el orden de las comprobaciones, porque ha sido precisamente el orden específico (del caso más "especial" al más general) el que nos ha permitido simplificar las condiciones.

    En general, ordenar los casos de manera que evaluemos primero los casos particulares y después los más generales que incluyen a los particulares permite simplificar las condiciones de los casos más generales. El precio a pagar es obligarnos a mantener el orden de las comprobaciones y a que los programas sean un poco más complejos (porque es el programador el que tiene que darse cuenta que las condiciones posteriores incluyen la negación de las comprobaciones anteriores), aunque más cortos.

if ... elseif ... else ... (0) 6 - Convertidor de RGB A HSL

<?php
$red   = rand(0, 255);
$green = rand(0, 255);
$blue  = rand(0, 255);

$r = $red   / 255;
$g = $green / 255;
$b = $blue  / 255;

$M = max($r, $g, $b);
$m = min($r, $g, $b);
$C = $M - $m;

if ($C == 0) {
    $h = 0;
} elseif ($M == $r) {
    $h = ($g - $b) / $C;
} elseif ($M == $g) {
    $h = ($b - $r) / $C + 2;
} elseif ($M == $b) {
    $h = ($r - $g) / $C + 4;
}
if ($h < 0) {
    $h = $h + 6;
}
$h = $h * 60;
$h = round($h);
$H = $h % 360;

$L = ($M + $m) / 2;

if ($L == 1) {
    $S = 0;
} else {
    $S = $C / (1 - abs(2 * $L - 1));
}
$L = round($L, 3) * 100;
$S = round($S, 3) * 100;

print "  <p>El color <strong>rgb($red $green $blue)</strong> es el color <strong>hsl($H $S% $L%)</strong>.</p>\n";

if ... elseif ... else ... (0) 7 A - Convertidor de centímetros a kilómetros, metros y centímetros (con todas las unidades)

<?php
$centimetros = rand(0, 200000);

$km = intdiv($centimetros, 100000);
$cm = $centimetros % 100000;
$m  = intdiv($cm, 100);
$cm = $cm % 100;

print "  <p>$centimetros centímetros son $km km $m m $cm cm.</p>\n";

if ... elseif ... else ... (0) 7 B - Convertidor de centímetros a kilómetros, metros y centímetros (sin unidades innecesarias)

La idea básica es que habrá que comprobar con una estructura if ... si el valor a escribir en cada unidad es 0 porque cuando es 0 no hay que escribir el valor. Pero además tener en cuenta dos detalles:

<?php
$centimetros = rand(0, 200000);

$km = intdiv($centimetros, 100000);
$cm = $centimetros % 100000;
$m  = intdiv($cm, 100);
$cm = $cm % 100;

print "  <p>$centimetros centímetros son";
if ($centimetros == 0) {
    print " 0 cm</p>\n";
} else {
    if ($km != 0) {
        print " $km km";
    }
    if ($m != 0) {
        print " $m m";
    }
    if ($cm != 0) {
        print " $cm cm";
    }
    print ".</p>\n";
}

if ... elseif ... else ... (0) 7 C - Convertidor de centímetros a kilómetros, metros y centímetros (con comas)

El criterio para incluir comas es que hay que escribir una coma después de una unidad si alguna de las unidades que se van a escribir después es distinta de 0.

<?php
$centimetros = rand(0, 200000);

$km = intdiv($centimetros, 100000);
$cm = $centimetros % 100000;
$m  = intdiv($cm, 100);
$cm = $cm % 100;

print "  <p>$centimetros centímetros son";
if ($centimetros == 0) {
    print " 0 cm</p>\n";
} else {
    if ($km != 0) {
        print " $km km";
        if ($m != 0 || $cm != 0) {
            print ",";
        }
    }
    if ($m != 0) {
        print " $m m";
        if ($cm != 0) {
            print ",";
        }
    }
    if ($cm != 0) {
        print " $cm cm";
    }
    print ".</p>\n";
}

if ... elseif ... else ... (0) 7 D - Convertidor de centímetros a kilómetros, metros y centímetros (con comas e "y")

<?php
$centimetros = rand(0, 200000);

$km = intdiv($centimetros, 100000);
$cm = $centimetros % 100000;
$m  = intdiv($cm, 100);
$cm = $cm % 100;

print "  <p>$centimetros centímetros son";

if ($centimetros == 0) {
    print " 0 cm</p>\n";
} else {
    if ($km != 0) {
        print " $km km";
        if ($m != 0 && $cm == 0 || $m == 0 && $cm != 0) {
            print " y";
        } elseif ($m != 0 || $cm != 0) {
            print ",";
        }
    }

    if ($m != 0) {
        print " $m m";
        if ($cm != 0) {
            print " y";
        }
    }

    if ($cm != 0) {
        print " $cm cm";
    }
    print ".</p>\n";
}