aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2023-04-01 21:27:06 +0100
committerPaulo Custodio <pauloscustodio@gmail.com>2023-04-01 21:27:06 +0100
commit0834b3095c35d37388c439897edad20ec166b34f (patch)
tree75dd3d68e1b82e215f8b43a4e640855cafdc3e81
parent9bffa9ba8ff5ce1136c9402af90fcada5ddc9208 (diff)
downloadperlweeklychallenge-club-0834b3095c35d37388c439897edad20ec166b34f.tar.gz
perlweeklychallenge-club-0834b3095c35d37388c439897edad20ec166b34f.tar.bz2
perlweeklychallenge-club-0834b3095c35d37388c439897edad20ec166b34f.zip
Add C solution
-rw-r--r--challenge-038/paulo-custodio/c/ch-1.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/challenge-038/paulo-custodio/c/ch-1.c b/challenge-038/paulo-custodio/c/ch-1.c
new file mode 100644
index 0000000000..7eb3b645fd
--- /dev/null
+++ b/challenge-038/paulo-custodio/c/ch-1.c
@@ -0,0 +1,74 @@
+/*
+Challenge 038
+
+TASK #1
+Date Finder
+Create a script to accept a 7 digits number, where the first number can only
+be 1 or 2. The second and third digits can be anything 0-9. The fourth and
+fifth digits corresponds to the month i.e. 01,02,03…,11,12. And the last
+2 digits respresents the days in the month i.e. 01,02,03….29,30,31. Your
+script should validate if the given number is valid as per the rule and then
+convert into human readable format date.
+
+RULES
+If 1st digit is 1, then prepend 20 otherwise 19 to the 2nd and 3rd digits to
+make it 4-digits year.
+
+The 4th and 5th digits together should be a valid month.
+
+The 6th and 7th digits together should be a valid day for the above month.
+
+For example, the given number is 2230120, it should print 1923-01-20.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+bool is_leap_year(int y) {
+ return y % 400 == 0 ? true : y % 100 == 0 ? false : y % 4 == 0 ? true : false;
+}
+
+int days_of_month(int y, int m) {
+ switch (m) {
+ case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31;
+ case 4: case 6: case 9: case 11: return 30;
+ case 2: return is_leap_year(y) ? 29 : 28;
+ default: assert(0); return -1;
+ }
+}
+
+bool decode_date(int code, int* y, int* m, int* d) {
+ *d = code % 100; code /= 100;
+ if (*d < 1 || *d > 31) return false;
+
+ *m = code % 100; code /= 100;
+ if (*m < 1 || *m > 12) return false;
+
+ int year_lsb = code % 100; code /= 100;
+ int year_msb = code;
+ if (year_msb != 1 && year_msb != 2) return false;
+
+ *y = (year_msb == 1 ? 2000 : 1900) + year_lsb;
+
+ if (*d > days_of_month(*y, *m)) return false;
+
+ return true;
+}
+
+int main(int argc, char* argv[]) {
+ if (argc != 2) {
+ fputs("usage: ch-1 date", stderr);
+ return EXIT_FAILURE;
+ }
+
+ int date_code = atoi(argv[1]);
+ int y, m, d;
+ if (!decode_date(date_code, &y, &m, &d)) {
+ fputs("invalid date", stderr);
+ return EXIT_FAILURE;
+ }
+
+ printf("%04d-%02d-%02d\n", y, m, d);
+}