aboutsummaryrefslogtreecommitdiff
path: root/challenge-106/abigail
diff options
context:
space:
mode:
authorAbigail <abigail@abigail.be>2021-03-31 20:56:03 +0200
committerAbigail <abigail@abigail.be>2021-03-31 20:57:29 +0200
commitb96bc945b68514ba79e2c5a6f781d6e1cb63aa29 (patch)
tree18e5225b332f689d97e888157e3231aaeca75f38 /challenge-106/abigail
parentaa4f9e49e6aaa1ca25bcd2999c98b62f23ff5eaf (diff)
downloadperlweeklychallenge-club-b96bc945b68514ba79e2c5a6f781d6e1cb63aa29.tar.gz
perlweeklychallenge-club-b96bc945b68514ba79e2c5a6f781d6e1cb63aa29.tar.bz2
perlweeklychallenge-club-b96bc945b68514ba79e2c5a6f781d6e1cb63aa29.zip
C solution for week 106, part 2
Diffstat (limited to 'challenge-106/abigail')
-rw-r--r--challenge-106/abigail/README.md1
-rw-r--r--challenge-106/abigail/c/ch-2.c102
-rw-r--r--challenge-106/abigail/t/ctest.ini3
3 files changed, 106 insertions, 0 deletions
diff --git a/challenge-106/abigail/README.md b/challenge-106/abigail/README.md
index 6c1a682ffc..2f760b9b2e 100644
--- a/challenge-106/abigail/README.md
+++ b/challenge-106/abigail/README.md
@@ -94,6 +94,7 @@ Wikipedia](https://en.wikipedia.org/wiki/Repeating_decimal).
### Solutions
* [AWK](perl/ch-2.awk)
* [Bash](bash/ch-2.sh)
+* [C](c/ch-2.c)
* [Perl](perl/ch-2.pl)
### Blog
diff --git a/challenge-106/abigail/c/ch-2.c b/challenge-106/abigail/c/ch-2.c
new file mode 100644
index 0000000000..2bff0e1281
--- /dev/null
+++ b/challenge-106/abigail/c/ch-2.c
@@ -0,0 +1,102 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# include <math.h>
+
+/*
+ * See ../README.md
+ */
+
+/*
+ * Run as: cc -o ch-2.o ch-2.c; ./ch-2.o < input-file
+ */
+
+# define BASE 10
+typedef int number;
+
+/*
+ * Perform long division. See ../README.md for details.
+ */
+
+char * long_division (int numerator, int denominator) {
+ /*
+ * Calculate the maximum size of the result
+ */
+ size_t fraction_len =
+ (numerator < denominator ? 1 :
+ floor (log10 (numerator / denominator))) + // Digits before decimal dot
+ 1 + // Decimal dot
+ denominator + // Digits after decimal dot
+ 2 + // Parens
+ 1; // Trailing NUL byte
+ /*
+ * Allocate a string to hold the caption.
+ */
+ char * fraction;
+ if ((fraction = (char *) malloc (fraction_len * (sizeof (char)))) == NULL) {
+ perror ("Mallocing string failed");
+ exit (1);
+ }
+
+ /*
+ * Add the first part of the result (upto, and including the dot)
+ */
+ int position;
+ snprintf (fraction, fraction_len, "%d.%n",
+ numerator / denominator, &position);
+
+ /*
+ * Allocate memory to remember which numerators we have seen;
+ * initialize the entries to 0.
+ */
+ number * seen;
+ if ((seen = (number *) malloc (denominator * (sizeof (number)))) == NULL) {
+ perror ("Mallocing seen structure failed");
+ exit (1);
+ }
+ for (number i = 0; i < denominator; i ++) {
+ seen [i] = 0;
+ }
+
+ /*
+ * We already have the part before the decimal dot; for the part
+ * behind it, we need numerator < denominator
+ */
+ numerator %= denominator;
+
+ while (!seen [numerator]) {
+ if (!numerator) {
+ fraction [position] = '\0';
+ return (fraction);
+ }
+ seen [numerator] = position;
+ fraction [position] = BASE * numerator / denominator + '0';
+ numerator = BASE * numerator % denominator;
+ position ++;
+ }
+
+ /*
+ * We now have to place the parens -- which means shifting
+ * part of the string created so far.
+ */
+ fraction [position + 2] = '\0';
+ fraction [position + 1] = ')';
+ for (int i = position; i > seen [numerator]; i --) {
+ fraction [i] = fraction [i - 1];
+ }
+ fraction [seen [numerator]] = '(';
+ return (fraction);
+}
+
+
+
+int main (void) {
+ number numerator, denominator;
+ while (scanf ("%d %d", &numerator, &denominator) == 2) {
+ char * fraction = long_division (numerator, denominator);
+ printf ("%s\n", fraction);
+ free (fraction);
+ }
+
+ return (0);
+}
diff --git a/challenge-106/abigail/t/ctest.ini b/challenge-106/abigail/t/ctest.ini
index 91aa95b6cb..247492708c 100644
--- a/challenge-106/abigail/t/ctest.ini
+++ b/challenge-106/abigail/t/ctest.ini
@@ -11,3 +11,6 @@
2-4 = Unit fractions
2-5 = Dyadic fractions
2-6 = Prime fractions
+
+[2-5/c]
+skip = Requires too much memory