Εργαστήριο 2 στη Ηaskell
Εξάσκηση (εκφωνήσεις και λύσεις ασκήσεων)
Άσκηση H2E1 Γράψτε τις ακόλουθες αναδρομικές συναρτήσεις που αφορούν αριθμητικές τιμές:
doubleFactorial n
, που υπολογίζει το διπλό παραγοντικό ενός αριθμούn
. Το διπλό παραγοντικό ορίζεται ως το γινόμενο όλων των ακεραίων από το 1 μέχρι και τον αριθμόn
που είναι είτε άρτιοι είτε περιττοί, ανάλογα με το εάν τοn
είναι άρτιο ή περιττό αντίστοιχα (π.χ. το διπλό παραγοντικό του 7 είναι 1 * 3 * 5 * 7 = 105).pow x, y
, που υπολογίζει τοx^y
(μεx
καιy
ακέραιες θετικές τιμές)- Έστω ότι δίνεται η συνάρτηση
plusOne x = x + 1
. Χωρίς να χρησιμοποιήσετε τον τελεστή+
, ορίστε τη συνάρτησηaddition
έτσι ώστε ηaddition x y
να προσθέτει ταx
καιy
. log2 x
, που υπολογίζει τον ακέραιο λογάριθμο με βάση 2 του ορίσματος που δέχεται (π.χ.log2 1 = 0
,log2 16 = 4
,log2 11 = 3
).
Λύση άσκησης H2E1
Άσκηση H2E2 Γράψτε τις ακόλουθες αναδρομικές συναρτήσεις που αφορούν λίστες. Προσέξτε ότι όλες οι ακόλουθες συναρτήσεις υπάρχουν στο Prelude, άρα θα πρέπει να δοθούν διαφορετικά ονόματα για τους ελέγχους σας με το GHCi.
replicate :: Int -> a -> [a]
, που λαμβάνει έναν μετρητή και ένα στοιχείο και επιστρέφει μια λίστα στην οποία το στοιχείο επαναλαμβάνεταιcount
φορές. Για παράδειγμαreplicate 3 'a' = "aaa"
.valueAt :: [a] -> Int -> a
, που επιστρέφει το στοιχείο σε μια συγκεκριμένη θέση. Το πρώτο στοιχείο βρίσκεται στη θέση 0, το δεύτερο στη θέση 1, κ.λπ. (π.χ.valueAt [7,8,1,3] 2 = 1
). Η συνάρτηση αυτή υπάρχει στο Prelude και είναι η(!!)
.myZip :: [a] -> [b] -> [(a, b)]
, που δέχεται δύο λίστες και τις συνδυάζει, έτσι ώστε, στη λίστα που προκύπτει, το πρώτο ζεύγος να σχηματίζεται από τα στοιχεία στην πρώτη θέση των δύο λιστών, το δεύτερο ζεύγος στη λίστα να σχηματίζεται από τα στοιχεία στη δεύτερη θέση των δύο λιστών κ.ο.κ. Για παράδειγμαmyZip [1,2,3] "abc" = [(1, 'a'), (2, 'b'), (3, 'c')]
. Αν οι δύο λίστες δεν έχουν το ίδιο μέγεθος τότε σταματάμε όταν μια από τις δύο λίστες δεν έχει πλέον στοιχεία. Η συνάρτηση αυτή υπάρχει στο Prelude με όνομαzip
.
Λύση άσκησης H2E2
Άσκηση H2E3 Γράψτε τις ακόλουθες αναδρομικές συναρτήσεις, προσθέτοντας και τις κατάλληλες υπογραφές τύπων:
takeInt
, επιστρέφει τα πρώταn
στοιχεία μιας λίστας. Για παράδειγμα, ηtakeInt 4 [11,21,31,41,51,61]
θα πρέπει να επιστρέφει[11,21,31,41]
. Η συνάρτηση αυτή υπάρχει στο Prelude με όνομαtake
.dropInt
, αφαιρεί τα πρώτα n στοιχεία μιας λίστας και επιστρέφει τα υπόλοιπα. Για παράδειγμα, ηdropInt 3 [11,21,31,41,51]
θα πρέπει να επιστρέφει[41,51]
. Η συνάρτηση αυτή υπάρχει στο Prelude με όνομαdrop
.sumInt
, επιστρέφει το άθροισμα των στοιχείων μιας λίστας. Η συνάρτηση αυτή υπάρχει στο Prelude με όνομαsum
.scanSum
, προσθέτει τα στοιχεία μιας λίστας και επιστρέφει μια λίστα με τα συσσωρευτικά αθροίσματα. Για παράδειγμα, ηscanSum [2,3,4,5]
θα πρέπει να επιστρέφει[2,5,9,14]
.
Λύση άσκησης H2E3
$ ghci h2e3.hs
GHCi, version 9.4.8: https://www.haskell.org/ghc/ :? for help
[1 of 2] Compiling Main ( h2e3.hs, interpreted )
Ok, one module loaded.
ghci> takeInt 4 [11,21,31,41,51,61]
[11,21,31,41]
ghci> dropInt 3 [11,21,31,41,51]
[41,51]
ghci> sumInt [1,2,3,4,5]
15
ghci> scanSum [2,3,4,5]
[2,5,9,14]
Άσκηση H2E4
Χρησιμοποιήστε τη συνάρτηση map
για να δημιουργήσετε συναρτήσεις που δεδομένης μιας λίστας xs
με ακεραίους να επιστρέφει:
- Μια λίστα με το αντίθετο κάθε στοιχείου. Χρησιμοποιήστε τη συνάρτηση
negate
. - Μια λίστα με λίστες ακεραίων
xss
, που για κάθε στοιχείο τουxs
, να περιέχει τους διαιρέτες τουxs
. Χρησιμοποιήστε τη συνάρτησηdivisors p = [ f | f <- [1..p], mod p f == 0 ]
για να λάβετε τους διαιρέτες.
Λύση άσκησης H2E4
h2e4.hs | |
---|---|
Άσκηση H2E5 Ο αλγόριθμος του Luhn χρησιμοποιείται ως ένας απλός έλεγχος εγκυρότητας για αριθμούς καρτών που εκδίδουν οι τράπεζες. Οι κανόνες είναι οι ακόλουθοι:
- Από το προτελευταίο ψηφίο και προς τα αριστερά με βήματα 2 ψηφίων, διπλασίασε κάθε ψηφίο.
- Αν το αποτέλεσμα του διπλασιασμού είναι μεγαλύτερο από 9, αφαίρεσε 9.
- Πρόσθεσε όλα τα ψηφία μαζί.
- Αν ο άθροισμα είναι πολλαπλάσιο του 10, η κάρτα είναι έγκυρη.
Για παράδειγμα ο αριθμός 1 7 8 4
είναι έγκυρος διότι:
Υλοποιήστε ένα πρόγραμμα που να δέχεται από τον χρήστη έναν αριθμό και να εμφανίζει αν είναι έγκυρος αριθμός πιστωτικής κάρτας ή όχι.