Rutas
/
Crystal
Crystal
/
Ejercicios
/
Mitigación del colapso
Mitigación del colapso

Mitigación del colapso

Ejercicio de aprendizaje

Introducción

Crystal tiene lo que se conoce como expresiones de control; se usan para controlar la forma en que se ejecutará el programa y toman un valor verdadero o falso. Existen operadores que se pueden usar para crear valores verdaderos o falsos; se conocen como operadores de igualdad y comparación.

Hay dos expresiones de control principales que se usan para controlar qué código se ejecutará y cuál no. Es decir, qué rama concreta se ejecutará.

Esas dos son: la expresión if y la expresión unless.

Operadores de comparación

Los operadores de comparación se usan para comparar valores y devuelven un valor true o false. Estos operadores requieren que se comparen dos valores del mismo tipo. Si los valores no son del mismo tipo, el compilador lanzará un error. Aquí tienes una lista de los operadores de comparación y un ejemplo de cuándo dan un valor true:

Método Descripción Ejemplo
< menor que 4 < 5
<= menor o igual que 4 <= 4
> mayor que 3 > 1
>= mayor o igual que 2 >= 2

Operadores de igualdad

Los operadores de igualdad son similares a los operadores de comparación, pero se usan para comprobar si dos valores son iguales o no.

El operador == comprueba si dos valores son iguales, incluido el tipo del valor. Si los valores son iguales, devolverá true; en caso contrario, devolverá false. El operador == puede comparar cualquier tipo de valor con cualquier otro tipo de valor. El operador != funciona de la misma manera, pero devolverá true si los valores no son iguales y false si son iguales.

El condicional if

El condicional if se usa para comprobar si una condición dada es verdadera o falsa. Si la condición es verdadera, se ejecutará el código que hay dentro del condicional if. Un condicional if termina con la palabra clave end.

if 1 == 1
  puts "1 is equal to 1"
end
# => 1 is equal to 1

if 1 > 2
  puts "1 is greater than 2"
end
# => no output

El condicional unless

El condicional unless funciona de forma muy similar al condicional if, pero ejecutará el código que hay dentro del condicional unless si la condición es falsa.

unless 1 == 1
  puts "1 is not equal to 1"
end
# => no output

unless 1 > 2
  puts "1 is not greater than 2"
end
# => 1 is not greater than 2

La instrucción else

La instrucción else se puede usar junto con los condicionales if y unless. La instrucción else se ejecutará si no se ejecuta la rama if o la rama unless.

Aunque se puede usar una rama `else` junto con `unless,`, no es recomendable hacerlo porque perjudica la legibilidad.
En su lugar, se recomienda usar `if !condition` con una rama `else`.
if 1 == 1
  puts "1 is equal to 1"
else
  puts "1 is not equal to 1"
end
# => 1 is equal to 1

unless 1 < 2
  puts "1 is not greater than 2"
else
  puts "1 is greater than 2"
end
# => 1 is greater than 2

Condicionales «encadenados»

La instrucción elsif se puede usar junto con el condicional if. La instrucción elsif se ejecutará si no se ejecuta la rama if y la condición de la instrucción elsif es verdadera. Las instrucciones elsif se pueden encadenar y se ejecutará la primera condición que sea verdadera. También puede haber una instrucción else al final del condicional if, que se ejecutará si ninguna de las instrucciones anteriores ha sido verdadera.

if 1 != 1
  puts "1 is not equal to 1"
elsif 1 > 2
  puts "1 is greater than 2"
else
  puts "1 is not equal to 1 and 1 is not greater than 2"
end
# => 1 is not equal to 1 and 1 is not greater than 2

Tipos con condicionales

Cuando se le asignan tipos diferentes, la variable tendrá ambos tipos. Esto se debe a que el compilador no sabe qué rama se ejecutará. Esta asignación múltiple, también conocida como unión, se explicará en conceptos posteriores. Esto se puede ver en el siguiente ejemplo:

if 1 == 1
  a = 1
else
  a = "1"
end

typeof(a) # => Int32 | String

Operador ternario

