Forums: » Register « |  Free Tools |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support |

New Free Tools on Dev Shed!

#1
September 15th, 2003, 12:53 PM
 murugesan
Dinesh_P_V

Join Date: Aug 2003
Location: India
Posts: 259
Time spent in forums: 12 h 1 m 3 sec
Reputation Power: 0
Just a puzzle- to find day, given the date

How can we find a day of any date just using three variables.
For example if the date(15th september 2003) is
15 9 2003
then output should be
Monday
The condition is that total number of variables used in the whole program must be only 3 variables.
Hope Dinesh will solve this.

-Murugesan

#2
September 15th, 2003, 01:23 PM
 ClayDowling
Contributing User

Join Date: Oct 2002
Location: Flint, MI
Posts: 328
Time spent in forums: 1 h 19 m 25 sec
Reputation Power: 12
Challenge accepted:

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{

char date[12];
time_t today_t;
struct tm* today;

printf("Enter your date in this form: mm/dd/yyyy: ");
scanf("%11s", date);

today = (struct tm*)calloc(1, sizeof(struct tm));
sscanf(date, "%2d/%2d/%4d", &today->tm_mon, &today->tm_mday, &today->tm_year);
today->tm_mon--;

if (today->tm_year > 37 && today->tm_year < 70) {
printf("You're effed, mate.  That's negative dates, and it breaks things.\n");
return EXIT_FAILURE;
}

if (today->tm_year < 38) today->tm_year += 100;
if (today->tm_year > 1900) today->tm_year -= 1900;
today_t = mktime(today);
today = localtime(&today_t);

printf("%2.2d/%2.2d/%4.4d is a ", today->tm_mon + 1, today->tm_mday, today->tm_year + 1900);
switch(today->tm_wday) {
case 0:
printf("Sunday");
break;
case 1:
printf("Monday");
break;
case 2:
printf("Tuesday");
break;
case 3:
printf("Wednesday");
break;
case 4:
printf("Thursday");
break;
case 5:
printf("Friday");
break;
case 6:
printf("Saturday");
break;
}
printf("\n");

system("PAUSE");
return 0;
}```

The one proviso is that it doesn't work well for any date before 1970, or after 2037 on a 32 bit machine. Since it's currently impossible to have a "today" prior to 1970, and I intend to upgrade to a 64 bit machine by 2037, it's okay.
__________________
Clay Dowling
Lazarus Notes
Articles and commentary on web development
http://www.lazarusid.com/notes/

#3
September 15th, 2003, 01:36 PM
 murugesan
Dinesh_P_V

Join Date: Aug 2003
Location: India
Posts: 259
Time spent in forums: 12 h 1 m 3 sec
Reputation Power: 0
Great ClayDowling. You did it. Hats off.
Can we have it using three variables without involving arrays, structures.....
This is because
we can have many variables like
char var1[1000];
int var2[2000];
struct mystruct ms[300];
This too involve three variable
But what I need is that just three variables of basic type which does not involve any complex data type.
Just three variables not even using structures. (not structures means)
we can have three structure variables such as
struct mystruct1 ms1;
struct mystruct2 ms2;
struct mystruct3 ms3;
under each structure we can have
struct mystruct1
{
int arr[1000];
char arr1[200];
..............
}
This is not the case I need.
Really great program from you. Expecting next answer from you.
-Murugesan

#4
September 15th, 2003, 03:08 PM
 Scorpions4ever
Banned ;)

Join Date: Nov 2001
Location: Woodland Hills, Los Angeles County, California, USA
Posts: 9,536
Time spent in forums: 2 Months 3 Days 6 h 44 m 56 sec
Reputation Power: 4106
The following code will work for FreeBSD and only uses 2 variables. It won't work on other *NIX systems (I tried Linux and OpenBSD), because the date command on these systems doesn't support the -j option. You can modify to work for other *NIX systems by using two shell commands instead:
1. Run a shell command to set the date to the date entered the user
2. Run a shell command to display the current date (date "+%A")

The disadvantage of the above approach is that the date is set to the date entered by the user (and you need root privs). You could always record the current date first to correct that  If you're wondering, the -j option on FreeBSD tells date to read the date, but not set it, which is why one shell command does the trick on FreeBSD[/edit]
Code:
```#include <stdio.h>
#include <stdlib.h>

