[ dalmasica @ 04.11.2009. 15:56 ] @
Napisite program koji ce ucitati jedan datum (3 prirodna broja, redom dan, mjesec i godina) i prirodni broj n, te ispisati
datum koji slijedi n dana nakon ucitanog datuma.
Napomene: Datumi ce bit iz segmenta od 1.1.1950. (nedjelja) do 31.12.2050. Treba pripaziti da je ucitani datum postojeci,
a u protivnom vratiti poruku “Greska!”. Svaka cetvrta godina je prijestupna (npr. jedna od takvih je i 2008), sto znaci da
veljaca tada ima 29, a ne 28 dana. Sijecanj, ozujak, svibanj, srpanj, kolovoz, listopad i prosinac imaju po 31 dan, a ostali
mjeseci, osim veljace, po 30 dana.
Ispis treba biti u formatu “d.m.g.”. Na primjer, ako su uˇcitani brojevi 14, 3, 2008 i 1, program treba ispisati “15.3.2008.”
(bez navodnika).
[ Mihajlo Cvetanović @ 04.11.2009. 16:30 ] @
Zadatak se najelegantnije rešava tako što se naprave funkcije koje pretvaraju datum u broj dana od početnog datuma (1. januar 1.), kao i inverzna koja pretvara broj dana u datum. Kada imamo broj dana od početnog datuma onda je dodavanje i oduzimanje dana prosto sabiranje i oduzimanje. Svaki drugi pristup je komplikovaniji.

Evo na prvu loptu, pretraga u Guglu nudi sledeće: http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html

Tu je dato čak i kako proveriti da li je neki datum ispravan. Ako je upotrebom obe funkcije izlazni datum istovetan ulaznom onda je datum ispravan.
[ proka_92 @ 13.11.2009. 02:23 ] @
Ili oni algoritmi nisu dobri, ili ih ja nisam lepo srocio za C...
[ Mihajlo Cvetanović @ 13.11.2009. 09:42 ] @
Stavi ovde to što si sročio, ne zaboravi [code ] tagove, pa da vidimo...
[ dalmasica @ 13.11.2009. 22:49 ] @
ovo mi se i ne čini baš lijepo riješenje, ako netko zna malo bolje i ljepše, bila bih vam zahvalana!!
[ proka_92 @ 15.11.2009. 16:58 ] @
Evo ja sam odradio ovako, i izbacuje neki nebulozan datum...
Code:

#include<stdio.h>
int g(y,m,d){
    m = (m + 9) % 12;
    y = y - m/10;
    return 365*y + y/4 - y/100 + y/400 + (m*306 + 5)/10 + d - 1; }
int d(int g,int *y,int *mm,int *dd){
    int ddd,mi;
    (*y) = (10000*g + 14780)/3652425;
    ddd = g - (365*(*y) + (*y)/4 - (*y)/100 + (*y)/400);
    if (dd < 0){
     (*y) = (*y) - 1;
     ddd = g - (365*(*y) + (*y)/4 - (*y)/100 + (*y)/400);}
    mi = (100*ddd + 52)/3060;
    (*mm) = (mi + 2)%12 + 1;
    (*y) = (*y) + (mi + 2)/12;
    (*dd) = ddd - (mi*306 + 5)/10 + 1; }
void unos(int *y,int *m,int *d){
    printf("Unesi dan:");
    scanf("%d",&*d);
    printf("Unesi mesec:");
    scanf("%d",&*m);
    printf("Unesi godinu:");
    scanf("%d",&*y);}
