#1
  1. No Profile Picture
    Dinesh_P_V
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    India
    Posts
    259
    Rep 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. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2002
    Location
    Flint, MI
    Posts
    328
    Rep Power
    13
    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/
  4. #3
  5. No Profile Picture
    Dinesh_P_V
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    India
    Posts
    259
    Rep 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
  6. #4
  7. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,643
    Rep Power
    4248
    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 :) [edit] 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;
    };
    Last edited by Scorpions4ever; September 15th, 2003 at 03:35 PM.
    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

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  8. #5
  9. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,117
    Rep Power
    1803
    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_weekint dayint monthint 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_LEAPyear ) && month FEB )
        {
            
    day++ ;
        }

        return(( (
    year 1) + ((year 1) / 4) - ((year 1) / 100) + ((year 1) / 400) + day ) % ) ;

    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_weekdaymonthyear ) )
        {
            case 
    0printf"Sunday" ) ;
                break ;
            case 
    1printf"Monday" ) ;
                break ;
            case 
    2printf"Tuesday" ) ;
                break ;
            case 
    3printf"Wednesday" ) ;
                break ;
            case 
    4printf"Thursday" ) ;
                break ;
            case 
    5printf"Friday" ) ;
                break ;
            case 
    6printf"Saturday" ) ;
                break ;
        }

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

    Clifford.
  10. #6
  11. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,643
    Rep Power
    4248
    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 :)
    [edit]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.
    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

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  12. #7
  13. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,117
    Rep Power
    1803
    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).
  14. #8
  15. No Profile Picture
    Dinesh_P_V
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    India
    Posts
    259
    Rep 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.

IMN logo majestic logo threadwatch logo seochat tools logo