Crystal tiene un operador ternario, un condicional if-else de una sola línea: condition ? expression_if_truthy : expression_if_falsey

1 == 1 ? puts("1 is equal to 1") : puts("1 is not equal to 1")
# => 1 is equal to 1

Instrucciones

En este ejercicio, vamos a desarrollar un sistema de control sencillo para un reactor nuclear.

Para que un reactor produzca energía, debe encontrarse en un estado de criticidad. Si el reactor está en un estado inferior al de criticidad, puede dañarse. Si el estado del reactor va más allá de la criticidad, puede sobrecargarse y provocar una fusión del núcleo. Queremos mitigar las probabilidades de una fusión del núcleo y gestionar correctamente el estado del reactor.

Las siguientes tres tareas están relacionadas con escribir código para mantener el estado ideal del reactor.

1. Comprobar la criticidad

Lo primero que debe hacer un sistema de control es comprobar si el reactor está equilibrado en criticidad. Se dice que un reactor es crítico si cumple las siguientes condiciones:

  • La temperatura es inferior a 800 K.
  • El número de neutrones emitidos por segundo es mayor que 500.
  • El producto de la temperatura y los neutrones emitidos por segundo es menor que 500000.

Implementa el método Reactor.criticality_balanced?, que recibe temperature, medida en kelvin, y neutrons_emitted como parámetros, y devuelve true si se cumplen las condiciones de criticidad, y false si no.

Reactor.criticality_balanced?(750, 600)
# => true

2. Determinar el rango de potencia de salida

Una vez que el reactor ha empezado a producir energía, hay que determinar su eficiencia. La eficiencia se puede agrupar en 4 bandas:

  1. green -> eficiencia del 80% o más,
  2. orange -> eficiencia inferior al 80%, pero de al menos el 60%,
  3. red -> eficiencia por debajo del 60%, pero aún del 30% o más,
  4. black -> eficiencia inferior al 30%.

El valor porcentual se puede calcular como (generated_power/theoretical_max_power)*100, donde generated_power = voltage * current. Ten en cuenta que el valor porcentual normalmente no es un número entero, así que asegúrate de considerar el uso adecuado de las comparaciones < y <=.

Implementa el método Reactor.reactor_efficiency, con tres parámetros: voltage, current y theoretical_max_power. Esta función debe devolver la banda de eficiencia del reactor: «green», «orange», «red» o «black».

Reactor.reactor_efficiency(200,50,15000)
# => "orange"

3. Mecanismo a prueba de fallos

Tu tarea final consiste en crear un mecanismo a prueba de fallos para evitar la sobrecarga y la fusión del núcleo. Este mecanismo determinará si el reactor está por debajo, en, o por encima del umbral de criticidad ideal. La criticidad se puede aumentar, disminuir o detener insertando (o extrayendo) barras de control en el reactor.

Implementa el método llamado Reactor.fail_safe(), que recibe 3 parámetros: temperature, medida en kelvin, neutrons_produced_per_second y threshold, y devuelve un código de estado para el reactor.

  • Si temperature * neutrons_produced_per_second < 90% de threshold, devuelve un código de estado «LOW», que indica que se deben extraer las barras de control para producir energía.

  • Si temperature * neutrons_produced_per_second está dentro de un margen de más o menos el 10% de threshold, el reactor está en criticidad y se debe devolver el código de estado «NORMAL», que indica que el reactor está en condiciones óptimas y que las barras de control están en una posición ideal.

  • Si temperature * neutrons_produced_per_second no está dentro de los rangos anteriores, el reactor va camino de la fusión del núcleo y se debe devolver un código de estado «DANGER» para apagar el reactor de inmediato.

temperature = 1000
neutrons_produced_per_second = 30
threshold = 5000
Reactor.fail_safe(temperature, neutrons_produced_per_second, threshold)
# => "DANGER"
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Crystal Exercism

¿Listo para empezar Mitigación del colapso?

Regístrate en Exercism para aprender y dominar Crystal con 26 conceptos142 ejercicios y mentoría humana real, todo gratis.