Duck, Duck, Josephus

Given an Integer array:

1. Start from the first number
2. Jump forward n positions where n is the value of the current position
3. Delete the current position, making what was the next position the current position.
4. Goto step 2 until there is one number remaining
5. Print that number

Rules

The array wraps-around (the next number after the last number in the array is the first number).

A zero removes itself (Obviously).

Negative numbers are not allowed as input.

Test Cases

[1] => 1
[1,2] => 1
[1,2,3] => 3
[1,2,2] => 1
[1,2,3,4] => 1
[6,2,3,4] => 4
[1,2,3,4,5] => 5
[0,1] => 1
[0,0,2,0,0] => 0


Step-by-step example

[1,4,2,3,5]
^          start from the first position
^        jump 1 position (value of the position)
[1,  2,3,5] remove number in that position
^      take next position of the removed number (the 'new' 'current' position)
^  jump 2 positions
[1,  2,3  ] remove number in that position
^          take next position (looping on the end of the array)
^      jump 1 position
[1,    3  ] remove number in that position
^    take next position (looping)
^          jump 3 positions (looping on the end of the array)
[      3  ] remove number in that position
print 3


Example #2

[4,3,2,1,6,3]
^            start from the first position
^    jump 4 positions
[4,3,2,1,  3] remove number in that position
^  take next position
^        jump 3 positions
[4,3,  1,  3] remove number in that position
^      take next position
^  jump 1 positions
[4,3,  1    ] remove number in that position
^            take next position
^          jump 4 positions
[4,    1    ] remove number in that position
^      take next position
^            jump 1 position
[      1    ] remove number in that position
print 1


This is , the shortest answer in bytes wins!

• Nice first challenge! – Luis Mendo Dec 12 '17 at 13:49
• @LuisMendo Yes.. the "skip like a..." challenges – ZaMoC Dec 12 '17 at 13:58
• @Jenny_mathy I didn't think there would be a similar one, but as Luis said, the wraparound array makes an interesting challenge for golfing. I think :/ – workoverflow Dec 12 '17 at 14:00
• @EriktheOutgolfer Not really a dupe. The elements there are indistinguishable and the step size is fixed. Luis's is much closer, but still sufficiently different I think. – Martin Ender Dec 12 '17 at 14:12
• Does it need to actually print the final number, or can it just return it? Does it need to actually return the number, or can it just operate on the array in-place so the after the function is run, the array contains just the number? – Reinstate Monica -- notmaynard Dec 12 '17 at 16:48

Perl, 62 bytes

@_=@ARGV;while(@_>1){splice(@_,$i=($i+$_[$i])%@_,1)}print$_[0]  Requires that the numbers are added at command line. Default $i equivalent to 0.

@_=@ARGV;                         # gets the array passed on command line
while(@_>1)                       # if there is more than one element in array, loop
{
splice(@_,$i=($i+$_[$i])%@_,1) # embedded assignment to $i, removes element. } print$_[0]                        # prints remaining element


Perl 5, 43 + 2 (-ap) = 45 bytes

$_="@F[$%@F+1..$#F,0..$%@F-1]",redo if/ /


try it online

Pushy, 11 bytes

@Lt:&:};.;#


Try it online!

This challenge is well suited to be run on a stack:

             \ Implicit: Input on stack
@            \ Reverse the stack
Lt:     ;   \ len(stack)-1 times do:
&: ;     \    (last item) times do:
}      \      Cyclically shift the stack right
.    \    Pop top of stack
#  \ Print remaining value


Python 2, 57 bytes

A couple bytes longer than Mr Xcoder's solution, but I thought it was worth posting this alternate approach.

def f(a,p=0):
while a[1:]:p=(p+(a+a)[p])%len(a);del a[p]


Try it online!

Initially I did this recursively, but it's a few bytes longer:

def f(a,p=0):
if a[1:]:p=(p+(a+a)[p])%len(a);del a[p];f(a,p)


Try it online!

Common Lisp, 129 bytes

(do*((m(coerce(read)'list))(k(rplacd(last m)m)))((eq(cdr m)m)(princ(car m)))(setf k(nthcdr(1-(car m))m)m(cdr(rplacd k(cddr k)))))


Try it online!

><>, 23 + 3 = 26 bytes

{:l3(?\:?\~~
1-&{&\n;\


Try It Online

Takes a series of integers via the -v option.

How It Works

{:l3(?\   Get the first element of the stack and dupe it
.....\n; If the length of the stack is only 2 (the first element twice), then print the number and end the program, else enter the loop

.....\:?\.. Enter the loop with the array and a copy of the first value.
1-&{&\..\   Exit the loop if the copy is 0, else shift the stack right and decrement the copy.

{:l3(?\..\~~ Pop the excess 0 and the current element of the array
...         Go back to the beginning, having one less element than before


Perl, 36 bytes

Includes +2 for ap

perl -apE '--($m||=$_+1)?$F[@F]:$\=\$_ for@F}{' <<< "1 4 2 3 5"; echo


Nicely evil...