g | x | w | all
Bytes Lang Time Link
031Uiua251016T131838ZJake
036R250622T142305Zpajonk
nanCommodore 64 Assembler250620T215540ZJani Joe
012Charcoal250617T125115ZNeil
044brainfuck250627T180029Zmatteo_c
0188086 machine code .COM format250626T075908ZErikF
027C clang250618T011148Za stone
050Swift 6250621T143927ZmacOSist
029jq250615T212207ZGammaFun
024Python250615T231418ZLucenapo
011oK250620T090333Zzgrep
034Haskell250615T222331ZIbozz91
025JavaScript Node.js250620T034851Zl4m2
nanPerl 5 a250618T061929ZXcali
00705AB1E250617T082332ZKevin Cr
004Vyxal250617T081233Zlyxal
025Ruby250617T222453ZValue In
007APLDyalog Unicode 20250617T095554ZMat_rdv
052APLNARS250617T075458ZRosario
034Retina 0.8.2250617T051305ZNeil
062Excel250617T011302Zz..
028JavaScript ES6250615T212341ZArnauld
006Jelly250615T194722ZJonathan

Uiua, 31 bytes

⍢(˜↘⟜⊢|⍣(≠0⊢)0)

Try it online!

Outputs empty list for escaped, non-empty for trapped

R, 37 36 bytes

f=\(L)!sum(L|1)||L[1]&f(L[-1:-L[1]])

Attempt This Online!

Commodore 64 Assembler, 19 14 Bytes (6502/KickAssembler)

Routine

CWEFTA: lax #0      // 2 Reset A and X.
walk:   dey         // 1 Have we taken more steps than the size of array?
        bmi end     // 2 If yes, we're stuck in a loop and couldn't escape.
        clc         // 1 Clear carry flag
        adc array,x // 2 Add array element at index X to A
        tax         // 1 Make it the new array index
        cmp length  // 2 Have we gone past the end of the array yet?
        bcc walk    // 2 If not, continue moving forward in the array
end:    rts         // 1 Positive Y for escape, negative for failure

Explanation

Try It Out (in your favourite IDE or CLI)

First in this test program the array and its length are copied to zero page, then our golfing code routine is called, and finally border colour is changed according to the result in Y register: White for successful escape, Black for failure.

.const length = $2  // Length of the array is held on ZP address $2
.const array = $3   // Array itself starts from ZP address $3

BasicUpstart2(start)

start:  sei         // Disable IRQs (stop BASIC and KERNAL from messing with ZP)
        lax le
        tay
        sty length  // Copy array length from our program to zero page
copy:   lda ar-1,x  // Copy array from our program to zero page
        sta array-1,x
        dex
        bne copy
        jsr CWEFTA  // CALL OUR ROUTINE
        cpy #0      // Is Y positive or negative?
        bmi nega    // Jump if negative
        ldy #WHITE  // Otherwise, load white
        .by $2c     // BIT abs to skip the next two bytes
nega:   ldy #BLACK  // Load black
        sty $d020   // White border=escaped, black=didn't
        cli         // Re-enable interrupts...
        rts         // ...and return to BASIC prompt

ar:     .by 0,4,1,78,2
le:     .by (le-ar)

// Can We Escape From The Array?
CWEFTA: lax #0      // 2 Reset A and X.
walk:   dey         // 1 Have we taken more steps than the size of array?
        bmi end     // 2 If yes, we're stuck in a loop and couldn't escape.
        clc         // 1 Clear carry flag
        adc array,x // 2 Add array element at index X to A
        tax         // 1 Make it the new array index
        cmp length  // 2 Have we gone past the end of the array yet?
        bcc walk    // 2 If not, continue moving forward in the array
end:    rts         // 1 Positive Y for escape, negative for failure

Charcoal, 12 bytes

FA¿ⅈ←M⊖ι→‹ⅈ⁰

Try it online! Link is to verbose version of code. Outputs an inverted Charcoal boolean, i.e. nothing if we escape, - if we don't. Explanation:

FA

Loop through the values.

¿ⅈ←

If we're skipping values then decrement the count left to skip, otherwise...

M⊖ι→

... start skipping values according to the current value, unless that is zero, in which case skip everything.

‹ⅈ⁰

See whether we skipped everything. (¬‹ⅈ⁰ would see whether we escaped.)

brainfuck, 44 bytes

>>-,+[->+<[>-]>[<<[-]+>>->]<<-[-<<,>>]-,+]<.

