Διαδρομές
/
Crystal
Crystal
/
Ασκήσεις
/
Συνθέτης φωτογραφιών
Συνθέτης φωτογραφιών

Συνθέτης φωτογραφιών

Άσκηση εκμάθησης

Εισαγωγή

Το δυαδικό, το οκταδικό και το δεκαεξαδικό (γνωστό και ως hex) είναι διαφορετικά συστήματα αρίθμησης με διαφορετικές βάσεις. Το δυαδικό έχει βάση το 2, το οκταδικό έχει βάση το 8 και το δεκαεξαδικό έχει βάση το 16. Οι συνηθισμένοι ακέραιοι στο Crystal είναι βάσης 10. Το δυαδικό, το οκταδικό και το δεκαεξαδικό είναι όλα αναπαραστάσεις ακεραίων. Αυτό σημαίνει ότι αναπαριστούν θετικούς και αρνητικούς αριθμούς (συμπεριλαμβανομένου του μηδενός) χωρίς κλάσματα ή δεκαδικά ψηφία και υποστηρίζουν όλες τις πράξεις που μπορούμε να κάνουμε με ακεραίους.

Δυαδικό

Το δυαδικό είναι ένα σύστημα αρίθμησης βάσης 2, που χρησιμοποιεί μόνο τα ψηφία 0 και 1. Συνήθως αναπαριστά τις καταστάσεις 0 ("off") και 1 ("on") της ροής του ηλεκτρισμού μέσα από τρανζίστορ και διακόπτες στους υπολογιστές, καθώς και τα θετικά και αρνητικά φορτία στα μαγνητικά μέσα αποθήκευσης. Το δυαδικό μπορεί να αναπαραστήσει όλους τους ακεραίους που χρησιμοποιούνται στη βάση 10.

Ένα απόσπασμα από το σύστημα βάσης 2 μοιάζει κάπως έτσι, αν και συνεχίζεται άπειρα και δεν σταματά στο 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

Έτσι, αν θέλουμε να αναπαραστήσουμε τον αριθμό 6, στο δυαδικό θα ήταν: 110

Αξία θέσης 4 2 1
Δυαδικός αριθμός 1 1 0

Και η πράξη θα ήταν: 4 + 2 + 0 = 6

Άλλο ένα παράδειγμα: 19

Αξία θέσης 16 8 4 2 1
Δυαδικός αριθμός 1 0 0 1 1

Ο δυαδικός αριθμός θα ήταν: 10011 Και η πράξη θα ήταν: 16 + 0 + 0 + 2 + 1 = 19

Το δυαδικό στο Crystal

Στο Crystal, μπορούμε να αναπαραστήσουμε δυαδικά literals χρησιμοποιώντας το πρόθεμα 0b. Αν γράψεις 0b10011, το Crystal θα το ερμηνεύσει ως δυαδικό αριθμό και θα το μετατρέψει σε βάση 10.

0b10011
# => 19

typeof(0b10011)
# => Int32

Αν γράψεις έναν αριθμό με πρόθεμα 0b που δεν είναι στο δυαδικό σύστημα, θα πετάξει ένα σφάλμα μεταγλώττισης.

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

Πράξεις με δυαδικούς αριθμούς

Εφόσον οι δυαδικοί αριθμοί είναι ακέραιοι, μπορούμε να κάνουμε πάνω τους όλες τις πράξεις που μπορούμε και με τους ακεραίους.

0b10011 + 0b10011
# => 38

0b10011 * 0b10011
# => 361

0b10011 / 3
# => 6.333333333333333

Μετατροπή από και προς τη δυαδική αναπαράσταση

Το Crystal θα μετατρέψει αυτόματα ένα δυαδικό literal σε Int32. Για να μετατρέψεις ένα Int32 σε δυαδική αναπαράσταση, χρησιμοποίησε τη μέθοδο <int>.to_s(base) με το όρισμα της βάσης ορισμένο σε 2. Η μέθοδος θα επιστρέψει μια αναπαράσταση συμβολοσειράς του δυαδικού αριθμού:

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

Για να μετατρέψεις μια αναπαράσταση συμβολοσειράς ενός δυαδικού σε ακέραιο, μπορούμε να χρησιμοποιήσουμε τη μέθοδο <int>.to_i(base), περνώντας τη βάση (2) ως όρισμα:

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

Το να δώσεις λάθος βάση (ή μια μη έγκυρη δυαδική αναπαράσταση) θα πετάξει ένα ArgumentError:

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

Δυαδικές μέθοδοι

