Track
/
Crystal
Crystal
/
Esercizi
/
Il fusionista delle foto
Il fusionista delle foto

Il fusionista delle foto

Esercizio di apprendimento

Introduzione

Il binario, l'ottale e l'esadecimale (noto anche come hex) sono diversi sistemi di numerazione, con basi diverse. Il binario è in base 2, l'ottale in base 8 e l'esadecimale in base 16. In Crystal, i normali numeri interi sono in base 10. Il binario, l'ottale e l'esadecimale sono tutte rappresentazioni di numeri interi. Questo significa che rappresentano numeri positivi e negativi (incluso lo zero) senza frazioni o decimali e supportano tutte le operazioni che possiamo fare con i numeri interi.

Binario

Il binario è un sistema di numerazione in base 2, che usa solo le cifre 0 e 1. Rappresenta comunemente gli stati 0 («off») e 1 («on») del flusso elettrico attraverso transistor e interruttori nei computer, così come le cariche positive e negative nei supporti di memorizzazione magnetica. Il binario può rappresentare tutti i numeri interi che si usano in base 10.

Uno stralcio del sistema in base 2 è questo, anche se continua all'infinito e non si ferma a 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

Quindi, se vogliamo rappresentare il numero 6, in binario sarebbe: 110

Place value 4 2 1
Binary number 1 1 0

E l'operazione sarebbe: 4 + 2 + 0 = 6

Un altro esempio: 19

Place value 16 8 4 2 1
Binary number 1 0 0 1 1

Il numero binario sarebbe: 10011 E l'operazione sarebbe: 16 + 0 + 0 + 2 + 1 = 19

Il binario in Crystal

In Crystal, possiamo rappresentare i letterali binari usando il prefisso 0b. Se scriviamo 0b10011, Crystal lo interpreterà come numero binario e lo convertirà in base 10.

0b10011
# => 19

typeof(0b10011)
# => Int32

Se scrivi un numero con il prefisso 0b che non è nel sistema binario, verrà generato un errore di compilazione.

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

Operazioni con i numeri binari

Dato che i numeri binari sono numeri interi, possiamo eseguire su di essi tutte le operazioni che possiamo fare con i numeri interi.

0b10011 + 0b10011
# => 38

0b10011 * 0b10011
# => 361

0b10011 / 3
# => 6.333333333333333

Convertire da e verso la rappresentazione binaria

Crystal convertirà automaticamente un letterale binario in Int32. Per convertire un Int32 in una rappresentazione binaria, usa il metodo <int>.to_s(base) con l'argomento base impostato a 2. Il metodo restituirà una rappresentazione sotto forma di stringa del numero binario:

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

Per convertire la rappresentazione di un binario sotto forma di stringa in un numero intero, possiamo usare il metodo <int>.to_i(base), passando la base (2) come argomento:

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

Indicare la base sbagliata (o una rappresentazione binaria non valida) genererà un ArgumentError:

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

Metodi per il binario

Esistono alcuni metodi che si possono usare sui numeri interi per ottenere informazioni sulla rappresentazione binaria del numero.

<int>.bit_length restituirà il numero di bit necessari per rappresentare il numero:

19.bit_length
# => 5

<int>.bit(index) restituirà il bit all'indice indicato, partendo da destra (bit meno significativo):

19.bit(0)
# => 1

0b10011.bit(1)
# => 1

Ottale

L'ottale è un sistema di numerazione in base 8. Usa le cifre 0, 1, 2, 3, 4, 5, 6 e 7.

In Crystal, possiamo rappresentare i numeri ottali usando il prefisso 0o. Come per il binario, Crystal converte automaticamente una rappresentazione ottale in un Int32.

0o123
# => 83

Scrivere un numero con il prefisso 0o che non è nel sistema ottale genererà un errore di compilazione.

Convertire da e verso la rappresentazione ottale

Come per il binario, possiamo usare il metodo <int>.to_s(base) per convertire un Int32 in una rappresentazione ottale. E possiamo usare il metodo <int>.to_i(base) per convertire una rappresentazione ottale in un Int32.

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

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

Come per il binario, indicare la base sbagliata genererà un ArgumentError.

Esadecimale

L'esadecimale è un sistema di numerazione in base 16. Usa le cifre da 0 a 9 e le lettere A, B, C, D, E e F. A è 10, B è 11, C è 12, D è 13, E è 14 e F è 15.

