/* 060208-5.c
 * 15 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   es_laborable (long jul);
char *txtDsem (int dSem);
long  domPascua (int A);

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

int main (void)
{
  int dia, mes, ano; /* fecha en formato Gregoriano (día/mes/año) */
  long f1;
  int  i;

  diaSistema (&dia, &mes, &ano);
  f1 = domPascua (ano);
  diaGrg (f1, &dia, &mes, &ano);
  printf ("Domingo de Pascua: %02d/%02d/%4d\n", dia, mes, ano);

  diaSistema (&dia, &mes, &ano);
  f1 = diaJul (dia, mes, ano);
  for (i = 0; i < 365; i++) {
    diaGrg (f1 + i, &dia, &mes, &ano);
    printf ("%02d/%02d/%04d", dia, mes, ano);
    if (es_laborable (f1 + i))
      printf (" laborable\n");
    else
      printf (" fiesta\n");
  }

  return 0;
}

/* Respuesta 5.a) */
long domPascua (int A)
{
  int a, b, c, d, e;

  a = A % 19;
  b = A % 4;
  c = A % 7;
  d = (19 * a + 24) % 30;
  e = (2 * b + 4 * c + 6 * d + 5) % 7;

  return diaJul (1, 3, A) + 22 - 1 + d + e;
}

/* Respuesta 5.b) */
int es_laborable (long jul)
{
  int dSem;
  int dia, mes, ano; /* fecha en formato Gregoriano (día/mes/año) */
  long dPas;

  dSem = diaSem (jul);

  if (dSem > 4)
    return 0;

  diaGrg (jul, &dia, &mes, &ano);
  if ((mes ==  1 && (dia == 1 || dia == 6)) ||
      (mes ==  3 &&  dia == 19)             ||
      (mes ==  5 &&  dia == 1)              ||
      (mes ==  7 &&  dia == 25)             ||
      (mes ==  8 &&  dia == 15)             ||
      (mes == 10 &&  dia == 12)             ||
      (mes == 11 &&  dia ==  1)             ||
      (mes == 12 && (dia == 6 || dia == 8 || dia == 25)))
    return 0;

  if (mes == 4 && (  dia == 28 ||
                   (dia == 29 || dia == 30) && dSem == 0))
    return 0;

  dPas = domPascua (ano);
  if (jul == dPas - 2 || jul == dPas - 3)
    return 0;

  return 1;
}

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)
 * ------------ */

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

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;
}