4 ms·
Gave it a try. I enjoy writing readable code but it's hard to judge one's own work. What do you all think? def monotonic(arr): """ Turn an unorde
by alecst 5y ago
Gave it a try. I enjoy writing readable code but it's hard to judge one's own work. What do you all think?
def monotonic(arr):
"""
Turn an unordered list into a list of lists of monotone
sequences. All sequences are converted to increasing.
Start reading the list in chunks of two to decide if we're increasing or not.
"""
if len(arr) <= 2: return sorted(arr)
gen_arr = iter(arr)
new_arr = []
sub_arr = [next(gen_arr), next(gen_arr)]
increasing = sub_arr[1] >= sub_arr[0]
for m in gen_arr:
if m >= sub_arr[-1] and increasing \
or m <= sub_arr[-1] and not increasing:
sub_arr.append(m)
else:
new_arr.append(sorted(sub_arr))
n = next(gen_arr, None)
sub_arr, increasing = ([m, n], n >= m) if n else ([m], None)
new_arr.append(sorted(sub_arr))
return new_arr
Edit: thanks for the feedback. Changing `<` to `<=` has fixed some edge cases. Also swapped an if statement with a sort.
I think you could make it even more readable by traversing the list twice and keeping track of the runs.
- xorcist 5y agoThis is the easiest one to read, thanks for that. If the intention of posting it was an invitation for review, here's a quick one. Making the first entry a special case is probably a good idea, but it must also take into account when the first sub_arr is also the only: >>> monotonic([1, 2]) [] There's also the fact that equality is considered a valid increase both not a valid decrease. One might expect that either it is valid as both or none. This is not necessarily wrong but may give surprising results: >>> monotonic([2, 1, 1, 1, 1, 2]) [[1, 2], [1, 1], [1, 1], [1, 2]] Otherwise a readable and straightforward implementation of a somewhat underspecified problem.
- alecst 5y agoThanks. That was absolutely my intention and I'm grateful you replied. I amended this solution by changing strict > to >=, which seems to have fixed some of the problematic behavior.
- xorcist 5y agoAccepting equality is probably desirable, but as the test for ascending is first it will have precedence. If we accept both we probably need to defer the decision to find which it is. Otherwise there will be an inconsistency like: >>> monotonic([2, 2, 1]) [[2, 2], [1]] >>> monotonic([1, 1, 2]) [[1, 1, 2]] As a separate detail, zeros are regarded false in Python: >>> monotonic([1, 2, 1, 0]) [[1, 2], [1]]
- benburk 5y agoFails for [1, 1, 2, 3, 3, 2, 1, 1] -> [[1, 1, 2, 3, 3], [1, 2], [1, 2], [1]]
- alecst 5y agoThanks. I was inconsistent in my use of >= and >. Making them consistent has fixed this edge case.