int main(void) {
char *ptr, *ptr2;

if ((ptr = (char *)malloc(100 * sizeof(char))) == NULL) {
fprintf(stderr, "Fatal error. Could not malloc memory for ptr.\n");
return 1;
}
if ((ptr2 = (char *)malloc(100 * sizeof(char))) == NULL) {
fprintf(stderr, "Fatal error. Could not malloc memory for ptr2.\n");
return 1;
}

printf("Enter a date in MM/DD/YYYY format: ");
scanf("%s", ptr);
sprintf(ptr2, "date -j -f \"%%m/%%d/%%Y\" \"%s\" \"+%%A\"", ptr);
system(ptr2);
free(ptr);
free(ptr2);

return 0;
};```
__________________
Up the Irons
What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
"Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
Down with Sharon Osbourne

Last edited by Scorpions4ever : September 15th, 2003 at 03:35 PM.

#5
September 15th, 2003, 07:03 PM
 clifford
Contributing User

Join Date: Aug 2003
Location: UK
Posts: 4,967
Time spent in forums: 1 Month 4 Days 3 h 48 m 59 sec
Reputation Power: 1801
Here is a function that takes day, month, and year as parameters, and returns a value 0(Sunday) to 7(Saturday). It uses no other variables, neither does it use any time/date library functions. In fact it uses no library code at all. It does modify the value of day, to use it for another purpose - "days since start of year", which in my opinion is bad coding practice, but hey! I've used some macros and #defines to make the code more readable.

PHP Code:
``` /* Macro to determine if year is leam    */ #define IS_LEAP( y )    ((((y) % 4) == 0) && (((y) % 100) != 0) || (((y) % 1000) == 0)) /* Days to the end of each month (December not needed) */ #define END_OF_JAN  31 #define END_OF_FEB  (END_OF_JAN + 28)   /* Leap is accounted for in code */ #define END_OF_MAR  (END_OF_FEB + 31)   #define END_OF_APR  (END_OF_MAR + 30) #define END_OF_MAY  (END_OF_APR + 31) #define END_OF_JUN  (END_OF_MAY + 30) #define END_OF_JUL  (END_OF_JUN + 31) #define END_OF_AUG  (END_OF_JUL + 31) #define END_OF_SEP  (END_OF_AUG + 30) #define END_OF_OCT  (END_OF_SEP + 31) #define END_OF_NOV  (END_OF_OCT + 30) /* Month values (to make switch readable)   */ #define JAN     1 #define FEB     2 #define MAR     3 #define APR     4 #define MAY     5 #define JUN     6 #define JUL     7 #define AUG     8 #define SEP     9 #define OCT     10 #define NOV     11 #define DEC     12 /* Returns 0 (Sunday) to 6 (Saturday)   */ int day_of_week( int day, int month, int year ) {     /* Convert day of month to day of year  */     switch( month )     {         /* nothing need be done for January */         case FEB : day += END_OF_JAN ;             break;         case MAR : day += END_OF_FEB ;             break;         case APR : day += END_OF_MAR ;             break;         case MAY : day += END_OF_APR ;             break;         case JUN : day += END_OF_MAY ;             break;         case JUL : day += END_OF_JUN ;             break;         case AUG : day += END_OF_JUL ;             break;         case SEP : day += END_OF_AUG ;             break;         case OCT : day += END_OF_SEP ;             break;         case NOV : day += END_OF_OCT ;             break;         case DEC : day += END_OF_NOV ;             break;     }          /* Account for leap years */     if( IS_LEAP( year ) && month > FEB )     {         day++ ;     }     return(( (year - 1) + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400) + day ) % 7 ) ; }  ```

