Van Eck sequence

From Rosetta Code
Task
Van Eck sequence
You are encouraged to solve this task according to the task description, using any language you may know.

The sequence is generated by following this pseudo-code:

A:  The first term is zero.
    Repeatedly apply:
        If the last term is *new* to the sequence so far then:
B:          The next term is zero.
        Otherwise:
C:          The next term is how far back this last term occured previously.


Example

Using A:

0

Using B:

0 0

Using C:

0 0 1

Using B:

0 0 1 0

Using C: (zero last occurred two steps back - before the one)

0 0 1 0 2

Using B:

0 0 1 0 2 0

Using C: (two last occurred two steps back - before the zero)

0 0 1 0 2 0 2 2

Using C: (two last occurred one step back)

0 0 1 0 2 0 2 2 1

Using C: (one last appeared six steps back)

0 0 1 0 2 0 2 2 1 6

...


Task
  1. Create a function/procedure/method/subroutine/... to generate the Van Eck sequence of numbers.
  2. Use it to display here, on this page:
  1. The first ten terms of the sequence.
  2. Terms 991 - to - 1000 of the sequence.


References



11l

Translation of: Python: List based
F van_eck(c)
   [Int] r
   V n = 0
   V seen = [0]
   V val = 0
   L
      r.append(val)
      I r.len == c
         R r
      I val C seen[1..]
         val = seen.index(val, 1)
      E
         val = 0
      seen.insert(0, val)
      n++

