简体   繁体   中英

Shuffle a list recursively

I am trying to shuffle a list recursively, that has numbers between 1 - 13 , such that each number in the even indices will be on the right side of the list and the numbers in the odd indices will be on the left side of the new list.
For example take l=[1, 13, 10, 1, 5, 2, 5, 3] .
Function should return: [1, 10, 5, 5, 13, 1, 2, 3] .
Here's my work:

def shuffle(arr, start, stop):
   if stop == 0:
       return [arr[stop-1]]
   return [arr[start]] + shuffle(arr, start + 2, stop - 2) + [arr[stop-1]]

Note: start =0, stop = len(arr) . (and surely the length of the array is a power of 2).

My code output is [1, 10, 5, 5, 3, 13, 1, 2, 3] , I have been trying for hours to get rid of the extra 3 in the middle, but I'm really having a hard time.
When I wrote the return, I thought about solving a smaller problem, and that's how I usually approach recursive answers, and I am taking the first even number and putting it into the left of the list, then sending the "smaller" list, then putting back the last odd number in the list.

I would really appreciate any help of how to fix this problem, I'm trying to overcome this problem for hours, and I feel like understanding how to fix this will help me understand recursion more.
Thanks in advance.

Edit: Sorry if it wasn't clear but I know how to solve it normally, my goal is to solve it recursively.

Instead of using a start and stop , try using a single index and use negative indexing to traverse the list from the right side:

l=[1, 13, 10, 1, 5, 2, 5, 3]

def shuffle(arr, index=0):
  if index >= len(arr):
    return []
  return [arr[index]] + shuffle(arr, index + 2) + [arr[-1-index]]

print(shuffle(l))

This approach only works for lists with an even number of elements, but that should be ok based on what you've told us.

You could partition the list and only recurse for the shuffling of the left and right portions:

from random import choice

def shuffle(A,left=None,done=0):
  if left is None:
    A    = A[::2]+A[1::2]   # partition list
    left = len(A[1::2])     # compute left size for recursion
  if done>left:return A     # all shuffled
  if done<left:            
      rLeft  = choice(range(done,left))            # shuffle left part
      A[done],A[rLeft] = A[rLeft],A[done]
  if left+done<len(A):
      rRight = choice(range(left+done,len(A)))     # shuffle right part
      A[-1-done],A[rRight] = A[rRight],A[-1-done]
  return shuffle(A,left,done+1)                    # recurse

output:

L = [1, 13, 10, 1, 5, 2, 5, 3]

print(shuffle(L))
[10, 5, 5, 1, 2, 1, 3, 13]

Feels much cleaner to me to just create a new list directly:

def shuffle(array):
    return array[0::2] + array[1::2]

l = [1, 13, 10, 1, 5, 2, 5, 3]
print(shuffle(l))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM