Curso Básico de Programación
en Visual Basic

Soluciones de la Décima Entrega. (10/Ene/98)


Pues se me fue la olla más de la cuenta... y a pesar de que algunos me lo han recordado... en fin... aquí están las soluciones de los ejercicios de la décima entrega.

Por si no te acuerdas, estos eran los ejercicios: (es que yo ya no me acordaba... y como he perdido la chuleta con las soluciones, tendré que resolverlos... hum!)

Si quieres pasar directamente a las soluciones y saltarte este "cachito", pulsa aquí.


[repetición del final de la entrega 10]

Ahora los ansiados ejercicios, (realmente ha sido cortita esta entrega ¿verdad?)

Para los ejercicios, usando este trozo para guardar números aleatorios en un array unidimensional, espero que no tengas problemas para guardarlos en un array multidimensional.

T = Int(Rnd * 31) + 20 'Número de rascadas, T valdrá de 20 a 50
For i = 1 To T
    H = Int(Rnd * 23) + 1 'H valdrá de 1 a 23
    Horas(H) = Horas(H) + 1
Next

Los ejercicios usando este ejemplo:

  1. Saber que hora tiene el valor mayor y a que hora empezaste a rascarte (es decir la primera hora del array que contiene un valor)
  2. Que hora fue la última en que te arrascaste (no necesita explicación...)
  3. Modificar el ejemplo anterior para que el número de veces que te rascas valga (aleatoriamente) de 100 a 1000 y saber también cual de estas horas tiene el valor menor (en caso de que haya varios, sólo tienes que averiguar uno de ellos)

Para que no te compliques mucho la vida, decirte que con un par de líneas, puedes averiguar el mayor o el menor... no sea que quieras hacer un mogollón de comparaciones.


Las soluciones:

Primero: He hecho un pequeño cambio al ejemplo que se usaría, para que también se incluya la HORA CERO, esta sería una de las formas de conseguirlo:

 

'Ejercicio 1
Dim T%, i%, H%, Horas%(0 To 23)

Randomize

T = Int(Rnd * 31) + 20 'Número de rascadas, T valdrá de 20 a 50
For i = 1 To T
    H = Int(Rnd * 24) 'H valdrá de 0 a 23
    Horas(H) = Horas(H) + 1
Next


Dim ValorMayor%, HoraValorMayor%, HoraInicioRascada%

'Este valor será para saber que no se ha asignado
Const NoAsignado = -1

ValorMayor = 0
HoraValorMayor = NoAsignado
HoraInicioRascada = NoAsignado

'Las horas van de 0 a 23
For H = 0 To 23
    'Si esta hora tiene algún valor, hacer las comprobaciones
    If Horas(H) Then
        '
        '===Para saber la primera hora de la rascada===
        '
        'Si la hora de inicio no se ha asignado
        If HoraInicioRascada = NoAsignado Then
            'Asignar esta hora
            HoraInicioRascada = H
        End If
        '
        '===Para saber la hora que tiene el valor mayor===
        '
        'Si el valor actual es mayor...
        If Horas(H) > ValorMayor Then
	    ValorMayor = Horas(H)
            HoraValorMayor = H
        End If
    End If
Next

'Para mostrar los valores:
'HoraValorMayor será la hora que tiene el valor mayor
'El valor mayor se puede conseguir así:
'    ValorMayor
'    Horas(HoraValorMayor) Esta forma dará error si no hay ninguna hora con el valor mayor
'
'HoraInicioRascada será la hora en la que empezaste a rascarte...
'

Lo único que hay que notar es lo siguiente:
Ya que las horas empezarán por CERO, debemos asignar un valor "inexistente" a los valores de las variables que contendrán las horas de inicio y de mayor valor...
¿Por qué? Porque el Basic asigna automáticamente el valor cero a las variables numéricas y como estas variables pueden tener un valor de CERO (0) a Veintitrés (23), el valor por defecto puede ser un valor válido... así que asignándole -1 (menos uno), nos aseguramos que no tendrá un valor que pueda confundirnos... ¿lo captas? si no es así... ya te enterarás cuando te ocurra... ;-)

 

El segundo: Usando la parte de asignación de las horas, es lo mismo que para saber la primera hora, pero usando otra variable.

'Ejercicio 2
Dim UltimaHora As Integer

'Este valor será para saber que no se ha asignado
Const NoAsignado = -1

UltimaHora = NoAsignado

'Las horas van de 0 a 23
For H = 0 To 23
    'Si esta hora tiene algún valor, hacer las comprobaciones
    If Horas(H) Then
        '
        '===Para saber la ultima hora de la rascada===
        '
        'Si la hora actual es mayor que la asignada
        If H > UltimaHora Then
            'Asignar esta hora
            UltimaHora = H
        End If
    End If
Next

Esta solución no tiene mayor inconveniente, una vez comprendida la primera solución.

 

El tercero: Para que el número aleatorio que se asigna esté entre 100 y 1000, cambia la asignación a T de esta forma:

T = Int(Rnd * 901) + 100

Recuerda que Int(Rnd * 901) produce un valor que va desde 0 a 900 ambos inclusive, así que sumándole 100 tendremos un valor de 100 a 1000.

Para averiguar la hora con el menor valor, usaremos dos variables, una para guardar el valor menor y otra para que "recuerde" a que hora ocurrió eso...