print(‘Van Eck: first 10 terms:   ’van_eck(10))
print(‘Van Eck: terms 991 - 1000: ’van_eck(1000)[(len)-10..])
Output:
Van Eck: first 10 terms:   [0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
Van Eck: terms 991 - 1000: [4, 7, 30, 25, 67, 225, 488, 0, 10, 136]

8080 Assembly

	org	100h
	lxi	h,ecks	; Zero out 2000 bytes
	lxi	b,0
	lxi	d,2000
zero:	mov	m,b
	inx	h
	dcx	d
	mov	a,d
	ora	e
	jnz 	zero
	lxi	b,-1	; BC = Outer loop variable
outer:	inx	b
	mvi	a,3	; Are we there yet? 1000 = 03E8h
	cmp	b	; Compare high byte
	jnz	go
	mvi	a,0E8h	; Compare low byte
	cmp	c
	jz	done
go:	mov	d,b	; DE = Inner loop variable
	mov	e,c
inner:	dcx	d
	mov	a,d	; <= 0?
	ral
	jc	outer
	push	b	; Keep both pointers
	push	d
	mov	h,b	; Load BC = eck[BC]
	mov	l,c
	call	eck
	mov	c,m
	inx	h
	mov	b,m
	xchg		; Load HL = -eck[DE]
	call	eck
	xchg
	ldax 	d
	cma
	mov	l,a
	inx	d
	ldax 	d
	cma
	mov	h,a
	inx	h 	; Two's complement
	dad	b	; -eck[DE] + eck[BC]
	mov	a,h	; Unfortunately this does not set flags
	ora	l	; Check zero
	pop	d	; Meanwhile, restore the pointers
	pop	b
	jnz	inner	; If no match, continue with inner loop
	mov	h,b	; If we _did_, then get &eck[BC + 1]
	mov	l,c 
	inx	h
	call 	eck
	mov	a,c	; Store BC - DE at that address
	sub	e
	mov	m,a
	inx	h
	mov	a,b
	sbb	d
	mov	m,a
	jmp 	outer	; And continue the outer loop
done:	lxi	h,0	; Print first 10 terms
	call	p10
	lxi	h,990	; Print last 10 terms
p10:	mvi 	b,10	; Print 10 terms starting at term HL
	call	eck
ploop:	mov	e,m	; Load term into DE
	inx	h
	mov	d,m 
	inx	h
	push 	b	; Keep counter 
	push 	h	; Keep pointer
	xchg		; Term in HL
	call	printn	; Print term
	pop 	h	; Restore pointer and counter
	pop 	b
	dcr	b
	jnz	ploop
	lxi	d,nl	; Print a newline afterwards
	jmp	prints
eck:	push	b	; Set HL = &eck[HL]
	lxi	b,ecks	; Base address
	dad	h	; Multiply by two 
	dad	b	; Add base 
	pop	b
	ret
printn:	lxi	d,buf	; Print the number in HL
	push	d	; Buffer pointer on stack
	lxi	b,-10	; Divisor
pdigit:	lxi	d,-1	; Quotient
pdiv:	inx 	d
	dad	b
	jc 	pdiv
	mvi	a,'0'+10
	add	l	; Make ASCII digit
	pop	h
	dcx	h	; Store digit
	mov	m,a
	push 	h
	xchg
	mov	a,h	; Quotient nonzero?
	ora	l
	jnz	pdigit	; Then there are more digits
	pop	d 	; Otherwise, print string using CP/M
prints:	mvi	c,9
	jmp	5
nl:	db	13,10,'$'
	db	'.....'
buf:	db	' $'
ecks:	equ	$
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

8086 Assembly

LIMIT:	equ	1000
	cpu	8086
	org	100h
section	.text
	mov	di,eck		; Zero out the memory
	xor	ax,ax
	mov	cx,LIMIT
	rep	stosw
	mov	bx,eck		; Base address
	mov	cx,LIMIT	; Limit
	xor	ax,ax
	mov	si,-1		; Outer loop index
outer:	inc	si		
	dec	cx
	jcxz	done
	mov	di,si		; Inner loop index
inner:	dec	di
	js	outer
	shl	si,1		; Shift the loop indices (each entry is 2 bytes)
	shl	di,1
	mov	ax,[si+bx]	; Find a match?
	cmp	ax,[di+bx]
	je	match
	shr	si,1		; If not, shift SI and DI back and keep going
	shr	di,1
	jmp	inner
match:	mov	ax,si		; Calculate the new value
	sub	ax,di
	shr	ax,1		; Compensate for shift
	mov	[si+bx+2],ax	; Store value
	shr	si,1		; Shift SI back and calculate next value
	jmp	outer
done:	xor	si,si		; Print first 10 elements
	call	p10
	mov	si,LIMIT-10	; Print last 10 elements⌈
p10:	mov	cx,10		; Print 10 elements starting at SI
	shl	si,1		; Items are 2 bytes wide
	add	si,eck
.item:	lodsw			; Retrieve item
	call	printn		; Print it 
	loop	.item
	mov	dx,nl		; Print a newline afterwards
	jmp	prints
printn:	mov	bx,buf		; Print AX
	mov	bp,10
.digit:	xor	dx,dx		; Extract digit
	div	bp
	add	dl,'0'		; ASCII digit
	dec	bx	
	mov	[bx],dl		; Store in buffer
	test	ax,ax		; Any more digits?
	jnz	.digit
	mov	dx,bx
prints:	mov	ah,9		; Print string in buffer
	int	21h
	ret 
section	.data
nl:	db	13,10,'$'
	db	'.....'
buf:	db	' $'
section	.bss
eck:	resw	LIMIT
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

AArch64 Assembly

Works with: as version Raspberry Pi 3B version Buster 64 bits
/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program vanEckSerie64.s   */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeConstantesARM64.inc"

.equ MAXI,      1000

/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResultElement:    .asciz " @ "
szCarriageReturn:   .asciz "\n"

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
sZoneConv:                  .skip 24
TableVanEck:                .skip 8 * MAXI
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                             // entry of program 
    mov x2,#0                     // begin first element
    mov x3,#0                     // current counter
    ldr x4,qAdrTableVanEck        // table address
    str x2,[x4,x3,lsl 3]          // store first zéro
1:                                // begin loop 
    mov x5,x3                     // init current indice
2:
    sub x5,x5,1                   // decrement
    cmp x5,0                      // end table ?
    blt 3f
    ldr x6,[x4,x5,lsl 3]          // load element
    cmp x6,x2                     // and compare with the last element
    bne 2b                        // not equal
    sub x2,x3,x5                  // else compute gap
    b 4f
3:
    mov x2,#0                     // first, move zero to next element
4:
    add x3,x3,#1                  // increment counter
    str x2,[x4,x3,lsl 3]          // and store new element
    cmp x3,MAXI
    blt 1b
    
    mov x2,0
5:                                // loop display ten elements
    ldr x0,[x4,x2,lsl 3]
    ldr x1,qAdrsZoneConv
    bl conversion10               // call décimal conversion
    ldr x0,qAdrsMessResultElement
    ldr x1,qAdrsZoneConv          // insert conversion in message
    bl strInsertAtCharInc
    mov x1,0                      // final zéro
    strb w1,[x0,5]                // 
    bl affichageMess              // display message
    add x2,x2,1                   // increment indice
    cmp x2,10                     // end ?
    blt 5b                        // no -> loop
    ldr x0,qAdrszCarriageReturn
    bl affichageMess
    
    mov x2,MAXI - 10
6:                                // loop display ten elements 990-999
    ldr x0,[x4,x2,lsl 3]
    ldr x1,qAdrsZoneConv
    bl conversion10               // call décimal conversion
    ldr x0,qAdrsMessResultElement
    ldr x1,qAdrsZoneConv          // insert conversion in message
    bl strInsertAtCharInc
    mov x1,0                      // final zéro
    strb w1,[x0,5]                // 
    bl affichageMess              // display message
    add x2,x2,1                   // increment indice
    cmp x2,MAXI                   // end ?
    blt 6b                        // no -> loop
    ldr x0,qAdrszCarriageReturn
    bl affichageMess

100:                              // standard end of the program 
    mov x0, 0                     // return code
    mov x8, EXIT                  // request to exit program
    svc 0                         // perform the system call
qAdrszCarriageReturn:    .quad szCarriageReturn
qAdrsMessResultElement:  .quad sMessResultElement
qAdrsZoneConv:           .quad sZoneConv  
qAdrTableVanEck:         .quad TableVanEck
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 0  0  1  0  2  0  2  2  1  6
 4  7  30  25  67  225  488  0  10  136

ABC

HOW TO RETURN vaneck.sequence length:
    PUT {[1]: 0} IN seq
    WHILE #seq < length:
        PUT #seq-1 IN i
        WHILE i>0 AND seq[i]<>seq[#seq]: PUT i-1 IN i
        SELECT:
            i=0: PUT 0 IN seq[#seq+1]
            ELSE: PUT #seq-i IN seq[#seq+1]
    RETURN seq

PUT vaneck.sequence 1000 IN eck
FOR i IN {1..10}: WRITE eck[i]>>4
WRITE /
FOR i IN {991..1000}: WRITE eck[i]>>4
WRITE /
Output:
   0   0   1   0   2   0   2   2   1   6
   4   7  30  25  67 225 488   0  10 136

Action!

INT FUNC LastPos(INT ARRAY a INT count,value)
  INT pos
  
  pos=count-1
  WHILE pos>=0 AND a(pos)#value
  DO
    pos==-1
  OD
RETURN (pos)

PROC Main()
  DEFINE MAX="1000"
  INT ARRAY seq(MAX)
  INT i,pos

  seq(0)=0
  FOR i=1 TO MAX-1
  DO
    pos=LastPos(seq,i-1,seq(i-1))
    IF pos>=0 THEN
      seq(i)=i-1-pos
    ELSE
      seq(i)=0
    FI
  OD

  PrintE("Van Eck first 10 terms:")
  FOR i=0 TO 9
  DO
    PrintI(seq(i)) Put(32)
  OD
  PutE() PutE()

  PrintE("Van Eck terms 991-1000:")
  FOR i=990 TO 999
  DO
    PrintI(seq(i)) Put(32)
  OD
RETURN
Output:

Screenshot from Atari 8-bit computer

Van Eck first 10 terms:
0 0 1 0 2 0 2 2 1 6

Van Eck terms 991-1000:
4 7 30 25 67 225 488 0 10 136

Ada

with Ada.Text_IO;

procedure Van_Eck_Sequence is

   Sequence : array (Natural range 1 .. 1_000) of Natural;

   procedure Calculate_Sequence is
   begin
      Sequence (Sequence'First) := 0;
      for Index in Sequence'First .. Sequence'Last - 1 loop
         Sequence (Index + 1) := 0;
         for I in reverse Sequence'First .. Index - 1 loop
            if Sequence (I) = Sequence (Index) then
               Sequence (Index + 1) := Index - I;
               exit;
            end if;
         end loop;
      end loop;
   end Calculate_Sequence;

   procedure Show (First, Last : in Positive) is
      use Ada.Text_IO;
   begin
      Put ("Element" & First'Image & " .." & Last'Image & " of Van Eck sequence: ");
      for I in First .. Last loop
         Put (Sequence (I)'Image);
      end loop;
      New_Line;
   end Show;

begin
   Calculate_Sequence;
   Show (First =>   1, Last =>    10);
   Show (First => 991, Last => 1_000);
end Van_Eck_Sequence;
Output:
Element 1 .. 10 of Van Eck sequence:  0 0 1 0 2 0 2 2 1 6
Element 991 .. 1000 of Van Eck sequence:  4 7 30 25 67 225 488 0 10 136

ALGOL 68

BEGIN # find elements of the Van Eck Sequence - first term is 0, following  #
      # terms are 0 if the previous was the first appearance of the element #
      #        or how far back in the sequence the last element appeared    #
    # returns the first n elements of the Van Eck sequence                  #
    OP VANECK = ( INT n )[]INT:
       BEGIN
            [ 1 : IF n < 0 THEN 0 ELSE n FI ]INT result; FOR i TO n DO result[ i ] := 0 OD;
            [ 0 : UPB result ]INT pos;  FOR i FROM 0 TO n DO pos[ i ] := 0 OD;
            FOR i FROM 2 TO n DO
                INT j    = i - 1;
                INT prev = result[ j ];
                IF pos[ prev ] /= 0 THEN
                    # not a new element                                     #
                    result[ i ] := j - pos[ prev ]
                FI;
                pos[ prev ] := j
            OD;
            result
       END # VANECK # ;
    # construct the first 1000 terms of the sequence                        #
    []INT seq = VANECK 1000;
    # show the first and last 10 elements                                   #
    FOR i TO 10 DO print( ( " ", whole( seq[ i ], 0 ) ) ) OD;
    print( ( newline ) );
    FOR i FROM UPB seq - 9 TO UPB seq DO print( ( " ", whole( seq[ i ], 0 ) ) ) OD;
    print( ( newline ) )
END
Output:
 0 0 1 0 2 0 2 2 1 6
 4 7 30 25 67 225 488 0 10 136

ALGOL-M

begin
integer array eck[1:1000];
integer i, j;

for i := 1 step 1 until 1000 do 
    eck[i] := 0;

for i := 1 step 1 until 999 do
begin
    j := i - 1;
    while j > 0 and eck[i] <> eck[j] do
        j := j - 1;
    if j <> 0 then
        eck[i+1] := i - j;
end;

for i := 1 step 1 until 10 do
    writeon(eck[i]);
write("");
for i := 991 step 1 until 1000 do
    writeon(eck[i]);

end
Output:
     0     0     1     0     2     0     2     2     1     6
     4     7    30    25    67   225   488     0    10   136

ALGOL W

Translation of: ALGOL 68
begin % find elements of the Van Eck Sequence - first term is 0, following  %
      % terms are 0 if the previous was the first appearance of the element %
      %        or how far back in the sequence the last element appeared    %
    % sets s to the first n elements of the Van Eck sequence                %
    procedure VanEck ( integer array s ( * ) ; integer value n ) ;
    begin
        integer array pos ( 0 :: n );
        for i := 1 until n do s(   i ) := 0;
        for i := 0 until n do pos( i ) := 0;
        for i := 2 until n do begin
            integer j, prev;
            j    := i - 1;
            prev := s( j );
            if pos( prev ) not = 0 then begin
                    % not a new element                                     %
                    s( i ) := j - pos( prev )
            end if_pos_prev_ne_0 ;
            pos( prev ) := j
        end for_j;
    end VanEck ;
    % construct the first 1000 terms of the sequence                        %
    integer MAX_VAN_ECK;
    MAX_VAN_ECK := 1000;
    begin
        integer array seq ( 1 :: MAX_VAN_ECK );
        VanEck( seq, MAX_VAN_ECK );
        % show the first and last 10 elements                               %
        for i := 1 until 10 do writeon( i_w := 1, s_w := 0, " ", seq( i ) );
        write();
        for i := MAX_VAN_ECK - 9 until MAX_VAN_ECK do writeon( i_w := 1, s_w := 0, " ", seq( i ) );
        write()
    end
end.
Output:
 0 0 1 0 2 0 2 2 1 6
 4 7 30 25 67 225 488 0 10 136

Amazing Hopper

#include <basico.h>

algoritmo
    
    decimales '0'
    dimensionar(2) matriz de ceros (vaneck)
    
    iterar para (i=2, #(i<=1000), ++i )
         matriz.buscar en reversa(#(vaneck[i]),#(vaneck[1:i-1]))
         ---retener--- no es cero?, entonces{ menos'i' por'-1' }
         meter en 'vaneck'
    siguiente

    imprimir ( "Van Eck: first 10 terms  : ",#(vaneck[1:10]), NL,\
               "Van Eck: terms 991 - 1000: ", #(vaneck[991:1000]), NL)

terminar
Output:
Van Eck: first 10 terms  : 0,0,1,0,2,0,2,2,1,6
Van Eck: terms 991 - 1000: 4,7,30,25,67,225,488,0,10,136

APL

Works with: Dyalog APL
(10↑,[.5]¯10)(⊢,(⌽∊¯1)(1↓⌽)⍳⊃)999⊢,0
Output:
0 0  1  0  2   0   2 2  1   6
4 7 30 25 67 225 488 0 10 136

AppleScript

Functional

AppleScript is not the tool for the job, but here is a quick assembly from ready-made parts:

use AppleScript version "2.4"
use scripting additions


-- vanEck :: Int -> [Int]
on vanEck(n)
    -- First n terms of the vanEck sequence.
    
    script go
        on |λ|(xns, i)
            set {x, ns} to xns
            set prev to item (1 + x) of ns
            
            if 0  prev then
                set v to i - prev
            else
                set v to 0
            end if
            
            {{v, insert(ns, x, i)}, v}
        end |λ|
    end script
    
    
    {0} & item 2 of mapAccumL(go, ¬
        {0, replicate(n, 0)}, enumFromTo(1, n - 1))
end vanEck


--------------------------- TEST ---------------------------
on run
    unlines({¬
        "First 10 terms:", ¬
        showList(vanEck(10)), ¬
        "", ¬
        "Terms 990 to 1000:", ¬
        showList(items -10 thru -1 of vanEck(1000))})
end run



------------------------- GENERIC --------------------------

-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
    if m  n then
        set lst to {}
        repeat with i from m to n
            set end of lst to i
        end repeat
        lst
    else
        {}
    end if
end enumFromTo


-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
    tell mReturn(f)
        set v to startValue
        set lng to length of xs
        repeat with i from 1 to lng
            set v to |λ|(v, item i of xs, i, xs)
        end repeat
        return v
    end tell
end foldl


-- insert :: [Int] -> Int -> Int -> [Int]
on insert(xs, i, v)
    -- A list updated at position i with value v.
    set item (1 + i) of xs to v
    xs
end insert


-- intercalate :: String -> [String] -> String
on intercalate(delim, xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, delim}
    set s to xs as text
    set my text item delimiters to dlm
    s
end intercalate


-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    -- The list obtained by applying f
    -- to each element of xs.
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map


-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    -- 2nd class handler function lifted into 1st class script wrapper. 
    if script is class of f then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn


-- 'The mapAccumL function behaves like a combination of map and foldl; 
-- it applies a function to each element of a list, passing an 
-- accumulating parameter from |Left| to |Right|, and returning a final 
-- value of this accumulator together with the new list.' (see Hoogle)
-- mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
on mapAccumL(f, acc, xs)
    script
        on |λ|(a, x, i)
            tell mReturn(f) to set pair to |λ|(item 1 of a, x, i)
            {item 1 of pair, (item 2 of a) & {item 2 of pair}}
        end |λ|
    end script
    
    foldl(result, {acc, []}, xs)
end mapAccumL


-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary 
-- assembly of a target length
-- replicate :: Int -> a -> [a]
on replicate(n, a)
    set out to {}
    if 1 > n then return out
    set dbl to {a}
    
    repeat while (1 < n)
        if 0 < (n mod 2) then set out to out & dbl
        set n to (n div 2)
        set dbl to (dbl & dbl)
    end repeat
    return out & dbl
end replicate


-- showList :: [a] -> String
on showList(xs)
    "[" & intercalate(", ", map(my str, xs)) & "]"
end showList


-- str :: a -> String
on str(x)
    x as string
end str


-- unlines :: [String] -> String
on unlines(xs)
    -- A single string formed by the intercalation
    -- of a list of strings with the newline character.
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set s to xs as text
    set my text item delimiters to dlm
    s
end unlines
Output:
First 10 terms:
[0, 0, 1, 0, 2, 0, 2, 2, 1, 6]

Terms 999 to 1000:
[4, 7, 30, 25, 67, 225, 488, 0, 10, 136]

Idiomatic

On the contrary, it's right up AppleScript's street.

on vanEckSequence(limit)
    script o
        property sequence : {}
        property lookup : {}
    end script
    
    set term to 0
    repeat with i from 1 to (limit - 1) -- 1-based indices.
        set end of o's sequence to term
        set t to term + 1 -- 1-based index.
        repeat (t - (count o's lookup)) times
            set end of o's lookup to missing value
        end repeat
        set previous_i to item t of o's lookup
        set item t of o's lookup to i
        if (previous_i is missing value) then
            set term to 0
        else
            set term to i - previous_i
        end if
    end repeat
    set end of o's sequence to term
    
    return o's sequence
end vanEckSequence

-- Task code:
tell vanEckSequence(1000) to return {items 1 thru 10, items 991 thru 1000}
Output:
{{0, 0, 1, 0, 2, 0, 2, 2, 1, 6}, {4, 7, 30, 25, 67, 225, 488, 0, 10, 136}}

ARM Assembly

Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program vanEckSerie.s   */

 /* REMARK 1 : this program use routines in a include file 
   see task Include a file language arm assembly 
   for the routine affichageMess conversion10 
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"

.equ MAXI,      1000

/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResultElement:    .asciz " @ "
szCarriageReturn:   .asciz "\n"

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
sZoneConv:                  .skip 24
TableVanEck:                .skip 4 * MAXI
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                             @ entry of program 
    mov r2,#0                     @ begin first element
    mov r3,#0                     @ current counter
    ldr r4,iAdrTableVanEck        @ table address
    str r2,[r4,r3,lsl #2]         @ store first zéro
1:                                @ begin loop 
    mov r5,r3                     @ init current indice
2:
    sub r5,#1                     @ decrement
    cmp r5,#0                     @ end table ?
    movlt r2,#0                   @ yes, move zero to next element
    blt 3f
    ldr r6,[r4,r5,lsl #2]         @ load element
    cmp r6,r2                     @ and compare with the last element
    bne 2b                        @ not equal
    sub r2,r3,r5                  @ else compute gap
3:
    add r3,r3,#1                  @ increment counter
    str r2,[r4,r3,lsl #2]         @ and store new element
    cmp r3,#MAXI
    blt 1b
    
    mov r2,#0
4:                                @ loop display ten elements
    ldr r0,[r4,r2,lsl #2]
    ldr r1,iAdrsZoneConv
    bl conversion10               @ call décimal conversion
    ldr r0,iAdrsMessResultElement
    ldr r1,iAdrsZoneConv          @ insert conversion in message
    bl strInsertAtCharInc
    mov r1,#0                     @ final zéro
    strb r1,[r0,#5]               @ 
    bl affichageMess              @ display message
    add r2,#1                     @ increment indice
    cmp r2,#10                    @ end ?
    blt 4b                        @ no -> loop
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
    
    mov r2,#MAXI - 10
5:                                @ loop display ten elements 990-999
    ldr r0,[r4,r2,lsl #2]
    ldr r1,iAdrsZoneConv
    bl conversion10               @ call décimal conversion
    ldr r0,iAdrsMessResultElement
    ldr r1,iAdrsZoneConv          @ insert conversion in message
    bl strInsertAtCharInc
    mov r1,#0                     @ final zéro
    strb r1,[r0,#5]               @ 
    bl affichageMess              @ display message
    add r2,#1                     @ increment indice
    cmp r2,#MAXI                    @ end ?
    blt 5b                        @ no -> loop
    ldr r0,iAdrszCarriageReturn
    bl affichageMess

100:                              @ standard end of the program 
    mov r0, #0                    @ return code
    mov r7, #EXIT                 @ request to exit program
    svc #0                        @ perform the system call
iAdrszCarriageReturn:    .int szCarriageReturn
iAdrsMessResultElement:  .int sMessResultElement
iAdrsZoneConv:           .int sZoneConv  
iAdrTableVanEck:         .int TableVanEck

/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"
 0    0    1    0    2    0    2    2    1    6
 4    7    30   25   67   225  488  0    10   136

Arturo

Max: 1000
a: array.of: Max 0

loop 0..Max-2 'n [
    if 0 =< n-1 [
        loop (n-1)..0 'm [
            if a\[m]=a\[n] [
                a\[n+1]: n-m
                break
            ]
        ]
    ]
]

print "The first ten terms of the Van Eck sequence are:"
print first.n:10 a

print ""
print "Terms 991 to 1000 of the sequence are:"
print last.n:10 a
Output:
The first ten terms of the Van Eck sequence are:
0 0 1 0 2 0 2 2 1 6 

Terms 991 to 1000 of the sequence are:
4 7 30 25 67 225 488 0 10 136

AWK

# syntax: GAWK -f VAN_ECK_SEQUENCE.AWK
# converted from Go
BEGIN {
    limit = 1000
    for (i=0; i<limit; i++) {
      arr[i] = 0
    }
    for (n=0; n<limit-1; n++) {
      for (m=n-1; m>=0; m--) {
        if (arr[m] == arr[n]) {
          arr[n+1] = n - m
          break
        }
      }
    }
    printf("terms 1-10:")
    for (i=0; i<10; i++) { printf(" %d",arr[i]) }
    printf("\n")
    printf("terms 991-1000:")
    for (i=990; i<1000; i++) { printf(" %d",arr[i]) }
    printf("\n")
    exit(0)
}
Output:
terms 1-10: 0 0 1 0 2 0 2 2 1 6
terms 991-1000: 4 7 30 25 67 225 488 0 10 136

BASIC

Works with: QBasic
10 DEFINT A-Z
20 DIM E(1000)
30 FOR I=0 TO 999
40 FOR J=I-1 TO 0 STEP -1
50 IF E(J)=E(I) THEN E(I+1)=I-J: GOTO 80
60 NEXT J
70 E(I+1)=0
80 NEXT I
90 FOR I=0 TO 9: PRINT E(I);: NEXT
95 PRINT
100 FOR I=990 TO 999: PRINT E(I);: NEXT
Output:
 0  0  1  0  2  0  2  2  1  6
 4  7  30  25  67  225  488  0  10  136

BASIC256

Translation of: FreeBASIC
limite = 1001
dim a(limite) fill 0

for n = 0 to limite-1
    for m = n-1 to 0 step -1
        if a[m] = a[n] then
            a[n+1] = n-m
            exit for
        end if   
    next m
next n

print "Secuencia de Van Eck:" & Chr(10)
print "Primeros 10 terminos: ";
for i = 0 to 9
    print a[i]; " ";
next i
print chr(10) & "Terminos 991 al 1000: ";
for i = 990 to 999
    print a[i]; " ";
next i

Chipmunk Basic

Translation of: FreeBASIC
Works with: Chipmunk Basic version 3.6.4
Works with: QBasic
100 cls
110 limite = 1000
120 dim a(limite)
130 '
140 for n = 0 to limite-1
150   for m = n-1 to 0 step -1
160     if a(m) = a(n) then
170       a(n+1) = n-m
180       exit for
190     endif
200   next m
210 next n
220 '
230 print "Secuencia de Van Eck:";chr$(10)
240 print "Primeros 10 terminos: ";
250 for i = 0 to 9
260   print a(i);
270 next i
280 print chr$(10);"Terminos 991 al 1000: ";
290 for i = 990 to 999
300   print a(i);
310 next i
320 end

Craft Basic

define limit = 1000

dim list[limit]

print "calculating van eck sequence..."

for n = 0 to limit - 1

	for m = n - 1 to 0 step -1

		if list[m] = list[n] then

			let c = n + 1
			let list[c] = n - m

			break m

		endif

		wait

	next m

next n

print "first 10 terms: "

for i = 0 to 9

	print list[i]

next i

print "terms 991 to 1000: "

for i = 990 to 999

	print list[i]

next i
Output:
calculating van eck sequence...

first 10 terms: 0 0 1 0 2 0 2 2 1 6

terms 991 to 1000: 4 7 30 25 67 225 488 0 10 136

FreeBASIC

Const limite = 1000

Dim As Integer a(limite), n, m, i

For n = 0 To limite-1
    For m = n-1 To 0 Step -1
        If a(m) = a(n) Then a(n+1) = n-m: Exit For
    Next m
Next n

Print "Secuencia de Van Eck:" &Chr(10)
Print "Primeros 10 terminos: ";
For i = 0 To 9
    Print a(i) &" ";
Next i
Print Chr(10) & "Terminos 991 al 1000: ";
For i = 990 To 999
    Print a(i) &" ";
Next i 
End
Output:
Secuencia de Van Eck:

Primeros 10 terminos: 0 0 1 0 2 0 2 2 1 6
Terminos 991 al 1000: 4 7 30 25 67 225 488 0 10 136

GW-BASIC

Translation of: FreeBASIC
Works with: PC-BASIC version any
Works with: BASICA
Works with: Chipmunk Basic
Works with: QBasic
100 CLS
110 L = 1000
120 DIM A(L)
130 FOR N = 0 TO L
140   LET A(N) = 0
150 NEXT N
160 FOR N = 0 TO L-1
170   FOR M = N-1 TO 0 STEP -1
180     IF A(M) = A(N) THEN A(N+1) = N - M : GOTO 200
190   NEXT M
200 NEXT N
210 PRINT "Secuencia de Van Eck:"; CHR$(10)
220 PRINT "Primeros 10 terminos: ";
230 FOR I = 0 TO 9
240   PRINT A(I);
250 NEXT I
260 PRINT CHR$(10); "Terminos 991 al 1000: ";
270 FOR I = 990 TO 999
280   PRINT A(I);
290 NEXT I
300 END

PureBasic

Translation of: FreeBASIC
If OpenConsole()
  Define.i n, m, i, limite
  limite = 1001
  Dim a.i(limite)
  
  For n = 0 To limite-1
    For m = n-1 To 0 Step -1
      If a(m) = a(n)
        a(n+1) = n-m
        Break
      EndIf   
    Next m
  Next n
  
  PrintN("Secuencia de Van Eck:" + #CRLF$)
  Print("Primeros 10 terminos: ")
  For i = 0 To 9
    Print(Str(a(i)) + " ")
  Next i
  Print(#CRLF$ + "Terminos 991 al 1000: ")
  For i = 990 To 999
    Print(Str(a(i)) + " ")
  Next i
  
  PrintN(#CRLF$ + "Press ENTER to exit" + #CRLF$ ): Input()
  CloseConsole()
EndIf

QBasic

Translation of: FreeBASIC
Works with: QBasic version 1.1
Works with: QuickBasic version 4.5
CONST limite = 1000
DIM a(limite)

FOR n = 0 TO limite - 1
    FOR m = n - 1 TO 0 STEP -1
        IF a(m) = a(n) THEN
            a(n + 1) = n - m
            EXIT FOR
        END IF
    NEXT m
NEXT n

PRINT "Secuencia de Van Eck:"; CHR$(10)
PRINT "Primeros 10 terminos: ";
FOR i = 0 TO 9
    PRINT a(i);
NEXT i
PRINT CHR$(10); "Terminos 991 al 1000: ";
FOR i = 990 TO 999
    PRINT a(i);
NEXT i
END

XBasic

Translation of: FreeBASIC
Works with: Windows XBasic
PROGRAM  "Van Eck sequence"
VERSION  "0.0000"

DECLARE FUNCTION  Entry ()

FUNCTION  Entry ()
  l = 1000
  DIM a[l]
  FOR n = 0 TO l-1
    FOR m = n-1 TO 0 STEP -1
      IF a[m] = a[n] THEN
         a[n+1] = n-m
         EXIT FOR
      END IF
    NEXT m
  NEXT n
  PRINT "Secuencia de Van Eck:"; CHR$(10)
  PRINT "Primeros 10 terminos: ";
  FOR i = 0 TO 9
    PRINT a[i]; " ";
  NEXT i
  PRINT CHR$(10); "Terminos 991 al 1000: ";
  FOR i = 990 TO 999
    PRINT a[i]; " ";
  NEXT i
END FUNCTION
END PROGRAM

Yabasic

Translation of: FreeBASIC
limite = 1001
dim a(limite)

for n = 0 to limite-1
    for m = n-1 to 0 step -1
        if a(m) = a(n) then
            a(n+1) = n-m
            break
        fi
    next m
next n

print "Secuencia de Van Eck: \n"
print "Primeros 10 terminos: ";
for i = 0 to 9
    print a(i), " ";
next i
print "\nTerminos 991 al 1000: ";
for i = 990 to 999
    print a(i), " ";
next i
print

BCPL

get "libhdr"

let start() be
$(  let eck = vec 999
    
    for i = 0 to 999 do eck!i := 0
    for i = 0 to 998 do
        for j = i-1 to 0 by -1 do
            if eck!i = eck!j then
            $(  eck!(i+1) := i-j
                break
            $)
    
    for i = 0 to 9 do writed(eck!i, 4)
    wrch('*N')
    for i = 990 to 999 do writed(eck!i, 4)
    wrch('*N')
$)
Output:
   0   0   1   0   2   0   2   2   1   6
   4   7  30  25  67 225 488   0  10 136

BQN

EckStep  ⊢∾(⊑⊑⌽∊1↓⌽)(0˙)((1+⊑⊐˜ 1↓⊢))
Eck  {(EckStep(𝕩-1))0}
(Eck 10)990↓Eck 1000
Output:
┌─                               
╵ 0 0  1  0  2   0   2 2  1   6  
  4 7 30 25 67 225 488 0 10 136  
                                ┘

C

#include <stdlib.h>
#include <stdio.h>

int main(int argc, const char *argv[]) {
  const int max = 1000;
  int *a = malloc(max * sizeof(int));
  for (int n = 0; n < max - 1; n ++) {
    for (int m = n - 1; m >= 0; m --) {
      if (a[m] == a[n]) {
        a[n+1] = n - m;
        break;
      }
    }
  }

  printf("The first ten terms of the Van Eck sequence are:\n");
  for (int i = 0; i < 10; i ++) printf("%d ", a[i]);
  printf("\n\nTerms 991 to 1000 of the sequence are:\n");
  for (int i = 990; i < 1000; i ++) printf("%d ", a[i]);
  putchar('\n');

  return 0;
}
Output:
The first ten terms of the Van Eck sequence are:
0 0 1 0 2 0 2 2 1 6

Terms 991 to 1000 of the sequence are:
4 7 30 25 67 225 488 0 10 136

C#

Translation of: C
using System.Linq; class Program { static void Main() {
    int a, b, c, d, e, f, g; int[] h = new int[g = 1000];
    for (a = 0, b = 1, c = 2; c < g; a = b, b = c++)
        for (d = a, e = b - d, f = h[b]; e <= b; e++)
            if (f == h[d--]) { h[c] = e; break; }
    void sho(int i) { System.Console.WriteLine(string.Join(" ",
        h.Skip(i).Take(10))); } sho(0); sho(990); } }
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

C++

#include <iostream>
#include <map>

class van_eck_generator {
public:
    int next() {
        int result = last_term;
        auto iter = last_pos.find(last_term);
        int next_term = (iter != last_pos.end()) ? index - iter->second : 0;
        last_pos[last_term] = index;
        last_term = next_term;
        ++index;
        return result;
    }
private:
    int index = 0;
    int last_term = 0;
    std::map<int, int> last_pos;
};

int main() {
    van_eck_generator gen;
    int i = 0;
    std::cout << "First 10 terms of the Van Eck sequence:\n";
    for (; i < 10; ++i)
        std::cout << gen.next() << ' ';
    for (; i < 990; ++i)
        gen.next();
    std::cout << "\nTerms 991 to 1000 of the sequence:\n";
    for (; i < 1000; ++i)
        std::cout << gen.next() << ' ';
    std::cout << '\n';
    return 0;
}
Output:
First 10 terms of the Van Eck sequence:
0 0 1 0 2 0 2 2 1 6 
Terms 991 to 1000 of the sequence:
4 7 30 25 67 225 488 0 10 136

Clojure

(defn van-eck
  ([] (van-eck 0 0 {}))
  ([val n seen]
   (lazy-seq
    (cons val
          (let [next (- n (get seen val n))]
            (van-eck next
                     (inc n)
                     (assoc seen val n)))))))

(println "First 10 terms:" (take 10 (van-eck)))
(println "Terms 991 to 1000 terms:" (take 10 (drop 990 (van-eck))))
Output:
First 10 terms: (0 0 1 0 2 0 2 2 1 6)
Terms 991 to 1000 terms: (4 7 30 25 67 225 488 0 10 136)

CLU

% Generate the first N elements of the Van Eck sequence
eck = proc (n: int) returns (array[int]) 
    ai = array[int]
    e: ai := ai$fill(0, n, 0)
    
    for i: int in int$from_to(ai$low(e), ai$high(e)-1) do
        for j: int in int$from_to_by(i-1, ai$low(e), -1) do
            if e[i] = e[j] then
                e[i+1] := i-j
                break
            end
        end
    end
    return(e)
end eck

% Show 0..9 and 990..999
start_up = proc ()
    po: stream := stream$primary_output()
    e: array[int] := eck(1000)
    
    stream$puts(po, "  0 -   9: ")
    for i: int in int$from_to(0,9) do
        stream$putright(po, int$unparse(e[i]), 4)
    end
    stream$puts(po, "\n990 - 999: ")
    for i: int in int$from_to(990,999) do
        stream$putright(po, int$unparse(e[i]), 4)
    end
    stream$putl(po, "")
end start_up
Output:
  0 -   9:    0   0   1   0   2   0   2   2   1   6
990 - 999:    4   7  30  25  67 225 488   0  10 136

COBOL

        IDENTIFICATION DIVISION.
        PROGRAM-ID. VAN-ECK.
        
        DATA DIVISION.
        WORKING-STORAGE SECTION.
        01 CALCULATION.
            02 ECK      PIC 999 OCCURS 1000 TIMES.
            02 I        PIC 9999.
            02 J        PIC 9999.
        01 OUTPUT-FORMAT.
            02 ITEM     PIC ZZ9.
            02 IDX      PIC ZZZ9.
        
        PROCEDURE DIVISION.
        B.  PERFORM GENERATE-ECK.
            PERFORM SHOW VARYING I FROM 1 BY 1 UNTIL I = 11.
            PERFORM SHOW VARYING I FROM 991 BY 1 UNTIL I = 1001.
            STOP RUN.
        
        SHOW.
            MOVE I TO IDX.
            MOVE ECK(I) TO ITEM.
            DISPLAY 'ECK(' IDX ') = ' ITEM.
        
        GENERATE-ECK SECTION.
        B.  SET ECK(1) TO 0.
            SET I TO 1.
            PERFORM GENERATE-TERM 
                VARYING I FROM 2 BY 1 UNTIL I = 1001.
            
        GENERATE-TERM SECTION.
        B.  SUBTRACT 2 FROM I GIVING J.
        LOOP.
            IF J IS LESS THAN 1 GO TO TERM-IS-NEW.
            IF ECK(J) = ECK(I - 1) GO TO TERM-IS-OLD.
            SUBTRACT 1 FROM J.
            GO TO LOOP.
        
        TERM-IS-NEW.
            SET ECK(I) TO 0.
            GO TO DONE.
         
        TERM-IS-OLD.
            COMPUTE ECK(I) = (I - J) - 1.
            
        DONE. EXIT.
Output:
ECK(   1) =   0
ECK(   2) =   0
ECK(   3) =   1
ECK(   4) =   0
ECK(   5) =   2
ECK(   6) =   0
ECK(   7) =   2
ECK(   8) =   2
ECK(   9) =   1
ECK(  10) =   6
ECK( 991) =   4
ECK( 992) =   7
ECK( 993) =  30
ECK( 994) =  25
ECK( 995) =  67
ECK( 996) = 225
ECK( 997) = 488
ECK( 998) =   0
ECK( 999) =  10
ECK(1000) = 136

Comal

0010 DIM eck#(0:1000)
0020 FOR i#:=1 TO 999 DO
0030   j#:=i#-1
0040   WHILE j#>0 AND eck#(i#)<>eck#(j#) DO j#:-1
0050   IF j#<>0 THEN eck#(i#+1):=i#-j#
0060 ENDFOR i#
0070 ZONE 5
0080 FOR i#:=1 TO 10 DO PRINT eck#(i#),
0090 PRINT
0100 FOR i#:=991 TO 1000 DO PRINT eck#(i#),
0110 PRINT
0120 END
Output:
0    0    1    0    2    0    2    2    1    6
4    7    30   25   67   225  488  0    10   136

Common Lisp

;;Tested using CLISP

(defun VanEck (x) (reverse (VanEckh x 0 0 '(0))))

(defun VanEckh (final index curr lst)
	(if (eq index final) 
		lst
		(VanEckh final (+ index 1) (howfar curr lst) (cons curr lst))))

(defun howfar (x lst) (howfarh x lst 0))

(defun howfarh (x lst runningtotal) 
	(cond
		((null lst) 0)
		((eq x (car lst)) (+ runningtotal 1))
		(t (howfarh x (cdr lst) (+ runningtotal 1)))))

(format t "The first 10 elements are ~a~%" (VanEck 9))
(format t "The 990-1000th elements are ~a~%" (nthcdr 990 (VanEck 999)))
Output:
The first 10 elements are (0 0 1 0 2 0 2 2 1 6)
The 990-1000th elements are (4 7 30 25 67 225 488 0 10 136)
(defun van-eck-nm-sequence (n m)
  (loop with ac repeat m
        for i = (position (car ac) (cdr ac)) do
        (push (if i (1+ i) 0) ac)
        finally (return (nthcdr (1- n) (nreverse ac)))))

(format t "The first 10 elements are: ~{~a ~}~%" (van-eck-nm-sequence 1 10))
(format t "The 991-1000th elements are: ~{~a ~}" (van-eck-nm-sequence 991 1000))
Output:
The first 10 elements are: 0 0 1 0 2 0 2 2 1 6 
The 991-1000th elements are: 4 7 30 25 67 225 488 0 10 136 

Cowgol

include "cowgol.coh";

sub print_list(ptr: [uint16], n: uint8) is
    while n > 0 loop
        print_i16([ptr]);
        print_char(' ');
        n := n - 1;
        ptr := @next ptr;
    end loop;
    print_nl();
end sub;

const LIMIT := 1000;
var eck: uint16[LIMIT];
MemZero(&eck as [uint8], @bytesof eck);
var i: @indexof eck;
var j: @indexof eck;

i := 0;
while i < LIMIT-1 loop
    j := i-1;
    while j != -1 loop
        if eck[i] == eck[j] then
            eck[i+1] := i-j;
            break;
        end if;
        j := j - 1;
    end loop;
    i := i + 1;
end loop;

print_list(&eck[0], 10);
print_list(&eck[LIMIT-10], 10);
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

D

Translation of: Java
import std.stdio;

void vanEck(int firstIndex, int lastIndex) {
    int[int] vanEckMap;
    int last = 0;
    if (firstIndex == 1) {
        writefln("VanEck[%d] = %d", 1, 0);
    }
    for (int n = 2; n <= lastIndex; n++) {
        int vanEck = last in vanEckMap ? n - vanEckMap[last] : 0;
        vanEckMap[last] = n;
        last = vanEck;
        if (n >= firstIndex) {
            writefln("VanEck[%d] = %d", n, vanEck);
        }
    }
}

void main() {
    writeln("First 10 terms of Van Eck's sequence:");
    vanEck(1, 10);
    writeln;
    writeln("Terms 991 to 1000 of Van Eck's sequence:");
    vanEck(991, 1000);
}
Output:
First 10 terms of Van Eck's sequence:
VanEck[1] = 0
VanEck[2] = 0
VanEck[3] = 1
VanEck[4] = 0
VanEck[5] = 2
VanEck[6] = 0
VanEck[7] = 2
VanEck[8] = 2
VanEck[9] = 1
VanEck[10] = 6

Terms 991 to 1000 of Van Eck's sequence:
VanEck[991] = 4
VanEck[992] = 7
VanEck[993] = 30
VanEck[994] = 25
VanEck[995] = 67
VanEck[996] = 225
VanEck[997] = 488
VanEck[998] = 0
VanEck[999] = 10
VanEck[1000] = 136

Delphi

See Pascal.

Draco

/* Fill array with Van Eck sequence */
proc nonrec make_eck([*] word eck) void:
    int i, j, max;
    max := dim(eck,1)-1;
    for i from 0 upto max do eck[i] := 0 od;
    
    for i from 0 upto max-1 do
        j := i - 1;
        while j >= 0 and eck[i] ~= eck[j] do
            j := j - 1
        od;
        if j >= 0 then
            eck[i+1] := i - j
        fi
    od
corp

/* Print eck[0..9] and eck[990..999] */
proc nonrec main() void:
    word i;
    [1000] word eck;
    make_eck(eck);
    
    for i from 0 upto 9 do write(eck[i]:4) od;
    writeln();
    for i from 990 upto 999 do write(eck[i]:4) od;
    writeln()
corp
Output:
   0   0   1   0   2   0   2   2   1   6
   4   7  30  25  67 225 488   0  10 136

Dyalect

Translation of: Go
let max = 1000
var a = Array.Empty(max, 0)
for n in 0..(max-2) {
    var m = n - 1
    while m >= 0 {
        if a[m] == a[n] {
            a[n+1] = n - m
            break
        }
        m -= 1
    }
}
print("The first ten terms of the Van Eck sequence are: \(a[0..10].ToArray())")
print("Terms 991 to 1000 of the sequence are: \(a[991..999].ToArray())")
Output:
The first ten terms of the Van Eck sequence are: [0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
Terms 991 to 1000 of the sequence are: [7, 30, 25, 67, 225, 488, 0, 10, 136]

EasyLang

len arr[] 1000
for n to 1000 - 1
   for m = n - 1 downto 1
      if arr[m] = arr[n]
         arr[n + 1] = n - m
         break 1
      .
   .
.
for i to 10
   write arr[i] & " "
.
print ""
for i = 991 to 1000
   write arr[i] & " "
.

F#

The function

// Generate Van Eck's Sequence. Nigel Galloway: June 19th., 2019
let ecK()=let n=System.Collections.Generic.Dictionary<int,int>()
          Seq.unfold(fun (g,e)->Some(g,((if n.ContainsKey g then let i=n.[g] in n.[g]<-e;e-i else n.[g]<-e;0),e+1)))(0,0)

The Task

First 50
ecK() |> Seq.take 50 |> Seq.iter(printf "%d "); printfn "";;
Output:
0 0 1 0 2 0 2 2 1 6 0 5 0 2 6 5 4 0 5 3 0 3 2 9 0 4 9 3 6 14 0 6 3 5 15 0 5 3 5 2 17 0 6 11 0 3 8 0 3 3 
50 from 991
ecK() |> Seq.skip 990 |> Seq.take 50|> Seq.iter(printf "%d "); printfn "";;
Output:
4 7 30 25 67 225 488 0 10 136 61 0 4 12 72 0 4 4 1 24 41 385 0 7 22 25 22 2 84 68 282 464 0 10 25 9 151 697 0 6 41 20 257 539 0 6 6 1 29 465 
I thought the longest sequence of non zeroes in the first 100 million items might be interesting

It occurs between 32381749 and 32381774:

9 47 47 1 10 33 27 548 548 1 6 33 6 2 154 15657 695734 270964 235721 238076 4896139 655158 7901804 146089 977945 21475977

Alternative recursive procedure

open System.Collections.Generic
let VanEck() =
    let rec _vanEck (num:int) (pos:int) (lastOccurence:Dictionary<int, int>) =
        match lastOccurence.TryGetValue num with
        | (true, position) ->
            set num pos (pos - position) lastOccurence
        | _ -> 
            set num pos 0 lastOccurence
    and set num pos next lastOccurenceByNumber = seq {
            lastOccurenceByNumber.[num] <- pos
            yield next
            yield! _vanEck next (pos + 1) lastOccurenceByNumber
        }

    seq { 
        yield 0
        yield! _vanEck 0 1 (new Dictionary<int, int>())
    }

VanEck() |> Seq.take 10 |> Seq.map (sprintf "%i") |> String.concat " " |> printfn "The first ten terms of the sequence : %s"
VanEck() |> Seq.skip 990 |> Seq.take 10 |> Seq.map (sprintf "%i") |> String.concat " " |> printfn "Terms 991 - to - 1000 of the sequence : %s"

Factor

USING: assocs fry kernel make math namespaces prettyprint
sequences ;

: van-eck ( n -- seq )
    [
        0 , 1 - H{ } clone '[
            building get [ length 1 - ] [ last ] bi _ 3dup
            2dup key? [ at - ] [ 3drop 0 ] if , set-at
        ] times
    ] { } make ;

1000 van-eck 10 [ head ] [ tail* ] 2bi [ . ] bi@
Output:
{ 0 0 1 0 2 0 2 2 1 6 }
{ 4 7 30 25 67 225 488 0 10 136 }

Fortran

      program VanEck
      implicit none
      integer eck(1000), i, j
      
      eck(1) = 0
      do 20 i=1, 999
          do 10 j=i-1, 1, -1
              if (eck(i) .eq. eck(j)) then
                  eck(i+1) = i-j
                  go to 20
              end if
 10       continue
          eck(i+1) = 0
 20   continue
 
      do 30 i=1, 10
 30       write (*,'(I4)',advance='no') eck(i)
      write (*,*)
      
      do 40 i=991, 1000
 40       write (*,'(I4)',advance='no') eck(i)
      write (*,*)
      
      end program
Output:
   0   0   1   0   2   0   2   2   1   6
   4   7  30  25  67 225 488   0  10 136

Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website.

In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.

Solution

File:Fōrmulæ - Van Eck sequence 01.png

Test case

File:Fōrmulæ - Van Eck sequence 02.png

File:Fōrmulæ - Van Eck sequence 03.png

Go

package main

import "fmt"

func main() {
    const max = 1000
    a := make([]int, max) // all zero by default
    for n := 0; n < max-1; n++ {
        for m := n - 1;  m >= 0; m-- {
            if a[m] == a[n] {
                a[n+1] = n - m
                break
            }    
        }
    }
    fmt.Println("The first ten terms of the Van Eck sequence are:")
    fmt.Println(a[:10])
    fmt.Println("\nTerms 991 to 1000 of the sequence are:")
    fmt.Println(a[990:])
}
Output:
The first ten terms of the Van Eck sequence are:
[0 0 1 0 2 0 2 2 1 6]

Terms 991 to 1000 of the sequence are:
[4 7 30 25 67 225 488 0 10 136]

Alternatively, using a map to store the latest index of terms previously seen (output as before):

package main

import "fmt"

func main() {
    const max = 1000
    a := make([]int, max) // all zero by default
    seen := make(map[int]int)
    for n := 0; n < max-1; n++ {
        if m, ok := seen[a[n]]; ok {
            a[n+1] = n - m            
        } 
        seen[a[n]] = n          
    }
    fmt.Println("The first ten terms of the Van Eck sequence are:")
    fmt.Println(a[:10])
    fmt.Println("\nTerms 991 to 1000 of the sequence are:")
    fmt.Println(a[990:])
}

Haskell

import Data.List (elemIndex)
import Data.Maybe (maybe)

vanEck :: Int -> [Int]
vanEck n = reverse $ iterate go [] !! n
  where
    go [] = [0]
    go xxs@(x:xs) = maybe 0 succ (elemIndex x xs) : xxs

main :: IO ()
main = do
  print $ vanEck 10
  print $ drop 990 (vanEck 1000)
Output:
[0,0,1,0,2,0,2,2,1,6]
[4,7,30,25,67,225,488,0,10,136]

And if we wanted to look a little further than the 1000th term, we could accumulate a Map of most recently seen positions to improve performance:

{-# LANGUAGE TupleSections #-}

import Data.List (mapAccumL)
import qualified Data.Map.Strict as M hiding (drop)
import Data.Maybe (maybe)

--------------------- VAN ECK SEQUENCE -------------------

vanEck :: [Int]
vanEck = 0 : snd (mapAccumL go (0, M.empty) [1 ..])
  where
    go (x, dct) i =
      ((,) =<< (, M.insert x i dct))
        (maybe 0 (i -) (M.lookup x dct))

--------------------------- TEST -------------------------
main :: IO ()
main =
  mapM_ print $
    fmap
      ((drop . subtract 10) <*> flip take vanEck)
      [10, 1000, 10000, 100000, 1000000]
Output:
[0,0,1,0,2,0,2,2,1,6]
[4,7,30,25,67,225,488,0,10,136]
[7,43,190,396,2576,3142,0,7,7,1]
[92,893,1125,47187,0,7,34,113,140,2984]
[8,86,172,8878,172447,0,6,30,874,34143]

J

The tacit verb (function)

VanEck=. (, (<:@:# - }: i: {:))^:(]`0:)

The output

   VanEck 9
0 0 1 0 2 0 2 2 1 6
   
   990 }. VanEck 999
4 7 30 25 67 225 488 0 10 136

A structured derivation of the verb (function)

next  =. <:@:# - }: i: {:    NB. Next term of the sequence
VanEck=. (, next)^:(]`0:) f. NB. Appending terms and fixing the verb

Java

Use map to remember last seen index. Computes each value of the sequence in O(1) time.

import java.util.HashMap;
import java.util.Map;

public class VanEckSequence {

    public static void main(String[] args) {
        System.out.println("First 10 terms of Van Eck's sequence:");
        vanEck(1, 10);
        System.out.println("");
        System.out.println("Terms 991 to 1000 of Van Eck's sequence:");
        vanEck(991, 1000);
    }
    
    private static void vanEck(int firstIndex, int lastIndex) {
        Map<Integer,Integer> vanEckMap = new HashMap<>();        
        int last = 0;
        if ( firstIndex == 1 ) {
            System.out.printf("VanEck[%d] = %d%n", 1, 0);
        }
        for ( int n = 2 ; n <= lastIndex ; n++ ) {
            int vanEck = vanEckMap.containsKey(last) ? n - vanEckMap.get(last) : 0;
            vanEckMap.put(last, n);
            last = vanEck;
            if ( n >= firstIndex ) {
                System.out.printf("VanEck[%d] = %d%n", n, vanEck);
            }
        }
        
    }

}
Output:
First 10 terms of Van Eck's sequence:
VanEck[1] = 0
VanEck[2] = 0
VanEck[3] = 1
VanEck[4] = 0
VanEck[5] = 2
VanEck[6] = 0
VanEck[7] = 2
VanEck[8] = 2
VanEck[9] = 1
VanEck[10] = 6

Terms 991 to 1000 of Van Eck's sequence:
VanEck[991] = 4
VanEck[992] = 7
VanEck[993] = 30
VanEck[994] = 25
VanEck[995] = 67
VanEck[996] = 225
VanEck[997] = 488
VanEck[998] = 0
VanEck[999] = 10
VanEck[1000] = 136

JavaScript

Either declaratively, without premature optimization:

Translation of: Python
(() => {
    'use strict';

    // vanEck :: Int -> [Int]
    const vanEck = n =>
        reverse(
            churchNumeral(n)(
                xs => 0 < xs.length ? cons(
                    maybe(
                        0, succ,
                        elemIndex(xs[0], xs.slice(1))
                    ),
                    xs
                ) : [0]
            )([])
        );

    // TEST -----------------------------------------------
    const main = () => {
        console.log('VanEck series:\n')
        showLog('First 10 terms', vanEck(10))
        showLog('Terms 991-1000', vanEck(1000).slice(990))
    };

    // GENERIC FUNCTIONS ----------------------------------

    // Just :: a -> Maybe a
    const Just = x => ({
        type: 'Maybe',
        Nothing: false,
        Just: x
    });

    // Nothing :: Maybe a
    const Nothing = () => ({
        type: 'Maybe',
        Nothing: true,
    });

    // churchNumeral :: Int -> (a -> a) -> a -> a
    const churchNumeral = n => f => x =>
        Array.from({
            length: n
        }, () => f)
        .reduce((a, g) => g(a), x)

    // cons :: a -> [a] -> [a]
    const cons = (x, xs) => [x].concat(xs)

    // elemIndex :: Eq a => a -> [a] -> Maybe Int
    const elemIndex = (x, xs) => {
        const i = xs.indexOf(x);
        return -1 === i ? (
            Nothing()
        ) : Just(i);
    };

    // maybe :: b -> (a -> b) -> Maybe a -> b
    const maybe = (v, f, m) =>
        m.Nothing ? v : f(m.Just);

    // reverse :: [a] -> [a]
    const reverse = xs =>
        'string' !== typeof xs ? (
            xs.slice(0).reverse()
        ) : xs.split('').reverse().join('');

    // showLog :: a -> IO ()
    const showLog = (...args) =>
        console.log(
            args
            .map(JSON.stringify)
            .join(' -> ')
        );

    // succ :: Int -> Int
    const succ = x => 1 + x;

    // MAIN ---
    return main();
})();
Output:
VanEck series:

"First 10 terms" -> [0,0,1,0,2,0,2,2,1,6]
"Terms 991-1000" -> [4,7,30,25,67,225,488,0,10,136]


or as a map-accumulation, building a look-up table:

Translation of: Python
(() => {
    "use strict";

    // vanEck :: Int -> [Int]
    const vanEck = n =>
        // First n terms of the vanEck series.
        [0].concat(mapAccumL(
            ([x, seen]) => i => {
                const
                    prev = seen[x],
                    v = Boolean(prev) ? (
                        i - prev
                    ) : 0;

                return [
                    [v, (seen[x] = i, seen)], v
                ];
            })(
            [0, {}]
        )(
            enumFromTo(1)(n - 1)
        )[1]);


    // ----------------------- TEST ------------------------
    const main = () =>
        fTable(
            "Terms of the VanEck series:\n"
        )(
            n => `${str(n - 10)}-${str(n)}`
        )(
            xs => JSON.stringify(xs.slice(-10))
        )(
            vanEck
        )([10, 1000, 10000]);


    // ----------------- GENERIC FUNCTIONS -----------------

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);


    // fTable :: String -> (a -> String) ->
    // (b -> String) -> (a -> b) -> [a] -> String
    const fTable = s =>
        // Heading -> x display function ->
        //           fx display function ->
        //    f -> values -> tabular string
        xShow => fxShow => f => xs => {
            const
                ys = xs.map(xShow),
                w = Math.max(...ys.map(y => [...y].length)),
                table = zipWith(
                    a => b => `${a.padStart(w, " ")} -> ${b}`
                )(ys)(
                    xs.map(x => fxShow(f(x)))
                ).join("\n");

            return `${s}\n${table}`;
        };


    // mapAccumL :: (acc -> x -> (acc, y)) -> acc ->
    // [x] -> (acc, [y])
    const mapAccumL = f =>
        // A tuple of an accumulation and a list
        // obtained by a combined map and fold,
        // with accumulation from left to right.
        acc => xs => [...xs].reduce(
            ([a, bs], x) => second(
                v => bs.concat(v)
            )(
                f(a)(x)
            ),
            [acc, []]
        );


    // second :: (a -> b) -> ((c, a) -> (c, b))
    const second = f =>
        // A function over a simple value lifted
        // to a function over a tuple.
        // f (a, b) -> (a, f(b))
        ([x, y]) => [x, f(y)];


    // str :: a -> String
    const str = x => x.toString();


    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        // A list constructed by zipping with a
        // custom function, rather than with the
        // default tuple constructor.
        xs => ys => xs.map(
            (x, i) => f(x)(ys[i])
        ).slice(
            0, Math.min(xs.length, ys.length)
        );

    // MAIN ---
    return main();
})();
Output:
Terms of the VanEck series:

      0-10 -> [0,0,1,0,2,0,2,2,1,6]
  990-1000 -> [4,7,30,25,67,225,488,0,10,136]
9990-10000 -> [7,43,190,396,2576,3142,0,7,7,1]

jq

# Input: an array
# If the rightmost element, .[-1], does not occur elsewhere, return 0;
# otherwise return the "depth" of its rightmost occurrence in .[0:-2]
def depth:
  .[-1] as $x
  | length as $length
  | first(range($length-2; -1; -1) as $i
          | select(.[$i] == $x) | $length - 1 - $i)
     // 0 ;

# Generate a stream of the first $n van Eck integers:
def vanEck($n):
  def v:
    recurse( if length == $n then empty
             else . + [depth] end );
  [0] | v | .[-1];

# The task:
[vanEck(10)], [vanEck(1000)][990:1001]

Output

[0,0,1,0,2,0,2,2,1,6]
[4,7,30,25,67,225,488,0,10,136]

Julia

function vanecksequence(N, startval=0)
    ret = zeros(Int, N)
    ret[1] = startval
    for i in 1:N-1
        lastseen = findlast(x -> x == ret[i], ret[1:i-1])
        if lastseen != nothing
            ret[i + 1] = i - lastseen
        end
    end
    ret
end

println(vanecksequence(10))
println(vanecksequence(1000)[991:1000])
Output:
[0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
[4, 7, 30, 25, 67, 225, 488, 0, 10, 136]

Alternate version, with a Dict for memoization (output is the same):

function vanecksequence(N, startval=0)
    ret = zeros(Int, N)
    ret[1] = startval
    lastseen = Dict{Int, Int}()
    for i in 1:N-1
        if haskey(lastseen, ret[i])
            ret[i + 1] = i - lastseen[ret[i]]
        end
        lastseen[ret[i]] = i
    end
    ret
end

Kotlin

Translation of: Java
fun main() {
    println("First 10 terms of Van Eck's sequence:")
    vanEck(1, 10)
    println("")
    println("Terms 991 to 1000 of Van Eck's sequence:")
    vanEck(991, 1000)
}

private fun vanEck(firstIndex: Int, lastIndex: Int) {
    val vanEckMap = mutableMapOf<Int, Int>()
    var last = 0
    if (firstIndex == 1) {
        println("VanEck[1] = 0")
    }
    for (n in 2..lastIndex) {
        val vanEck = if (vanEckMap.containsKey(last)) n - vanEckMap[last]!! else 0
        vanEckMap[last] = n
        last = vanEck
        if (n >= firstIndex) {
            println("VanEck[$n] = $vanEck")
        }
    }
}
Output:
First 10 terms of Van Eck's sequence:
VanEck[1] = 0
VanEck[2] = 0
VanEck[3] = 1
VanEck[4] = 0
VanEck[5] = 2
VanEck[6] = 0
VanEck[7] = 2
VanEck[8] = 2
VanEck[9] = 1
VanEck[10] = 6

Terms 991 to 1000 of Van Eck's sequence:
VanEck[991] = 4
VanEck[992] = 7
VanEck[993] = 30
VanEck[994] = 25
VanEck[995] = 67
VanEck[996] = 225
VanEck[997] = 488
VanEck[998] = 0
VanEck[999] = 10
VanEck[1000] = 136

Lua

-- Return a table of the first n values of the Van Eck sequence
function vanEck (n)
  local seq, foundAt = {0}
  while #seq < n do
    foundAt = nil
    for pos = #seq - 1, 1, -1 do
      if seq[pos] == seq[#seq] then
        foundAt = pos
        break
      end
    end
    if foundAt then
      table.insert(seq, #seq - foundAt)
    else
      table.insert(seq, 0)
    end
  end
  return seq
end

-- Show the set of values in table t from key numbers lo to hi
function showValues (t, lo, hi)
  for i = lo, hi do
    io.write(t[i] .. " ")
  end
  print()
end

-- Main procedure
local sequence = vanEck(1000)
showValues(sequence, 1, 10)
showValues(sequence, 991, 1000)
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

MACRO-11

        .TITLE  VANECK
        .MCALL  .TTYOUT,.EXIT

        ; CALCULATE VAN ECK SEQUENCE
VANECK::MOV     #ECKBUF,R5
        MOV     R5,R0
        CLR     (R0)
1$:     MOV     R0,R1
        BR      3$
2$:     CMP     (R0),(R1)
        BEQ     4$
3$:     SUB     #2,R1
        CMP     R1,R5
        BGE     2$
        CLR     R3
        BR      5$
4$:     MOV     R0,R3
        SUB     R1,R3
        ASR     R3
5$:     ADD     #2,R0
        MOV     R3,(R0)
        CMP     R0,#BUFEND
        BLE     1$

        ; PRINT VALUES
        MOV     #ECKBUF,R3
        JSR     PC,PR10
        MOV     #ECKBUF+<2*^D990>,R3
        JSR     PC,PR10
        .EXIT

        ; PRINT 10 VALUES STARTING AT R3
PR10:   MOV     #^D10,R4
1$:     MOV     (R3)+,R0
        JSR     PC,PR0
        SOB     R4,1$
        MOV     #15,R0
        .TTYOUT
        MOV     #12,R0
        .TTYOUT
        RTS     PC

        ; PRINT NUMBER IN R0 AS DECIMAL
PR0:    MOV     #4$,R1
1$:     MOV     #-1,R2
2$:     INC     R2
        SUB     #12,R0
        BCC     2$
        ADD     #72,R0
        MOVB    R0,-(R1)
        MOV     R2,R0
        BNE     1$
3$:     MOVB    (R1)+,R0
        .TTYOUT
        BNE     3$
        RTS     PC
        .ASCII  /...../
4$:     .ASCIZ  / /
        .EVEN

ECKBUF: .BLKW   ^D1000
BUFEND  =       .
        .END    VANECK
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

MAD

            NORMAL MODE IS INTEGER
            DIMENSION E(1000)
            E(0)=0
            THROUGH L1, FOR I=0, 1, I.GE.1000
            THROUGH L2, FOR J=I-1, -1, J.L.0
            WHENEVER E(J).E.E(I)
                E(I+1) = I-J
                TRANSFER TO L1
            END OF CONDITIONAL
L2          CONTINUE
            E(I+1)=0
L1          CONTINUE
            THROUGH S, FOR I=0, 1, I.GE.10
S           PRINT FORMAT FMT, I, E(I), I+990, E(I+990)
            VECTOR VALUES FMT = $2HE(,I3,2H)=,I3,S5,2HE(,I3,2H)=,I3*$
            END OF PROGRAM
Output:
E(  0)=  0     E(990)=  4
E(  1)=  0     E(991)=  7
E(  2)=  1     E(992)= 30
E(  3)=  0     E(993)= 25
E(  4)=  2     E(994)= 67
E(  5)=  0     E(995)=225
E(  6)=  2     E(996)=488
E(  7)=  2     E(997)=  0
E(  8)=  1     E(998)= 10
E(  9)=  6     E(999)=136

Mathematica/Wolfram Language

TakeList[Nest[If[MemberQ[#//Most, #//Last], Join[#, Length[#] - Last@Position[#//Most, #//Last]], Append[#, 0]]&, {0}, 999], {10, -10}] // Column
Output:
{0,0,1,0,2,0,2,2,1,6}
{4,7,30,25,67,225,488,0,10,136}

Miranda

main :: [sys_message]
main = [ Stdout (show list ++ "\n")
       | list <- [take 10 eck, take 10 (drop 990 eck)]
       ]

eck :: [num]
eck = 0 : map item [1..]
      where item n = find last (tl sofar)
                     where sofar = reverse (take n eck)
                           last  = hd sofar

find :: *->[*]->num
find i = find' 1
         where find' n []     = 0
               find' n (a:as) = n, if a = i
                              = find' (n+1) as, otherwise
Output:
[0,0,1,0,2,0,2,2,1,6]
[4,7,30,25,67,225,488,0,10,136]

Modula-2

MODULE VanEck;
FROM InOut IMPORT WriteCard, WriteLn;

VAR i, j: CARDINAL;
    eck: ARRAY [1..1000] OF CARDINAL;

BEGIN
    FOR i := 1 TO 1000 DO
        eck[i] := 0;
    END;
    FOR i := 1 TO 999 DO
        j := i-1;
        WHILE (j > 0) AND (eck[i] <> eck[j]) DO
            DEC(j);
        END;
        IF j <> 0 THEN
            eck[i+1] := i-j;
        END;
    END;
    
    FOR i := 1 TO 10 DO
        WriteCard(eck[i], 4);
    END;
    WriteLn();
    
    FOR i := 991 TO 1000 DO
        WriteCard(eck[i], 4);
    END;
    WriteLn();
END VanEck.
Output:
   0   0   1   0   2   0   2   2   1   6
   4   7  30  25  67 225 488   0  10 136

Nim

const max = 1000
var a: array[max, int]
for n in countup(0, max - 2):
  for m in countdown(n - 1, 0):
    if a[m] == a[n]:
      a[n + 1] = n - m
      break

echo "The first ten terms of the Van Eck sequence are:"
echo a[..9]
echo "\nTerms 991 to 1000 of the sequence are:"
echo a[990..^1]
Output:
The first ten terms of the Van Eck sequence are:
@[0, 0, 1, 0, 2, 0, 2, 2, 1, 6]

Terms 991 to 1000 of the sequence are:
@[4, 7, 30, 25, 67, 225, 488, 0, 10, 136]

Pascal

I memorize the last position of each number that occured and use a circular buffer to remember last values. Running once through the list of last positions maybe faster Try it online! takes only 1.4 s for 32,381,775

program VanEck;
{
* A:  The first term is zero.
    Repeatedly apply:
        If the last term is *new* to the sequence so far then:
B:          The next term is zero.
        Otherwise:
C:          The next term is how far back this last term occured previousely.}
uses
  sysutils;
const
  MAXNUM = 32381775;//1000*1000*1000;
  MAXSEENIDX = (1 shl 7)-1;
var
  PosBefore : array of UInt32;
  LastSeen  : array[0..MAXSEENIDX]of UInt32;// circular buffer
  SeenIdx,HaveSeen : Uint32;

procedure OutSeen(Cnt:NativeInt);
var
  I,S_Idx : NativeInt;
Begin
  IF Cnt > MAXSEENIDX then
    Cnt := MAXSEENIDX;
  If  Cnt > HaveSeen  then
    Cnt := HaveSeen;
  S_Idx := SeenIdx;
  S_Idx := (S_Idx-Cnt);
  IF S_Idx < 0 then
    inc(S_Idx,MAXSEENIDX);
  For i := 1 to Cnt do
  Begin
    write(' ',LastSeen[S_Idx]);
    S_Idx:= (S_Idx+1) AND MAXSEENIDX;
  end;
  writeln;
end;

procedure Test(MaxTestCnt: Uint32);
var
  i, actnum, Posi, S_Idx: Uint32;
  {$IFDEF FPC}
  pPosBef, pSeen: pUint32;
  {$ELSE}
  pPosBef, pSeen: array of UInt32;
  {$ENDIF}
begin
  HaveSeen := 0;
  if MaxTestCnt > MAXNUM then
    EXIT;

  Fillchar(LastSeen, SizeOf(LastSeen), #0);
  //setlength and clear
  setlength(PosBefore, 0);
  setlength(PosBefore, MaxTestCnt);

 {$IFDEF FPC}
  pPosBef := @PosBefore[0];
  pSeen := @LastSeen[0];
 {$ELSE}
  SetLength(pSeen, SizeOf(LastSeen));
  setlength(pPosBef, MaxTestCnt);
  move(PosBefore[0], pPosBef[0], length(pPosBef));
  move(LastSeen[0], pSeen[0], length(pSeen));
 {$ENDIF}

  S_Idx := 0;
  i := 1;
  actnum := 0;
  repeat
    // save value
    pSeen[S_Idx] := actnum;
    S_Idx := (S_Idx + 1) and MAXSEENIDX;
    //examine new value often out of cache
    Posi := pPosBef[actnum];
    pPosBef[actnum] := i;
//  if Posi=0 ? actnum = 0:actnum = i-Posi
    if Posi = 0 then
      actnum := 0
    else
      actnum := i - Posi;
    inc(i);
  until i > MaxTestCnt;
  HaveSeen := i - 1;
  SeenIdx := S_Idx;

  {$IFNDEF FPC}

  move(pPosBef[0], PosBefore[0], length(pPosBef));
  move(pSeen[0], LastSeen[0], length(pSeen));
  {$ENDIF}
end;

Begin
  Test(10)  ; OutSeen(10000);
  Test(1000); OutSeen(10);
  Test(MAXNUM); OutSeen(28);
  setlength(PosBefore,0);
end.
Output:
 0 0 1 0 2 0 2 2 1 6
 4 7 30 25 67 225 488 0 10 136
 0 9 47 47 1 10 33 27 548 548 1 6 33 6 2 154 15657 695734 270964 235721 238076 4896139 655158 7901804 146089 977945 21475977 0

Perl

Translation of: Raku
use strict;
use warnings;
use feature 'say';

sub van_eck {
    my($init,$max) = @_;
    my(%v,$k);
    my @V = my $i = $init;
    for (1..$max) {
        $k++;
        my $t  = $v{$i} ? $k - $v{$i} : 0;
        $v{$i} = $k;
        push @V, $i = $t;
    }
    @V;
}

for (
    ['A181391', 0],
    ['A171911', 1],
    ['A171912', 2],
    ['A171913', 3],
    ['A171914', 4],
    ['A171915', 5],
    ['A171916', 6],
    ['A171917', 7],
    ['A171918', 8],
) {
    my($seq, $start) = @$_;
    my @seq = van_eck($start,1000);
    say <<~"END";
    Van Eck sequence OEIS:$seq; with the first term: $start
            First 10 terms: @{[@seq[0  ..  9]]}
    Terms 991 through 1000: @{[@seq[990..999]]}
    END
}
Output:
Van Eck sequence OEIS:A181391; with the first term: 0
        First 10 terms: 0 0 1 0 2 0 2 2 1 6
Terms 991 through 1000: 4 7 30 25 67 225 488 0 10 136

Van Eck sequence OEIS:A171911; with the first term: 1
        First 10 terms: 1 0 0 1 3 0 3 2 0 3
Terms 991 through 1000: 0 6 53 114 302 0 5 9 22 71

Van Eck sequence OEIS:A171912; with the first term: 2
        First 10 terms: 2 0 0 1 0 2 5 0 3 0
Terms 991 through 1000: 8 92 186 0 5 19 41 413 0 5

Van Eck sequence OEIS:A171913; with the first term: 3
        First 10 terms: 3 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 5 5 1 17 192 0 6 34 38 179

Van Eck sequence OEIS:A171914; with the first term: 4
        First 10 terms: 4 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 33 410 0 6 149 0 3 267 0 3

Van Eck sequence OEIS:A171915; with the first term: 5
        First 10 terms: 5 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 60 459 0 7 13 243 0 4 10 211

Van Eck sequence OEIS:A171916; with the first term: 6
        First 10 terms: 6 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 6 19 11 59 292 0 6 6 1 12

Van Eck sequence OEIS:A171917; with the first term: 7
        First 10 terms: 7 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 11 7 2 7 2 2 1 34 24 238

Van Eck sequence OEIS:A171918; with the first term: 8
        First 10 terms: 8 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 16 183 0 6 21 10 249 0 5 48

Phix

Just like the pascal entry, instead of searching/dictionaries use a fast direct/parallel lookup table, and likewise this can easily create a 32-million-long table in under 2s.
While dictionaries are pretty fast, there is a huge overhead adding/updating millions of entries compared to a flat list of int.

constant lim = 1000
sequence van_eck = repeat(0,lim),
         pos_before = repeat(0,lim)
for n=1 to lim-1 do
    integer vn = van_eck[n]+1,
            prev = pos_before[vn]
    if prev!=0 then
        van_eck[n+1] = n - prev
    end if
    pos_before[vn] = n
end for
printf(1,"The first ten terms of the Van Eck sequence are:%v\n",{van_eck[1..10]})
printf(1,"Terms 991 to 1000 of the sequence are:%V\n",{van_eck[991..1000]})
Output:
The first ten terms of the Van Eck sequence are:{0,0,1,0,2,0,2,2,1,6}
Terms 991 to 1000 of the sequence are:{4,7,30,25,67,225,488,0,10,136}

Picat

Translation of: FreeBasic

Note: Picat is 1-based.

main =>
  Limit = 1000,
  A = new_array(Limit+1),
  bind_vars(A,0),
  foreach(N in 1..Limit-1)
    M = find_last_of(A[1..N],A[N+1]),
    if M > 0 then
       A[N+2] := N-M+1
    end
  end,
  println(A[1..10]),
  println(A[991..1000]),
  nl.
Output:
{0,0,1,0,2,0,2,2,1,6}
{4,7,30,25,67,225,488,0,10,136}

Recursive

Same idea but recursive.

main =>
  L = a(1000),
  println(L[1..10]),
  println(L[991..1000]),
  nl.

a(0) = {0}.
a(1) = {0,0}.
a(N) = A ++ {cond(M > 0, N-M, 0)} =>
  A = a(N-1),
  M = find_last_of(slice(A,1,N-1),A.last).
Output:
{0,0,1,0,2,0,2,2,1,6,0}
{4,7,30,25,67,225,488,0,10,136}


PL/M

100H:
BDOS: PROCEDURE (FN, ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;

PRINT$NUMBER: PROCEDURE (N);
    DECLARE S (7) BYTE INITIAL ('..... $');
    DECLARE (N, P) ADDRESS, C BASED P BYTE;
    P = .S(5);
DIGIT:
    P = P - 1;
    C = N MOD 10 + '0';
    N = N / 10;
    IF N > 0 THEN GO TO DIGIT;
    CALL PRINT(P);
END PRINT$NUMBER;

PRINT$SLICE: PROCEDURE (LIST, N);
    DECLARE (I, N, LIST, L BASED LIST) ADDRESS;
    DO I=0 TO N-1;
        CALL PRINT$NUMBER(L(I));
    END;
    CALL PRINT(.(13,10,'$'));
END PRINT$SLICE;
    
DECLARE ECK (1000) ADDRESS;
DECLARE (I, J) ADDRESS;

ECK(0) = 0;
DO I=0 TO LAST(ECK)-1;
    J = I - 1;
    DO WHILE J <> 0FFFFH; /* WHAT IS SIGNED MATH */ 
        IF ECK(I) = ECK(J) THEN DO;
            ECK(I+1) = I-J;
            GO TO NEXT;
        END;
        J = J - 1;
    END;
    ECK(I+1) = 0;
NEXT:
END;

CALL PRINT$SLICE(.ECK(0), 10);
CALL PRINT$SLICE(.ECK(990), 10);
CALL EXIT;
EOF
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

Prolog

Works with: SWI Prolog
van_eck_init(v(0, 0, _assoc)):-
    empty_assoc(_assoc).

van_eck_next(v(Index, Last_term, Last_pos), v(Index1, Next_term, Last_pos1)):-
    (get_assoc(Last_term, Last_pos, V) ->
        Next_term is Index - V
        ;
        Next_term = 0
    ),
    Index1 is Index + 1,
    put_assoc(Last_term, Last_pos, Index, Last_pos1).

van_eck_sequence(N, Seq):-
    van_eck_init(V),
    van_eck_sequence(N, V, Seq).

van_eck_sequence(0, _, []):-!.
van_eck_sequence(N, V, [Term|Rest]):-
    V = v(_, Term, _),
    van_eck_next(V, V1),
    N1 is N - 1,
    van_eck_sequence(N1, V1, Rest).

write_list(From, To, _, _):-
    To < From,
    !.
write_list(_, _, _, []):-!.
write_list(From, To, N, [_|Rest]):-
    From > N,
    !,
    N1 is N + 1,
    write_list(From, To, N1, Rest).
write_list(From, To, N, [E|Rest]):-
    writef('%t ', [E]),
    F1 is From + 1,
    N1 is N + 1,
    write_list(F1, To, N1, Rest).
    
write_list(From, To, List):-
    write_list(From, To, 1, List),
    nl.

main:-
    van_eck_sequence(1000, Seq),
    writeln('First 10 terms of the Van Eck sequence:'),
    write_list(1, 10, Seq),
    writeln('Terms 991 to 1000 of the Van Eck sequence:'),
    write_list(991, 1000, Seq).
Output:
First 10 terms of the Van Eck sequence:
0 0 1 0 2 0 2 2 1 6 
Terms 991 to 1000 of the Van Eck sequence:
4 7 30 25 67 225 488 0 10 136 

Python

Python: Using a dict

def van_eck():
    n, seen, val = 0, {}, 0
    while True:
        yield val
        last = {val: n}
        val = n - seen.get(val, n)
        seen.update(last)
        n += 1
#%%
if __name__ == '__main__':
    print("Van Eck: first 10 terms:  ", list(islice(van_eck(), 10)))
    print("Van Eck: terms 991 - 1000:", list(islice(van_eck(), 1000))[-10:])
Output:
Van Eck: first 10 terms:   [0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
Van Eck: terms 991 - 1000: [4, 7, 30, 25, 67, 225, 488, 0, 10, 136]


Python: List based

The following alternative stores the sequence so far in a list seen rather than the first example that just stores last occurrences in a dict.

def van_eck():
    n = 0
    seen = [0]
    val = 0
    while True:
        yield val
        if val in seen[1:]:
            val = seen.index(val, 1)
        else:
            val = 0
        seen.insert(0, val)
        n += 1
Output:

As before.

Python: Composition of pure functions

As an alternative to the use of generators, a declarative definition in terms of a Church numeral function:

Works with: Python version 3.7
'''Van Eck sequence'''

from functools import reduce
from itertools import repeat


# vanEck :: Int -> [Int]
def vanEck(n):
    '''First n terms of the van Eck sequence.'''

    return churchNumeral(n)(
        lambda xs: cons(
            maybe(0)(succ)(
                elemIndex(xs[0])(xs[1:])
            )
        )(xs) if xs else [0]
    )([])[::-1]


# TEST ----------------------------------------------------
def main():
    '''Terms of the Van Eck sequence'''
    print(
        main.__doc__ + ':\n\n' +
        'First 10: '.rjust(18, ' ') + repr(vanEck(10)) + '\n' +
        '991 - 1000: '.rjust(18, ' ') + repr(vanEck(1000)[990:])
    )


# GENERIC -------------------------------------------------

# Just :: a -> Maybe a
def Just(x):
    '''Constructor for an inhabited Maybe (option type) value.
       Wrapper containing the result of a computation.
    '''
    return {'type': 'Maybe', 'Nothing': False, 'Just': x}


# Nothing :: Maybe a
def Nothing():
    '''Constructor for an empty Maybe (option type) value.
       Empty wrapper returned where a computation is not possible.
    '''
    return {'type': 'Maybe', 'Nothing': True}


# churchNumeral :: Int -> (a -> a) -> a -> a
def churchNumeral(n):
    '''n applications of a function
    '''
    return lambda f: lambda x: reduce(
        lambda a, g: g(a), repeat(f, n), x
    )


# cons :: a -> [a] -> [a]
def cons(x):
    '''Construction of a list from a head and a tail.
    '''
    return lambda xs: [x] + xs


# elemIndex :: Eq a => a -> [a] -> Maybe Int
def elemIndex(x):
    '''Just the index of the first element in xs
       which is equal to x,
       or Nothing if there is no such element.
    '''
    def go(xs):
        try:
            return Just(xs.index(x))
        except ValueError:
            return Nothing()
    return go


# maybe :: b -> (a -> b) -> Maybe a -> b
def maybe(v):
    '''Either the default value v, if m is Nothing,
       or the application of f to x,
       where m is Just(x).
    '''
    return lambda f: lambda m: v if None is m or m.get('Nothing') else (
        f(m.get('Just'))
    )


# succ :: Enum a => a -> a
def succ(x):
    '''The successor of a value.
       For numeric types, (1 +).
    '''
    return 1 + x


# MAIN ---
if __name__ == '__main__':
    main()
Output:
Terms of the Van Eck sequence:

        First 10: [0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
      991 - 1000: [4, 7, 30, 25, 67, 225, 488, 0, 10, 136]


Or if we lose sight, for a moment, of the good advice of Donald Knuth, and fall into optimising more than is needed for the first 1000 terms, then we can define the vanEck series as a map accumulation over a range, with an array of positions as the accumulator.

'''Van Eck series by map-accumulation'''

from functools import reduce
from itertools import repeat


# vanEck :: Int -> [Int]
def vanEck(n):
    '''First n terms of the vanEck sequence.'''
    def go(xns, i):
        x, ns = xns

        prev = ns[x]
        v = i - prev if 0 is not prev else 0
        return (
            (v, insert(ns, x, i)),
            v
        )

    return [0] + mapAccumL(go)((0, list(repeat(0, n))))(
        range(1, n)
    )[1]


# -------------------------- TEST --------------------------
# main :: IO ()
def main():
    '''The last 10 of the first N vanEck terms'''
    print(
        fTable(main.__doc__ + ':\n')(
            lambda m: 'N=' + str(m), repr,
            lambda n: vanEck(n)[-10:], [10, 1000, 10000]
        )
    )


# ----------------------- FORMATTING -----------------------
# fTable :: String -> (a -> String) ->
#                     (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
    '''Heading -> x display function -> fx display function ->
                     f -> xs -> tabular string.
    '''
    def go(xShow, fxShow, f, xs):
        ys = [xShow(x) for x in xs]
        w = max(map(len, ys))
        return s + '\n' + '\n'.join(map(
            lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
            xs, ys
        ))
    return go


# ------------------------ GENERIC -------------------------

# insert :: Array Int -> Int -> Int -> Array Int
def insert(xs, i, v):
    '''An array updated at position i with value v.'''
    xs[i] = v
    return xs


# mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
def mapAccumL(f):
    '''A tuple of an accumulation and a list derived by a
       combined map and fold,
       with accumulation from left to right.
    '''
    def go(a, x):
        tpl = f(a[0], x)
        return (tpl[0], a[1] + [tpl[1]])
    return lambda acc: lambda xs: (
        reduce(go, xs, (acc, []))
    )


# MAIN ---
if __name__ == '__main__':
    main()
Output:
The last 10 of the first N vanEck terms:

   N=10 -> [0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
 N=1000 -> [4, 7, 30, 25, 67, 225, 488, 0, 10, 136]
N=10000 -> [7, 43, 190, 396, 2576, 3142, 0, 7, 7, 1]

Quackery

  [ ' [ 0 ] 
    swap 1 - times 
      [ dup behead swap find 
        1+ 2dup swap found *
        swap join ]
    reverse ]                is van-eck ( n --> [ )

    10 van-eck echo cr
  1000 van-eck -10 split echo drop
Output:
[ 0 0 1 0 2 0 2 2 1 6 ]
[ 4 7 30 25 67 225 488 0 10 136 ]

Racket

#lang racket
(require racket/stream)

(define (van-eck)
  (define (next val n seen)
    (define val1 (- n (hash-ref seen val n)))
    (stream-cons val (next val1 (+ n 1) (hash-set seen val n))))
  (next 0 0 (hash)))

(define (get m n s)
  (stream->list
   (stream-take (stream-tail s m)
                (- n m))))

"First 10 terms:"          (get 0     10 (van-eck))
"Terms 991 to 1000 terms:" (get 990 1000 (van-eck)) ; counting from 0
Output:
"First 10 terms:"
(0 0 1 0 2 0 2 2 1 6)
"Terms 991 to 1000 terms:"
(4 7 30 25 67 225 488 0 10 136)

Raku

(formerly Perl 6) There is not a Van Eck sequence, rather a series of related sequences that differ in their starting value. This task is nominally for the sequence starting with the value 0. This Raku implementation will handle any integer starting value.

Specifically handles:

among others.

Implemented as lazy, extendable lists.

sub n-van-ecks ($init) {
    $init, -> $i, {
        state %v;
        state $k;
        $k++;
        my $t  = %v{$i}.defined ?? $k - %v{$i} !! 0;
        %v{$i} = $k;
        $t
    } ... *
}

for <
    A181391 0
    A171911 1
    A171912 2
    A171913 3
    A171914 4
    A171915 5
    A171916 6
    A171917 7
    A171918 8
> -> $seq, $start {

    my @seq = n-van-ecks($start);

    # The task
    put qq:to/END/

    Van Eck sequence OEIS:$seq; with the first term: $start
            First 10 terms: {@seq[^10]}
    Terms 991 through 1000: {@seq[990..999]}
    END
}
Output:
Van Eck sequence OEIS:A181391; with the first term: 0
        First 10 terms: 0 0 1 0 2 0 2 2 1 6
Terms 991 through 1000: 4 7 30 25 67 225 488 0 10 136


Van Eck sequence OEIS:A171911; with the first term: 1
        First 10 terms: 1 0 0 1 3 0 3 2 0 3
Terms 991 through 1000: 0 6 53 114 302 0 5 9 22 71


Van Eck sequence OEIS:A171912; with the first term: 2
        First 10 terms: 2 0 0 1 0 2 5 0 3 0
Terms 991 through 1000: 8 92 186 0 5 19 41 413 0 5


Van Eck sequence OEIS:A171913; with the first term: 3
        First 10 terms: 3 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 5 5 1 17 192 0 6 34 38 179


Van Eck sequence OEIS:A171914; with the first term: 4
        First 10 terms: 4 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 33 410 0 6 149 0 3 267 0 3


Van Eck sequence OEIS:A171915; with the first term: 5
        First 10 terms: 5 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 60 459 0 7 13 243 0 4 10 211


Van Eck sequence OEIS:A171916; with the first term: 6
        First 10 terms: 6 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 6 19 11 59 292 0 6 6 1 12


Van Eck sequence OEIS:A171917; with the first term: 7
        First 10 terms: 7 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 11 7 2 7 2 2 1 34 24 238


Van Eck sequence OEIS:A171918; with the first term: 8
        First 10 terms: 8 0 0 1 0 2 0 2 2 1
Terms 991 through 1000: 16 183 0 6 21 10 249 0 5 48

Refal

$ENTRY Go {
    , <Eck 1000>: e.Eck
    , <First 10 e.Eck>: (e.First10) e.Rest1
    , <Last 10 e.Eck>: (e.Rest2) e.Last10
    = <Prout e.First10>
      <Prout e.Last10>;
};

Eck {
    s.N = <Reverse <Repeat s.N EckStep>>;
};

Reverse {
    = ;
    e.X s.I = s.I <Reverse e.X>;
};

Repeat {
    0 s.F e.X = e.X;
    s.N s.F e.X = <Repeat <- s.N 1> s.F <Mu s.F e.X>>;
};

EckStep {
    = 0;
    s.N e.X, e.X: e.F s.N e.R,
             <Lenw e.F>: s.M e.F = <+ s.M 1> s.N e.X;
    s.N e.X = 0 s.N e.X;
};
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

REXX

using a list

This REXX version allows the specification of the   start   and   end   of the   Van Eck   sequence   (to be displayed)   as
well as the initial starting element   (the default is zero).

/*REXX pgm generates/displays the   'start ──► end'    elements of the Van Eck sequence.*/
parse arg LO HI $ .                              /*obtain optional arguments from the CL*/
if LO=='' | LO==","  then LO=   1                /*Not specified?  Then use the default.*/
if HI=='' | HI==","  then HI=  10                /* "      "         "   "   "     "    */
if  $=='' |  $==","  then  $=   0                /* "      "         "   "   "     "    */
$$=;               z= $                          /*$$: old seq:  $: initial value of seq*/
     do HI-1;      z= wordpos( reverse(z), reverse($$) );          $$= $;          $= $ z
     end   /*HI-1*/                              /*REVERSE allows backwards search in $.*/
                                                 /*stick a fork in it,  we're all done. */
say 'terms '  LO  " through "  HI  ' of the Van Eck sequence are: '  subword($,LO,HI-LO+1)
output   when using the default inputs:
terms  1  through  10  of the Van Eck sequence are:  0 0 1 0 2 0 2 2 1 6
output   when using the inputs of:     991   1000
terms  991  through  1000  of the Van Eck sequence are:  4 7 30 25 67 225 488 0 10 136
output   when using the inputs of:     1   20   6
terms  1  through  20  of the Van Eck sequence are:  6 0 0 1 0 2 0 2 2 1 6 10 0 6 3 0 3 2 9 0

using a dictionary

This REXX version   (which uses a dictionary)   is about   20,000   times faster   (when using larger numbers)   than
using a list   (in finding the previous location of an "old" number (term).

/*REXX pgm generates/displays the   'start ──► end'    elements of the Van Eck sequence.*/
parse arg LO HI sta .                            /*obtain optional arguments from the CL*/
if  LO=='' |  LO==","  then  LO=  1              /*Not specified?  Then use the default.*/
if  HI=='' |  HI==","  then  HI= 10              /* "      "         "   "   "     "    */
if sta=='' | sta==","  then sta=  0              /* "      "         "   "   "     "    */
$.0= sta;                    x= sta;      @.=.   /*$.: the  Van Eck  sequence as a list.*/
     do #=1 for HI-1                             /*X:  is the last term being examined. */
     if @.x==.  then do;   @.x= #;        $.#= 0;             x= 0;   end    /*new term.*/
                else do;     z= # - @.x;  $.#= z;   @.x= #;   x= z;   end    /*old term.*/
     end   /*#*/                                 /*Z:  the new term being added to list.*/
          LOw= LO - 1;     out= $.LOw            /*initialize the output value.         */
     do j=LO  to HI-1;     out= out $.j          /*build a list for the output display. */
     end   /*j*/                                 /*stick a fork in it,  we're all done. */
say 'terms '     LO     " through "     HI    ' of the Van Eck sequence are: '     out
output   is identical to the 1st REXX version.


RPL

Works with: Halcyon Calc version 4.2.7
RPL code Comment
≪ 
   DUP DUP SIZE GET → list item 
   ≪ list SIZE 1 - DUP 1 CF 
      WHILE DUP 1 FC? AND REPEAT 
         IF list OVER GET item == THEN 1 SF END            
         1 - END 
      - 1 FS? *
≫ ≫ 'LastOcc' STO

≪ { 0 } 2 ROT START DUP LastOcc + NEXT
≫ 'VANECK' STO

≪
   OVER SIZE { } ROT ROT FOR j
      OVER j GET + NEXT 
   SWAP DROP
≫ 'LASTL' STO 
( { sequence } -- pos_from_end )
Store sequence and last item
Initialize loop
Scan sequence backwards
   if item found then break
   decrement
Return pos or 0 if not found


( n -- { 0..VanEck(n) } )


( { n items } m -- { m..n } )
Extract items from mth position



Input:
10 VANECK
1000 VANECK 991 LASTL 
Output:
2: { 0 0 1 0 2 0 2 2 1 6 }
1: { 4 7 30 25 67 225 488 0 10 136 }

Ruby

Ruby: Using an Array

van_eck = Enumerator.new do |y|
  ar = [0]
  loop do
    y << (term = ar.last)  # yield
    ar << (ar.count(term)==1 ? 0 : ar.size - 1 - ar[0..-2].rindex(term))
  end
end

ve = van_eck.take(1000)
p ve.first(10), ve.last(10)
Output:
[0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
[4, 7, 30, 25, 67, 225, 488, 0, 10, 136]

Ruby: Using a Hash

class VenEch
  include Enumerable
  
  def initialize()
    @i = 0;
    @val = 0;
    @seen = {};
  end

  def add_num num
    @val = @i - @seen.fetch(num, @i)
    @seen[num] = @i
    @i += 1
  end

  def each(&block)
    loop { block.call(@val); add_num @val }
  end
end

ve = VenEch.new.take(1000)
p ve.first(10), ve.last(10)
Output:
[0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
[4, 7, 30, 25, 67, 225, 488, 0, 10, 136]

Rust

fn van_eck_sequence() -> impl std::iter::Iterator<Item = i32> {
    let mut index = 0;
    let mut last_term = 0;
    let mut last_pos = std::collections::HashMap::new();
    std::iter::from_fn(move || {
        let result = last_term;
        let mut next_term = 0;
        if let Some(v) = last_pos.get_mut(&last_term) {
            next_term = index - *v;
            *v = index;
        } else {
            last_pos.insert(last_term, index);
        }
        last_term = next_term;
        index += 1;
        Some(result)
    })
}

fn main() {
    let mut v = van_eck_sequence().take(1000);
    println!("First 10 terms of the Van Eck sequence:");
    for n in v.by_ref().take(10) {
        print!("{} ", n);
    }
    println!("\nTerms 991 to 1000 of the Van Eck sequence:");
    for n in v.skip(980) {
        print!("{} ", n);
    }
    println!();
}
Output:
First 10 terms of the Van Eck sequence:
0 0 1 0 2 0 2 2 1 6 
Terms 991 to 1000 of the Van Eck sequence:
4 7 30 25 67 225 488 0 10 136 

Scala

object VanEck extends App {

  def vanEck(n: Int): List[Int] = {

    def vanEck(values: List[Int]): List[Int] =
      if (values.size < n)
        vanEck(math.max(0, values.indexOf(values.head, 1)) :: values)
      else
        values

    vanEck(List(0)).reverse
  }

  val vanEck1000 = vanEck(1000)
  println(s"The first 10 terms are ${vanEck1000.take(10)}.")
  println(s"Terms 991 to 1000 are ${vanEck1000.drop(990)}.")
}
Output:
The first 10 terms are List(0, 0, 1, 0, 2, 0, 2, 2, 1, 6).
Terms 991 to 1000 are List(4, 7, 30, 25, 67, 225, 488, 0, 10, 136).

SETL

program vaneck;
    eck := [0];

    loop for i in [1..999] do
        prev := eck(..#eck-1);
        eck(i+1) := i - (max/[j : e=prev(j) | e=eck(i)] ? i);
    end loop;

    print(eck(1..10));
    print(eck(991..1000));
end program;
Output:
[0 0 1 0 2 0 2 2 1 6]
[4 7 30 25 67 225 488 0 10 136]

SNOBOL4

        define('eck(n)i,j')                     :(eck_end)
eck     eck = array(n,0)
        i = 0
eouter  i = lt(i,n - 1) i + 1                   :f(return)
        j = i
einner  j = gt(j,0) j - 1                       :f(eouter)
        eck<i + 1> = eq(eck<i>,eck<j>) i - j    :s(eouter)f(einner)
eck_end

        define('list(arr,start,stop)')          :(list_end)
list    list = list arr<start> ' '   
        start = lt(start,stop) start + 1        :s(list)f(return)
list_end
    
        ecks = eck(1000)
        output = list(ecks, 1, 10)
        output = list(ecks, 991, 1000)
end
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

Sidef

func van_eck(n) {

    var seen = Hash()
    var seq  = [0]
    var prev = seq[-1]

    for k in (1 ..^ n) {
        seq << (seen.has(prev) ? (k - seen{prev}) : 0)
        seen{prev} = k
        prev = seq[-1]
    }

    seq
}

say van_eck(10)
say van_eck(1000).last(10)
Output:
[0, 0, 1, 0, 2, 0, 2, 2, 1, 6]
[4, 7, 30, 25, 67, 225, 488, 0, 10, 136]

Swift

Translation of: Rust
struct VanEckSequence: Sequence, IteratorProtocol {
    private var index = 0
    private var lastTerm = 0
    private var lastPos = Dictionary<Int, Int>()
    
    mutating func next() -> Int? {
        let result = lastTerm
        var nextTerm = 0
        if let v = lastPos[lastTerm] {
            nextTerm = index - v
        }
        lastPos[lastTerm] = index
        lastTerm = nextTerm
        index += 1
        return result
    }
}
 
let seq = VanEckSequence().prefix(1000)

print("First 10 terms of the Van Eck sequence:")
for n in seq.prefix(10) {
    print(n, terminator: " ")
}
print("\nTerms 991 to 1000 of the Van Eck sequence:")
for n in seq.dropFirst(990) {
    print(n, terminator: " ")
}
print()
Output:
First 10 terms of the Van Eck sequence:
0 0 1 0 2 0 2 2 1 6 
Terms 991 to 1000 of the Van Eck sequence:
4 7 30 25 67 225 488 0 10 136 

Tcl

## Mathematically, the first term has index "0", not "1".  We do that, also.

set ::vE 0

proc vanEck {n} {
    global vE vEocc
    while {$n >= [set k [expr {[llength $vE] - 1}]]} {
        set kv [lindex $vE $k]
        ## value $kv @ $k is not yet stuffed into vEocc()
        lappend vE [expr {[info exists vEocc($kv)] ? $k - $vEocc($kv) : 0}]
        set vEocc($kv) $k
    }
    return [lindex $vE $n]
}

proc show {func from to} {
    for {set n $from} {$n <= $to} {incr n} {
        append r " " [$func $n]
    }
    puts "${func}($from..$to) =$r"
}

show vanEck 0 9
show vanEck 990 999
Output:
vanEck(0..9) = 0 0 1 0 2 0 2 2 1 6
vanEck(990..999) = 4 7 30 25 67 225 488 0 10 136

Visual Basic .NET

Translation of: C#
Imports System.Linq
Module Module1
    Dim h() As Integer
    Sub sho(i As Integer)
        Console.WriteLine(String.Join(" ", h.Skip(i).Take(10)))
    End Sub
    Sub Main()
        Dim a, b, c, d, f, g As Integer : g = 1000
        h = new Integer(g){} : a = 0 : b = 1 : For c = 2 To g
            f = h(b) : For d = a To 0 Step -1
                If f = h(d) Then h(c) = b - d: Exit For
            Next : a = b : b = c : Next : sho(0) : sho(990)
    End Sub
End Module
Output:

Same as C#.

V (Vlang)

Translation of: go
fn main() {
    max := 1000
    mut a := []int{len: max} // all zero by default
    for n in 0..max-1 {
        for m := n - 1;  m >= 0; m-- {
            if a[m] == a[n] {
                a[n+1] = n - m
                break
            }    
        }
    }
    println("The first ten terms of the Van Eck sequence are:")
    println(a[..10])
    println("\nTerms 991 to 1000 of the sequence are:")
    println(a[990..])
}
Output:
The first ten terms of the Van Eck sequence are:
[0 0 1 0 2 0 2 2 1 6]

Terms 991 to 1000 of the sequence are:
[4 7 30 25 67 225 488 0 10 136]

VTL-2

1000 :1)=0
1010 I=1
1020 J=I-1
1030 #=J=0*1090
1040 #=:J)=:I)*1070
1050 J=J-1
1060 #=1030
1070 :I+1)=I-J
1080 #=1100
1090 :I+1)=0
1100 I=I+1
1110 #=I<1000*1020
1120 I=1
1130 #=1170
1140 I=991
1150 #=1170
1160 #=9999
1170 R=!
1180 N=10
1190 ?=:I)
1200 $=32
1210 I=I+1
1220 N=N-1
1230 #=N=0=0*1190
1240 ?=""
1250 #=R
Output:
0 0 1 0 2 0 2 2 1 6
4 7 30 25 67 225 488 0 10 136

Wren

Translation of: Go
var max = 1000
var a = List.filled(max, 0)
var seen = {}
for (n in 0...max-1) {
    var m = seen[a[n]]
    if (m != null) a[n+1] = n - m
    seen[a[n]] = n
}
System.print("The first ten terms of the Van Eck sequence are:")
System.print(a[0...10])
System.print("\nTerms 991 to 1000 of the sequence are:")
System.print(a[990..-1])
Output:
The first ten terms of the Van Eck sequence are:
[0, 0, 1, 0, 2, 0, 2, 2, 1, 6]

Terms 991 to 1000 of the sequence are:
[4, 7, 30, 25, 67, 225, 488, 0, 10, 136]

XPL0

int Seq(1001), Back, N, M, Term;

func New;       \Return 'true' if last term is new to sequence
[for Back:= N-2 downto 1 do
        if Seq(Back) = Seq(N-1) then return false;
return true;
];

func VanEck;    \Return term of Van Eck sequence
[Seq(N):= if New then 0 else N-Back-1;
N:= N+1;
return Seq(N-1);
];

[N:= 1;
for M:= 1 to 1000 do
    [Term:= VanEck;
    if M<=10 or M>=991 then
        [IntOut(0, Term);
        if M=10 or M=1000 then Crlf(0) else Text(0, ", ");
        ];
    ];
]
Output:
0, 0, 1, 0, 2, 0, 2, 2, 1, 6
4, 7, 30, 25, 67, 225, 488, 0, 10, 136

zkl

Translation of: Raku
fcn vanEck(startAt=0){	// --> iterator
   (startAt).walker(*).tweak(fcn(n,seen,rprev){
      prev,t := rprev.value, n - seen.find(prev,n);
      seen[prev] = n;
      rprev.set(t);
      t
   }.fp1(Dictionary(),Ref(startAt))).push(startAt)
}
foreach n in (9){
   ve:=vanEck(n);
   println("The first ten terms of the Van Eck (%d) sequence are:".fmt(n));
   println("\t",ve.walk(10).concat(","));
   println("   Terms 991 to 1000 of the sequence are:");
   println("\t",ve.drop(990-10).walk(10).concat(","));
}
Output:
The first ten terms of the Van Eck (0) sequence are:
	0,0,1,0,2,0,2,2,1,6
   Terms 991 to 1000 of the sequence are:
	4,7,30,25,67,225,488,0,10,136
The first ten terms of the Van Eck (1) sequence are:
	1,0,0,1,3,0,3,2,0,3
   Terms 991 to 1000 of the sequence are:
	0,6,53,114,302,0,5,9,22,71
The first ten terms of the Van Eck (2) sequence are:
	2,0,0,1,0,2,5,0,3,0
   Terms 991 to 1000 of the sequence are:
	8,92,186,0,5,19,41,413,0,5
The first ten terms of the Van Eck (3) sequence are:
	3,0,0,1,0,2,0,2,2,1
   Terms 991 to 1000 of the sequence are:
	5,5,1,17,192,0,6,34,38,179
The first ten terms of the Van Eck (4) sequence are:
	4,0,0,1,0,2,0,2,2,1
   Terms 991 to 1000 of the sequence are:
	33,410,0,6,149,0,3,267,0,3
The first ten terms of the Van Eck (5) sequence are:
	5,0,0,1,0,2,0,2,2,1
   Terms 991 to 1000 of the sequence are:
	60,459,0,7,13,243,0,4,10,211
The first ten terms of the Van Eck (6) sequence are:
	6,0,0,1,0,2,0,2,2,1
   Terms 991 to 1000 of the sequence are:
	6,19,11,59,292,0,6,6,1,12
The first ten terms of the Van Eck (7) sequence are:
	7,0,0,1,0,2,0,2,2,1
   Terms 991 to 1000 of the sequence are:
	11,7,2,7,2,2,1,34,24,238
The first ten terms of the Van Eck (8) sequence are:
	8,0,0,1,0,2,0,2,2,1
   Terms 991 to 1000 of the sequence are:
	16,183,0,6,21,10,249,0,5,48