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

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

Δημοσ.

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

 Σ' ένα παλιό βιβλίο μαθηματικών του Γεωργίου Μπόζη βρήκα έναν σχετικά σύντομο αλγόριθμο υπολογισμού της ημέρας του Πάσχα. Ξεκινά από τον υπολογισμό της λεγόμενης επακτής (δηλ. της σεληνιακής ηλικίας κατά την 31η Δεκεμβρίου κάποιου έτους) κι έτσι βρίσκει την ημερομηνία της εαρινής πανσελήνου. Ως γνωστόν, το ορθόδοξο Πάσχα είναι η πρώτη Κυριακή μετά την εαρινή πανσέληνο. Χωρίς να μπαίνω σε πολλές λεπτομέρειες υλοποίησα τον αλγόριθμο αυτό σε Prolog και βλέπω ότι εκ πρώτης όψεως  λειτουργεί καλά. 
 Συγκεκριμένα έγραψα το κατηγόρημα easter σε δύο εκδοχές. Η πρώτη εκδοχή είναι με ένα όρισμα, δηλαδή για παράδειγμα easter(2000). H Prolog απαντά ότι το Πάσχα του 2000 ήταν στις 30 Απριλίου. 
Μία δεύτερη εκδοχή είναι η easter(Χ,Y) η οποία επιστρέφει την ημερομηνία του Πάσχα για όλα τα έτη που ανήκουν στο κλειστό διάστημα [X,Y]. 
Εκείνο που θα ήθελα από εσάς είναι αν θα μπορούσε κάποιος να μου πει αν υπάρχει ενσωματωμένο κατηγόρημα στην Prolog που να υπολογίζει μία ημερομηνία, με δεδομένη τη διαφορά της σε ημέρες από μία άλλη. Το ρωτάω αυτό για να δω αν χρειάζεται να προσπαθήσω να γράψω κάποιο τέτοιο κατηγόρημα μόνος μου. 
 Άν είχα στη διάθεσή μου κάποιο τέτοιο κατηγόρημα θα μπορούσα να υπολογίζω ένα πολύ μεγάλο σύνολο κινητών εορτών που είναι συνάρτηση του Πάσχα, όπως πχ η Κυριακή του Τελώνη ή η Τσικνοπέμπτη. Ίσως έτσι να μπορούσε να δημιουργηθεί ένα κατηγόρημα που να επιστρέφει το πλήρες εορτολόγιο με μόνο όρισμα το έτος. 
 Δίνω λοιπόν τον κώδικα και ας τον επεκτείνει ή ας τον βελτιώσει όποιος μπορεί. Κανονικά δεν ήθελα να τυπώνει Αγγλικά στα μηνύματα, αλλά τα προτιμώ απ' το να γράφω Ελληνικά με λατινικούς χαρακτήρες. Μια και το φέρνει η κουβέντα, μήπως γνωρίζει κάποιος πώς θα ενεργοποιήσω στην Prolog την υποστήριξη του Unicode ;

Ιδού ο κώδικας : 

easter(Year,Day) :- A is Year mod 19, B is Year mod 4, C is Year mod 7,
                    Tmp is 19*A+16,D is Tmp mod 30, Tmp_2 is 2*B+4*C+6*D, 
                    E is Tmp_2 mod 7,
                    Day is 3 + D + E, !.
easter(Year) :- easter(Year,Day),
                Day=<30,write("In the year "),write(Year),write(" "),write("Easter will be celebrated on "),
                write("April "),write(Day),nl, !.
easter(Year) :- easter(Year,Day),
                Day>30, write("In the year "),write(Year),write(" "),write("Easter will be celebrated on "),
                D is abs(Day-30),write(" May "),write(D),nl, !.
easter(Year1,Year2) :- between(Year1,Year2,Y),easter(Y), fail.
easter(Year1,Year2) :- !.

Έτσι λοιπόν δίνοντας την εντολή easter(2020,2030) ή Prolog επιστρέφει : 

