Publi

Algoritmos: Repartir el tiempo total de una tarea a lo largo de varios días en C

Cuando tenemos una tarea que debemos llevar a cabo a largo medio/plazo, normalmente debemos dedicar un tiempo cada día a esa tarea pero, ¿cuánto tiempo necesitamos dedicar a esa tarea (como mínimo) para terminar en un plazo establecido?

Gracias a Alejandro por la sugerencia de este programa.

Primero el programa, y luego lo comentamos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
*************************************************************
* @file calcula_horas.c
*************************************************************/


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

typedef struct
{
  int hours;
  int minutes;
  float raw;
} Thm;

time_t getTime(int day, int month, int year);
int calculateDaysInRange(int daysInRange[7], time_t start, time_t end);
int calculateTotalDays(int workDays[7], int daysInRange[7]);
int calculateHoursADay(Thm *result, int totalDays, int hoursToWork, int totalHours);

int main(int argc, char *argv[])
{
  int error;
  int i ;
  int totalDays;
  time_t start = getTime(1, 6, 2013);
  time_t end = getTime(18, 6, 2013);
  /* Which days can we work in this task? */
  /* Starts on sunday */
  /* YOU MUST FILL THIS ARRAY */
  int workDays[7] = { 0, 1, 0, 1, 1, 0, 1};
  int hoursToWork=4;
  /* Number of sundays, mondays, tuesdays, wednesdays, etc between start and end date */
  int daysInRange[7] = { 0, 0, 0, 0, 0, 0, 0};
  Thm thm;

  error = calculateDaysInRange(daysInRange, start, end);
  if (!error)
    {
      totalDays = calculateTotalDays(workDays, daysInRange);
      error = calculateHoursADay(&thm, totalDays, hoursToWork, 42);
      if (!error)
    {
      printf ("From: %s\n", ctime(&start));
      printf ("To: %s\n", ctime(&end));
      for (i=0; i<7; i++)
        printf ("Day %d: %d\n", i, daysInRange[i]);
      printf ("total days: %d\n", totalDays);
      printf ("Hours a Day: %d hours and %d minutes (%f h)\n", thm.hours, thm.minutes, thm.raw);
    }
      else
    {
      printf("You can't spend more time than available\n");
      printf("But you should work %d hours and %d minutes a day to complete your task.\n", thm.hours, thm.minutes);
    }
    }
  else
    printf ("There was a problem...\n");
  return EXIT_SUCCESS;
}

time_t getTime(int day, int month, int year)
{
  struct tm tm;

  /* Clean tm struct */
  memset(&tm, 0x00, sizeof(tm));
  tm.tm_mday = day;
  tm.tm_mon = month-1;
  tm.tm_year = year-1900;

  return mktime(&tm);
}

int calculateDaysInRange(int daysInRange[7], time_t start, time_t end)
{
  time_t diff = difftime(end, start);
  struct tm *start_tm = localtime(&start);

  int totalDays = 1 + diff / 86400; /* From day 1 to 10, there are 10 days (10 - 1 + 1) */
  /* So, all days in the week will be (totalDays/7) times in the date range except
     (totalDays%7) days from the starting date, they will be (totalDays/7)+1 times */

  int repeat = totalDays / 7;
  int i;
  for (i=0; i<7; ++i)
    daysInRange[i]=repeat;

  for (i=0; i<totalDays%7; ++i)
    daysInRange[(start_tm->tm_wday+i)%7]++;

  return 0;         /* No error */
}

int calculateTotalDays(int workDays[7], int daysInRange[7])
{
  int i;
  int total=0;

  for (i=0; i<7; ++i)
    {
      daysInRange[i]=(workDays[i])?daysInRange[i]:0;
      total+=daysInRange[i];
    }
  return total;
}

int calculateHoursADay(Thm *result, int totalDays, int hoursToWork, int totalHours)
{
  int availableHours = totalDays*hoursToWork;

  result->hours= totalHours/totalDays;
  result->minutes = (totalHours%totalDays)*60/totalDays;
  result->raw=(float)totalHours/totalDays;

  if (availableHours<totalHours)
    return -1;

  return 0;
}

Al programa le falta un poco más de interacción con el usuario, ya que no se preguntan las fechas, ni el número de horas a trabajar ni los días, pero sería fácil añadirlo. Lo primero que hacemos es determinar las fechas de inicio y fin con getTime(), luego llamamos a calculateDaysInRange que almacenará en daysInRange el número de domingos, lunes, martes, miércoles, jueves, viernes y sábados que hay entre esas dos fechas. Tras eso, combinamos el resultado con el array workDays (donde especificamos qué días a la semana vamos a trabajar en esa tarea, empezando por el domingo), y por último, calcularemos cuántas horas a la semana debemos trabajar en esta tarea.

Si la tarea se puede realizar en el número de horas que nos quedan disponibles, decimos cuánto tardaremos, si no, diremos cuánto tiempo deberíamos emplear.

También podría interesarte....

Leave a Reply