aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbigail <abigail@abigail.be>2021-02-17 18:43:33 +0100
committerAbigail <abigail@abigail.be>2021-02-17 18:43:33 +0100
commitade625b24f12025b278ef2cfaaf857ac81df4319 (patch)
tree058a33a77c090241fbf39501d1c3ae1664652976
parent55f9274d96dd43136acc8cfdd6e8991fc562fada (diff)
downloadperlweeklychallenge-club-ade625b24f12025b278ef2cfaaf857ac81df4319.tar.gz
perlweeklychallenge-club-ade625b24f12025b278ef2cfaaf857ac81df4319.tar.bz2
perlweeklychallenge-club-ade625b24f12025b278ef2cfaaf857ac81df4319.zip
C solution for week 100, part 1
-rw-r--r--challenge-100/abigail/README.md1
-rw-r--r--challenge-100/abigail/c/ch-1.c75
2 files changed, 76 insertions, 0 deletions
diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md
index ddce3fd34a..ff62f9e3ba 100644
--- a/challenge-100/abigail/README.md
+++ b/challenge-100/abigail/README.md
@@ -21,6 +21,7 @@ Output: 07:15 pm or 07:15pm
* [GNU AWK](awk/ch-1.gawk)
* [Bash](bash/ch-1.sh)
* [Befunge-93](befunge-93/ch-1.bf93)
+* [C](c/ch-1.c)
* [Perl](perl/ch-1.pl)
### Blog
diff --git a/challenge-100/abigail/c/ch-1.c b/challenge-100/abigail/c/ch-1.c
new file mode 100644
index 0000000000..8ea41facc9
--- /dev/null
+++ b/challenge-100/abigail/c/ch-1.c
@@ -0,0 +1,75 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# include <ctype.h>
+
+/*
+ * See ../README.md
+ */
+
+/*
+ * Run as: cc -o ch-1.o ch-1.c; ./ch-1.o < input-file
+ */
+
+int main (void) {
+ char * line = NULL;
+ size_t len = 0;
+ size_t str_len;
+
+ while ((str_len = getline (&line, &len, stdin)) != -1) {
+ char * ptr = line;
+
+ /*
+ * Parse hour and minute from line
+ */
+ int hour = atoi (ptr);
+ while (isdigit (* ptr)) {
+ ptr ++;
+ }
+ ptr ++; /* The ':' separating hour and minute */
+ int minute = atoi (ptr);
+
+ /*
+ * Advance the pointer to the first character of the
+ * AM/PM marker; if there is none, it will point
+ * to the NUL byte. (And * ptr is then false).
+ */
+ while (* ptr && (isdigit (* ptr) || isspace (* ptr))) {
+ ptr ++;
+ }
+
+ /*
+ * Calculate the new AM/PM marker:
+ * - If there was one, there new one will be empty.
+ * - Else, if the hour is 12 or larger, it's PM
+ * - Else, it's AM
+ */
+ char * new_ampm = * ptr ? "" : hour >= 12 ? "pm" : "am";
+
+ /*
+ * Calculate the new hour:
+ * - we always mod the hour by 12;
+ * this has the effect of making 12 AM (and 12 PM)
+ * equal to 0, and subtracts 12 from time in 24-hour
+ * format, for times after noon.
+ * - if we started from a 24 hour time, and the hour is
+ * now 0, make it 12.
+ * - if we started from PM time, add 12 to the hour.
+ */
+ hour %= 12;
+ if (!* ptr && hour == 0) {
+ hour = 12;
+ }
+ if (tolower (* ptr) == 'p') {
+ hour += 12;
+ }
+
+ /*
+ * Print the result.
+ */
+ printf ("%02d:%02d%s\n", hour, minute, new_ampm);
+ }
+ free (line);
+
+ return (0);
+}