In the year 2020 Easter will be celebrated on April 19
In the year 2021 Easter will be celebrated on  May 2
In the year 2022 Easter will be celebrated on April 24
In the year 2023 Easter will be celebrated on April 16
In the year 2024 Easter will be celebrated on  May 5
In the year 2025 Easter will be celebrated on April 20
In the year 2026 Easter will be celebrated on April 12
In the year 2027 Easter will be celebrated on  May 2
In the year 2028 Easter will be celebrated on April 16
In the year 2029 Easter will be celebrated on April 8
In the year 2030 Easter will be celebrated on April 28

Ετοιμάστε λοιπόν τις μαγειρίτσες και κλείστε τα αρνιά από τώρα...!

Ευχαριστώ, να είστε καλά, 

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

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

No clue,  Δεν έχω ιδέα από prolog. Αυτό φαντάζομαι το είδες https://www.swi-prolog.org/pldoc/man?section=timedate

Εφόσον δεν υποστηρίζει πράξεις με dates, κάτι πολύ απλό που μπορείς να κάνεις

stamp_date_time(get_time()+60*60*24*meres)
βάζεις δηλαδή timestamp το 'σημερινό' + τα δευτερόλεπτα των ημερών που θες.

Δίνω ένα παράδειγμα σε js ασ πούμε

αν θέλω να δω την ημερομηνία 15 μέρες πριν από σήμερα παίρνω το timestamp το σημερινό αφαιρώ millseconds 15 ημερών (γιατί σε js το timestamp είναι σε millsecond ενώ prolog βλέπω ότι είναι σε second) και ζητάω την ημερομηνία του νέου timestamp

dekapente_meres_prin = new Date(Date.now()-1000*60*60*24*15)
>> Date Wed Sep 25 2019 21:03:16 GMT+0200 (Central European Summer Time)

To Date.now() είναι το get_time()της prolog και το new Date() είναι το stamp_date_time() της prolog

To Date.now() μπορεί να είναι το timestamp οποιασδήποτε ημερομηνίας και εφαρμόζοντας σε αυτό τη διαφορά παίρνεις την νέα ημερομηνία.
 

Spoiler

 

Προσοχή στα όρια που θέτει η prolog μετά την καταστροφή της γης θα έχεις πρόβλημα με τον υπολογισμό του πασχα😁

the current implementation uses libtai to realise conversion between time-stamps and calendar dates for a period of 10 million years.

Ενώ η js με τα milliseconds σου δίνει περιθώριο μόνο για 285.616 χρόνια.

As such, the Date type stores dates as the number of milliseconds that have passed since midnight on January 1,
1970 UTC (Universal Time Code). Using this data storage format, the Date type can accurately represent
dates 285,616 years before or after January 1, 1970.

 

 

Επεξ/σία από k33theod
Δημοσ.

Καλησπέρα ! 

Συγνώμη που άργησα ν' απαντήσω, αλλά κάποιες μέρες λόγω διαφόρων υποχρεώσεων, δεν ανοίγω τον υπολογιστή καθόλου. Πραγματικά χαίρομαι πάρα πολύ και για τις δύο παραπάνω απαντήσεις στο αρχικό μου μήνυμα. 
Φίλε solar power, θα το κοιτάξω αυτό που λες περί της Rosetta Code, αλλά αισθάνομαι λίγο περίεργα, κυρίως γιατί δεν έχω ξανακάνει κάτι τέτοιο. Δεν έχω ξαναμπεί σε τέτοια διαδικασία και ως εκ τούτου δεν ξέρω πού ακριβώς να στείλω τη ρουτίνα μου και πώς να το διατυπώσω, ώστε αυτό που στέλνω να γίνει δεκτό. Επίσης η λύση με τα time stamps μου έδωσε ένα πολύ καλό έναυσμα για να συνεχίσω πάνω σ' αυτό που ψάχνω.
 Σας ευχαριστώ όλους για τις απαντήσεις σας γιατί έτσι ενθαρρύνετε έναν απλό άσπρο γάτο να συνεχίσει να νιαουρίζει στο Insomnia εκθέτοντας τις απόψεις του για διάφορα θέματα. Τέλος το ήρεμο και φιλικό ύφος των απαντήσεων μαρτυράει συνολικά το επίπεδο στο οποίο βρίσκεται ως ιστότοπος το ίδιο το Insomnia. 