To demonstrate the code working, I used the following code. This only declares the variables for the parameters passed to day_of_week(), so you could do all this in one function with the user input and text output, but I felt that a separate function was more useful, and easier to understand separated from the user interface.
PHP Code:
```  int main() {     int day ;     int month ;     int year ;          printf( "\nDate: dd mm yyy : " ) ;     scanf( "%d %d %d", &day, &month, &year ) ;          switch( day_of_week( day, month, year ) )     {         case 0: printf( "Sunday" ) ;             break ;         case 1: printf( "Monday" ) ;             break ;         case 2: printf( "Tuesday" ) ;             break ;         case 3: printf( "Wednesday" ) ;             break ;         case 4: printf( "Thursday" ) ;             break ;         case 5: printf( "Friday" ) ;             break ;         case 6: printf( "Saturday" ) ;             break ;     } }  ```

In all fairness, thanks go to http://css.engineering.uiowa.edu/~e...ofweekcalc.html for the calendrical formula bit.

Clifford.

#6
September 15th, 2003, 07:16 PM
 Scorpions4ever
Banned ;)

Join Date: Nov 2001
Location: Woodland Hills, Los Angeles County, California, USA
Posts: 9,536
Time spent in forums: 2 Months 3 Days 6 h 44 m 56 sec
Reputation Power: 4106
Nice! I was thinking of the day counting approach myself, but was too lazy to google for a fixed known date to offset the day with
Oddly enough, the approach I took was similar, except that I used #define for each month rather than a sum of days and removed the breaks from my switch statement.
Code:
```#define JAN 31
#define FEB 28
#define MAR 31
...
#define DEC 31

switch (month) {
case 12:
day += NOV;
case 11:
day += OCT;
....
}```

Notice the absence of break statements in the switch. I was using the default fallthrough of the switch statement to add days
[/edit]

Last edited by Scorpions4ever : September 15th, 2003 at 07:27 PM.

#7
September 16th, 2003, 03:59 AM
 clifford
Contributing User

Join Date: Aug 2003
Location: UK
Posts: 4,967
Time spent in forums: 1 Month 4 Days 3 h 48 m 59 sec
Reputation Power: 1801
The fall through case occurred to me also, but I could not bring myself to do something so against my professional coding standards, even for a game! However, in this case it would probably have been less error prone! All those defines took too much thinking about that late at night! (GMT).

#8
September 16th, 2003, 12:41 PM
 murugesan
Dinesh_P_V

Join Date: Aug 2003
Location: India
Posts: 259
Time spent in forums: 12 h 1 m 3 sec
Reputation Power: 0
Thanks for that much replies

Hello friends,
Thanks for that much much replies. On my part (violating coding styles )

Code:
```#include <stdio.h>
int main()
{
int day,month,y;
while(1)
{
printf("\nEnter date : ");
scanf("%d%d%d",&day,&month,&y);
if(day==0)
return 0;
if((y%400==0||y%4==0&&y%100!=0)&&month>2)
day+=1;
y--;
y%=400;
day=day+((y/100)*5+(y%100)/4+y%100)%7;
if(month>2)
day-=2;
for(month--;month>0;month--)
if(month/8==0&&month%2!=0||month/8!=0&&month%2==0)
day+=3;
else
day+=2;
day%=7;
switch(day)
{
case 0:
printf("\nSUNDAY");
break;
case 1:
printf("\nMONDAY");
break;
case 2:
printf("\nTUESDAY");
break;
case 3:
printf("\nWEDNESDAY");
break;
case 4:
printf("\nTHURSDAY");
break;
case 5:
printf("\nFRIDAY");
break;
case 6:
printf("\nSATURDAY");
break;
}
}//end of while
}```

-Murugesan

Last edited by murugesan : October 20th, 2004 at 01:38 AM.

 Viewing: Dev Shed Forums > Programming Languages > C Programming > Just a puzzle- to find day, given the date