main(){
    int y,m,d,n,y1,m1,d1;
    unos(&y,&m,&d);
    printf("Unesi broj dana:");
    scanf("%d",&n);
    d(g(y,m,d)+n,&y1,&m1,&d1);
    printf("%d %d %d",d1,m1,y1);
    getchar();getchar();
[ Mihajlo Cvetanović @ 15.11.2009. 18:23 ] @
Neće da mi kompajlira jer ima greške.

1. Izostavio si tipove argumenata funkcije d (pretpostavljam int)
2. Izostavio si return na kraju funkcije d (pretpostavljam da funkcija zapravo nema povratnu vrednost)
3. Izostavio si povratnu vrednost funkcije main (ovo jeste int)
4. Imaš promenljivu d u funkciji main koja sakriva funkciju d, jedno od ta dva mora da se preimenuje.

Kako je to tebi uopšte prolazilo?

Inače, otkrio sam posle debagovanja zašto neće da radi. 32-bitni int nije dovoljno veliki da primi rezultat 10000*g+14780 i dolazi do prelivanja bitova i pogrešnog rezultata. Umesto 10000 stavi 10000I64 (tako je kod VC++, a za druge kompajlere ne znam). To će naterati kompajler da na tom mestu operiše 64-bitnim integerima.
[ proka_92 @ 16.11.2009. 20:14 ] @
Citat:


1. Izostavio si tipove argumenata funkcije d (pretpostavljam int)

Ovde ne znam o cemu pricas, koliko vidim ima argumente...
Citat:


2. Izostavio si return na kraju funkcije d (pretpostavljam da funkcija zapravo nema povratnu vrednost)

Pa po onom sajtu treba da vraca vise vrednosti, u C-u je to nemoguce, tako da sam preko pokazivaca vratio te vrednosti...
Citat:


3. Izostavio si povratnu vrednost funkcije main (ovo jeste int)

Ako mislis na
Code:
return 0;
, nama u skoli nikada nije pomenuto da to treba da stavljamo, ako bi mogao da mi objasnis zasto treba da se stavlja...
Citat:


4. Imaš promenljivu d u funkciji main koja sakriva funkciju d, jedno od ta dva mora da se preimenuje.

Preimenovao...
Citat:

Umesto 10000 stavi 10000I64

Koristim Ubuntu, gedit(text editor), tako da koliko vidim to ne moze da se izvede...


[Ovu poruku je menjao proka_92 dana 16.11.2009. u 23:35 GMT+1]
[ Mihajlo Cvetanović @ 17.11.2009. 07:08 ] @
Pokledaj onda na internetu kako se pišu 64-bitni literali za GCC. Mora da postoji. Možda broj može da se kastuje u long long, ili nešto slično.

Uzgred za prvu tačku mislio sam da umesto "int g(y,m,d)" stoji "int g(int y, int m, int d)", a za drugu tačku umesto "int d(...)" da stoji "void d(...)". Treća tačka proističe iz standarda, main mora da vraća int, i mora da ima ili nula parametara, ili dva (int argc, const char* argv[]).
[ Picsel @ 17.11.2009. 08:40 ] @
Za long long stavi 10000ll (dva slova L)
[ proka_92 @ 17.11.2009. 17:59 ] @
Hvala na pomoci i sugestijama... Koliko vidim ovaj kod radi:
Code:
#include<stdio.h>
int g(int y,int m,int d){
    m = (m + 9) % 12;
    y = y - m/10;
    return 365*y + y/4 - y/100 + y/400 + (m*306 + 5)/10 + d - 1; }
void k(int g,int *y,int *mm,int *dd){
    int ddd,mi;
    (*y) = (10000ll*g + 14780)/3652425;
    ddd = g - (365*(*y) + (*y)/4 - (*y)/100 + (*y)/400);
    if (dd < 0){
     (*y) = (*y) - 1;
     ddd = g - (365*(*y) + (*y)/4 - (*y)/100 + (*y)/400);}
    mi = (100*ddd + 52)/3060;
    (*mm) = (mi + 2)%12 + 1;
    (*y) = (*y) + (mi + 2)/12;
    (*dd) = ddd - (mi*306 + 5)/10 + 1; }
void unos(int *y,int *m,int *d){
    printf("Unesi dan:");
    scanf("%d",&*d);
    printf("Unesi mesec:");
    scanf("%d",&*m);
    printf("Unesi godinu:");
    scanf("%d",&*y);}
main(){
    int y,m,d,n,y1,m1,d1;
    unos(&y,&m,&d);
    printf("Unesi broj dana:");
    scanf("%d",&n);
    k(g(y,m,d)+n,&y1,&m1,&d1);
    printf("\n%d %d %d",d1,m1,y1);
    getchar();getchar();
    return 0;}

EDIT:
Ne radi lepo za prestupne godine, za 25.2.2000. posle 4 dana izbaci 0.3.2000.

[Ovu poruku je menjao proka_92 dana 17.11.2009. u 19:41 GMT+1]
[ idb @ 18.11.2009. 15:21 ] @
Da li si razmisljao da koristis "C Time Library" (time.h), ili to zadatkom nije dozvoljeno?
[ proka_92 @ 19.11.2009. 12:28 ] @
Nije dozvoljeno...
[ tkaranovic @ 19.11.2009. 15:22 ] @
Ovde izgleda nije niko čuo za računare i Dejana Ristanovića :)

Na ovoj adrsi ima pascal kod koji se može prevesti:

O kalendaru...


[ dalmasica @ 22.11.2009. 15:25 ] @
Napiˇsite program koji ´ce uˇcitati dva datuma (svaki se sastoji od po 3 prirodna broja, redom dan, mjesec i godina), te ispisati
koliko razliˇcitih dana ima u segmentu izmedu ta dva datuma (ukljuˇcivo i njih).
Napomene: Datumi ce bit iz segmenta od 1.1.1950. (nedjelja) do 31.12.2050. Treba pripaziti da je uˇcitani datum postoje´ci,
a u protivnom vratiti poruku “Greska!”. Svaka ˇcetvrta godina je prijestupna (npr. jedna od takvih je i 2008), ˇsto znaci da
veljaˇca tada ima 29, a ne 28 dana. Sijeˇcanj, oˇzujak, svibanj, srpanj, kolovoz, listopad i prosinac imaju po 31 dan, a ostali
mjeseci, osim veljaˇce, po 30 dana.
Datum ispiˇsite u formatu “d.m.g.”.

Kako da usporedim datume??

Napiˇsite program koji ´ce uˇcitati tri datuma (svaki se sastoji od po 3 prirodna broja, redom dan, mjesec i godina), te ispisati
datum kojem je dan preuzet iz najranijeg datuma, mjesec iz srednjeg datuma, a godina iz najkasnijeg.
Napomene: Datumi ce bit iz segmenta od 1.1.1950. (nedjelja) do 31.12.2050. Treba pripaziti da je uˇcitani datum postoje´ci,
a u protivnom vratiti poruku “Greska!”. Svaka ˇcetvrta godina je prijestupna (npr. jedna od takvih je i 2008), ˇsto znaci da
veljaˇca tada ima 29, a ne 28 dana. Sijeˇcanj, oˇzujak, svibanj, srpanj, kolovoz, listopad i prosinac imaju po 31 dan, a ostali
mjeseci, osim veljaˇce, po 30 dana.
Datum ispiˇsite u formatu “d.m.g.”.

Ako tko riješi, nek mi napiše kod!!!


Unaprijed HVALA!