Wieczny kalendarz

0

Witam!!!
Poszukuję algorytmy zapisanego w pseidokodzie(lub pascalu) wiecznego kalndarza. Program mialby dzialac w ten sposób iż podajemy dzien miesiąc i rok a on nam ma wyswietlic jaki to dzień tygodnia.
z góry dziekuje i pozdrawiam

0

data = rok, m, d
przszerabiamy to na liczbę dni (licząc np od 1600r - wcześniej był inny kalendarz...)

n = dni(rom,m,d)

dzień_tygodnia = n mod 7;

0

wlasnie wczoraj dostalismy takie zadanie na Algorytmach i Strukturach danych :>
dziwny zbieg okolicznosci ;)

0

Wiem ze powinien korzytac z algorytmu Zellera. Tylko o co w nim chodzi jak go tu zasotowac :/

oto algorytm:

M := 1 + (Month + 9) mod 12 ; if M>10 then Dec(Year) ;
C := Year div 100 ; D := Year mod 100 ;
N := ((13M-1) div 5 + D + D div 4 + C div 4 + 5C + 1) mod 7 ; ?
N := ((13M-1) div 5 + D + D div 4 + C div 4 + 5C) mod 7 ; ?

0

www.pliki.orge.pl/Kalendarz.exe

Kiedys, bardzo dawno, pisalem cos takiego :> Moge poszukac kodu, ale uprzedzam ze to bylo w C++ pisane :>

P.S to chyba nie jest takie trudne, zeby umieszczac to w tym dziale? :>

0

Othello byłbym Ci bardzo wdzięczny gdybys kod udostępnił.

0

na wiki macie bardzo zoptymalizowany wzorek w C:

    int dzien,d,m,y;
    scanf("%d %d %d", &d, &m, &y);
    dzien=(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;
    printf("%d",dzien);

chociaż ja to jakoś "normalniej" zrobie, żeby nie było, że tylko kod skopiowałem.

aha... wczesniej napisałem:

TeWuX napisał(a)

wlasnie wczoraj dostalismy takie zadanie na Algorytmach i Strukturach danych

Chodziło mi o przedmiot Programowanie C/C++... jakby to kogoś interesowało :P

//dop.
Jak ktoś potrzebuje, jak ja na zajęcia, prostego, niezoptymalizowanego algorytmu, to tu coś na naskrobałem w C:

int Przestepny(int rok)
{
    if ( ((rok%4)==0) && ((rok%100)!=0) || ((rok%400)==0) ) return 1;
      else return 0;
}

int DzienTyg2(int d, int m, int y)
{
    int i;
    int x=0;
    for (i=1; i<y; i++)
        x += (7*31 + 4*30 + 28 + Przestepny(i))%7;
    for (i=1; i<m; i++)
    {
        if (i==2) x += 28 + Przestepny(y);
        else
        if (i<=7) x += 30 + (i%2);
        else x+= 31 - (i%2);
    }
    return (x+d)%7; 
}

powinno działać ;P

0

wielkie dzieki za funkcje: )
można jeszcze Cie prosić o wyjaśnienie co w danym momencie algorytm wykonuje i dokładnie jak działa
jeszcze raz wielkie dzieki

0
// sprawdza czy rok jest przestepny, według kalendarza gregoriańskiego, czyli:
// rok jest przestępny jeśli jest podzielny przez 4 z wyjątkiem lat podzielnych przez 
// 100, chyba że jest podzielny przez 400 :)
int Przestepny(int rok)
{
    if ( ((rok%4)==0) && ((rok%100)!=0) || ((rok%400)==0) ) return 1;
      else return 0;
}
// d-day, m-month, y-year
int DzienTyg2(int d, int m, int y)
{
    int i;
    int x=0;
    // liczy dni w latach od 1 roku do roku y-1
    // i bierze reszte z dzielenia przez 7
    for (i=1; i<y; i++)
        x += (7*31 + 4*30 + 28 + Przestepny(i))%7;
    // zlicza dni w miesiacach w roku y, od stycznia do mieciąca m-1
    for (i=1; i<m; i++)
    {
        // jesli luty to licz 28 dni, jesli rok przestepny to dodaj 1
        if (i==2) x += 28 + Przestepny(y);
        else
    // w 7 i 8 miesiac mają po 31 dni
    // wiec trzeba bylo zrobić odpowiednie założenia
        if (i<=7) x += 30 + (i%2);
        else x+= 31 - (i%2);
    }
    // do uzyskanej wartosci dodaje dni d i daje modulo 7
    return (x+d)%7;
}

i teraz wartosc 0 to niedziela, a od 1 do 6 masz od pon. do soboty.

to jest taki przykład "brute-force", u kilku kolesi z roku widziałem troche dłuższe algorytmy (znaczy więcej linijek kodu) , ale nie korzystające z pętli.

0
dzien=(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;

Jesli to dziala to jestem pod wrazeniem [diabel]

0
othello napisał(a)
dzien=(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;

Jesli to dziala to jestem pod wrazeniem [diabel]

działa, działa... http://pl.wikipedia.org/wiki/Kalendarz_wieczny
na jego podstawie sprawdzałem czy mój algorytm działa.

0

int Przestepny(int rok)
{
if ( ((rok%4)==0) && ((rok%100)!=0) || ((rok%400)==0) ) return 1;
else return 0;
}

int DzienTyg2(int d, int m, int y)
{
int i;
int x=0;
for (i=1; i<y; i++)
x += (731 + 430 + 28 + Przestepny(i))%7;
for (i=1; i<m; i++)
{
if (i==2) x += 28 + Przestepny(y);
else
if (i<=7) x += 30 + (i%2);
else x+= 31 - (i%2);
}
return (x+d)%7;
}

A CO ZE ZLOZONOSCIA OBLICZENIOWA????

0

Złożoność obliczeniowa, jest liniowa... O(n), gdzie n = y+m.

No może mistrzostwo świata to to nie jest, już wspominałem, że to jest mój własny algorytm, zrobiony najprostszym sposobem.
Jakby mi zależało na szybkości to bym wziął ten wzór z wikipedii. :P

0

Witam
A mógłby ktoś rozpisać ten program w pascalu? :> , bo ja na informatyce dostałęm właśnie takie zadanie, a że z c++ niebyt rozumiem założenie programu, to mam ogromny problem. z góry thx :-)

0
// 0 - niedziela, 1 - poniedziałek, 6 - sobota
function dtyg(d, m, r: integer): integer;
var
  w: integer;
begin
  if m>2 then m := m-2 else
  begin
    m := m+10;
    r := r-1;
  end;
  w := r div 100;
  r := r mod 100;
  dtyg := (d + (13*m-1) div 5 + r  + r div 4 + w div 4 + 5*w) mod 7;
end;

Pamiętaj, że w 1582 wprowadzono kalendarz gregoriański, czyli do tej daty są prawidłowe wyniki.

0

aha, to fajnie, a po tej dacie to co muszę zrobić, żeby podawane wyniki były prawidłowe?

0

Brac pod uwage kalendarz julianski, a wczesniej jakis inny (bez przesuniec i cudow o ile pamietam).

0

a czy potrafilibyście napisać ten program w asamblerze???

0

Tak, jeśli chodzi o język asemblera x86 lub ARM.

Zapoznaj się z opcją "nowy temat", ten ma ponad dwa lata, musiałeś głęboko grzebać, żeby to wykopać...

1 użytkowników online, w tym zalogowanych: 0, gości: 1