Trilhas
/
Crystal
Crystal
/
Exercícios
/
Fusionista de fotos
Fusionista de fotos

Fusionista de fotos

Exercício de aprendizagem

Introdução

Binário, octal e hexadecimal (também chamado de hex) são sistemas de numeração diferentes, com bases diferentes. O binário é base 2, o octal é base 8 e o hexadecimal é base 16. Em Crystal, os inteiros normais são base 10. Binário, octal e hexadecimal são todos representações de inteiros. Isso significa que eles representam números positivos e negativos (incluindo o zero) sem frações ou decimais e dão suporte a todas as operações que podemos fazer com inteiros.

Binário

Binário é um sistema de numeração de base 2, que usa apenas os dígitos 0 e 1. Ele costuma representar os estados 0 ("desligado") e 1 ("ligado") do fluxo elétrico através de transistores e interruptores nos computadores, assim como as cargas positiva e negativa nos meios de armazenamento magnético. O binário consegue representar todos os inteiros usados na base 10.

Um trecho do sistema de base 2 é assim, embora ele continue infinitamente e não pare no 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

Então, se quisermos representar o número 6, em binário ele seria: 110

Valor posicional 4 2 1
Número binário 1 1 0

E a operação seria: 4 + 2 + 0 = 6

Outro exemplo: 19

Valor posicional 16 8 4 2 1
Número binário 1 0 0 1 1

O número binário seria: 10011 E a operação seria: 16 + 0 + 0 + 2 + 1 = 19

Binário em Crystal

Em Crystal, podemos representar literais binários usando o prefixo 0b. Se escrevermos 0b10011, o Crystal vai interpretá-lo como um número binário e convertê-lo para a base 10.

0b10011
# => 19

typeof(0b10011)
# => Int32

Se você escrever um número com o prefixo 0b que não esteja no sistema binário, isso vai lançar um erro de compilação.

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

Operações com números binários

Como números binários são inteiros, podemos realizar neles todas as operações que fazemos com inteiros.

0b10011 + 0b10011
# => 38

0b10011 * 0b10011
# => 361

0b10011 / 3
# => 6.333333333333333

Convertendo de e para a representação binária

O Crystal converte automaticamente um literal binário em Int32. Para converter um Int32 em uma representação binária, use o método <int>.to_s(base) com o argumento de base definido como 2. O método retorna uma representação em string do número binário:

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

Para converter uma representação em string de um binário em um inteiro, podemos usar o método <int>.to_i(base), passando a base (2) como argumento:

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

Informar a base errada (ou uma representação binária inválida) vai lançar um ArgumentError:

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

Métodos binários

Existem alguns métodos que podem ser usados em inteiros para obter informações sobre a representação binária do número.

<int>.bit_length retorna o número de bits necessários para representar o número:

19.bit_length
# => 5

<int>.bit(index) retorna o bit no índice informado, começando da direita (bit menos significativo):

19.bit(0)
# => 1

0b10011.bit(1)
# => 1

Octal

Octal é um sistema de numeração de base 8. Ele usa os dígitos 0, 1, 2, 3, 4, 5, 6 e 7.

Em Crystal, podemos representar números octais usando o prefixo 0o. Assim como no binário, o Crystal converte automaticamente uma representação octal em um Int32.

0o123
# => 83

Colocar o prefixo 0o em um número que não esteja no sistema octal vai lançar um erro de compilação.

Convertendo de e para a representação octal

Assim como no binário, podemos usar o método <int>.to_s(base) para converter um Int32 em uma representação octal. E podemos usar o método <int>.to_i(base) para converter uma representação octal em um Int32.

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

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

Assim como no binário, informar a base errada vai lançar um ArgumentError.

Hexadecimal

Hexadecimal é um sistema de numeração de base 16. Ele usa os dígitos de 0 a 9 e as letras A, B, C, D, E e F. A é 10, B é 11, C é 12, D é 13, E é 14 e F é 15.

