Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Αγαπητοί φίλοι, 

 Πιστεύω ότι οι περισσότεροι από εμάς έχουμε ήδη μπει σε εορταστική διάθεση περιμένοντας τη νέα χρονιά. Προσωπικά, αν και είμαι γάτος, δεν θα μπορούσα ν' αποτελέσω εξαίρεση στον κανόνα αυτό. Είπα λοιπόν από σήμερα ν' αρχίσω να ετοιμάζομαι για το 2020 που σε δύο εβδομάδες περίπου έρχεται και να υποδεχτώ το νέο έτος γράφοντας λίγες γραμμές κώδικα στη γλώσσα Prolog. Αυτή τη φορά θέλω να φτιάξω μια μικρή ρουτίνα που να διατρέξει όλους τους μήνες του νέου έτους και να μου πει αν υπάρχουν τριήμερα αργιών, πόσα και ποια ακριβώς είναι. 
 Ξεκινάμε γνωρίζοντας ότι το 2020 είναι δίσεκτο, επομένως ο Φεβρουάριος έχει 29 ημέρες. Ορίζουμε λοιπόν το κατηγόρημα month(X,Y) που επιστρέφει πόσες ακριβώς μέρες έχει ο X-οστός μήνας του έτους. Απλά τα πράγματα. Όρισμα εισόδου είναι το Χ που ανήκει στο κλειστό διάστημα [1,12] -αύξων αριθμός του μήνα- και όρισμα εξόδου είναι το Y που μπορεί να λάβει τις τιμές 29 ή 30 ή 31, ανάλογα με τον μήνα. 

month(2,29).
month(X,Y) :- member(X,[4,6,7,9,11]), Y is 30, !.
month(X,Y) :- member(X,[1,3,5,8,10,12]), Y is 31.

Συνεχίζουμε ορίζοντας κάποιες ημερομηνίες που είναι ούτως ή άλλως αργίες, ανεξαρτήτως ποια μέρα πέφτουν. Για παράδειγμα η 25η Μαρτίου είναι μία τέτοια ημερομηνία. Επίσης από προηγούμενη ρουτίνα που έχω γράψει, θυμάμαι ότι φέτος το Πάσχα είναι στις 19 Απριλίου. Αυτές τις ημερομηνίες θα τις λέμε special days μέσα στο πρόγραμμα και θα τις ορίζουμε ως εξής : 

// special_day(D,M) αυτό θα σημαίνει ότι κατά την ημερομηνία D του μηνός M έχουμε μια θεσπισμένη δημόσια αργία. 

special_day(1,1).
special_day(6,1).
special_day(2,3).  // Καθαρά Δευτέρα
special_day(25,3).
special_day(17,4). // Μεγ. Παρασκευή
special_day(19,4). // Κυριακή του Πάσχα
special_day(20,4). // Δευτέρα του Πάσχα
special_day(1,5).
special_day(8,6). // Αγίου Πνεύματος
special_day(15,8).
special_day(28,10).
special_day(25,12).
special_day(26,12).

Δεν αρκεί όμως ο παραπάνω ορισμός, γιατί η ημερομηνία D του μηνός M μπορεί να είναι αργία επειδή απλά πέφτει Σάββατο η Κυριακή. Άρα πρέπει να γραφεί ένα ακόμα κατηγόρημα που να χρησιμοποιεί τις ενσωματωμένες συναρτήσεις ημερολογίου της Prolog και να αληθεύει όταν η ημερομηνία D του μηνός M πέφτει μέσα σε Σαββατοκύριακο. 

weekend(D,M) :- month(M,K),between(1,K,W),day_of_the_week(date(2020,M,W),X), X>=6, D is W.

Άρα μια ημερομηνία (D,M) μπορεί να είναι αργία για τους εξής δύο λόγους : 

(A) Επειδή πέφτει Σάββατο ή Κυριακή, (Β) Επειδή ταυτίζεται με κάποια από τις ειδικές ημερομηνίες που ορίσαμε παραπάνω. 
Όμως π.χ. η Κυριακή του Πάσχα είναι αργία και για τους δύο αυτούς λόγους, άρα πρέπει να φροντίσουμε ώστε να μην αναφερθεί δύο φορές. Έτσι, για το πότε μία ημερομηνία θεωρείται αργία είναι σκόπιμο να γράψουμε ένα κατηγόρημα που λέγεται holiday(D,M) και στους ορισμούς του να ενσωματώνει όλες τις παραπάνω προβλέψεις. 

holiday_aux(D,M) :- weekend(D,M);special_day(D,M). // Στην Prolog το ελληνικό ερωτηματικό σημαίνει διάζευξη.
holiday(D,M) :- distinct(holiday_aux(D,M)).