Outputs 0 if the answer is true, 1 if false.

Assumes that:

The used algorithm works in the following way:

  1. the answer cell is automatically initialized with 0;
  2. try to read an int/char from the input;
    • if 0 is read, the array input is inescapable and the answer cell is set to 1 and go to step 2 (we could also go directly to step 3 but I found it harder to implement);
    • if any other number n is read, skip the next n-1 input chars and go to step 2;
    • if EOF is reached, go to step 3.
  3. output the value of the answer cell.

Ungolfed and commented program:

>>

read input until EOF
-,+
[
    -

    if read 0 set error
    >temp0[-]+
    >temp1[-]
    <<x[
        do nothing
    x>-]>
    [<
        set error
        <[-]+>
    x>->]<<

    skip (n minus 1) input chars
    -
    [-<<,>>]

    -,+
]

output: 0 if true; 1 if false
<.

8086 machine code (.COM format), 18 bytes

Returns AX=0/ZF (false: cannot finish) or AX<>0/!ZF (truthy: did finish)

I iterate through the array until either I hit 0 as an next-entry offset or exceed the bounds of the array. To determine the bounds, I shorten the array length by one to account for the mandatory first element and then subtract the offsets from the remaining array length; if the remaining length goes negative, the array bounds have been exceeded.

Notes:

Machine code bytes (in hex)

49 33 C0 AC 84 C0 74 09 2B C8 78 05 48 03 F0 EB F2 C3

Assembly source

;; DS:[SI]: array
;; CX: array length
;; Returns:
;;     AX=0 or ZF (FALSE): array traversal does not complete
;;     AX<>0 or !ZF (TRUE): traversal does complete

PROC TRAVENDS
START:
DEC CX ; Adjust the count to account for mandatory first element
XOR AX,AX ; Not using AH: clear both parts
SCANLOOP:
LODSB
TEST AL,AL ; Is it 0 (the only value that fails)?
JZ DONE ; Can't continue
SUB CX,AX ; Adjust the new array length remaining (0=last element)
JS DONE ; Done if remaining length is <0 (past the bounds)
DEC AX ; Adjust for LODSB
ADD SI,AX ; Move array pointer
JMP SHORT SCANLOOP
DONE:
RET
ENDP TRAVENDS

Test harness

IDEAL
P8086

MODEL   TINY
CODESEG
ORG 100H