Μ' ένα πολύ θερμό και μακρόσυρτο νιαούρισμα, 

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

Δημοσ.

Στο rossetacode κάνεις πρώτα εγγραφή. Μετά πας στη σελίδα που σε ενδιαφέρει να προσθέσεις κώδικα και επιλέγεις edit.

Ανοίγει όλο το αρχείο, σε ένα textbox και κοιτάς απλά μια υλοποίηση σε μια οποιαδήποτε γλώσσα τι tags χρησιμοποιεί. Βρίσκεις μετά σε ποια θέση θα προσθέσεις το κώδικά σου.βάσει σειράς ταξινόμησης. Αν θες δες σελίδες με παραδείγματα σε prolog και πάτα το edit, βρες τον κώδικα και πάρε ένα αντίγραφο. Πάνω σε αυτό αλλάζεις το περιεχόμενο και χωρίς να αλλάξεις κάτι στην τρέχουσα σελίδα πας σε αυτήν που θες να προσθέσεις κώδικα, με το έτοιμο πια περιεχόμενο. Το μόνο που χρειάζεται είναι ο κώδικας που θα βάλεις να εκτελεί την άσκηση. Αυτός ο σύνδεσμος που έδωσα ζητάει και άλλα, τα οποία όμως δεν θα σου είναι δύσκολο να τα βάλεις.

Δημοσ. (επεξεργασμένο)
Στις 10/10/2019 στις 6:33 ΜΜ, White_Cat είπε

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

 Σ' ένα παλιό βιβλίο μαθηματικών του Γεωργίου Μπόζη βρήκα έναν σχετικά σύντομο αλγόριθμο υπολογισμού της ημέρας του Πάσχα. Ξεκινά από τον υπολογισμό της λεγόμενης επακτής (δηλ. της σεληνιακής ηλικίας κατά την 31η Δεκεμβρίου κάποιου έτους) κι έτσι βρίσκει την ημερομηνία της εαρινής πανσελήνου. Ως γνωστόν, το ορθόδοξο Πάσχα είναι η πρώτη Κυριακή μετά την εαρινή πανσέληνο. Χωρίς να μπαίνω σε πολλές λεπτομέρειες υλοποίησα τον αλγόριθμο αυτό σε Prolog και βλέπω ότι εκ πρώτης όψεως  λειτουργεί καλά. 
 Συγκεκριμένα έγραψα το κατηγόρημα easter σε δύο εκδοχές. Η πρώτη εκδοχή είναι με ένα όρισμα, δηλαδή για παράδειγμα easter(2000). H Prolog απαντά ότι το Πάσχα του 2000 ήταν στις 30 Απριλίου. 
Μία δεύτερη εκδοχή είναι η easter(Χ,Y) η οποία επιστρέφει την ημερομηνία του Πάσχα για όλα τα έτη που ανήκουν στο κλειστό διάστημα [X,Y]. 
Εκείνο που θα ήθελα από εσάς είναι αν θα μπορούσε κάποιος να μου πει αν υπάρχει ενσωματωμένο κατηγόρημα στην Prolog που να υπολογίζει μία ημερομηνία, με δεδομένη τη διαφορά της σε ημέρες από μία άλλη. Το ρωτάω αυτό για να δω αν χρειάζεται να προσπαθήσω να γράψω κάποιο τέτοιο κατηγόρημα μόνος μου. 
 Άν είχα στη διάθεσή μου κάποιο τέτοιο κατηγόρημα θα μπορούσα να υπολογίζω ένα πολύ μεγάλο σύνολο κινητών εορτών που είναι συνάρτηση του Πάσχα, όπως πχ η Κυριακή του Τελώνη ή η Τσικνοπέμπτη. Ίσως έτσι να μπορούσε να δημιουργηθεί ένα κατηγόρημα που να επιστρέφει το πλήρες εορτολόγιο με μόνο όρισμα το έτος. 
 Δίνω λοιπόν τον κώδικα και ας τον επεκτείνει ή ας τον βελτιώσει όποιος μπορεί. Κανονικά δεν ήθελα να τυπώνει Αγγλικά στα μηνύματα, αλλά τα προτιμώ απ' το να γράφω Ελληνικά με λατινικούς χαρακτήρες. Μια και το φέρνει η κουβέντα, μήπως γνωρίζει κάποιος πώς θα ενεργοποιήσω στην Prolog την υποστήριξη του Unicode ;

