# Liste circulare

Un tip special de lista este lista circulara. Daca stii ceva programare, ai intalnit probabil buffere circulare sau siruri circulare. Aici vor fi numite doar ring (inel) - un nume scurt si simplu.

In sectiunile precedente referitoare la liste am vazut cum putem citi elemente din ele folosind mecanismul de indexare:

    puts [52, 55, 59][1]

Ce se intampla daca doresti indexul ‘100’? Ei bine, este evident ca nu exista un element la indexul 100 deoarece lista are doar trei elemente in ea. Deci Sonic Pi va returna ‘nil’ adica nimic.

Sa ne imaginam insa ca ai un contor cum ar fi bataia curenta, care creste continnuu. Sa cream contorul si lista:

    counter = 0
    notes = [52, 55, 59]

Putem acum folosi contorul pentru a citi o nota din lista:

    puts notes[counter]

Super, am obtinut ‘52’. Acum, sa incrementam contorul si sa citim o alta nota:

    counter = (inc counter)
    puts notes[counter]

Am obtinut ‘55’ si daca mai incercam o data obtinem ‘59’. Totusi, daca incercam din nou vom ramane fara numere in lista si vom obtine ‘nil’. Dar daca am dori sa o luam pur si simplu de la inceputul listei din nou? Pentru asta exista listele circulare.

## Crearea listelor circulare

Putem crea liste circulare in doua moduri. Fie folosim functia ‘ring’ cu elementele din lista ca parametri:

    (ring 52, 55, 59)

Sau putem lua o lista normala si sa o transformam intr-una circulara trimitandu-i mesajul ‘.ring’:

    [52, 55, 59].ring

## Indexarea listelor circulare

Putem folosi o lista circulara la fel ca pe una normala cu diferenta ca putem folosi indecsi negativi sau mai mari decat lungimea listei si vom obtine intotdeauna un element din lista:

    (ring 52, 55, 59)[0] #=> 52
    (ring 52, 55, 59)[1] #=> 55
    (ring 52, 55, 59)[2] #=> 59
    (ring 52, 55, 59)[3] #=> 52
    (ring 52, 55, 59)[-1] #=> 59

## Folosirea listelor circulare

Sa presupunem ca folosim o variabila care reprezinta numarul bataii curente. Putem folosi acest numar ca index in lista circulare pentru a aduce nota care urmeaza sa fie redata, sau timpul de release sau orice altceva ce am memorat in lista respectiva, indiferent de bataia la care s-a ajuns.

## Gamele si acordurile sunt liste circulare

E util de stiut ca listele returnate de ‘scale’ si ‘chord’ sunt liste circulare si pot fi citite folosind orice valori pentru indecsi.

## Constructori pentru listele circulare

Pe langa ‘ring’ exista si alte functii care pot construi o lista circulara pentru noi.

- ‘range’ iti cere sa specifici un punct de inceput, unul de sfarsit si dimensiunea pasului.
- ‘bools’ iti permite sa folosesti ‘0’ si ‘1’ pentru a reprezenta valori booleene.
- ‘knit’ iti permite sa tesi o secventa de valori care se repeta.
- ‘spread’ creeaza o lista circulara cu distributie euclidiana.

Poti cauta mai multe informatii in documentatia pentru functiile respective.