aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbigail <abigail@abigail.be>2021-05-26 20:12:07 +0200
committerAbigail <abigail@abigail.be>2021-05-26 20:12:07 +0200
commit627209bce4d1c1d616d3d24faa176733805110ae (patch)
treef2fd4a88cebfd514da4db244448153f8d2294977
parent95fa51719a7bb78211161a49764aee5b6a53088a (diff)
downloadperlweeklychallenge-club-627209bce4d1c1d616d3d24faa176733805110ae.tar.gz
perlweeklychallenge-club-627209bce4d1c1d616d3d24faa176733805110ae.tar.bz2
perlweeklychallenge-club-627209bce4d1c1d616d3d24faa176733805110ae.zip
C solution for week 114, part 1
-rw-r--r--challenge-114/abigail/README.md1
-rw-r--r--challenge-114/abigail/c/ch-1.c97
2 files changed, 98 insertions, 0 deletions
diff --git a/challenge-114/abigail/README.md b/challenge-114/abigail/README.md
index 317c387333..ba6d2722ec 100644
--- a/challenge-114/abigail/README.md
+++ b/challenge-114/abigail/README.md
@@ -18,6 +18,7 @@ Output: 1001
### Solutions
* [AWK](awk/ch-1.awk)
* [Bash](bash/ch-1.sh)
+* [C](c/ch-1.c)
* [Perl](perl/ch-1.pl)
### Blog
diff --git a/challenge-114/abigail/c/ch-1.c b/challenge-114/abigail/c/ch-1.c
new file mode 100644
index 0000000000..798f875954
--- /dev/null
+++ b/challenge-114/abigail/c/ch-1.c
@@ -0,0 +1,97 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# include <stdbool.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 * line_ptr = line;
+ str_len --; /* Don't care about newline. */
+ /*
+ * Do we have just 9s?
+ */
+ bool all_nines = true;
+ for (size_t i = 0; i < str_len; i ++) {
+ if (line [i] != '9') {
+ all_nines = false;
+ break;
+ }
+ }
+ if (all_nines) {
+ printf ("1");
+ for (size_t i = 0; i < str_len - 1; i ++) {
+ printf ("0");
+ }
+ printf ("1\n");
+ continue;
+ }
+
+ /*
+ * Single character?
+ */
+ if (str_len == 1) {
+ line [0] ++;
+ printf ("%s", line);
+ continue;
+ }
+
+ size_t mid = str_len / 2;
+
+ /*
+ * Is the first part reversed greater than the last part?
+ */
+ bool is_greater = false;
+ ssize_t i;
+ size_t j;
+ for (i = mid - 1, j = mid + (str_len & 1); i >= 0; i --, j ++) {
+ if (line [i] > line [j]) {
+ is_greater = true;
+ break;
+ }
+ if (line [i] < line [j]) {
+ break;
+ }
+ }
+ /*
+ * If not greater, we need to add one of the first part (including
+ * the middle part). We do this by starting from the middle, turning
+ * 9s into 0s, and adding 1 to something not a 9. In the latter
+ * case, we terminate the loop.
+ */
+ if (!is_greater) {
+ for (i = mid - 1 + (str_len & 1); i >= 0; i --) {
+ if (line [i] == '9') {
+ line [i] = '0';
+ }
+ else {
+ line [i] ++;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Now, copy the first half to the second; reversed
+ */
+ for (i = mid - 1, j = mid + (str_len & 1); i >= 0; i --, j ++) {
+ line [j] = line [i];
+ }
+
+ printf ("%s", line);
+ }
+ free (line);
+
+ return (0);
+}