Ιδού ο κώδικας : 

easter(Year,Day) :- A is Year mod 19, B is Year mod 4, C is Year mod 7,
                    Tmp is 19*A+16,D is Tmp mod 30, Tmp_2 is 2*B+4*C+6*D, 
                    E is Tmp_2 mod 7,
                    Day is 3 + D + E, !.
easter(Year) :- easter(Year,Day),
                Day=<30,write("In the year "),write(Year),write(" "),write("Easter will be celebrated on "),
                write("April "),write(Day),nl, !.
easter(Year) :- easter(Year,Day),
                Day>30, write("In the year "),write(Year),write(" "),write("Easter will be celebrated on "),
                D is abs(Day-30),write(" May "),write(D),nl, !.
easter(Year1,Year2) :- between(Year1,Year2,Y),easter(Y), fail.
easter(Year1,Year2) :- !.

Έτσι λοιπόν δίνοντας την εντολή easter(2020,2030) ή Prolog επιστρέφει : 

In the year 2020 Easter will be celebrated on April 19
In the year 2021 Easter will be celebrated on  May 2
In the year 2022 Easter will be celebrated on April 24
In the year 2023 Easter will be celebrated on April 16
In the year 2024 Easter will be celebrated on  May 5
In the year 2025 Easter will be celebrated on April 20
In the year 2026 Easter will be celebrated on April 12
In the year 2027 Easter will be celebrated on  May 2
In the year 2028 Easter will be celebrated on April 16
In the year 2029 Easter will be celebrated on April 8
In the year 2030 Easter will be celebrated on April 28

Ετοιμάστε λοιπόν τις μαγειρίτσες και κλείστε τα αρνιά από τώρα...!

Ευχαριστώ, να είστε καλά, 

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

Άσπρε Γάτε μας τρολαρεις νομίζω. Είναι δυνατόν εδώ μέσα να υπάρχει άνθρωπος που να ξέρει καλύτερη prolog από εσένα; Σε παρακολουθώ απο πέρυσι και με έχεις βοηθήσει αρκετά με τους κώδικες σου σε μάθημα στην σχολή. Απο την SW PROLOG που έγραφα πέρυσι δεν συνάντησα έτοιμο τέτοιο κατηγόρημα. Τώρα αν κάποια άλλη υλοποίηση το έχει δεν γνωρίζω.
By the way είχα γράψει πριν από αρκετά χρόνια ότι όταν η MySQL απόκτησε store procedures και functions την ίδια συνάρτηση και την επέκτεινα και με τις κινητές μια σταθερές εορτές (π.χ. Αγίου Θεοδώρου) με βάση την ημερομηνία του Πάσχα. 

Επεξ/σία από gian
Δημοσ.

Προς τον αγαπητό gian...

Σ' ευχαριστώ πάρα πολύ για την απάντηση.. Δεν τρολάρω, ούτε ισχυρίζομαι ότι ξέρω πολύ καλά Prolog. Άλλωστε η Prolog υπάρχει εδώ και δεκαετίες, με αποτέλεσμα η βιβλιογραφία που υπάρχει να είναι ειλικρινά τεράστια. 

Ευχαριστώ, 
Ο Άσπρος Γάτος

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

Έχω κάνει και εγώ μια συνάρτηση με διαφορετικό αλγόριθμο  http://www.eortologio.gr/arthra/paschalion.php σε js συγκρίνοντάς την με αυτή του άσπρου γάτου μου βγάζει λάθος το έτος 2021. Έχω μια υποψία ότι μπορεί να οφείλεται σε διαφορά time zone. Μπορεί κάποιος να την τρέξει και να μου πει αποτέλεσμα. 