Possiamo rappresentare i numeri esadecimali in Crystal usando il prefisso 0x. Come per il binario e l'ottale, Crystal convertirà automaticamente i letterali esadecimali in Int32.

#=> 0x123
291

Scrivere un numero non esadecimale con il prefisso 0x genererà un errore di compilazione.

Convertire da e verso la rappresentazione esadecimale

Come per il binario, possiamo usare il metodo <int>.to_s(base) per convertire un Int32 in una rappresentazione esadecimale. E possiamo usare il metodo <int>.to_i(base) per convertire una rappresentazione esadecimale in un Int32.

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

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

Come per il binario e l'ottale, indicare la base sbagliata genererà un ArgumentError.

Precisione

Quando convertiamo un numero in una rappresentazione sotto forma di stringa, possiamo specificare la precisione del numero. Ovvero il numero minimo di cifre usate per rappresentare il numero. Se il numero ha meno cifre della precisione, alla rappresentazione sotto forma di stringa verranno aggiunti degli zeri iniziali. Per farlo, si passa l'argomento precision al metodo <int>.to_s(<base>, precision: <value>).

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

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

Istruzioni

Il tuo amico si è stancato di pagare per un software di fotoritocco e ha deciso di scriverne uno tutto suo. Ha deciso di chiamare il nuovo software Foto Fusionist.

Foto Fusionist è un software di fotoritocco in grado di fare molte cose, ma finora ne hai implementate solo alcune. Il tuo amico però è molto soddisfatto dei progressi e ti ha chiesto di implementare qualche altra funzionalità.

1. Convertire una rappresentazione binaria in un numero intero

Come prima funzionalità, il tuo amico vuole poter convertire la rappresentazione binaria di un numero in un numero intero. Serve perché il software possa leggere la rappresentazione binaria di un canale di colore e convertirla in un numero intero.

Implementa il metodo FotoFusionist.binary_to_int, che accetta un argomento binary di tipo String. Il metodo deve restituire la rappresentazione come numero intero del numero binario.

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

2. Ottenere il bit meno significativo da un numero intero

La seconda funzionalità che il tuo amico vuole è poter ottenere il bit meno significativo da un numero intero. Il bit meno significativo è il bit più a destra. Si chiama bit meno significativo perché ha il valore più piccolo.

Il bit meno significativo serve a valutare se un'immagine può essere ottimizzata riducendo il numero di bit usati per rappresentare il canale di colore.

Implementa il metodo FotoFusionist.least_significant_bit, che accetta un argomento number di tipo Int32. Il metodo deve restituire il bit meno significativo del numero.

FotoFusionist.least_significant_bit(0b10011)
# => 1

FotoFusionist.least_significant_bit(0b10010)
# => 0

3. Ottenere il valore esadecimale da un canale di colore

La terza funzionalità che il tuo amico vuole è poter ottenere il valore esadecimale da un canale di colore. Il valore esadecimale serve per poter convertire il canale di colore in una rappresentazione esadecimale, e tale rappresentazione deve essere composta da due cifre.

Implementa il metodo FotoFusionist.hex_value, che accetta un argomento number di tipo Int32. Il metodo deve restituire il valore esadecimale del numero come String.

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

4. Ottenere il valore esadecimale da un colore RGB

La quarta funzionalità che il tuo amico vuole è poter ottenere il valore esadecimale da un colore RGB. Serve a permettere a chi usa il software di ottenere una rappresentazione del colore come un'unica stringa. Un colore RGB è un colore rappresentato da tre canali di colore: rosso, verde e blu. Ogni canale di colore è rappresentato da un numero compreso tra 0 e 255.

Il valore esadecimale di un colore RGB è la rappresentazione del colore in esadecimale, con prima il canale rosso, poi il canale verde e infine il canale blu.

Implementa il metodo FotoFusionist.hex_value_from_rgb, che accetta tre argomenti: red, green e blue di tipo Int32. Il metodo deve restituire il valore esadecimale del colore RGB come String.

FotoFusionist.hex_value_from_rgb(255, 0, 0)
# => "ff0000"
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Crystal Exercism

Vuoi iniziare Il fusionista delle foto?

Iscriviti a Exercism per imparare e padroneggiare Crystal con 26 concetti142 esercizi e il mentoring di persone reali, tutto gratis.