Rutas
/
Crystal
Crystal
/
Ejercicios
/
Fusionista de fotos
Fusionista de fotos

Fusionista de fotos

Ejercicio de aprendizaje

Introducción

El binario, el octal y el hexadecimal (también conocido como hex) son distintos sistemas de numeración con bases distintas. El binario es base 2, el octal es base 8 y el hexadecimal es base 16. Los números enteros normales son base 10 en Crystal. El binario, el octal y el hexadecimal son representaciones de números enteros. Esto significa que representan números positivos y negativos (incluido el cero) sin fracciones ni decimales y que admiten todas las operaciones que podemos hacer con números enteros.

Binario

El binario es un sistema de numeración en base 2 que usa únicamente los dígitos 0 y 1. Suele representar los estados 0 («apagado») y 1 («encendido») del flujo eléctrico a través de transistores e interruptores en los ordenadores, así como las cargas positiva y negativa de los soportes de almacenamiento magnético. El binario puede representar todos los números enteros que se usan en base 10.

Un fragmento del sistema en base 2 tiene este aspecto, aunque continúa hasta el infinito y no se detiene en 128:

128 64 32 16 8 4 2 1
2 ** 7 2 ** 6 2 ** 5 2 ** 4 2 ** 3 2 ** 2 2 ** 1 2 ** 0

Así que, si queremos representar el número 6, en binario sería: 110

Valor posicional 4 2 1
Número binario 1 1 0

Y la operación sería: 4 + 2 + 0 = 6

Otro ejemplo: 19

Valor posicional 16 8 4 2 1
Número binario 1 0 0 1 1

El número binario sería: 10011 Y la operación sería: 16 + 0 + 0 + 2 + 1 = 19

El binario en Crystal

En Crystal, podemos representar literales binarios con el prefijo 0b. Si escribimos 0b10011, Crystal lo interpretará como un número binario y lo convertirá a base 10.

0b10011
# => 19

typeof(0b10011)
# => Int32

Si escribes un número con el prefijo 0b que no sea del sistema binario, se producirá un error de compilación.

0b10211
# => Error: unexpected token: "211"

Operaciones con números binarios

Como los números binarios son números enteros, podemos realizar con ellos todas las operaciones que hacemos con números enteros.

0b10011 + 0b10011
# => 38

0b10011 * 0b10011
# => 361

0b10011 / 3
# => 6.333333333333333

Conversión desde y hacia la representación binaria

Crystal convertirá automáticamente un literal binario en Int32. Para convertir un Int32 a una representación binaria, usa el método <int>.to_s(base) con el argumento base establecido en 2. El método devolverá una representación en forma de string del número binario:

19.to_s(2)
# => "10011"

Para convertir una representación en forma de string de un binario a un número entero, podemos usar el método <int>.to_i(base), pasando la base (2) como argumento:

"10011".to_i(2)
# => 19

Si se indica una base incorrecta (o una representación binaria no válida), se producirá un ArgumentError:

"011021".to_i(2)
# => Invalid Int32: "011021" (ArgumentError)

Métodos para números binarios

Hay ciertos métodos que se pueden usar con números enteros para obtener información sobre la representación binaria del número.

<int>.bit_length devolverá el número de bits necesarios para representar el número:

19.bit_length
# => 5

<int>.bit(index) devolverá el bit que ocupa el índice indicado, empezando por la derecha (el bit menos significativo):

19.bit(0)
# => 1

0b10011.bit(1)
# => 1

Octal

El octal es un sistema de numeración en base 8. Usa los dígitos 0, 1, 2, 3, 4, 5, 6 y 7.

En Crystal, podemos representar números octales con el prefijo 0o. Igual que con el binario, Crystal convierte automáticamente una representación octal a Int32.

0o123
# => 83

Si se pone el prefijo 0o a un número que no sea del sistema octal, se producirá un error de compilación.

Conversión desde y hacia la representación octal

Igual que con el binario, podemos usar el método <int>.to_s(base) para convertir un Int32 a una representación octal. Y podemos usar el método <int>.to_i(base) para convertir una representación octal a un Int32.

83.to_s(8)
# => "123"

"123".to_i(8)
# => 83

Igual que con el binario, si se indica una base incorrecta, se producirá un ArgumentError.

Hexadecimal