function pasxa(etos)
{
	let e = (((etos-2)%19)*11)%30;
	let month=(e>23)?3:2;
	let day = 44 + 13 - e ;
	let tag = new Date (etos,month,day).getDay();
	day =day+7-tag; 
	return new Date(etos,month,day);
}

pasxa (2021)
>Date Sun May 09 2021 00:00:00 GMT+0200 (Central European Summer Time)

Δείχνει 9 Mai ενώ το Πάσχα είναι 2 Μαι

Επεξ/σία από k33theod
Δημοσ. (επεξεργασμένο)

Καλησπέρα ! 

Επειδή δεν ξέρω js δεν μπορώ να βρω που είναι ακριβώς το λάθος στον κώδικά σου. Πάντως θα πρέπει να εξετάσεις προσεκτικά, πρώτον τι ακριβώς δίνει ο αλγόριθμος που βρήκες εσύ και δεύτερον αν βασίζεται στο παλιό ή το νέο ημερολόγιο. 
 Όπως είπαμε, το ορθόδοξο Πάσχα είναι η πρώτη Κυριακή μετά την πρώτη εαρινή πανσέληνο. Ίσως ο αλγόριθμος που εντόπισες εσύ να δίνει την ημ/νια της 1ης εαρινής πανσελήνου και όχι αυτήν του Πάσχα. Κάτι τέτοιο μου περνάει απ' το μυαλό, χωρίς να είμαι σίγουρος φυσικά, γιατί τις αστρονομικές εξισώσεις περί του σεληνιακού κύκλου δεν τις πολυκαταλαβαίνω, για να είμαι ειλικρινής. Απλά βρήκα έναν αλγόριθμο σ' ένα βιβλίο μαθηματικών, τον έγραψα σε Prolog και διαπίστωσα ότι δουλεύει. Τώρα τον ξαναέγραψα σε C, ώστε να μπορούμε να τον τρέξουμε όλοι. 

#include <stdio.h>
void main() { 
int year=0,a=0,b=0,c=0,d=0,e=0,day=0,month=0;
do {
printf("Please enter a year between 1900 and 2099 ");scanf("%d",&year); }
while((year<1900)||(year>2099));
a=year%19;b=year%4;c=year%7;
d=(19*a+16)%30;e=(2*b+4*c+6*d)%7;
day=d+e+3;
if(day<=30) month=4;
if(day>30) { month=5; day-=30; }
if(month==4) printf("\n\nIn the year %d Easter will be celebrated on April %d",year,day);
if(month==5) printf("\n\nIn the year %d Easter will be celebrated on May %d",year,day); }
	

Να είστε καλά, 

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

Υ.Γ : Συνέχεια από τα προηγούμενα... Ο κανόνας λέει ότι "Αν η πρώτη εαρινή πανσέληνος κατά το έτος Χ πέφτει Κυριακή, τότε το Πάσχα γιορτάζεται την αμέσως επόμενη Κυριακή". Άρα η μετατροπή day = day + 7 - tag που γράφεις στο δικό σου κώδικα, μάλλον πρέπει να γίνεται αποκλειστικά και μόνο αν η προηγηθείσα συνάρτηση getday() επιστρέψει Κυριακή. Άρα την day = day + 7 - tag μάλλον (χωρίς να κόβω το λαιμό μου) θα έπρεπε να τη βάλεις μέσα σ' ένα if που να λέει "Αν η προηγούμενη getday() έδωσε Κυριακή, μόνο τότε κάνε τη μετατροπή". 

Επεξ/σία από White_Cat
Δημοσ. (επεξεργασμένο)

Απλά υποψιάζομαι λάθος στο time zone και θα ήθελα κάποιος να τρέξει τον κώδικα που έδωσα στο προηγούμενο ποστ στην consola και να μου πει τι βγαίνει στον browser στην Ελλάδα. copy paste την συνάρτηση  copy paste την εντολή όπως η εικόνα.

Ο δικός σου αλγόριθμος είναι εντάξει εδώ ειναι η υλοποιήσή του σε js

