I want a wrap around index like 1232123...., and the frame size is 3. How to implement it? Does it has a term?
for i in 1..100 {
let idx = loop_index(i);
print!("{} ", idx);
}
Expected output for frame 3:
1 2 3 2 1 2 3 2 1...
Expected output for frame 4:
1 2 3 4 3 2 1 2 3 4 3 2 1...
CodePudding user response:
For a size of 3, notice that the sequence 1232 has length 4, and then it repeats. In general, for size n
, the length is 2*(n-1)
. If we take the modulo i % (2*(n-1))
, the task becomes simpler: turn a sequence 0123..(2*(n-1)-1)
into 123..(n-1)n(n-1)..321
. And this can be done using abs
and basic arithmetic:
n = 3
r = 2 * (n - 1)
for i in range(20):
print(n - abs(n - (i % r)) - 1))
CodePudding user response:
When you reach the top number, you start decreasing; when you reach the bottom number, you start increasing.
Don't change direction until you reach the top or bottom number.
def count_up_and_down(bottom, top, length):
assert(bottom < top)
direction = 1
x = bottom
for _ in range(length):
yield x
direction = -1 if x == top else 1 if x == bottom else direction
x = x direction
for i in count_up_and_down(1, 4, 10):
print(i, end=' ')
# 1 2 3 4 3 2 1 2 3 4
Alternatively, combining two range
s with itertools
:
from itertools import chain, cycle, islice
def count_up_and_down(bottom, top, length):
return islice(cycle(chain(range(bottom, top), range(top, bottom, -1))), length)
for i in count_up_and_down(1, 4, 10):
print(i, end=' ')
# 1 2 3 4 3 2 1 2 3 4