Perl Weekly Challenge 131: Consecutive Arrays

by Abigail

Challenge

You are given a sorted list of unique positive integers.

Write a script to return list of arrays where the arrays are consecutive integers.

Example 1

Input:  (1, 2, 3, 6, 7, 8, 9)
Output: ([1, 2, 3], [6, 7, 8, 9])

Example 2

Input:  (11, 12, 14, 17, 18, 19)
Output: ([11, 12], [14], [17, 18, 19])

Example 3

Input:  (2, 4, 6, 8)
Output: ([2], [4], [6], [8])

Example 4

Input:  (1, 2, 3, 4, 5)
Output: ([1, 2, 3, 4, 5])

Solution

We will be reading the array from standard input, with all the numbers on the same line. We will be writing each array to a different line of standard output.

We will be iterating over the numbers, keeping the previous processed number in a variable prev, which we initialize to 0. For each number we first print a separator, then the number. The separator printed depends on the previous and current number:

Perl

With the input array in $_, and having $prev initialized to 0, the gist of the program is just a one liner:

print $prev ? $prev + 1 == $_ ? " " : "\n" : "", $prev = $_ for /[0-9]+/g

Find the full program on GitHub.

AWK

The AWK solution is quite similar. AWK auto splits the input on white space, making each field available in variables $1, $2, etc.

{
    prev = 0
    for (i = 1; i <= NF; i ++) {
        printf ("%s%d", prev == 0 ? "" : (prev + 1 == $i) ? " " : "\n",
                       (prev = $i))
    }
    printf ("\n")
}

Find the full program on GitHub.

C

In C, we use sscanf to extract the numbers from a given string, then follow the same steps we used in our Perl and AWK solutions. Here, we have the line of input in variable line_ptr:

int num;
int offset;
int prev = 0;
while (sscanf (line_ptr, "%d%n", &num, &offset) == 1) {
    printf ("%s%d", prev     == 0   ? ""
                  : prev + 1 == num ? " "
                  :                   "\n", num);
    prev = num;
    line_ptr += offset;
}
printf ("\n");

Find the full program on GitHub.


Please leave any comments as a GitHub issue.