The Recamán's sequence generates Natural numbers.

Starting from a(0)=0, the n'th term a(n), where n>0, is the previous term minus n i.e a(n) = a(n-1) - n but only if this is both positive and has not been previousely generated.


If the conditions don't hold then a(n) = a(n-1) + n.



Task

 Generate and show here the first 15 members of the sequence.
 Find and show here, the first duplicated number in the sequence.
 Optionally: Find and show here, how many terms of the sequence are needed until all the integers 0..1000, inclusive, are generated.


References

 A005132, The On-Line Encyclopedia of Integer Sequences.
 The Slightly Spooky Recamán Sequence, Numberphile video.
 Recamán's sequence, on Wikipedia.


100H:
BDOS: PROCEDURE(F,A); DECLARE F BYTE, A ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT;
PRINT$CH: PROCEDURE(C); DECLARE C BYTE; CALL BDOS(2,C); END PRINT$CH;
PRINT$STR: PROCEDURE(S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT$STR;
 
/* PRINT NUMBER */
PRINT$NUM: PROCEDURE(N);
    DECLARE (N, P) ADDRESS, C BASED P BYTE;
    DECLARE S(6) BYTE INITIAL('.....$');
    P = .S(5);
DIGIT:
    P = P-1;
    C = '0' + N MOD 10;
    N = N/10;
    IF N>0 THEN GO TO DIGIT;
    CALL PRINT$STR(P);
END PRINT$NUM;
 
/* IS X IN THE FIRST N TERMS OF THE SEQUENCE */
FIND: PROCEDURE(SEQ,X,N) BYTE;
    DECLARE SEQ ADDRESS, (I, X, N, A BASED SEQ) BYTE;
    DO I=0 TO N-1;
        IF A(I)=X THEN RETURN 0FFH;
    END;
    RETURN 0;
END FIND;
 
/* GENERATE THE N'TH TERM OF THE SEQUENCE */
GENERATE: PROCEDURE(SEQ,N) BYTE;
    DECLARE SEQ ADDRESS, (N, A BASED SEQ) BYTE;
    IF N=0 THEN
        A(N)=0;
    ELSE DO;
        DECLARE (SUB, ADD) BYTE;
        SUB = A(N-1) - N;
        ADD = A(N-1) + N;
        /* A(N-1) - N NEGATIVE? */
        IF A(N-1) <= N THEN
            A(N) = ADD;
        /* A(N-1) - N ALREADY GENERATED? */
        ELSE IF FIND(SEQ,SUB,N) THEN
            A(N) = ADD;
        ELSE
            A(N) = SUB;
    END;
    RETURN A(N);
END GENERATE;
 
DECLARE I BYTE, A(30) BYTE;
CALL PRINT$STR(.'FIRST 15 MEMBERS: $');
DO I=0 TO 14;
    CALL PRINT$NUM(GENERATE(.A, I));
    CALL PRINT$CH(' ');
END;
CALL PRINT$STR(.(13,10,'FIRST REPEATED TERM: A($'));
 
I=15;
DO WHILE NOT FIND(.A, GENERATE(.A, I), I);
    I = I+1;
END;
 
CALL PRINT$NUM(I);
CALL PRINT$STR(.') = $');
CALL PRINT$NUM(A(I));
CALL PRINT$STR(.(13,10,'$'));
CALL EXIT;
EOF