Διαδρομές
/
Scala
Scala
/
Ασκήσεις
/
Ρωμαϊκοί αριθμοί
Ρωμαϊκοί αριθμοί

Ρωμαϊκοί αριθμοί

Μέτριο

Εισαγωγή

Σήμερα, οι περισσότεροι άνθρωποι στον κόσμο χρησιμοποιούν αραβικούς αριθμούς (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).

Note

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

Φρόντισε να δεις το βίντεο Deep Dive στο τέλος, για να εξερευνήσεις τις διαφορετικές προσεγγίσεις που μπορείς να ακολουθήσεις!

Ειδικές οδηγίες για το track

Για κάτι λίγο διαφορετικό, μπορείς επίσης να δοκιμάσεις μια λύση με συνάρτηση unfold. Πιθανότατα γνωρίζεις ήδη τις foldLeft/Right: "map" μια ολόκληρη συλλογή σε κάτι άλλο (συνήθως σε κάτι που δεν είναι συλλογή). Οι unfoldLeft/Right είναι οι "αντίστροφες" πράξεις: "map" κάτι (συνήθως κάτι που δεν είναι συλλογή) σε μια συλλογή. Έτσι, το unfold είναι μια λογική προσθήκη στο καθιερωμένο ρεπερτόριο του συναρτησιακού προγραμματισμού και μέρος του.

Αυτή η άσκηση μπορεί να ιδωθεί ως μια περίπτωση για unfold: "map" ένα Int σε ένα String (το οποίο φυσικά είναι έμμεσα ένα Seq[Char]).

Δυστυχώς, οι unfoldLeft/Right δεν περιλαμβάνονται στη βιβλιοθήκη συλλογών της Scala. Αλλά μπορείς να πάρεις την υλοποίηση από εδώ.

Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Scala Exercism

Έτοιμος να ξεκινήσεις την άσκηση Ρωμαϊκοί αριθμοί;

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

Αναλυτική ματιά στο Ρωμαϊκοί αριθμοί!

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