MAIN:
MOV BX,0A00H ; Preload "10" for the following DIV; set parse state to "space"
XOR CX,CX ; Number of array elements
MOV SI,81H ; Command line
MOV DI,OFFSET ARRDATA ; Array output
ARRLOOP:
XOR DX,DX ; Zero out the number value
NUMLOOP:
LODSB ; Get character
SUB AL,' '
JZ ISSPACE ; Is space, next element
JS ISDONE ; Is some other control character (we're assuming 0DH), done parsing elements
SUB AL,'0'-' ' ; Not in '0'-'9'
JS SYNTAX
CMP AL,9
JA SYNTAX
TEST BL,BL ; Came out of "space" state?
JNZ INNUM
INC CX ; Increase array count
MOV BL,1 ; Set state to "number"
INNUM:
MOV AH,DL
AAD ; Store (prev*10)+curr
MOV DX,AX
JMP SHORT NUMLOOP
ISDONE:
MOV BL,2 ; Completed array
ISSPACE:
TEST BL,BL ; Still in "space" state?
JZ ENDSPACE
NUMDONE:
XCHG AX,DX ; Just left "number" state: store in array
STOSB
ENDSPACE:
CMP BL,2
JZ ARRDONE ; Done array?
MOV BL,0 ; In "space" state
JMP SHORT ARRLOOP
ARRDONE:
MOV [ARRSIZE],CX ; Store array length for later use
TEST CX,CX ; Quit if no elements stored
JZ SYNTAX

PRINTARR: ; Print array (always at least one entry)
MOV AH,9
MOV DX,OFFSET ARRSTARTTEXT
INT 21H
MOV SI,OFFSET ARRDATA
PRINTELEMS:
DEC CX
XOR AX,AX ; Division target
LODSB
TEST AL,AL
JZ ISZERO ; Is '0', just print it
CALL PROC PRINTNUM ; Print number
JMP SHORT ENDNUM
ISZERO:
MOV AH,2
MOV DL,'0'
INT 21H
ENDNUM:
MOV AH,9
TEST CX,CX ; Array done?
JZ ENDARR ; Yes, print next bit of output
MOV DX,OFFSET ARRMIDTEXT ; No, print a comma and space
INT 21H
JMP SHORT PRINTELEMS
ENDARR:
MOV DX,OFFSET ARRENDTEXT
INT 21H

TRAVERSE:
MOV CX,[ARRSIZE] ; Restore the array size
MOV SI,OFFSET ARRDATA ; Restore the array start
CALL PROC TRAVENDS ; Check if the traversal goes out of bounds
MOV AH,9
JZ PRINTFAIL ; function returns AX=0 (or ZF): false
PRINTSUCCESS:
MOV DX,OFFSET SUCCESSTEXT ; function returns AX<>0 (or !ZF): truthy
JMP SHORT ENDMAIN
PRINTFAIL:
MOV DX,OFFSET FAILTEXT
JMP SHORT ENDMAIN
SYNTAX:
MOV AH,9
MOV DX,OFFSET USAGETEXT
ENDMAIN:
INT 21H
MOV DX,OFFSET ENDTEXT ; Output CR+LF
INT 21H
MOV AX,4C00H ; Done
INT 21H

PROC PRINTNUM
DIV BH ; AL = AL/10
XOR DX,DX ; Storage register
MOV DL,AH ; Store remainder
PUSH DX ; Keep on stack for printing later
XOR AH,AH ; Make sure AH is clear to avoid division messups
TEST AL,AL ; Finished divisions: quotient=0
JNZ NOTDONE
JMP SHORT PRINTDIGIT
NOTDONE:
CALL PROC PRINTNUM ; Recurse and fall into print digit routine (AL>0)
PRINTDIGIT:
MOV AH,2
POP DX
ADD DL,'0'
INT 21H ; Print stored digit
RET
ENDP PRINTNUM


;; DS:[SI]: array
;; CX: array length
;; Returns: AX=0 (FALSE): array traversal does not complete, <>0 (TRUE): traversal does complete

PROC TRAVENDS
START:
DEC CX ; Adjust the count to be zero-based
XOR AX,AX ; Not using AH: clear both parts
SCANLOOP:
LODSB
TEST AL,AL ; Is it 0 (the only value that fails)?
JZ DONE ; Can't continue
SUB CX,AX ; Adjust the new array length remaining (0=last element)
JS DONE ; Done if remaining length is <0 (past the bounds)
DEC AX ; Adjust for LODSB
ADD SI,AX ; Move array pointer
JMP SHORT SCANLOOP
DONE:
RET
ENDP TRAVENDS

USAGETEXT DB "TRAVARR: array values$"
ARRSTARTTEXT DB "Array: [$"
ARRMIDTEXT DB ", $"
ARRENDTEXT DB "]: $"
SUCCESSTEXT DB "success$"
FAILTEXT DB "fail$"
ENDTEXT DB 0DH, 0AH, "$"

ARRSIZE DW ?
ARRDATA DB ?

END MAIN
ENDS

C (clang), 34 27 bytes

-7 thanks to @jdt

f(*a,l){l<1||f(a+*a,l-*a);}

Try it online! Takes input as a pointer to an array and its length. Returns nonzero if escape is possible, otherwise segfaults.

f(*a,l){                     /* function taking array of int a and its length l */
        l<1                  /* if length < 1: (implicitly return) */
           ||                /* else: */
             f(a+*a,l-*a);}  /* call f with the array advanced by its first 
                                element.  If this element is zero, then it
                                recurses infinitely, causing a stack overflow */

Swift 6, 50 bytes

let e={[]==$0||0<$0[0]&&e([]+$0.dropFirst($0[0]))}

Try it on SwiftFiddle!

jq, 36 29 bytes

-7 bytes by Niel for using null + 00 to simplify the loop condition.

until(.[0]+0==0;.[.[0]:])==[]

Try it online! Try it online!

.[.[0]:] slices off the first .[0] elements. We repeat this operation until either the array is empty or the first element is 0. The result is whether the array is empty.

Python, 30 26 24 bytes

def f(x):f(x[x[0]or.0:])

Attempt This Online!

oK, 11 bytes

~#{*x_\:x}/

Try it online!

Haskell, 36 34 bytes

f[]=1>0
f(x:a)=x>0&&(f$drop x$x:a)

Try it online!

-2 bytes thanks to Mat_rdv

JavaScript (Node.js), 25 bytes

a=>a.every(k=t=>k=--k||t)

Try it online!

a=>a.every(t=>a=--a||t) would fail [0] (it successfully decrease to nonzero)

Perl 5 -a, 31 + 1 = 32 bytes

$p+=$F[$p]while$F[$p];say$p>$#F

Try it online!

05AB1E, 7 bytes

Δ¬.$}g_

