I'm doing this HackerRank problem, which asks whether an array of up to 100000 integers can be sorted in ascending order by exactly one of the following:
- swapping two elements
- reversing a subarray
- doing nothing (i.e. it is already sorted)
I've written this code and it passes all the tests, but it seems very convoluted. Is there any way I can streamline this code to make it more Pythonic?
n = int(raw_input())
ar = map(int, raw_input().strip().split())
ar.insert(0, -1)
ar.append(1000001)
ups = 0
downs = 0
for i in xrange(1, n+1):
if ar[i] < ar[i-1] and ar[i] < ar[i+1]:
downs += 1
later_index = i
elif ar[i] > ar[i-1] and ar[i] > ar[i+1]:
ups += 1
first_index = i
for i in xrange(n, 0, -1):
if ar[i] > ar[i-1] and ar[i] > ar[i+1]:
swap_i = i
if downs == ups == 2:
ar[swap_i], ar[later_index] = ar[later_index], ar[swap_i]
if all(ar[i] < ar[i+1] for i in xrange(1, n)):
print 'yes'
print 'swap %d %d' % (swap_i, later_index)
else:
print 'no'
elif downs == ups == 1:
if first_index == 1 or later_index == n:
ar[swap_i], ar[later_index] = ar[later_index], ar[swap_i]
if all(ar[i] < ar[i+1] for i in xrange(1, n)):
print 'yes'
print 'swap %d %d' % (swap_i, later_index)
else:
print 'no'
else:
if first_index - later_index == -1:
ar[first_index], ar[later_index] = ar[later_index], ar[first_index]
if all(ar[i] < ar[i+1] for i in xrange(1, n)):
print 'yes'
print 'swap %d %d' % (first_index, later_index)
else:
print 'no'
else:
ar = ar[:first_index:] + ar[later_index:first_index-1:-1] + ar[later_index+1::]
if all(ar[i] < ar[i+1] for i in xrange(1, n)):
print 'yes'
print 'reverse %d %d' % (first_index, later_index)
else:
print 'no'
elif ups ==1 and downs == 0:
print 'yes'
print 'reverse %d %d' % (first_index, later_index)
else:
print 'no'
I feel there are far too many if-else
blocks ruining the program structure.