Skip like a frog!

JavaScript (ES6), 45 bytes

f=(a,k=0,x=a[k])=>1/x?f(a.splice(x,1)&&a,x):a

Test cases

f=(a,k=0,x=a[k])=>1/x?f(a.splice(x,1)&&a,x):a

console.log(JSON.stringify(f([1, 2, 3, 4, 5]))) // --> [1, 3, 4]
console.log(JSON.stringify(f([6, 1, 0, 5, 6]))) // --> [6, 1, 0, 5, 6]
console.log(JSON.stringify(f([1, 3, 2, 4, 11, 5, 2, 0, 13, 10, 1]))) // --> [1, 2, 11, 5, 2, 0, 13, 10, 1]
console.log(JSON.stringify(f([2, 2, 2, 2, 2, 2]))) // --> [2, 2]
console.log(JSON.stringify(f([1, 2, 3, 1, 2, 3, 1, 2, 3]))) // -> [1, 2]
console.log(JSON.stringify(f([3, 1, 2, 4, 0]))) // --> []


Haskell, 50 bytes

g.pure.(0:) is an anonymous function taking and returning a list of Ints, use as (g.pure.(0:))[1,2,3,4,5].

g.pure.(0:)
g(a,_:b:c)=g$splitAt b$a++b:c
g(a,_)=a

Try it online!

How it works

  • The function g takes a tuple argument representing a split list. a is the list of initial elements kept at the previous step, _ is the element to be discarded, b is the next element to be used as a length, and c is the remaining elements.
    • If there are enough elements in the second part of the tuple to select a b, then a new split is performed and g recurses. Otherwise, it halts with a as the result.
  • The anonymous function g.pure.(0:) starts it all by calling g with the tuple ([],0:l), where l is the input and 0 gets immediately discarded by g.
    • pure here uses the Applicative instance for (binary) tuples, and with the result type ([Int],[Int]) conveniently puts its argument as the second element in a tuple with [] as first element.

Python 3, 59 bytes

f=lambda a,i=0:f(a[:a[i]]+a[a[i]+1:],a[i])if i<len(a)else a

Try it online!