Podemos representar números hexadecimais em Crystal usando o prefixo 0x. Assim como no binário e no octal, o Crystal converte automaticamente literais hexadecimais em Int32.

#=> 0x123
291

Colocar o prefixo 0x em um número que não seja hexadecimal vai lançar um erro de compilação.

Convertendo de e para a representação hexadecimal

Assim como no binário, podemos usar o método <int>.to_s(base) para converter um Int32 em uma representação hexadecimal. E podemos usar o método <int>.to_i(base) para converter uma representação hexadecimal em um Int32.

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

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

Assim como no binário e no octal, informar a base errada vai lançar um ArgumentError.

Precisão

Ao converter um número para uma representação em string, podemos especificar a precisão do número. Ou seja, a quantidade mínima de números usada para representar o número. Se o número tiver menos dígitos que a precisão, zeros à esquerda serão adicionados à representação em string. Isso é feito passando o argumento precision para o método <int>.to_s(<base>, precision: <value>).

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

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

Instruções

Seu amigo se cansou de pagar por software de edição de fotos e decidiu escrever o próprio. Seu amigo decidiu chamar o novo software de Foto Fusionist.

O Foto Fusionist é um software de edição de fotos que consegue fazer muitas coisas, mas você só implementou algumas delas até agora. Mesmo assim, seu amigo está muito feliz com o progresso e pediu que você implementasse mais alguns recursos.

1. Converter representação binária em inteiro

Para o primeiro recurso, seu amigo quer conseguir converter a representação binária de um número em um inteiro. Isso é feito porque o software conseguirá ler a representação binária de um canal de cor e convertê-la em um inteiro.

Implemente o método FotoFusionist.binary_to_int, que recebe um argumento binary do tipo String. O método deve retornar a representação inteira do número binário.

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

2. Obter o bit menos significativo de um inteiro

O segundo recurso que seu amigo quer é conseguir obter o bit menos significativo de um inteiro. O bit menos significativo é o bit que fica mais à direita. Ele é chamado de bit menos significativo porque tem o menor valor.

O bit menos significativo é necessário para avaliar se uma imagem pode ser otimizada, reduzindo a quantidade de bits usada para representar o canal de cor.

Implemente o método FotoFusionist.least_significant_bit, que recebe um argumento number do tipo Int32. O método deve retornar o bit menos significativo do número.

FotoFusionist.least_significant_bit(0b10011)
# => 1

FotoFusionist.least_significant_bit(0b10010)
# => 0

3. Obter o valor hexadecimal de um canal de cor

O terceiro recurso que seu amigo quer é conseguir obter o valor hexadecimal de um canal de cor. O valor hexadecimal é necessário para converter o canal de cor em uma representação hexadecimal, e a representação hexadecimal fornecida precisa ser composta por dois dígitos.

Implemente o método FotoFusionist.hex_value, que recebe um argumento number do tipo Int32. O método deve retornar o valor hexadecimal do número como uma String.

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

4. Obter o valor hexadecimal de uma cor RGB

O quarto recurso que seu amigo quer é conseguir obter o valor hexadecimal de uma cor RGB. Isso é necessário para que a pessoa usuária possa obter uma única representação em string de uma cor. Uma cor RGB é uma cor representada por três canais de cor: vermelho, verde e azul. Cada canal de cor é representado por um número entre 0 e 255.

O valor hexadecimal de uma cor RGB é uma representação em string da cor em hexadecimal, com o canal de cor vermelho primeiro, depois o canal de cor verde e, por fim, o canal de cor azul.

Implemente o método FotoFusionist.hex_value_from_rgb, que recebe três argumentos: red, green e blue, do tipo Int32. O método deve retornar o valor hexadecimal da cor RGB como uma String.

FotoFusionist.hex_value_from_rgb(255, 0, 0)
# => "ff0000"
Editar via GitHub O link abre em uma nova janela ou aba
Crystal Exercism

Tudo pronto para começar Fusionista de fotos?

Crie sua conta no Exercism para aprender e dominar Crystal com 26 conceitos142 exercícios e mentoria humana de verdade, tudo de graça.