Υπάρχουν ορισμένες μέθοδοι που μπορούν να χρησιμοποιηθούν σε ακεραίους για να πάρουμε πληροφορίες για τη δυαδική αναπαράσταση του αριθμού.

Το <int>.bit_length θα επιστρέψει τον αριθμό των bits που χρειάζονται για να αναπαραστήσουν τον αριθμό:

19.bit_length
# => 5

Το <int>.bit(index) θα επιστρέψει το bit στη δεδομένη θέση, ξεκινώντας από τα δεξιά (το λιγότερο σημαντικό bit):

19.bit(0)
# => 1

0b10011.bit(1)
# => 1

Οκταδικό

Το οκταδικό είναι ένα σύστημα αρίθμησης βάσης 8. Χρησιμοποιεί τα ψηφία 0, 1, 2, 3, 4, 5, 6 και 7.

Στο Crystal, μπορούμε να αναπαραστήσουμε οκταδικούς αριθμούς χρησιμοποιώντας το πρόθεμα 0o. Όπως με το δυαδικό, το Crystal μετατρέπει αυτόματα μια οκταδική αναπαράσταση σε Int32.

0o123
# => 83

Το να βάλεις πρόθεμα 0o σε έναν αριθμό που δεν είναι στο οκταδικό σύστημα θα πετάξει ένα σφάλμα μεταγλώττισης.

Μετατροπή από και προς την οκταδική αναπαράσταση

Όπως με το δυαδικό, μπορούμε να χρησιμοποιήσουμε τη μέθοδο <int>.to_s(base) για να μετατρέψουμε ένα Int32 σε οκταδική αναπαράσταση. Και μπορούμε να χρησιμοποιήσουμε τη μέθοδο <int>.to_i(base) για να μετατρέψουμε μια οκταδική αναπαράσταση σε Int32.

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

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

Όπως με το δυαδικό, το να δώσεις λάθος βάση θα πετάξει ένα ArgumentError.

Δεκαεξαδικό

Το δεκαεξαδικό είναι ένα σύστημα αρίθμησης βάσης 16. Χρησιμοποιεί τα ψηφία 0 - 9 και τα γράμματα A, B, C, D, E και F. Το A είναι 10, το B είναι 11, το C είναι 12, το D είναι 13, το E είναι 14 και το F είναι 15.

Μπορούμε να αναπαραστήσουμε δεκαεξαδικούς αριθμούς στο Crystal χρησιμοποιώντας το πρόθεμα 0x. Όπως με το δυαδικό και το οκταδικό, το Crystal θα μετατρέψει αυτόματα τα δεκαεξαδικά literals σε Int32.

#=> 0x123
291

Το να βάλεις πρόθεμα 0x σε έναν μη δεκαεξαδικό αριθμό θα πετάξει ένα σφάλμα μεταγλώττισης.

Μετατροπή από και προς τη δεκαεξαδική αναπαράσταση

Όπως με το δυαδικό, μπορούμε να χρησιμοποιήσουμε τη μέθοδο <int>.to_s(base) για να μετατρέψουμε ένα Int32 σε δεκαεξαδική αναπαράσταση. Και μπορούμε να χρησιμοποιήσουμε τη μέθοδο <int>.to_i(base) για να μετατρέψουμε μια δεκαεξαδική αναπαράσταση σε Int32.

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

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

Όπως με το δυαδικό και το οκταδικό, το να δώσεις λάθος βάση θα πετάξει ένα ArgumentError.

Ακρίβεια

Όταν μετατρέπουμε έναν αριθμό σε αναπαράσταση συμβολοσειράς, μπορούμε να ορίσουμε την ακρίβειά του. Δηλαδή τον ελάχιστο αριθμό ψηφίων που χρησιμοποιούνται για να αναπαρασταθεί ο αριθμός. Αν ο αριθμός έχει λιγότερα ψηφία από την ακρίβεια, θα προστεθούν μηδενικά μπροστά στην αναπαράσταση συμβολοσειράς. Αυτό γίνεται περνώντας το όρισμα precision στη μέθοδο <int>.to_s(<base>, precision: <value>).

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

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

Οδηγίες

Ο φίλος σου βαρέθηκε να πληρώνει για λογισμικό επεξεργασίας φωτογραφιών και αποφάσισε να γράψει το δικό του. Ο φίλος σου αποφάσισε να ονομάσει το νέο λογισμικό Foto Fusionist.