Έτσι λοιπόν ορίσαμε πότε κάποια ημερομηνία (D,M) θα θεωρείται αργία. Τότε η Prolog στο ερώτημα holiday(D,M) θα απαντά true. 
Το πιο ωραίο κατηγόρημα είναι αυτό που βρίσκει τα τριήμερα αργιών. Δέχεται ως μοναδικό όρισμα τον αύξοντα αριθμό του μήνα (έστω Μ) και ψάχνει μέσα στο μήνα για τριάδες διαδοχικών αργιών. Τυπώνει το αποτέλεσμα στην οθόνη. 

three_day_holidays(M) :- month(M,Q), between(1,Q,K), holiday(K,M), Z is K+1, Z2 is K+2, holiday(Z,M),holiday(Z2,M), write(K), write("/"),write(M),nl,write(Z),write("/"),write(M),nl,write(Z2),write("/"),write(M),nl.

Έτσι λοιπόν αν δώσουμε three_day_holidays(2) η Prolog απαντά false γιατί ο Φεβρουάριος δεν έχει κανένα τριήμερο. 
Ας γράψουμε ένα κατηγόρημα που να τον ονομάσουμε ας πούμε run και να διατρέχει όλους τους μήνες τυπώνοντας όλα τα τριήμερα. 

run :- write("The white cat emits a long, warm and friendly meeeeow to give all users its best wishes for Christmas and the new year."),nl,between(1,12,M),three_day_holidays(M),fail.
run :- !.

Άν τρέξω το κατηγόρημα run η Prolog δίνει : 

The white cat emits a long, warm and friendly meeeeow to give all users its best wishes for Christmas and the new year.
4/1
5/1
6/1 [Η γιορτή των Φώτων πέφτει φέτος Δευτέρα]

17/4
18/4
19/4
20/4 [Μεγ. Παρασκευή, Μεγ. Σάββατο, Κυριακή & Δευτέρα του Πάσχα]

1/5 [Φέτος η Πρωτομαγιά πέφτει Παρασκευή]
2/5
3/5 

6/6
7/6
8/6 [Η ημέρα του Αγ. Πνεύματος πέφτει πάντα Δευτέρα]

25/12 [Τα Χριστούγεννα του 2020 πέφτουν Παρασκευή]
26/12
27/12

Ανάλογα με το ποια ακριβώς έκδοση της Prolog χρησιμοποιείτε, ορισμένοι μεταγλωττιστές ενδέχεται να εμφανίσουν το τετραήμερο του Απριλίου 2 φορές (δηλ. ως 17/4,18/4,19/4 & 18/4,19,4 & 20/4) ανάλογα με το αν και πως λειτουργεί στη συγκεκριμένη έκδοση η δήλωση distinct. 

Καλές γιορτές, υγεία σε όλους !
Ας μας βρει το 2020 όλους μας πιο δυνατούς και ευτυχισμένους ! 

Ο Άσπρος Γάτος

Επεξ/σία από White_Cat
  • Like 3
  • Thanks 1
Δημοσ.
13 ώρες πριν, gian είπε

Καλές Γιορτές Γάτε. Για άλλη μια φορά γαταπληκτικός!

Σόρρυ, δεν άντεξα :)

Στις 15/12/2019 στις 1:01 ΜΜ, White_Cat είπε

Είπα λοιπόν από σήμερα ν' αρχίσω να ετοιμάζομαι για το 2020 που σε δύο εβδομάδες περίπου έρχεται και να υποδεχτώ το νέο έτος γράφοντας λίγες γραμμές κώδικα στη γλώσσα Prolog.

Καλές γιορτές, υγεία σε όλους !

Ας μας βρει το 2020 όλους μας πιο δυνατούς και ευτυχισμένους ! 

Ο Άσπρος Γάτος

Μια και είσαι από τους λίγους που ανεβάζεις συχνά εδώ κώδικα, δεν θα ήταν καλύτερο να ανοίξεις ένα ενιαίο νήμα (πχ "οι κώδικες του γάτου") και να τους έχεις όλους εκεί ώστε να είναι πιο εύκολο να ανατρέξει κάποιος στο μέλλον και να τους διαβάσει; Έτσι θα μπορεί να είναι κάποιος subscribed στο νήμα σου και να ενημερώνεται κάθε φορά που γράφεις νέο post ενώ τώρα μπορεί να του ξεφύγει κάποιο νήμα.

Χρόνια πολλά σε όλους μας. Να περάσουμε καλά αύριο.

  • Like 1

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...