From d5374bbc189ac31fd88e842984591852d2cddfdc Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Fri, 26 Jun 2020 21:22:00 -0300 Subject: [PATCH] C version --- README.md | 8 ++-- c/hours.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++ c/hours.h | 14 +++++++ c/main.c | 85 ++++++++++++++++++++++++++++++++++++++++ c/makefile | 7 ++++ 5 files changed, 221 insertions(+), 5 deletions(-) create mode 100644 c/hours.c create mode 100644 c/hours.h create mode 100644 c/main.c create mode 100644 c/makefile diff --git a/README.md b/README.md index c3e9720..ce452ff 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,9 @@ For the total hours a person should work in the day, we'll consider 08:48 (or At 09:00 ``` -$ wc 08:00 +$ wh 08:00 So far, you worked 01:00 You still need to work 07:48 -You still need to work till 17:48 ``` Reasoning: By starting at 08:00, up to 12:00, the user would've worked 4 @@ -36,10 +35,9 @@ hours; going back to work at 13:00, they would still need to work 4h48m, till At 18:00 ``` -$ wc 08:00 12:00 13:00 -So far, you worked, 09:00. +$ wh 08:00 12:00 13:00 +So far, you worked 09:00. You did 00:12 hours of extra work. -You could've left at 17:48 ``` ## Languages diff --git a/c/hours.c b/c/hours.c new file mode 100644 index 0000000..4bbf2ca --- /dev/null +++ b/c/hours.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include +#include "hours.h" + +struct hoursStruct { + int minutes; +}; + +/** + * Create a new hours structure. + */ +hours* hours_new(char *input) +{ + struct hoursStruct* result = NULL; + + char *duplicate = malloc(sizeof(char) * strlen(input) + 1); + sprintf(duplicate, "%s", input); + + char *colon = strchr(duplicate, ':'); + if (colon == NULL) { + goto cleanup; + } + + char* minutes_pos = colon + 1; + *colon = '\0'; + + int hours = atoi(duplicate); + int minutes = atoi(minutes_pos); + + if (hours < 0 || hours > 23) { + goto cleanup; + } + + if (minutes < 0 || minutes > 59) { + goto cleanup; + } + + int total_minutes = hours * 60 + minutes; + + result = malloc(sizeof(struct hoursStruct)); + result->minutes = total_minutes; + +cleanup: + free(duplicate); + return result; +} + +/** + * Create an Hours with the current time. + */ +hours* hours_right_now() +{ + struct hoursStruct* result = malloc(sizeof(struct hoursStruct)); + time_t right_now; + time(&right_now); + struct tm* local = localtime(&right_now); + + result->minutes = local->tm_hour * 60 + local->tm_min; + return result; +} + +/** + * Substract one hour from another. Returns a new hours struct. + */ +hours* hours_sub(hours* self, hours* other) +{ + struct hoursStruct* result = malloc(sizeof(struct hoursStruct)); + result->minutes = other->minutes - self->minutes; + return result; +} + +/** + * Add one hour to to another. Returns a new hours struct. + */ +hours* hours_add(hours* self, hours* other) +{ + struct hoursStruct* result = malloc(sizeof(struct hoursStruct)); + result->minutes = other->minutes + self->minutes; + return result; +} + +/** + * Pretty display for hours. + */ +char *hours_display(hours* self) +{ + int hours = (int)ceil(self->minutes / 60); + int minutes = self->minutes - (hours * 60); + + char* result = malloc(sizeof(char) * 6); // XX:XX\0 + sprintf(result, "%02d:%02d", hours, minutes); + return result; +} + +/** + * Checks if the hours happens before the other; returns -1 if it is earlier or 1 if it is later. + */ +int hours_preceed(hours* self, hours* other) { + return self->minutes < other->minutes + ? -1 + : 1; +} + +/** + * Free the memory used by the hours. + */ +void hours_free(hours* self) { + free(self); +} diff --git a/c/hours.h b/c/hours.h new file mode 100644 index 0000000..9ce4ac6 --- /dev/null +++ b/c/hours.h @@ -0,0 +1,14 @@ +#ifndef HOURS_H +#define HOURS_H + +typedef struct hoursStruct hours; + +hours* hours_new(char *input); +hours* hours_right_now(); +hours* hours_sub(hours* self, hours* other); +hours* hours_add(hours* self, hours* other); +char* hours_display(hours* self); +void hours_free(hours* self); +int hours_preceed(hours* self, hours* other); + +#endif diff --git a/c/main.c b/c/main.c new file mode 100644 index 0000000..831123c --- /dev/null +++ b/c/main.c @@ -0,0 +1,85 @@ +#include +#include + +#include "hours.h" + +int main(int argc, char* argv[]) { + hours *start = NULL; + hours *lunch_break = NULL; + hours *lunch_return = NULL; + + if (argc <= 1) { + printf("Usage: wh START_TIME [LUNCH_BREAK] [LUNCH_RETURN]\n"); + return EXIT_FAILURE; + } + + if (argc >= 2) { + start = hours_new(argv[1]); + if (start == NULL) { + printf("Invalid START_TIME\n"); + return EXIT_FAILURE; + } + } + + if (argc >= 3) { + lunch_break = hours_new(argv[2]); + if (lunch_break == NULL) { + printf("Invalid LUNCH_BREAK\n"); + return EXIT_FAILURE; + } + } else { + lunch_break = hours_new("12:00"); + } + + if (argc >= 4) { + lunch_return = hours_new(argv[3]); + if (lunch_return == NULL) { + printf("Invalid LUNCH_RETURN\n"); + return EXIT_FAILURE; + } + } else { + lunch_return = hours_new("13:00"); + } + + hours* now = hours_right_now(); + hours* so_far; + if (hours_preceed(now, lunch_return) == -1) { + so_far = hours_sub(start, now); + } else { + hours* before_lunch = hours_sub(start, lunch_break); + hours* after_lunch = hours_sub(lunch_return, now); + + so_far = hours_add(before_lunch, after_lunch); + + hours_free(before_lunch); + hours_free(after_lunch); + } + + char *display = hours_display(so_far); + + printf("So far, you've worked %s\n", display); + + hours* must_work = hours_new("08:48"); + if (hours_preceed(so_far, must_work) == -1) { + hours* remaining = hours_sub(so_far, must_work); + char *still = hours_display(remaining); + printf("You still need to work %s\n", still); + free(still); + hours_free(remaining); + } else { + hours* exceeding = hours_sub(must_work, so_far); + char* extra = hours_display(exceeding); + printf("You did %s of extra work\n", extra); + free(extra); + hours_free(exceeding); + } + + free(display); + hours_free(so_far); + hours_free(now); + hours_free(start); + hours_free(lunch_break); + hours_free(lunch_return); + + return EXIT_SUCCESS; +} diff --git a/c/makefile b/c/makefile new file mode 100644 index 0000000..d4f0dfe --- /dev/null +++ b/c/makefile @@ -0,0 +1,7 @@ +OBJS = main.o hours.o + +wh: $(OBJS) + gcc $^ -o $@ + +%.o: %.c %.h + gcc -c $< -Wall