Το Foto Fusionist είναι ένα λογισμικό επεξεργασίας φωτογραφιών που μπορεί να κάνει πολλά πράγματα, αλλά μέχρι στιγμής έχεις υλοποιήσει μόνο μερικά από αυτά. Ωστόσο, ο φίλος σου είναι πολύ ευχαριστημένος με την πρόοδο και σου ζήτησε να υλοποιήσεις μερικές ακόμα λειτουργίες.

1. Μετέτρεψε τη δυαδική αναπαράσταση σε ακέραιο

Για την πρώτη λειτουργία, ο φίλος σου θέλει να μπορεί να μετατρέπει τη δυαδική αναπαράσταση ενός αριθμού σε ακέραιο. Αυτό γίνεται γιατί το λογισμικό θα μπορεί να διαβάζει τη δυαδική αναπαράσταση ενός καναλιού χρώματος και να τη μετατρέπει σε ακέραιο.

Υλοποίησε τη μέθοδο FotoFusionist.binary_to_int που δέχεται ένα όρισμα binary τύπου String. Η μέθοδος θα πρέπει να επιστρέφει την ακέραια αναπαράσταση του δυαδικού αριθμού.

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

2. Πάρε το λιγότερο σημαντικό bit από έναν ακέραιο

Η δεύτερη λειτουργία που θέλει ο φίλος σου είναι να μπορεί να παίρνει το λιγότερο σημαντικό bit από έναν ακέραιο. Το λιγότερο σημαντικό bit είναι το bit που βρίσκεται πιο δεξιά. Ονομάζεται λιγότερο σημαντικό bit επειδή έχει τη μικρότερη τιμή.

Το λιγότερο σημαντικό bit χρειάζεται για να αξιολογηθεί αν μια εικόνα μπορεί να βελτιστοποιηθεί μειώνοντας τον αριθμό των bit που χρησιμοποιούνται για την αναπαράσταση του καναλιού χρώματος.

Υλοποίησε τη μέθοδο FotoFusionist.least_significant_bit που δέχεται ένα όρισμα number τύπου Int32. Η μέθοδος θα πρέπει να επιστρέφει το λιγότερο σημαντικό bit του αριθμού.

FotoFusionist.least_significant_bit(0b10011)
# => 1

FotoFusionist.least_significant_bit(0b10010)
# => 0

3. Πάρε τη δεκαεξαδική τιμή από ένα κανάλι χρώματος

Η τρίτη λειτουργία που θέλει ο φίλος σου είναι να μπορεί να παίρνει τη δεκαεξαδική τιμή από ένα κανάλι χρώματος. Η δεκαεξαδική τιμή χρειάζεται για να μπορεί το κανάλι χρώματος να μετατραπεί σε δεκαεξαδική αναπαράσταση, και η συγκεκριμένη δεκαεξαδική αναπαράσταση πρέπει να αποτελείται από δύο ψηφία.

Υλοποίησε τη μέθοδο FotoFusionist.hex_value που δέχεται ένα όρισμα number τύπου Int32. Η μέθοδος θα πρέπει να επιστρέφει τη δεκαεξαδική τιμή του αριθμού ως String.

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

4. Πάρε τη δεκαεξαδική τιμή από ένα χρώμα RGB

Η τέταρτη λειτουργία που θέλει ο φίλος σου είναι να μπορεί να παίρνει τη δεκαεξαδική τιμή από ένα χρώμα RGB. Αυτό χρειάζεται ώστε ένας χρήστης να μπορεί να πάρει μια ενιαία αναπαράσταση συμβολοσειράς ενός χρώματος. Ένα χρώμα RGB είναι ένα χρώμα που αναπαρίσταται από τρία κανάλια χρώματος: κόκκινο, πράσινο και μπλε. Κάθε κανάλι χρώματος αναπαρίσταται από έναν αριθμό μεταξύ 0 και 255.

Η δεκαεξαδική τιμή ενός χρώματος RGB είναι μια αναπαράσταση συμβολοσειράς του χρώματος σε δεκαεξαδικό, με πρώτο το κόκκινο κανάλι χρώματος, μετά το πράσινο κανάλι χρώματος και τέλος το μπλε κανάλι χρώματος.

Υλοποίησε τη μέθοδο FotoFusionist.hex_value_from_rgb που δέχεται τρία ορίσματα: red, green και blue τύπου Int32. Η μέθοδος θα πρέπει να επιστρέφει τη δεκαεξαδική τιμή του χρώματος RGB ως String.

FotoFusionist.hex_value_from_rgb(255, 0, 0)
# => "ff0000"
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Crystal Exercism

Έτοιμος να ξεκινήσεις την άσκηση Συνθέτης φωτογραφιών;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Crystal με 26 έννοιες142 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.