El hexadecimal es un sistema de numeración en base 16. Usa los dígitos del 0 al 9 y las letras A, B, C, D, E y F. A es 10, B es 11, C es 12, D es 13, E es 14 y F es 15.

Podemos representar números hexadecimales en Crystal con el prefijo 0x. Igual que con el binario y el octal, Crystal convertirá automáticamente los literales hexadecimales a Int32.

#=> 0x123
291

Si se pone el prefijo 0x a un número que no sea hexadecimal, se producirá un error de compilación.

Conversión desde y hacia la representación hexadecimal

Igual que con el binario, podemos usar el método <int>.to_s(base) para convertir un Int32 a una representación hexadecimal. Y podemos usar el método <int>.to_i(base) para convertir una representación hexadecimal a un Int32.

291.to_s(16)
# => "123"

"123".to_i(16)
# => 291

Igual que con el binario y el octal, si se indica una base incorrecta, se producirá un ArgumentError.

Precisión

Al convertir un número a una representación en forma de string, podemos especificar la precisión del número. Es decir, la cantidad mínima de números que se usan para representar el número. Si el número tiene menos dígitos que la precisión, se añadirán ceros a la izquierda en la representación en forma de string. Esto se consigue pasando el argumento precision al método <int>.to_s(<base>, precision: <value>).

291.to_s(16, precision: 5)
# => "00123"

543.to_s(precision: 2)
# => "543"

Instrucciones

Tu amigo se ha cansado de pagar por un programa de edición de fotos y ha decidido escribir el suyo propio. Tu amigo ha decidido llamar al nuevo programa Foto Fusionist.

Foto Fusionist es un programa de edición de fotos que puede hacer muchas cosas, pero por ahora solo has implementado unas pocas. Sin embargo, tu amigo está muy contento con el progreso y te ha pedido que implementes algunas funcionalidades más.

1. Convertir una representación binaria en un número entero

Para la primera funcionalidad, tu amigo quiere poder convertir la representación binaria de un número en un número entero. Esto se hace porque el programa podrá leer la representación binaria de un canal de color y convertirla en un número entero.

Implementa el método FotoFusionist.binary_to_int, que recibe un argumento binary de tipo String. El método debe devolver la representación entera del número binario.

FotoFusionist.binary_to_int("10011")
# => 19

2. Obtener el bit menos significativo de un número entero

La segunda funcionalidad que quiere tu amigo es poder obtener el bit menos significativo de un número entero. El bit menos significativo es el bit que está más a la derecha. Se llama bit menos significativo porque es el que tiene el menor valor.

El bit menos significativo es necesario para evaluar si una imagen se puede optimizar reduciendo el número de bits que se usan para representar el canal de color.

Implementa el método FotoFusionist.least_significant_bit, que recibe un argumento number de tipo Int32. El método debe devolver el bit menos significativo del número.

FotoFusionist.least_significant_bit(0b10011)
# => 1

FotoFusionist.least_significant_bit(0b10010)
# => 0

3. Obtener el valor hexadecimal de un canal de color

La tercera funcionalidad que quiere tu amigo es poder obtener el valor hexadecimal de un canal de color. El valor hexadecimal es necesario para poder convertir el canal de color a una representación hexadecimal, y esa representación hexadecimal debe estar formada por dos dígitos.

Implementa el método FotoFusionist.hex_value, que recibe un argumento number de tipo Int32. El método debe devolver el valor hexadecimal del número como String.

FotoFusionist.hex_value(19)
# => "13"

4. Obtener el valor hexadecimal de un RGB

La cuarta funcionalidad que quiere tu amigo es poder obtener el valor hexadecimal de un color RGB. Esto es necesario para que un usuario pueda obtener una única representación de un color como string. Un color RGB es un color que se representa mediante tres canales de color: rojo, verde y azul. Cada canal de color se representa mediante un número entre 0 y 255.

El valor hexadecimal de un color RGB es una representación del color en hexadecimal como string, con el canal de color rojo primero, luego el canal verde y, por último, el canal azul.

Implementa el método FotoFusionist.hex_value_from_rgb, que recibe tres argumentos: red, green y blue, de tipo Int32. El método debe devolver el valor hexadecimal del color RGB como String.

FotoFusionist.hex_value_from_rgb(255, 0, 0)
# => "ff0000"
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Crystal Exercism

¿Listo para empezar Fusionista de fotos?

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