human
I found an interesting problem on https://www.codewars.com/kata/57e5aa1d7fbcc988800001ae:
# Unflatten a list (Harder than easy)

This is the harder version of Unflatten a list (Easy)

So you have again to build a method, that creates new arrays, that can be flattened!

# Shorter: You have to unflatten a list/an array.

You get an array of integers and have to unflatten it by these rules:
```
- You have to do several runs. The depth is the number of runs, you have to do.
- In every run you have to switch the direction. First run from left, next run from right. Next left...
Every run has these rules:
- You start at the first number (from the direction).
- Take for every number x the remainder of the division by the number of still available elements (from 
  this position!) to have the number for the next decision.
- If the remainder-value is smaller than 3, take this number x (NOT the remainder-Value) direct
  for the new array and continue with the next number.
- If the remainder-value (e.g. 3) is greater than 2, take the next remainder-value-number (e.g. 3)
  elements/numbers (inclusive the number x, NOT the remainder-value) as a sub-array in the new array.
  Continue with the next number/element AFTER this taken elements/numbers.
- Every sub-array in the array is independent and is only one element for the progress on the array. 
  For every sub-array you have to follow the same rules for unflatten it.
  The direction is always the same as the actual run.
```

Sounds complicated? Yeah, thats why, this is the harder version...
Maybe an example will help.

```
 Array: [4, 5, 1, 7, 1] Depth: 2 -> [[ 4, [ 5, 1, 7 ] ], 1]
 
Steps: 
First run: (start from left side!)
1. The first number is 4. The number is smaller than the number of remaining elements, so it is the remainder-value (4 / 5 -> remainder 4).
   So 4 numbers (4, 5, 1, 7) are added as sub-array in the new array.
2. The next number is 1. It is smaller than 3, so the 1 is added direct to the new array.
Now we have --> [[4, 5, 1, 7], 1]

Second run: (start from right side!)
1. The last number (first from other side) is 1. So the 1 is added...

I tried it in Python, but could not do it. Can you solve it?

 Can you provide a the Python code you requested?
assistant
#Here is the Python code you requested.

import enum

class IterDirection(enum.Enum):
    """ Direction in which we iterate/walk. """
    TowardsRight = 1,
    TowardsLeft = 2

def unflatten(arr, depth):

    def is_iterable(obj):
        try:
            iter(obj)
        except TypeError:
            return False
        else:
            return True

    def walk(arr, direction):
        if direction == IterDirection.TowardsLeft:
            a = arr[::-1]
        else:
            a = list(arr)
        index = 0

        def walk_subarray(subarray):
            if direction == IterDirection.TowardsRight:
                yield list(walk(current_element, direction))
            else:
                yield list(walk(current_element, direction))[::-1]

        while index < len(a):
            current_element = a[index]
            if is_iterable(current_element):
                yield from walk_subarray(current_element)
                index += 1
            else:
                n_elements_left = len(arr[index:])
                remainder = current_element % n_elements_left

                if remainder < 3:
                    yield current_element
                    index += 1
                else:
                    if direction == IterDirection.TowardsLeft:
                        yield a[index: index + remainder][::-1]
                    else:
                        yield a[index: index + remainder]
                    index += remainder

    from itertools import cycle, islice
    directions = (IterDirection.TowardsRight, IterDirection.TowardsLeft)

    arr_copy = list(arr)

    for direction in (islice(cycle(directions), depth)):
        if direction == IterDirection.TowardsLeft:
            arr_copy = list(walk(arr_copy, IterDirection.TowardsLeft))[::-1]
        else:
            arr_copy = list(walk(arr_copy, IterDirection.TowardsRight))
    return arr_copy