import sys

def rec_seq_down( N ):  # N = 7, 6, 5, ..., 0
    if N < 0:
        return
    print( N, end = ' ' )
    rec_seq_down( N-1)

def rec_seq_up( N ):  # N = 15, 14, ..., 0,
    if N < 0:
        return

    print(" in", end = ' ' )
    rec_seq_up( N-1 )  # N = 15-1, 14-1, 13-1, ..., 0-1,
    print(" out", end = ' ' )
    print( N, end = ' ' )  # N = 15, 14, ..., 0


def rec_seq_downup( N ):
    if N < 4:
        print( " bottom reached ", end = '' )
        return
    print( N, end = ' ' )
    rec_seq_downup( N-1 )
    print( N, end = ' ' )

def rec_seq_updown( N, currentVal ): #  currentVal = 0
    if currentVal > N :
        print( " bottom reached ", end = '' )
        return
    print( currentVal, end = ' ' )
    rec_seq_updown( N, currentVal+1 )
    print( currentVal, end = ' ' )

'''
0 1 2 3 4 5 6  bottom reached 6 5 4 3 2 1 0

0  recursive call                         0
  1   recursive call                    1
    2   recursive call                2
      3  recursive call             3
        4  recursive call         4
          5  recursive call     5
            6  recursive call 6
              bottom reached
'''

def rec_max( arr ):
    if len(arr) == 1:
        return arr[0]
    maxrest = rec_max( arr[1:] )
    maxval = max( arr[0], maxrest )
    print("max in", arr, "is", maxval )
    return maxval

def rec_isSorted( arr ):
    if len(arr) == 1:
        return True
    sortedRest = rec_isSorted( arr[1:] )
    allsorted = arr[0] <= arr[1] and sortedRest
    print( arr, "is the array sorted --", allsorted )
    return allsorted

def rec_multiply( x, y ):
    if y == 1:
        return x
    return x + rec_multiply( x, y-1 )

def rec_reverse( arr ):
    if len(arr) <= 1:
        return arr
    first = arr[0]
    reversed = rec_reverse( arr[1:] )
    reversed.append( first )
    return reversed

def rec_reverse2( arr ):
    if len(arr) <= 1:
        return arr
    reversed = rec_reverse( arr[1:] )
    return reversed.append( arr[0] )

def rec_sum( arr ):
    if len(arr) == 0:
        return 0
    return arr[0] + rec_sum( arr[1:] )

# --------------------------------------------------------
#           M  A  I  N
# --------------------------------------------------------


rec_seq_down( 7 )
print()
print("--------------------------")

rec_seq_up( 15 )
print()
print("..........................")

rec_seq_downup( 11 )
print()
print("..........................")

rec_seq_updown( 11, 0 )
print()
print("..........................")

arr = [ 2, 5, 1, 5, 2, 8, 4, 2, 6, 3 ]
#arr = [ 2,4,5,20, 10,11,12,13,14,15 ]
print( "array:", arr )
print( "max in the array  is ", rec_max( arr ) )
print()

print( "array:", arr )
print( "is sorted -- ", rec_isSorted( arr ) )
print()

arr2 = [ 2, 5, 11, 15, 22, 28, 34, 34, 46, 53 ]
print( "array:", arr2 )
print( "is sorted --", rec_isSorted( arr2 ) )
print()

print( "array:", arr2 )
print( rec_reverse( arr2 ) )
print()

arr2 = [1, 2, 0, 0, 10, 0]
print( "array:", arr2 )
print( "sum:", rec_sum( arr2 ) )


# --- beware of system stack size - possible overflow.
print( rec_multiply( 10, 14 ) )
print( rec_multiply( 10, 100 ) )
sys.setrecursionlimit( 2000 )
print( rec_multiply( 100, 1000 ) )










