Reputation: 65
Suppose you have the following list
a_list = [1, 2, 3, 4, 8, 7, 6]
We want to find the smallest ‘number’ of increasing sequences that contain all elements of the list from either side of the list.
For the example above, we would get
sequence = [[1,2,3,4,8], [6,7]]
Which gives an answer of 2. This is because we can form an increasing sequence from left to right as [1,2,3,4,8]. We can also form an increasing sequence from right to left as [6,7].
I have considered creating two lists which give all the increasing sequences of the list and the reverse of the list, as such
left_to_right = [[1,2,3,4,8],[7], [6]]
right_to_left = [[6,7,8], [4], [3], [2], [1]]
but I am not sure where to go from there. Any thoughts?
Upvotes: 1
Views: 120
Reputation: 3291
EDIT: The original below is unnecessarily complex. Increasing "from the left" just means decreasing. So just iterate over the list once, keeping track of increasing and decreasing sequences with a boolean flag, making them as long as possible, and then count at the end. This should work. Not tested.
increasing = None
current_item = _list[0]
all_sequences = []
current_sequence = [_list[0]]
for item in _list[1:]:
if increasing is None:
increasing = item > current_sequence[-1]
current_sequence.append(item)
elif (item > current_item and increasing) or (item < current_item and not increasing):
current_sequence.append(item)
elif (item > current_item and not increasing) or (item < current_item and increasing):
all_sequences.append(current_sequence)
current_sequence = [item]
increasing = None
current_item = item
all_sequences.append(current_sequence)
result = len(all_sequences)
Original Answer: Here's some thoughts
First, I assume that your function will always make the sequences as long as possible. So you get this:
left_to_right = [[1,2,3,4,8],[7], [6]]
And not, for example, this:
left_to_right = [[1,2],[3],[4,8],[7], [6]]
(which is technically also a list of increasing sequences).
Your next job it to make sure you get all the numbers in the list. So you must pick some increasing sequences. The longer the sequence you pick, the more numbers you get to "use up" while not adding too many more sequences. To take your example:
left_to_right = [[1,2,3,4,8],[7], [6]]
right_to_left = [[6,7,8], [4], [3], [2], [1]]
Join the two lists together:
all = left_to_right + right_to_left
Now find the longest sequence:
longest = max(all, key=lambda x:len(x))
That will give you
[1,2,3,4,8]
Now repeat, grabbing the next longest sequence, keep going until you have captured all the numbers in the list. That would give you:
[[1,2,3,4,8], [6,7,8]]
As a final step, check for duplicates. Then you will get
[[1,2,3,4,8], [6,7]]
as desired
I suspect this should always give you the fewest sequences. But maybe if there are duplicates I might be wrong.
Upvotes: 2