I have a problem that asks me to write a program that has a defined list (as the argument) and will then find all runs of Y
consecutive numbers that increase or decrease by 1. It will then return the list of indices of the first element of each of these runs.
For example, if Y = 3
, then l1 = [1,2,3,5,10,9,8,9,10,11,7,8,7]
returns [0,4,6,7]
. I got the code working somewhat, but it only works if I 'hard code' how many numbers I am checking. For example, if Y = 3
, then my IF statement is checking l1[i]
, l1[i] + 1
and l1[i] + 2
). I need it to work dynamically no matter what I set Y
to.
Below is my code with my 'base logic':
A = [1,2,3,5,10,9,8,9,10,11,7,8,7]
new_indices = []
for index, number in enumerate(A[:-2]):
urgent_number = abs(A[index + 1])
next_number = abs(A[index + 2])
if (number + 1 == urgent_number and number + 2 == next_number) or (number - 1 == urgent_number and number - 2 == next_number):
new_indices.append(index)
print(new_indices)
Below is my attempt to try and incorporate a while loop to do this dynamically. I'm close, but I just can't seem to figure it out:
A = [1,2,3,5,10,9,8,9,10,11,7,8,7]
Y = 3 #length of list
new_indices = []
for index, number in enumerate(A[:-2]):
urgent_number = abs(A[index + 1])
next_number = abs(A[index + 2])
x = 0
while x < Y:
if (number + 1 == urgent_number and number + 2 == next_number) or (number - 1 == urgent_number and number - 2 == next_number):
new_indices.append(index)
x += 1
print(new_indices)
prints out [0,0,0,4,4,4,6,6,6,7,7,7]
. However, I'm looking for [0,4,6,7]
.
Since you've gotten all the start indices and just need to remove the duplicates, you can do:
from itertools import groupby
original_result = [0,0,0,4,4,4,6,6,6,7,7,7]
final_result = [key for key, _ in groupby(original_result)]
[key for key, _ in groupby(original_result)]
to get the desired output.
This outputs:
[0, 4, 6, 7]
If you need to deal with variable run length specifically, you can find all the valid list slices that could make up a run, and then validate whether or not that slices makes up a run:
A = [1,2,3,5,10,9,8,9,10,11,7,8,7]
RUN_LENGTH = 3
indices = []
for s in range(len(A) - RUN_LENGTH):
is_incrementally_increasing = \
all(i2 - i1 == 1 for i1, i2 in zip(A[s:s+RUN_LENGTH], A[s+1:s+RUN_LENGTH]))
is_incrementally_decreasing = \
all(i1 - i2 == 1 for i1, i2 in zip(A[s:s+RUN_LENGTH], A[s+1:s+RUN_LENGTH]))
if is_incrementally_increasing or is_incrementally_decreasing:
indices.append(s)
print(indices)
This also outputs:
[0, 4, 6, 7]