/* 060208-5.c
 * 45 min
 */
#include <stdio.h>

/* Prototipos de funciones dadas */
void  diaSistema (int *dd, int *mm, int *aa);
long  diaJul (int dd, int mm, int aa);
void  diaGrg (long jul, int *dd, int *mm, int *aa);
int   diaSem (long jul);
int   festJul (long jul);
char *txtDsem (int dSem);

void f_a (void);
void f_b (void);
void f_c (long f1, long f2);

  /* 10 min */
int main (void)
{
  int dia, mes, ano; /* fecha en formato Gregoriano (día/mes/año) */
  long f1, f2;       /* fecha 1 y fecha 2 en formato numérico (Juliano) */

  f_a ();

  f_b ();

  printf ("Introduce fecha inicio (dia mes año): ");
  scanf ("%d%d%d", &dia, &mes, &ano);
  f1 = diaJul (dia, mes, ano);

  printf ("Introduce fecha final (dia mes año): ");
  scanf ("%d%d%d", &dia, &mes, &ano);
  f2 = diaJul (dia, mes, ano);

  if (f2 < f1) {
    printf ("Fechas incorrectas\n");
    return 1;
  }
  else
    f_c (f1, f2);

  return 0;
}

  /* 15 min */
void f_a (void)
{
  int dia, mes, ano; /* fecha en formato Gregoriano (día/mes/año) */
  long jul;          /* fecha en formato numérico (Juliano) */
  int  dSem;         /* día de la semana, 0: lunes, 6: domingo */
  int  i_m13;        /* contador de días martes y trece */

  printf ("Dos siguientes fechas martes y trece:\n");
  diaSistema (&dia, &mes, &ano);

  i_m13 = 0;
  if (dia > 13)
    mes++;

  do {
    if (mes == 13) {
      mes = 1;
      ano++;
    }
    jul = diaJul (13, mes, ano);
    dSem = diaSem (jul);
    if (dSem == 1) {
      printf ("%02d/%02d/%04d\n", 13, mes, ano);
      i_m13++;
    }
    mes++;
  } while (i_m13 < 2);
}

  /* 10 min */
void f_b (void)
{
  int dia, mes, ano; /* fecha en formato Gregoriano (día/mes/año) */
  long jul;          /* fecha en formato numérico (Juliano) */
  int  dSem;         /* día de la semana, 0: lunes, 6: domingo */
  int  i_asc;        /* contador de años santos compostelanos */

  printf ("Próximos cinco años santos compostelanos:\n");
  diaSistema (&dia, &mes, &ano);

  i_asc = 0;
  do {
    ano++;
    jul = diaJul (25, 7, ano);
    dSem = diaSem (jul);
    if (dSem == 0) {
      printf ("%d\n", ano);
      i_asc++;
    }
  } while (i_asc < 5);
}

  /* 10 min */
void f_c (long f1, long f2)
{
  int  dSem;         /* día de la semana, 0: lunes, 6: domingo */
  int  cDias[5];

  for (dSem = 0; dSem < 5; dSem++)
    cDias[dSem] = 0;

  while (f1 <= f2) {
    if (!festJul (f1)) {
      dSem = diaSem (f1);
      cDias[dSem]++;
    }
    f1++;
  }

  for (dSem = 0; dSem < 5; dSem++)
    printf ("%2d %s\n", cDias[dSem], txtDsem (dSem));
}

int diaSem (long jul)
{
  return jul % 7;
}

int festJul (long jul)
{
  int dSem;

  dSem = diaSem (jul);

  if (dSem > 4)
    return 1;

  return 0;
}

int es_bisiesto (int ano)
{
  return ano % 4 == 0 &&
        (ano % 100 != 0 || ano % 400 != 0);
}

int es_compostelano (int ano)
{
  return diaSem (diaJul (25, 7, ano)) == 6;
}

/* --------------------------------------------------------------------*/
/* A partir de aquí no vamos a preocuparnos de cómo se hacen las cosas */
/* --------------------------------------------------------------------*/


/* Obtiene una fecha en formato numérico (Juliano)
 * ------------ */
long diaJul (int dd, int mm, int aa)
{
  long jul;
  int  ja,
       jy,
       jm;

  jy = aa;

  if (jy == 0)
    return -1; /* No hay año 0 */

  if (jy < 0)
    ++jy;

  if (mm > 2) {
    jm = mm + 1;
  }
  else {
    --jy;
    jm = mm + 13;
  }

  jul =  (long) (365.25  * jy) +
         (long) (30.6001 * jm) +
                dd +
                1720995;

  if (dd + 31L * (mm + 12L * aa) >= (15 + 31L * (10 + 12L * 1582))) {
    ja = (int) (0.01 * jy);
    jul += 2 - ja + (int) (0.25 * ja);
  }

  return jul;
}

/* Obtiene una fecha en formato día/mes/año (Gregoriano) a partir
 * de un formato numérico (gregoriano)
 * ------------ */
void diaGrg (long jul, int *dd, int *mm, int *aa)
{
  long ja, jal, jb, jc, jd, je;
   
  if (jul >= 2299161) {
    jal = ((float) (jul - 1867216) - 0.25) / 36524.25;
    ja = jul + 1 + jal - (long) (0.25 * jal);
  }
  else if (jul < 0)
    ja = jul + 36525 *( 1 - jul / 36525);
  else
    ja = jul;
  jb = ja + 1524;
  jc = (long) (6680.0 + ((float) (jb - 2439870) - 122.1) / 365.25);
  jd = (long) (365 * jc + (0.25 * jc));
  je = (long) ((jb - jd) / 30.6001);
  *dd = jb - jd - (long) (30.6001 * je);
  *mm = je - 1;

  if (*mm > 12)
    *mm -= 12;
  *aa = jc - 4715;
  if (*mm > 2) --(*aa);
  if (*aa <= 0) --(*aa);
  if (jul < 0)
    *aa -= 100 * (1 - jul / 36525);
}

static char *cadenaDiaSemana [] = {
  "lunes",
  "martes",
  "miércoles",
  "jueves",
  "viernes",
  "sábado",
  "domingo"
};

/* Devuelve la cadena de un día de la semana
 * ------------ */
char *txtDsem (int dSem)
{
  return cadenaDiaSemana [dSem];
}

#include <time.h>
#include <stdlib.h>

/* Devuelve la fecha del sistema
 * ------------ */
void diaSistema (int *dd, int *mm, int *aa)
{
  time_t timer;
  struct tm *stm;

  timer = time (NULL);
  stm = localtime (&timer);

  *dd = stm->tm_mday;
  *mm = stm->tm_mon + 1;
  *aa = stm->tm_year + 1900;
}

/* Devuelve la hora del sistema
 * ------------ */
void horaSistema (int *hh, int *mm, int *ss)
{
  time_t timer;
  struct tm *stm;

  timer = time (NULL);
  stm = localtime (&timer);

  *hh = stm->tm_hour;
  *mm = stm->tm_min;
  *ss = stm->tm_sec;
}