Implementazioni di algoritmi/Calcolo della Pasqua

Wikibooks, manuali e libri di testo liberi.

Programmi di calcolo della Pasqua per il calendario gregoriano secondo il metodo di Gauss, in diversi linguaggi di programmazione.

Indice

[modifica] Basic

 10 'PASQUA.BAS
 20 'Calcolo data della pasqua calendario gregoriano
 30 M$(3) = "Marzo": M$(4) = "Aprile"
 40 FOR J% = 1 TO 10: KEY J%, "": NEXT J%: KEY OFF
 60 COLOR 15,1: CLS: LOCATE 2,10: PRINT "CALCOLO DELLA DATA DELLA PASQUA NEL CALENDARIO GREGORIANO"
 70 LOCATE 12, 30: INPUT "Anno "; A%
 80 IF A% =< 1582 THEN BEEP : GOTO 60
 100 E% = A% + 3999: A# = FIX(E% * 365.25) + E% \ 400 - E% \ 100
 120 B% = A% \ 100 + 1: F% = 5 * A% \ 4 - 3 * B% \ 4 + 2
 130 B% = (11 * (A% MOD 19) + (8 * B% + 5) \ 25 + 38 - 3 * B% \ 4) MOD 30
 140 B% = 44 - B% + ((B% = 25 AND (A% MOD 19) > 10) OR B% = 24)
 150 B% = B% - 30 * (B% < 21): F% = B% + 7 - ((F% + B%) MOD 7)
 160 M% = 3 - (F% > 31): F% = F% + 31 * (F% > 31) 'mese e giorno di Pasqua
 180 LOCATE 12, 30, 0: PRINT F% M$(M%) A%
 190 LOCATE 20, 8: PRINT "Premi 'Esc' per uscire dal programma o un tasto per cambiare anno"
 200 Z$ = INKEY$: IF Z$ = "" THEN 200 ELSE ZZ$ = MID$(Z$, 2, 1): S% = ASC(Z$)
 210 IF S% = 27 THEN SYSTEM ELSE 60

[modifica] JavaScript

 var a;
 var b;
 var c;
 var Y = 2007;
 var d;
 var e;
 var M;
 var N;
 var giorno;
 var mese;
 
 if (Y < 2099)
 {
        M = 24;
        N = 5;
 }
 else if (Y < 2199)
 {
        M = 24;
        N = 6;
 }
 else if (Y < 2299)
 {
        M = 25;
        N = 0;
 }
 else if (Y < 2399)
 {
        M = 26;
        N = 1;
 }
 else if(Y < 2499)
 {
        M = 25;
        N = 1;
 }
 
 a = Y % 19;
 b = Y % 4;
 c = Y % 7;
 d = ((19*a) + M) % 30
 e = ((2*b) + (4*c) + (6*d) + N) % 7;
 
 if (d + e < 10)
 {
        giorno = d+e+22;
        mese = 3;
 }
 else{
        giorno = d+e-9;
        mese = 4;
 }
 
 if (giorno==26 && mese==4)
 {
        giorno = 19;
        mese = 4;
 }
 
 if (giorno==25 && mese==4 && d==28 && e==6 && a>10)
 {
        giorno=18;
        mese=4;
 }

[modifica] C

#include <stdio.h>
 
struct dataCal 
{
        int giorno;
        int mese;
        int anno;
};
 
struct dataCal pasqua(int anno)
{
 
        int giorno, mese;
        int a, b, c, d, e, m, n;
        struct dataCal r;
 
        switch(anno/100)
        {
                case 15:      // 1583 - 1599 (FALL THROUGH)
                case 16:      // 1600 - 1699
                        m=22; n=2;    break;
 
                case 17:      // 1700 - 1799
                        m=23; n=3; break;
 
                case 18:      // 1800 - 1899
                        m=23; n=4; break;
 
                case 19:      // 1900 - 1999 (FALL THROUGH)
                case 20:      // 2000 - 2099
                        m=24; n=5;break;
 
                case 21:      // 2100 - 2199
                        m=24; n=6; break;
 
                case 22:      // 2200 - 2299
                        m=25; n=0; break;
 
                case 23:      // 2300 - 2399
                        m=26; n=1; break;
 
                case 24:      // 2400 - 2499
                        m=25; n=1; break;
        }
 
        a=anno%19;
        b=anno%4;
        c=anno%7;
        d=(19*a+m)%30;
        e=(2*b+4*c+6*d+n)%7;
        giorno=d+e;
 
        if (d+e<10)
        {
                giorno+=22;
                mese=3;
        }
 
        else
        {
                giorno-=9;
                mese=4;
 
                if ((giorno==26)||((giorno==25)&&(d==28)&&(e==6)&&(a>10)))
                {
                        giorno-=7;
                }
        }
 
        r.giorno=giorno;
        r.mese=mese;
        r.anno=anno;
        return(r);
}
 