Returns 1/0 for escaped/trapped respectively.

Try it online or verify all test cases.

Unfortunately, only 1 is truthy in 05AB1E, and everything else is falsey. Outputting an empty array when escaped and a non-empty array when trapped would be just 4 bytes by removing the trailing }g_:
Try it online or verify all test cases.

Explanation:

Δ     # Loop until the result no longer changes
      # (using the implicit input-list in the first iteration):
 ¬    #  Get the first item (without popping the list)
  .$  #  Remove that many leading items from the list
}     # After the changes-loop:
 g_   # Check that the resulting list is empty
      # (after which the result is output implicitly)

Vyxal, 4 bytes

hȯ)Ẋ

Try it Online!

Outputs an empty list for escaped, and a non empty list for trapped.

Explained

hȯ)Ẋ­⁡​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤‏‏​⁡⁠⁡‌⁢​‎⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢‏‏​⁡⁠⁡‌­
  )Ẋ  # ‎⁡Repeat until the input doesn't change, starting with the input:
 ȯ    # ‎⁢  Remove the first
h     # ‎⁣  result[0]
 ȯ    # ‎⁤  items of the result
💎

Created with the help of Luminespire.

Ruby, 25 bytes

Returns true if we escape, or throws SystemStackError if not. I could save 1 byte by switching to z&& and returning nil if we escape, but I don't want my returns to be falsy vs error so I won't.

f=->a{z,=a;!z||f[a[z..]]}

Attempt This Online!

APL(Dyalog Unicode 20), 7 bytes SBCS

⍬≡⊃⍛↓⍣≡

Try it on APLgolf!

Explanation

      ≡   Match (array equality)
     ⍣    Power
     ⍣≡   fixpoint (do until the argument stop changing)
    ↓     Drop
   ⍛      f⍛g Y ←→ (f Y) g Y
  ⊃       First element
  ⊃⍛↓     drop as many elements of a vector as indicated by its first element
 ≡       
⍬        Empty vector
⍬≡⊃⍛↓⍣≡  solution

APL(NARS), 52 chars

r←f w;i
i←r←1
→0×⍳i>≢w⋄→3×⍳0≠w[i]⋄r←0⋄→0
i+←w[i]⋄→2

// 8+6+27+11 = 52

0 It means false, 1 It means true. test: (,1 means one array of 1 ement that is 1)

  f ,1
1
  f 1 4 0
1
  f 0 4 1 78 2
0
  

Retina 0.8.2, 34 bytes

\d+
$*
^.(?>(?=(1)+)(?<-1>1*.)+)+$

Try it online! Link includes test cases. Explanation:

\d+
$*

Convert the values to unary.

^.(?>...)+$

Repeatedly match but without backtracking if the end of the array cannot be reached. This helps by not having to ensure that the correct number of positions were skipped but also by not having to ensure that each position was properly skipped.

(?=(1)+)

Look ahead to see how many positions to skip.

(?<-1>1*.)+

Use a .NET balancing group to skip that many positions.

Excel, 62 bytes

Expects the array in A1:A

=LET(F,LAMBDA(F,i,LET(x,INDEX(A:.A,i),IF(x,F(F,i+x)))),F(F,1))

Returns #REF! if we can escape and FALSE if we can't.

JavaScript (ES6), 28 bytes

Returns undefined if we can escape or 0 if we're trapped.

f=(a,i=0)=>a[i]&&f(a,i+a[i])

Try it online!

Jelly, 6 bytes

ṫ‘ḢƊÐL

A monadic Link that accepts a list of nonnegative integers and yields 0 (falsey) if we will escape the array, or a non-empty list (truthy) if we will be trapped.
(To not have inverted order, add for +1 byte)

Try it online! Or see the test-suite.

How?

ṫ‘ḢƊÐL - Link: list of non-negative integers
    ÐL - repeat while results are unique, applying:
   Ɗ   -   last three links as a monad - f(Current):
ṫ      -     tail of {Current} from each 1-index...
 ‘     -     ...incremented elements of {Current}
  Ḣ    -     head -> Current tailed from 1-index of its first element
                     ...or zero if {Current} is empty