Σήμερα, οι περισσότεροι άνθρωποι στον κόσμο χρησιμοποιούν αραβικούς αριθμούς (0–9). Αν όμως ταξίδευες πίσω δύο χιλιάδες χρόνια, θα έβλεπες ότι οι περισσότεροι Ευρωπαίοι χρησιμοποιούσαν ρωμαϊκούς αριθμούς αντ' αυτών.
Για να γράψουμε έναν ρωμαϊκό αριθμό χρησιμοποιούμε τα παρακάτω λατινικά γράμματα, καθένα από τα οποία έχει μια τιμή:
| M | D | C | L | X | V | I |
|---|---|---|---|---|---|---|
| 1000 | 500 | 100 | 50 | 10 | 5 | 1 |
Ένας ρωμαϊκός αριθμός είναι μια ακολουθία από αυτά τα γράμματα και η τιμή του είναι το άθροισμα των τιμών των γραμμάτων.
Για παράδειγμα, το XVIII έχει τιμή 18 (10 + 5 + 1 + 1 + 1 = 18).
Υπάρχει όμως ένας κανόνας που κάνει τα πράγματα πιο περίπλοκα: το ίδιο γράμμα δεν μπορεί να χρησιμοποιηθεί περισσότερες από τρεις φορές διαδοχικά.
Αυτό σημαίνει ότι δεν μπορούμε να εκφράσουμε αριθμούς όπως το 4 με το φαινομενικά φυσικό IIII.
Αντ' αυτού, για αυτούς τους αριθμούς, χρησιμοποιούμε μια μέθοδο αφαίρεσης μεταξύ δύο γραμμάτων.
Έτσι, σκεφτόμαστε το 4 όχι ως 1 + 1 + 1 + 1 αλλά ως 5 - 1.
Και, κάπως μπερδευτικά για τη σύγχρονη αντίληψή μας, γράφουμε πρώτα τον μικρότερο αριθμό.
Αυτό ισχύει μόνο στις εξής περιπτώσεις: 4 (IV), 9 (IX), 40 (XL), 90 (XC), 400 (CD) και 900 (CM).
Η σειρά έχει σημασία στους ρωμαϊκούς αριθμούς! Τα γράμματα (και οι ειδικοί συνδυασμοί παραπάνω) πρέπει να είναι ταξινομημένα κατά φθίνουσα τιμή από αριστερά προς τα δεξιά.
Ορίστε μερικά παραδείγματα:
105 => CV
---- => --
100 => C
+ 5 => V
106 => CVI
---- => --
100 => C
+ 5 => V
+ 1 => I
104 => CIV
---- => ---
100 => C
+ 4 => IV
Και ένα τελευταίο πιο σύνθετο παράδειγμα:
1996 => MCMXCVI
----- => -------
1000 => M
+ 900 => CM
+ 90 => XC
+ 5 => V
+ 1 => I
Η αποστολή σου είναι να μετατρέψεις έναν αριθμό από αραβικούς αριθμούς σε ρωμαϊκούς αριθμούς.
Σε αυτή την άσκηση μας ενδιαφέρουν μόνο οι παραδοσιακοί ρωμαϊκοί αριθμοί, στους οποίους ο μεγαλύτερος αριθμός είναι το MMMCMXCIX (ή 3.999).
Υπάρχουν πολλοί διαφορετικοί τρόποι για να μετατρέψεις αραβικούς αριθμούς σε ρωμαϊκούς και αντίστροφα. Σου προτείνουμε να ακολουθήσεις πρώτα μια αφελή προσέγγιση, για να εξοικειωθείς με την έννοια των ρωμαϊκών αριθμών, και ύστερα να αναζητήσεις πιο αποδοτικούς τρόπους.
Φρόντισε να δεις το βίντεο Deep Dive στο τέλος, για να εξερευνήσεις τις διαφορετικές προσεγγίσεις που μπορείς να ακολουθήσεις!
Για αυτή την άσκηση, θα χρειαστεί να υποστηρίξεις δύο διαφορετικούς τρόπους κλήσης της λέξης stringify:
roman (π.χ. stringify.roman 3999)roman (π.χ. stringify 3999)Για περισσότερες πληροφορίες, δες την τεκμηρίωση των χαρακτηριστικών καθώς και την τεκμηρίωση του attr.
Εκτός από το attr, η συνάρτηση attrs είναι χρήσιμη: επιστρέφει όλα τα χαρακτηριστικά της κλήσης της συνάρτησης ως λεξικό.
Πρόσεξε ότι αυτές οι δύο συναρτήσεις είναι καταστροφικές!
Η υλοποίηση του Arturo χρησιμοποιεί έναν "πίνακα χαρακτηριστικών".
attrs αδειάζει ρητά τον πίνακα αφού ανακτήσει τα χαρακτηριστικά.attr αφαιρεί ("κάνει pop") το χαρακτηριστικό από τον πίνακα.Ένα παράδειγμα:
showAttributes: function [x][
print attr 'question
print attrs
print attrs
]
showAttributes .question:"6 * 9" .answer:42 'arg
δίνει ως έξοδο
6 * 9
[answer:42]
[]
Σε κάθε βήμα, βλέπουμε το λεξικό χαρακτηριστικών να μικραίνει.
Συμπέρασμα: να θυμάσαι ότι μπορείς να ανακτήσεις τα χαρακτηριστικά μόνο μία φορά. Αν χρειάζεται να ανατρέξεις ξανά στα χαρακτηριστικά, αποθήκευσέ τα στην αρχή των συναρτήσεών σου.
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Arturo με 79 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.
Εξερεύνησε μια ποικιλία διαφορετικών λύσεων σε αυτήν τη δύσκολη άσκηση, από αναδρομή μέχρι αναζητήσεις βάσει πινάκων, μια λύση που χρησιμοποιεί αριθμούς μικτής βάσης και λίγη απλοϊκή κλεψιά από τη Common Lisp.