void main()
{
        int anno;
        struct dataCal r;
 
        for(anno=1583;anno<=2499;anno++)
        {
                r=pasqua(anno);
                printf("%02d-%02d-%d\n", r.giorno, r.mese, r.anno);   // gg-mm-aa
        }
}

[modifica] Java

 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
 
 public class Easter {
        public static class YearOutOfRangeException extends Exception {
                private static final long serialVersionUID = 5394938690797595980L;
        }
 
        public final static boolean isEaster(Date date) 
                throws YearOutOfRangeException  {
 
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
 
                int year = calendar.get(Calendar.YEAR);
                int dateYMD = year * 10000 + 
                                        calendar.get(Calendar.MONTH) * 100 +  
                                        calendar.get(Calendar.DAY_OF_MONTH);
                Date easter = find(year);
                calendar.setTime(easter);
                int easterYMD = year * 10000 + 
                                        calendar.get(Calendar.MONTH) * 100 +  
                                        calendar.get(Calendar.DAY_OF_MONTH);
                return ( easterYMD == dateYMD );
        }
 
 
        public final static Date find(int year) 
                throws YearOutOfRangeException {
 
                if ( (year < 1573) || (year > 2499) ) {
                        throw new Easter.YearOutOfRangeException();
                }
 
                int a = year % 19;
                int b = year % 4;
                int c = year % 7;
 
                int m = 0;
                int n = 0;
 
                if ( (year >= 1583) && (year <= 1699) ) { m = 22; n = 2; }
                if ( (year >= 1700) && (year <= 1799) ) { m = 23; n = 3; }
                if ( (year >= 1800) && (year <= 1899) ) { m = 23; n = 4; }
                if ( (year >= 1900) && (year <= 2099) ) { m = 24; n = 5; }
                if ( (year >= 2100) && (year <= 2199) ) { m = 24; n = 6; }
                if ( (year >= 2200) && (year <= 2299) ) { m = 25; n = 0; }
                if ( (year >= 2300) && (year <= 2399) ) { m = 26; n = 1; }
                if ( (year >= 2400) && (year <= 2499) ) { m = 25; n = 1; }
 
                int d = (19 * a + m) % 30;
                int e = (2 * b + 4 * c + 6 * d + n) % 7;   
 
                Calendar calendar = new GregorianCalendar();
                calendar.set(Calendar.YEAR , year);
 
                if ( d+e < 10 ) {
                        calendar.set(Calendar.YEAR , year);
                        calendar.set(Calendar.MONTH , Calendar.MARCH);
                        calendar.set(Calendar.DAY_OF_MONTH, d + e + 22);
                } else {
                        calendar.set(Calendar.MONTH , Calendar.APRIL);
                        int day = d+e-9;
                        if ( 26 == day ) {day = 19;}
                        if ( ( 25 == day ) && ( 28 == d) && ( e == 6 ) && ( a > 10 ) ) { day = 18; }
                        calendar.set(Calendar.DAY_OF_MONTH, day);
                }
 
                return calendar.getTime();
        }
 }

[modifica] Prolog

Questa versione è reversibile, cioè permette indifferentemente di calcolare il giorno della Pasqua dato l'anno, oppure gli anni in cui la Pasqua è caduta in un certo giorno.

 pasqua(Anno,Mese,Giorno):-
    numero(Anno,1600,2599),
    pasqua_ground(Anno,Mese,Giorno).
 
 pasqua_ground(Anno,aprile,19):- pasqua1(Anno,aprile,26,_,_,_),!.
 pasqua_ground(Anno,aprile,18):- pasqua1(Anno,aprile,25,28,6,A),
    A>10,!.
 pasqua_ground(Anno,Mese,Giorno):- pasqua1(Anno,Mese,Giorno,_,_,_).
 
 pasqua1(Anno,marzo,G,D,E,A):-
    gauss(Anno,D,E,A),
    D+E<10,
    G is (D + E + 22).
 pasqua1(Anno,aprile,G,D,E,A):-
    gauss(Anno,D,E,A),
    G is (D + E − 9).
 
 gauss(Anno,D,E,A):-
    A is Anno mod 19,
    B is Anno mod 4,
    C is Anno mod 7,
    S is fix(Anno/100),
    mn(S,M,N),
    D is (19*A+M) mod 30,
    E is (2*B+4*C+6*D+N) mod 7.
 
 numero(_,Min,Max):- Min>Max,!,fail.
 numero(X,X,_).
 numero(X,Min,Max):- Min1 is Min+1, numero(X,Min1,Max). 
 
 mn(16,22,2).  
 mn(17,23,3).  
 mn(18,23,4).
 mn(19,24,5).
 mn(20,24,5).
 mn(21,24,6).
 mn(22,25,0).
 mn(23,26,1).
 mn(24,25,1).

[modifica] Delphi

unit UPasqua;
 
interface
 
uses SysUtils;
 
function Pasqua(anno : Word) : TDateTime;
 
implementation
 
function Pasqua(anno : Word) : TDateTime;
var
  M, N : Word;
  a, b, c, d, e : Word;
  mese, giorno : Word;
