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
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;
wlasnie wczoraj dostalismy takie zadanie na Algorytmach i Strukturach danych :>
dziwny zbieg okolicznosci ;)
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 ; ?
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? :>
Othello byłbym Ci bardzo wdzięczny gdybys kod udostępnił.
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
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
// 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.
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]
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.
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????
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
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 - 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.
aha, to fajnie, a po tej dacie to co muszę zrobić, żeby podawane wyniki były prawidłowe?
Brac pod uwage kalendarz julianski, a wczesniej jakis inny (bez przesuniec i cudow o ile pamietam).
a czy potrafilibyście napisać ten program w asamblerze???
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ć...
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.