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

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


References

 Don't Know (the Van Eck Sequence) - Numberphile video.
 Wikipedia Article: Van Eck's Sequence.
  OEIS sequence: A181391.


(() => {
    '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();
})();