function pasxa(etos)
{
	let day = 3+ (19*(etos%19)+16)%30 + (2*(etos%4)+4*(etos%7)+6*((19*(etos%19)+16)%30))%7;
	return new Date(etos,3,day);
}

Συμπήκνωσα λίγο τις πράξεις αλλά είναι εντάξει

Untitled.png

Επεξ/σία από k33theod
Δημοσ.
21 ώρες πριν, k33theod είπε

Απλά υποψιάζομαι λάθος στο time zone και θα ήθελα κάποιος να τρέξει τον κώδικα που έδωσα στο προηγούμενο ποστ στην consola και να μου πει τι βγαίνει στον browser στην Ελλάδα. copy paste την συνάρτηση  copy paste την εντολή όπως η εικόνα.

Ο δικός σου αλγόριθμος είναι εντάξει εδώ ειναι η υλοποιήσή του σε js


function pasxa(etos)
{
	let day = 3+ (19*(etos%19)+16)%30 + (2*(etos%4)+4*(etos%7)+6*((19*(etos%19)+16)%30))%7;
	return new Date(etos,3,day);
}

Συμπήκνωσα λίγο τις πράξεις αλλά είναι εντάξει

Untitled.png

Καλησπέρα. Έτρεξα στην κονσόλα των κώδικα σου και φαίνεται σωστός. Επομένως η αρχική υπόθεση για το timezone που έκανες φαίνεται να ισχύει.

383669849_2019-10-177_34_36.png.0792a93641de9a58097f49c3f89e7cef.png

  • Like 1
Δημοσ. (επεξεργασμένο)
3 ώρες πριν, gian είπε

Καλησπέρα. Έτρεξα στην κονσόλα των κώδικα σου και φαίνεται σωστός. Επομένως η αρχική υπόθεση για το timezone που έκανες φαίνεται να ισχύει.

383669849_2019-10-177_34_36.png.0792a93641de9a58097f49c3f89e7cef.png

Αυτό το ξέρω ότι δίνει σωστό εννοούσα τον παρακάτω κώδικα 😄😄 ή αυτόν που έχω στο πρώτο ποστ είναι το ίδιο

function pasxa1(etos)
{
	let e = (((etos-2)%19)*11)%30;
	let month=(e>23)?3:2;
	let day = 57 - e ;
	day = day+7-new Date (etos,month,day).getDay(); 
	return new Date(etos,month,day);
}

 

Στις 16/10/2019 στις 3:14 ΜΜ, White_Cat είπε

Ο κανόνας λέει ότι "Αν η πρώτη εαρινή πανσέληνος κατά το έτος Χ πέφτει Κυριακή, τότε το Πάσχα γιορτάζεται την αμέσως επόμενη Κυριακή". Άρα η μετατροπή day = day + 7 - tag που γράφεις στο δικό σου κώδικα, μάλλον πρέπει να γίνεται αποκλειστικά και μόνο αν η προηγηθείσα συνάρτηση getday() επιστρέψει Κυριακή. Άρα την day = day + 7 - tag μάλλον (χωρίς να κόβω το λαιμό μου) θα έπρεπε να τη βάλεις μέσα σ' ένα if που να λέει "Αν η προηγούμενη getday() έδωσε Κυριακή, μόνο τότε κάνε τη μετατροπή". 

θα μπορούσα άλλα είναι το ίδιο, αν το tag είναι Κυριακή 0 δηλαδή προσθέτει 7 ημέρες και πάει στην επόμενη Κυριακή, αν είναι ασ πούμε Δευτέρα 1 δηλαδή προσθέτει 7-1 ημέρες και πάει στην Κυριακή κ.ο.κ οπότε δεν είναι αυτό το πρόβλημα.

Με τον αλγόριθμο αυτό https://physicsgg.me/2016/04/27/η-μαθηματική-εξίσωση-του-πάσχα/

υπάρχει πάλι το ίδιο πρόβλημα βγάζει το πάσχα του 2021 9 Απριλίου 😡

Επεξ/σία από k33theod

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

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

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

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

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

Σύνδεση

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

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