Aunque habrás comprobado que eso de averiguar el valor menor no es tan "lógico" como parece...
La explicación es que al asignar el valor CERO a una variable cuando se inicializa, este valor puede ser menor que cualquiera que se haya asignado, este problema no existe si se asignan valores negativos, pero como ese no es el caso...
Para solucionarlo, se pueden hacer varias cosas, aquí explico las dos que creo que cubren todas las posibilidades:

  1. Si HoraValorMenor aún no se ha asignado, la primera hora que se compruebe, será la hora con el menor valor.
  2. Cuando es la "primera" hora que se comprueba, ese debe ser el valor menor hasta el momento.
    Esto mismo se puede hacer para el valor mayor, si sabemos que pueden asignarse valores negativos... ya que si así fuera, al tener un valor cero, éste sería mayor que cualquier número negativo...
'Ejercicio 3
Dim T%, i%, H%, Horas%(0 To 23)

Randomize

T = Int(Rnd * 901) + 100 'Número de rascadas, T valdrá de 100 a 1000
For i = 1 To T
    H = Int(Rnd * 24) 'H valdrá de 0 a 23
    Horas(H) = Horas(H) + 1
Next

Dim ValorMenor%, HoraValorMenor%

'Este valor será para saber que no se ha asignado
Const NoAsignado = -1

ValorMenor = 0
HoraValorMenor = NoAsignado

'Las horas van de 0 a 23
For H = 0 To 23
    'Si esta hora tiene algún valor, hacer las comprobaciones
    If Horas(H) Then
        '
        '===Para saber la hora que tiene el valor menor===
        '
        'NOTA:
        'Para que FUNCIONE, hay que hacer una de estas dos cosas:
        '
        '1- Si no se ha asignado el valor menor...
        If HoraValorMenor = NoAsignado Then
            ValorMenor = Horas(H)
            HoraValorMenor = H
        End If
        '2- Si es el primer valor, será el menor...
        If H = 0 Then
            ValorMenor = Horas(H)
            HoraValorMenor = H
        End If
        '
        'hasta que se demuestre lo contrario...
        If Horas(H) < ValorMenor Then
            ValorMenor = Horas(H)
            HoraValorMenor = H
        End If
    End If
Next

Para Terminar: Bien, ya tenemos todas las soluciones, ahora pongámoslo todo junto y veamos para que sirve eso de NoAsignado...

'Todos los ejercicios
Dim T%, i%, H%, Horas%(0 To 23)

Randomize

T = Int(Rnd * 901) + 100 'Número de rascadas, T valdrá de 100 a 1000
For i = 1 To T
    H = Int(Rnd * 24) 'H valdrá de 0 a 23
    Horas(H) = Horas(H) + 1
Next

Dim ValorMayor%, HoraValorMayor%, HoraInicioRascada%
Dim UltimaHora%
Dim ValorMenor%, HoraValorMenor%

'Este valor será para saber que no se ha asignado
Const NoAsignado = -1

ValorMayor = 0
HoraValorMayor = NoAsignado
HoraInicioRascada = NoAsignado
UltimaHora = NoAsignado
ValorMenor = 0
HoraValorMenor = NoAsignado

'Las horas van de 0 a 23
For H = 0 To 23

    'Si esta hora tiene algún valor, hacer las comprobaciones
    If Horas(H) Then
        '
        '===Para saber la primera hora de la rascada===
        '
        'Si la hora de inicio no se ha asignado
        If HoraInicioRascada = NoAsignado Then
            'Asignar esta hora
            HoraInicioRascada = H
        End If
        '
        '===Para saber la ultima hora de la rascada===
        '
        'Si la hora no se ha asignado
        If H > UltimaHora Then
            'Asignar esta hora
            UltimaHora = H
        End If
        '
        '===Para saber la hora que tiene el valor mayor===
        '
        'Si el valor actual es mayor...
        If Horas(H) > ValorMayor Then
            ValorMayor = Horas(H)
            HoraValorMayor = H
        End If
        '
        '===Para saber la hora que tiene el valor menor===
        '
        'NOTA:
        'Para que FUNCIONE, hay que hacer una de estas dos cosas:
        '
        '1- Si no se ha asignado el valor menor...
        If HoraValorMenor = NoAsignado Then
            ValorMenor = Horas(H)
            HoraValorMenor = H
        End If

        '2- Si es el primer valor, será el menor...
        If H = 0 Then
            ValorMenor = Horas(H)
            HoraValorMenor = H
        End If
        '

        'hasta que se demuestre lo contrario...
        If Horas(H) < ValorMenor Then
            ValorMenor = Horas(H)
            HoraValorMenor = H
        End If
    End If
Next

'Mostrar los datos:
Dim sTmp As String

sTmp = "Estos son los valores:" & vbCrLf

If HoraInicioRascada <> NoAsignado Then
    sTmp = sTmp & "Hora de inicio de rascada: " & CStr(HoraInicioRascada) & vbCrLf
End If
If UltimaHora <> NoAsignado Then
    sTmp = sTmp & "Última hora de rascada: " & CStr(UltimaHora) & vbCrLf
End If
If HoraValorMenor <> NoAsignado Then
    sTmp = sTmp & "La hora en la que empezaste a rascarte fue: " & CStr(HoraValorMenor) & vbCrLf
End If
If HoraValorMayor <> NoAsignado Then
    sTmp = sTmp & "La hora en la que terminaste de rascarte fue: " & CStr(HoraValorMayor) & vbCrLf
End If

MsgBox sTmp

Ir al índice principal del Guille