# Task
 A range-collapse representation of an array of integers looks like this: `"1,3-6,8"`, where `3-6` denotes the range from `3-6`, i.e. `[3,4,5,6]`. 
 
 Hence `"1,3-6,8"` = `[1,3,4,5,6,8]`. Some other range-collapse representations of `[1,3,4,5,6,8]` include `"1,3-5,6,8", "1,3,4,5,6,8", etc`.

 Each range is written in the following format `"a-b"`, where `a < b`, and the whole range must belong to the array in an increasing order.

 You are given an array `arr`. Your task is to find the number of different range-collapse representations of the given array.

# Example
 
 For `arr = [1,3,4,5,6,8]`, the result should be `8`.
 ```
 "1,3-4,5,6,8"
 "1,3-4,5-6,8"
 "1,3-5,6,8"
 "1,3-6,8"
 "1,3,4-5,6,8"
 "1,3,4-6,8"
 "1,3,4,5-6,8"
 "1,3,4,5,6,8"```

# Input/OutPut


 - `[input]` integer array `arr`

  sorted array of different positive integers.


 - `[output]` an integer

  the number of different range-collapse representations of the given array.

Difficulty: introductory

Starter code:

def descriptions(arr):
	

Solutions:
def descriptions(arr):
    return 2**sum(a+1==b for a,b in zip(arr,arr[1:]))


def pair_apply(a, fn): 
    """
    Apply a funtion to each pair of consecutive 
    values in the array and return the resultant array
    """
    return [fn(x, y) for x, y in zip(a, a[1:])]

def run_length_encode(a):
    """Run length encode the given array"""
    a = [(x, 1) for x in a]
    i = 0
    while i < len(a) - 1:
        if a[i][0] == a[i + 1][0]:
            a[i] = (a[i][0], a[i][1] + 1)
            del a[i + 1]
        else:
            i += 1
    return a

def descriptions(arr):
    """
    Caluculate number of possible range collapse 
    permutations for givven array
    """
    deltas = pair_apply(arr, lambda x, y: y - x)
    rle_deltas = run_length_encode(deltas)
    result = 1
    for delta, count in rle_deltas:
        if delta == 1:
            result *= 2 ** count
    return result


def descriptions(arr):
  return 2**len([v for n,v in enumerate(arr) if v==arr[n-1]+1])

descriptions=lambda l:1<<sum(b-a==1for a,b in zip(l,l[1:]))

from math import factorial


def binomial(m, n):
    return factorial(n) / factorial(m) / factorial(n-m)


def descriptions(arr):
    count = 0
    for i in range(1, len(arr)):
        if arr[i] == arr[i-1] + 1:
            count += 1
    return 2**count


def descriptions(arr):
    r, prev, n = 1, arr[0], 1
    for x in arr[1:]:
        if x != prev + 1:
            r *= 2 ** (n - 1)
            n = 0
        prev = x
        n += 1
    return r * 2 ** (n - 1)


def descriptions(arr):
    return 2**sum(j-i==1 for i,j in zip(arr,arr[1:]))

from functools import reduce
from operator import mul
def descriptions(arr):
    r=[]
    seq=0
    for x,y in zip(arr[:-1],arr[1:]):
        if y-x==1:
            seq+=1
        else:
            if seq>0:
                r.append(seq+1)
                seq=0
    if seq>0:
        r.append(seq+1)
    return reduce(mul,[2**(x-1) for x in r]) if r else 1

descriptions=lambda arr:2**sum(arr[i]+1==arr[i+1] for i in range(len(arr)-1))

def descriptions(arr):
    return 2**sum(x+1 == y for x,y in zip(arr, arr[1:]))