begin
  if not (anno in [1583..2499]) then begin
     MessageBox(0, PChar(L + #39 + anno deve essere maggiore di 1582 ed inferiore di 2500),
                Errore, MB_OK or MB_ICONERROR);
     Result := Now;
     Exit;
  end;
 
  case anno of
    1583..1699 : begin M := 22; N := 2; end;
    1700..1799 : begin M := 23; N := 3; end;
    1800..1899 : begin M := 23; N := 4; end;
    1900..2099 : begin M := 24; N := 5; end;
    2100..2199 : begin M := 24; N := 6; end;
    2200..2299 : begin M := 25; N := 0; end;
    2300..2399 : begin M := 26; N := 1; end;
    2400..2499 : begin M := 25; N := 1; end;
    else begin M := 0; N := 0; end;
  end;
  a := anno mod 19;
  b := anno mod 4;
  c := anno mod 7;
 
  d := (19 * a + M) mod 30;
  e := (2 * b + 4 * c + 6 * d + N) mod 7;
 
  if d + e < 10 then begin
     mese := 3;
     giorno := d + e + 22;
  end
  else begin
     mese := 4;
     giorno := d + e - 9;
   end;
    if ((giorno = 26) and (mese = 4)) or
     ((giorno = 25) and (mese = 4) and (d = 28) and (e = 6) and (a > 10)) then
     Dec(giorno, 7);
    Result := EncodeDate(anno, mese, giorno);
 end;
 
end.

[modifica] SQL

  declare a decimal;
  declare b decimal;
  declare c decimal;
  declare d decimal;
  declare e decimal;
  declare M decimal;
  declare N decimal;
  declare giorno decimal;
  declare mese decimal;
  IF (Y < 2099) then
        SET M = 24;
        SET N = 5;
  elseif (Y < 2199) then
       SET M = 24;
       SET  N = 6;
  elseif (Y < 2299) then
        SET M = 25;
        SET N = 0;
  elseif (Y < 2399) then
        SET M = 26;
        SET N = 1;
  elseif (Y < 2499) then
        SET M = 25;
        SET N = 1;
  end IF;
  SET a = mod(Y,19);
  SET b = mod(Y,4);
  SET c = mod(Y,7);
  SET d = mod( ((19*a) + M) , 30);
  SET e = mod( ((2*b) + (4*c) + (6*d) + N) , 7);
  IF ((d + e) < 10) then
       SET giorno = d+e+22;
       SET mese = 3;
  else
       SET giorno = d+e-9;
       SET mese = 4;
  end IF;
  IF (giorno=26 AND mese=4) then
       SET giorno = 19;
       SET mese = 4;
  end IF;
  IF (giorno=25 AND mese=4 AND d=28 AND e=6 AND a>10) then
        SET giorno=18;
        SET mese=4;
  end IF;

[modifica] PHP

 function DataPasqua ($Y) 
 
 // LA DATA IN INGRESSO DEVE ESSERE IN FORMATO YYYY
 
 if ($Y<1583) { 
        return -1; ''// ANNO NON SUPPORTATO''
 }
 elseif ($Y<=1699) { 
        $M=22;
        $N=2;
 }
 elseif ($Y<=1799) {
        $M=23;
        $N=3;
 }
 elseif ($Y<=1899) {
        $M=23;
        $N=4;
 }
 elseif ($Y<=2099) { 
        $M=24;
        $N=5;
 }
 elseif ($Y<=2199) {
        $M=24;
        $N=6;
 }
 elseif ($Y<=2299) {
        $M=25;
        $N=0;
 }
 elseif ($Y<=2399) {
        $M=26;
        $N=1;
 }
 elseif ($Y<=2499) {
        $M=25;
        $N=1;
 }
 else {
        return -1; ''// ANNO NON SUPPORTATO''
 }
 
 
 // APPLICO L'ALGORITMO PER IL CALCOLO DELLA DATA DI PASQUA
 
 $a = ($Y)%19;
 $b = ($Y)%4;
 $c = ($Y)%7;
 $d = ((19*($a))+$M)%30;
 $e = ((2*($b)) + (4*($c)) + (6*($d)) + $N)%7;
 
 if (($d + $e) < 10) {
        $giorno = $d+$e+22;
        $mese = 3;
 }
 else {
        $giorno = $d+$e-9;
        $mese = 4;
 } 
 
 // ECCEZIONI
 
 if (($giorno == 26) && ($mese == 4)) {
        $giorno = 19;
        $mese = 4;
 }
 
 if (($giorno == 25) && ($mese == 4) && ($d == 28) && ($e == 6) && ($a>10)) {
        $giorno = 18;
        $mese = 4;
 }
 
 // LA FUNZIONE RESTITUISCE LA DATA IN FORMATO GGMMYYYY
 
 $ris = "";
 if ($giorno<10) $ris="0";
 $ris = $ris .$giorno."0".$mese.$Y;
 
 return $ris;
 
 }

[modifica] Altri progetti

Strumenti personali