aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-087/abigail/c/ch-1.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/challenge-087/abigail/c/ch-1.c b/challenge-087/abigail/c/ch-1.c
new file mode 100644
index 0000000000..a82d4e140c
--- /dev/null
+++ b/challenge-087/abigail/c/ch-1.c
@@ -0,0 +1,114 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <math.h>
+
+/*
+ * https://perlweeklychallenge.org/blog/perl-weekly-challenge-087/#TASK1
+ *
+ * See the notes in the Perl solution: ../perl/ch-1.pl
+ */
+
+
+# define DEFAULT_BUF_SIZE 128
+# define BUF_INCREMENT 1.25 /* Increment the buffer size by *
+ * a quarter each time we run out *
+ * of memory space. */
+
+/*
+ * Compare two integer values, returning -1, 0, 1 if the first
+ * is smaller, equal, or larger than the second.
+ */
+int cmp (const void * a, const void * b) {
+ long diff = * (long *) a - * (long *) b;
+ return diff < 0 ? -1
+ : diff > 0 ? 1
+ : 0;
+}
+
+int main (void) {
+ /* Arguments for getline () */
+ char * line = NULL;
+ size_t len = 0;
+
+ /* We'll store the numbers in array, which we will reuse for each *
+ * line we're processing. We also need to keep track of how much *
+ * memory we have allocated for the array. */
+ long * array = NULL;
+ size_t buf_size = DEFAULT_BUF_SIZE;
+
+ /* The target difference */
+ long target;
+
+ /* Give the array some starting memory to work with. */
+ if ((array = (long *) malloc (buf_size * sizeof (long))) == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ return (1);
+ }
+
+ size_t size = 0; /* Number of integers in array. */
+
+ while (getline (&line, &len, stdin) != -1) {
+ int offset;
+ char * line_ptr = line;
+ size = 0; /* Reset size of array */
+ long input; /* Each long read from the line */
+
+ /* Scan the line just read, one long at a time */
+ while (sscanf (line_ptr, "%ld%n", &input, &offset) == 1) {
+ line_ptr += offset;
+
+ if (++ size >= buf_size) {
+ /* Get some more memory. */
+ buf_size = (size_t) floorf (buf_size * BUF_INCREMENT);
+ if ((array = (long *) realloc (array,
+ buf_size * sizeof (long))) == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ return (1);
+ }
+ }
+
+ /* Store it */
+ array [size - 1] = input;
+ }
+
+ /* Quick sort to sort the array */
+ qsort (array, size, sizeof (long), cmp);
+
+ size_t max_streak = 0;
+ size_t max_index = 0;
+ size_t cur_streak = 0;
+
+ /*
+ * Iterate over the array, track streaks of increasing numbers.
+ * Also track the longest streak, and the index of where the
+ * longest streak ends. Note that we count starting from 0.
+ */
+ for (size_t i = 1; i < size; i ++) {
+ if (array [i] == array [i - 1] + 1) {
+ if (++ cur_streak > max_streak) {
+ max_streak = cur_streak;
+ max_index = i;
+ }
+ }
+ else {
+ cur_streak = 0;
+ }
+ }
+
+ if (max_streak == 0) {
+ /* Empty array, *or* a maximum streak of single number */
+ printf ("%d\n", 0);
+ }
+ else {
+ for (size_t i = max_index - max_streak; i <= max_index; i ++) {
+ printf ("%ld", array [i]);
+ if (i < max_index) {
+ printf (", ");
+ }
+ }
+ printf ("\n");
+ }
+ }
+ free (line);
+ free (array);
+}