Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pp:26:teme:racket-counters [2026/03/09 10:33]
mihaela.balint created
pp:26:teme:racket-counters [2026/03/27 23:12] (current)
mihaela.balint [Changelog]
Line 1: Line 1:
 ====== La cumpărături ====== ====== La cumpărături ======
  
-  * Data publicării: ​08.03.2026 +  * Data publicării: ​09.03.2026 
-  * Data ultimei modificări: ​08.03.2026 ([[pp:​26:​teme:​racket-supermarket#​changelog]])+  * Data ultimei modificări: ​09.03.2026 ([[pp:​26:​teme:​racket-counters#​changelog]])
   * Tema (o arhivă .zip cu toate fișierele .rkt folosite în etapa curentă) se va încărca pe [[https://​vmchecker.cs.pub.ro/​ui/#​PP|vmchecker]]   * Tema (o arhivă .zip cu toate fișierele .rkt folosite în etapa curentă) se va încărca pe [[https://​vmchecker.cs.pub.ro/​ui/#​PP|vmchecker]]
 ===== Descriere generală și organizare ===== ===== Descriere generală și organizare =====
Line 89: Line 89:
  ​(counter 3 2 '((mia . 2)))  ​(counter 3 2 '((mia . 2)))
  ​(counter 4 0 '​()))</​code>​  ​(counter 4 0 '​()))</​code>​
 +
 +===== Etapa 2 =====
 +
 +Etapa 2 își propune exploatarea faptului că funcțiile sunt valori de ordinul întâi. Veți defini funcții curry, veți abstractiza funcții cu implementări similare, și veți folosi funcționale - atât implementări proprii, cât și funcționalele predefinite în Racket. Vă încurajăm să valorificați oportunitățile de utilizare a funcțiilor anonime și funcționalelor,​ inclusiv când enunțul nu impune acest lucru.
 +
 +În această etapă, numărul de case din magazin nu mai este fixat. Avem:
 +  * o listă fast-counters de case care acceptă doar clienți care au cumpărat maxim ITEMS produse
 +  * o listă slow-counters de case deschise tuturor clienților
 +Pentru ca în viitor să putem determina ordinea ieșirii clienților din magazin, introducem un nou câmp în structura counter:
 +<code scheme>
 +(define-struct counter (index tt et queue))
 +</​code>​
 +  * ''​et''​
 +    * vine de la "exit time", și reprezintă timpul rămas până când primul client din coadă va părăsi această casă
 +    * depinde de numărul de produse cumpărate de acest client (1 produs = 1 minut) și de eventualele întârzieri suferite de casă 
 +
 +Simulatorul trebuie să modeleze atât situațiile de la etapa anterioară,​ cât și două noi situații:
 +  * când cel mai avansat client (din punct de vedere al exit time-ului) părăsește magazinul
 +  * când este necesară deschiderea unor noi case, pentru a micșora media timpilor totali de așteptare
 +
 +Inițial, veți adapta o serie de funcții de la etapa 1 la noua reprezentare (adică la numărul variabil de case și la prezența câmpului ''​et''​ în structură).
 +
 +Apoi, funcțiile principale pe care va trebui să le implementați sunt:
 +
 +<​file>​
 +(update f counters index)
 +</​file>​
 +  * update aplică transformarea ''​f''​ casei din ''​counters''​ care are indexul ''​index'',​ și întoarce lista ''​counters''​ actualizată
 +  ​
 +Exemplu: ​
 +<code scheme>
 +(update (λ (C) (struct-copy counter C [tt 0]))
 +        (list (counter 1 2 2 '()) (counter 2 5 5 '()))
 +        2)
 +</​code>​
 +=> 
 +<code scheme>
 +(list (counter 1 2 2 '()) (counter 2 0 5 '()))
 +</​code>​
 +
 +<​file>​
 +(remove-first-from-counter C)
 +</​file>​
 +  * remove-first-from-counter scoate prima persoană din coada casei ''​C''​
 +  * ''​tt''​-ul și ''​et''​-ul casei ''​C''​ trebuie ajustate în consecință ​
 +    * orice întârziere avea casa, ea dispare
 +    * dispar produsele clientului care pleacă (și minutele asociate acestora)
 +    * nicio altă casă nu este afectată (este ca și cum ar fi trecut timpul doar pe la casa ''​C'';​ acest lucru se va schimba în etapa 3)
 +
 +Exemplu:
 +<code scheme>
 +(remove-first-from-counter (counter 1 50 5 '((ana . 3) (leo . 35) (mia . 10))))
 +</​code>​
 +=> 
 +<code scheme>
 +(counter 1 45 35 '((leo . 35) (mia . 10)))
 +</​code>​
 +
 +<​file>​
 +(serve requests fast-counters slow-counters)
 +</​file>​
 +  * serve primește o listă de cereri (așezări la coadă, întârzieri,​ ieșiri de la casă, ajustări ale numărului de case) și le tratează în ordine, în sensul că actualizează casele din ''​fast-counters''​ și ''​slow-counters''​ pe măsură ce situația lor evoluează
 +
 +Exemplu (pentru ''​ITEMS = 5''​): ​
 +<code scheme>
 +(serve '((ana 8) (mia 2) (mara 14) (ion 7) (remove-first) (ensure 5) (remove-first))
 +       (list (empty-counter 1) (empty-counter 2))
 +       (list (empty-counter 3) (empty-counter 4)))
 +</​code>​
 +
 +  * observăm că avem două case fast (pentru simplitate le numim ''​C1''​ și ''​C2''​) și două case slow (le numim ''​C3''​ și ''​C4''​)
 +  * primele 4 cereri distribuie cei 4 clienți astfel:
 +    * ''​ana''​ la ''​C3''​ (prima casă slow cu ''​tt=0''​) => ''​%%C3 = (counter 3 8 8 '((ana . 8)))%%''​
 +    * ''​mia''​ la ''​C1''​ (prima casă fast cu ''​tt=0''​) => ''​%%C1 = (counter 1 2 2 '((mia . 2)))%%''​
 +    * ''​mara''​ la ''​C4''​ (casa slow cu ''​tt''​ minim) ​ => ''​%%C4 = (counter 4 14 14 '​((mara . 14)))%%''​
 +    * ''​ion''​ la ''​C3''​ (casa slow cu ''​tt''​ minim) ​  => ''​%%C3 = (counter 3 15 8 '((ana . 8) (ion . 7)))%%''​
 +  * remove-first scoate cel mai avansat client:
 +    * cel mai avansat client este ''​mia''​ (''​et=2''​)
 +    * ea este scoasă de la ''​C1'' ​            => ''​%%C1 = (counter 1 0 0 '​())%%''​ (observați ''​tt''​ și ''​et''​)
 +  * ensure compară media timpilor totali cu ''​5'':​
 +    * ''​tt1 + tt2 + tt3 + tt4 = 0 + 0 + 15 + 14 = 29''​ => ''​ttmed = 29 / 4 > 5''​
 +    * se adaugă o casă slow goală (''​C5''​) => ''​ttmed = 29 / 5 > 5''​
 +    * se adaugă o casă slow goală (''​C6''​) => ''​ttmed = 29 / 6 ≤ 5''​ (deci putem trece la cererea următoare)
 +  * remove-first scoate cel mai avansat client:
 +    * cel mai avansat client este ''​ana''​ (''​et=8''​)  ​
 +    * ea este scoasă de la ''​C3'' ​            => ''​%%C3 = (counter 3 7 7 '((ion . 7)))%%''​ (observați ''​tt''​ și ''​et''​)
 +
 +===== Etapa 3 =====
 +
 +Etapa 3 subliniază importanța abstractizării. Vă veți defini propriul TDA (tip de date abstract) cu o interfață completă (un set de constructori și operatori) prin care utilizatorul poate manipula valorile tipului, independent de implementarea din spate. Apoi, voi înșivă trebuie să folosiți TDA-ul doar prin intermediul interfeței (aspect esențial pentru o dezvoltare facilă în etapa 4). 
 +
 +Rezolvarea etapei începe cu implementarea TDA-ului ''​queue''​ în fișierul **queue.rkt**.
 +
 +Acest tip reprezintă o coadă (first-in-first-out) ca pe o structură:
 +<code scheme>
 +(define-struct queue (left right size-l size-r))
 +</​code>​
 +  * ''​left'',​ ''​right''​
 +    * sunt stive (last-in-first-out,​ implementate ca liste Racket) ​
 +    * o adăugare în coadă este o adăugare în stiva ''​right'' ​
 +    * ex adăugare: \\ adaug 1 => ''​%%right = '​(1)%%'',​ \\ adaug 2 => ''​%%right = '(2 1)%%''​
 +    * o extragere din coadă este o extragere din stiva ''​left''​ (când ''​left''​ este vidă, mutăm toate elementele din right în left, apoi extragem din left) 
 +    * mutarea este rezultatul unor operații ''​pop''​ (din ''​right''​) + ''​push''​ (în ''​left''​) repetate
 +    * ex mutare: \\ mut în ''​%%left = '​()%%''​ din ''​%%right = '(2 1)%%''​ => \\ ''​%%left = '​(2)%%'',​ ''​%%right = '​(1)%%''​ (primul ''​pop''​ din ''​right''​ îl extrage pe ''​2''​ și îi face ''​push''​ în ''​left''​) => \\ ''​%%left = '(1 2)%%'',​ ''​%%right = '​()%%''​ (apoi ''​pop''​ din ''​right''​ îl extrage pe ''​1''​ și îi face ''​push''​ în ''​left''​)
 +    * ex extragere: \\ extrag din coada cu ''​%%left = '​()%%'',​ ''​%%right = '(2 1)%%''​ => \\ ''​%%left = '(1 2)%%'',​ ''​%%right = '​()%%''​ (după mutarea elementelor) => \\ ''​%%left = '​(2)%%'',​ ''​%%right = '​()%%''​ (după extragerea primului element)
 +    * observați că primul element adăugat este primul element extras (first-in-first-out)
 +  * ''​size-l'',​ ''​size-r''​
 +    * sunt numere naturale, reprezentând numărul de elemente din cele două stive
 +
 +Sarcina voastră este să implementați interfața TDA-ului queue:
 +<​file>​
 +  empty-queue ​ :              -> queue  (constructor nular pentru o coadă goală)
 +  queue-empty?​ :        queue -> Bool   ​(operator care verifică dacă o coadă este goală)
 +  enqueue ​     : Elem x queue -> queue  (operatorul de adăugare în coadă)
 +  dequeue ​     :        queue -> queue  (operatorul de extragere din coadă)
 +  top          :        queue -> Elem   ​(operatorul de vizualizare a elementului din vârful cozii)
 +</​file>​
 +  ​
 +Această reprezentare asigură cost amortizat ''​O(1)''​ pentru operațiile de ''​enqueue''​ și ''​dequeue''​. Vom folosi acest TDA pentru câmpul ''​queue''​ al structurii ''​counter'',​ optimizând reprezentarea cu liste Racket din etapele 1 și 2.
 +
 +După ce ați finalizat implementarea TDA-ului, continuați implementarea în fișierul **etapa3.rkt**. ​
 +  
 +Mai întâi, adaptați funcțiile de la etapa 2 astfel încât ele să țină cont de noua reprezentare (în care câmpul ''​queue''​ din structura ''​counter''​ este de tip coadă (''​queue''​);​ este o coincidență că numele câmpului coincide cu numele tipului, nu o necesitate).
 +
 +În această etapă simulatorul modelează, în plus, trecerea timpului. Anterior, simulatorul trata așezările la cozi, întârzierile și deschiderile de noi case ca și cum s-ar produce în ordine, dar la un același moment de timp. Acest lucru nu corespunde realității - între evenimente este firesc să treacă timp, timp în care clienții avansează la case și, la un moment dat, părăsesc magazinul.
 +
 +Funcțiile principale pe care va trebui să le implementați sunt:
 +<​file>​
 +(pass-time-through-counter minutes)
 +</​file>​
 +  * este o funcție curry (aplicată parțial pe un număr de minute, va aștepta un al doilea argument de tip ''​counter''​)
 +  * odată ce și-a primit (pe rând) argumentele,​ ''​pass-time-through-counter''​ actualizează ''​tt''​-ul și ''​et''​-ul casei pentru a reflecta trecerea numărului dat de minute
 +  * câmpul ''​queue''​ nu se modifică, deoarece intenția este să folosim această funcție doar cu timpi mai mici sau egali cu timpul până la ieșirea primului client din coadă
 +  ​
 +Exemplu: ​
 +<code scheme>
 +((pass-time-through-counter 5) 
 + ​(counter 1 
 +          12 
 +          7 
 +          (make-queue '() '((ada . 7)) 0 1)))
 +</​code>​
 +=>
 +<code scheme>
 +(counter 1 7 2 (queue '() '((ada . 7)) 0 1))
 +</​code>​
 +
 +<​file>​
 +(serve requests fast-counters slow-counters)
 +</​file>​
 +  * ''​serve''​ actualizează casele din ''​fast-counters''​ și ''​slow-counters''​ pe măsură ce situația lor evoluează, pe baza listei ''​requests''​ în care elementele sunt:
 +    * cereri (așezări la coadă, întârzieri,​ ajustări ale numărului de case) \\ sau 
 +    * timpi care trec între cereri
 +
 +Exemplu pentru ''​ITEMS = 5'': ​
 +<code scheme>
 +(serve '((ana 14) (mia 2) 5 (ion 7) (delay 1 2) 7)
 +       (list (empty-counter 1))
 +       (list (empty-counter 2) (empty-counter 3)))
 +</​code>​
 + 
 +  * observăm că avem o casă fast (o numim ''​C1''​) și două case slow (le numim ''​C2''​ și ''​C3''​)
 +  * primele două cereri distribuie cei doi clienți astfel:
 +    * ''​ana''​ la ''​C2''​ => ''​%%C2 = (counter 2 14 14 (queue '() '((ana . 14)) 0 1))%%''​
 +    * ''​mia''​ la ''​C1''​ => ''​%%C1 = (counter 1 2 2 (queue '() '((mia . 2)) 0 1))%%''​
 +  * apoi trec ''​5''​ minute, după care situația este:
 +    * ''​mia''​ a ieșit de la ''​C1'',​ care a rămas goală => ''​%%C1 = (counter 1 0 0 (queue '() '() 0 0))%%''​
 +    * la ''​C2''​ au trecut ''​5''​ minute => ''​%%C2 = (counter 2 9 9 (queue '() '((ana . 14)) 0 1))%%''​
 +    * ''​C3''​ a rămas cum era: goală și neîntârziată => ''​%%C3 = (counter 3 0 0 (queue '() '() 0 0))%%''​
 +    * au părăsit magazinul, în ordine: ''​%%'​((1 . mia))%%'' ​ (''​1''​ reprezintă indexul casei de la care a ieșit ''​mia''​)
 +  * ''​ion''​ se așază la ''​C3''​ => ''​%%C3 = (counter 3 7 7 (queue '() '((ion . 7)) 0 1))%%''​
 +  * ''​C1''​ este întârziată cu ''​2''​ minute => ''​%%C1 = (counter 1 2 2 (queue '() '() 0 0))%%''​
 +  * apoi trec ''​7''​ minute, după care situația este:
 +    * întârzierea de la ''​C1''​ s-a consumat => ''​%%C1 = (counter 1 0 0 (queue '() '() 0 0))%%''​
 +    * la ''​C2''​ au trecut ''​7''​ minute => ''​%%C2 = (counter 2 2 2 (queue '() '((ana . 14)) 0 1))%%''​
 +    * ''​ion''​ a ieșit de la ''​C3'',​ care a rămas goală => ''​%%C3 = (counter 3 0 0 (queue '() '() 0 0))%%''​
 +    * au părăsit magazinul, în ordine:: ''​%%'​((1 . mia) (3 . ion))%%'' ​
 +
 +===== Etapa 4 =====
 +
 +Etapa 4 oferă un exemplu interesant de utilizare a fluxurilor. Veți reimplementa TDA-ul ''​queue''​ pentru a obține un plus de performanță și, cu condiția să fi respectat bariera de abstractizare în etapa 3, funcțiile implementate anterior vor funcționa fără modificări pe noua reprezentare. ​
 +
 +Din nou, rezolvarea etapei începe cu implementarea TDA-ului ''​queue''​ în fișierul **queue.rkt**.
 +
 +Din motive de performanță detaliate în schelet, reținem câmpul ''​left''​ al structurii ''​queue''​ ca flux (în contrast cu reprezentarea ca listă din etapa 3). Definiția structurii nu se modifică:
 +<code scheme>
 +(define-struct queue (left right size-l size-r))
 +</​code>​
 +  * o adăugare în coadă este o adăugare în stiva ''​right''​ (ca înainte)
 +  * o extragere din coadă este o extragere din stiva ''​left''​ (ca înainte)
 +  * după fiecare operație ''​enqueue''​ sau ''​dequeue''​ trebuie menținut invariantul ​ ''​%%size(left) ≥ size(right)%%'';​ astfel, niciun ''​dequeue''​ nu va găsi stiva ''​left''​ vidă 
 +  * când o operație ''​enqueue''​ sau ''​dequeue''​ produce situația ''​%%size(left) = size(right) - 1%%'',​ aplicăm o **rotație**: ​
 +    * mutăm "în mod leneș"​ toate elementele din ''​right''​ în ''​left''​
 +    * ce înseamnă "​leneș":​ elementele vor fi mutate, de fapt, unul câte unul, pe măsură ce extragem elemente din ''​left'',​ nu toate deodată (dacă s-ar muta deodată nu am rezolva problema complexității,​ ci doar am deplasa-o asupra altor operații)
 +  ​
 +Veți redefini interfața din etapa 3. Noile implementări depind de implementarea funcției de rotație:
 +<​file>​
 +(rotate left right Acc)
 +</​file>​
 +  * ''​rotate''​ calculează (cu evaluare întârziată) rezultatul ''​%%left ++ (reverse right)%%''​
 +  * rotația se efectuează doar atunci când ''​%%size(left) = size(right) - 1%%'',​ așadar găsește un număr echilibrat de elemente în cele două stive
 +  * la fiecare extragere din ''​left'',​ extragem ("​pop"​) și un element din ''​right''​ pe care îl adăugăm ("​push"​) în acumulatorul ''​Acc''​
 +  * când ''​left''​ devine goală, ''​right''​ conține un singur element (''​%%size(left) = size(right) - 1%%''​),​ iar ''​Acc''​ conține toate elementele aflate inițial în ''​right'',​ în ordine inversă; acum adăugăm elementul din ''​right''​ la începutul ''​Acc''​ (în timp ''​O(1)''​),​ și acesta este exact conținutul cu care trebuie să reinițializăm stiva ''​left''​
 +
 +Exemplu: ​
 +<code scheme>
 +(rotate (stream-cons 1 (stream-cons 2 (stream-cons 3 empty-stream)))
 +        '(7 6 5 4)
 +        empty-stream)
 +</​code>​
 +=>
 +''​%%#<​stream>​%%''​ \\
 +Mai precis, rezultatul este de forma:
 +<code scheme>
 +(stream-cons 1 
 +             ​(rotate (stream-cons 2 (stream-cons 3 empty-stream))
 +                     '​(6 5 4)
 +                     ​(stream-cons 7 empty-stream)))
 +</​code>​
 +și, conform comportamentului constructorului ''​stream-cons'',​ apelul recursiv al funcției ''​rotate''​ este întârziat.
 +Când accesăm restul acestui flux (de exemplu, la ''​dequeue''​),​ evaluăm apelul întârziat,​ obținând un rezultat de forma ''​%%(stream-cons 2 (rotate ....))%%'',​ etc. 
 +
 +După ce ați finalizat implementarea TDA-ului, continuați implementarea în fișierul **etapa4.rkt**.
 +  
 +Față de etapa anterioară,​ simulatorul tratează două cereri noi:
 +  * ''​(close index)''​ solicită închiderea casei cu indexul ''​index'',​ și redistribuirea clienților din coadă (cu excepția primului)
 +  * ''​(open index)''​ solicită deschiderea casei cu indexul ''​index''​
 +Apare distincția între case deschise și case închise: în această etapă, cererile de tip "​așezare la o casă",​ respectiv "​ensure"​ iau în considerare doar casele deschise. Modul în care reprezentați starea caselor (deschisă/​închisă) este la alegerea voastră.
 +
 +
 +Exemplu pentru ''​ITEMS = 5'':​
 +<code scheme>
 +(serve '((ana 7) (mia 2) 5 (ion 8) (dan 6) (close 2) (delay 1 15) (ema 2) (open 2) 2 (geo 5) (close 1) (ensure 7))
 +       (list (empty-counter 1))
 +       (list (empty-counter 2) (empty-counter 3)))
 +</​code>​
 +  * avem o casă fast (o numim ''​C1''​) și două case slow (le numim ''​C2''​ și ''​C3''​)
 +  * când ilustrăm starea caselor:
 +    * o casă este o colecție de ''​index'',​ ''​tt'',​ ''​et''​ și ''​queue''​ (dar puteți modifica structura, dacă doriți)
 +    * vizualizăm elementele fluxurilor între acolade (în loc să scriem ''#<​stream>'',​ ceea ce nu este tocmai informativ)
 +  * primele două cereri distribuie cei doi clienți astfel:
 +    * ''​ana''​ la ''​C2''​ => ''​%%C2 = (counter 2 7 7 (queue {(ana . 7)} '() 1 0))%%'' ​
 +    * ''​mia''​ la ''​C1''​ => ''​%%C1 = (counter 1 2 2 (queue {(mia . 2)} '() 1 0))%%''​
 +    * obs: în etapa trecută ''​ana''​ și ''​mia''​ apăreau ca elemente în stiva ''​right'';​ acum ele sunt în stiva ''​left'',​ deoarece s-a efectuat o rotație, necesară pentru menținerea invariantului ''​%%size(left) ≥ size(right)%%'' ​
 +  * apoi trec ''​5''​ minute, după care situația este:
 +    * ''​mia''​ a ieșit de la ''​C1'',​ care a rămas goală => ''​%%C1 = (counter 1 0 0 (queue {} '() 0 0))%%''​
 +    * la ''​C2''​ au trecut ''​5''​ minute => ''​%%C2 = (counter 2 2 2 (queue {(ana . 7)} '() 1 0))%%''​
 +    * ''​C3''​ a rămas cum era: goală și neîntârziată => ''​%%C3 = (counter 3 0 0 (queue {} '() 0 0))%%''​
 +  * următoarele două cereri distribuie cei doi clienți astfel:
 +    * ''​ion''​ la ''​C3''​ => ''​%%C3 = (counter 3 8 8 (queue {(ion . 8)} '() 1 0))%%''​
 +    * ''​dan''​ la ''​C2''​ => ''​%%C2 = (counter 2 8 2 (queue {(ana . 7)} '((dan . 6)) 1 1))%%''​
 +  * ''​C2''​ se închide => ''​ana''​ rămâne la ''​C2'',​ iar ''​dan''​ se mută la ''​C3''​
 +    * => ''​%%C2 = (counter 2 2 2 (queue {(ana . 7)} '() 1 0))%%''​ și nu mai primește clienți
 +    * => ''​%%C3 = (counter 3 14 8 (queue {(ion . 8)} '((dan . 6)) 1 1))%%''​
 +  * ''​C1''​ este întârziată cu ''​15''​ minute => ''​%%C1 = (counter 1 15 15 (queue {} '() 0 0))%%''​
 +  * ''​ema''​ se așază la ''​C3''​ => ''​%%C3 = (counter 3 16 8 (queue {(ion . 8) <​flux-neevaluat-care-va-produce-dan-și-ema>​} '() 3 0))%%''​
 +    * ''​C2''​ are ''​tt''​ mai mic, însă ''​C2''​ este închisă, deci se alege între ''​C1''​ și ''​C3''​
 +  * ''​C2''​ se deschide, fără să producă alte modificări
 +  * apoi trec ''​2''​ minute, după care situația este:
 +    * întârzierea de la ''​C1''​ s-a consumat parțial => ''​%%C1 = (counter 1 13 13 (queue {} '() 0 0))%%''​
 +    * ''​ana''​ a ieșit de la ''​C2''​ => ''​%%C2 = (counter 2 0 0 (queue {} '() 0 0))%%''​
 +    * la ''​C3''​ au trecut ''​2''​ minute => ''​%%C3 = (counter 3 14 6 (queue {(ion . 8) <​flux...>​} '() 3 0))%%''​
 +  * ''​geo''​ se așază la ''​C2''​ => ''​%%C2 = (counter 2 5 5 (queue {(geo . 5)} '() 1 0))%%''​
 +  * ''​C1''​ se închide, fără să producă alte modificări
 +  * ''​ensure''​ compară media timpilor totali ai caselor deschise cu ''​7''​
 +    * ''​tt2''​ + ''​tt3''​ = ''​5''​ + ''​14''​ = ''​19''​ => ''​tt-mediu = 19 / 2 > 7''​
 +    * ''​tt1''​ nu participă la medie întrucât ''​C1''​ este închisă
 +    * se adaugă o casă slow goală (''​C4''​) => ''​tt-mediu = 19 / 3 ≤ 7''​ (deci ne oprim aici cu adăugarea)
 +Rezultat final:
 +<code scheme>
 +(list
 + '​((1 . mia) (2 . ana))
 + (cons 2 (queue #<​stream>​ '() 1 0))
 + (cons 3 (queue #<​stream>​ '() 3 0)))
 +</​code>​
  
  
Line 104: Line 379:
  
 ===== Resurse ===== ===== Resurse =====
-  * {{:​pp:​26:​teme:​racket:​etapa1.zip|etapa 1}}+  * {{:​pp:​26:​teme:​racket:​etapa-4.zip|etapa 4}} 
 +  * {{:​pp:​26:​teme:​racket:​etapa-3.zip|etapa 3}} 
 +  * {{:​pp:​26:​teme:​racket:​etapa-2.zip|etapa 2}} 
 +  * {{:​pp:​26:​teme:​racket:​etapa-1.zip|etapa 1}}
   * {{:​pp:​26:​teme:​racket:​tutorial.rkt|tutorial structuri}}   * {{:​pp:​26:​teme:​racket:​tutorial.rkt|tutorial structuri}}
  
  
 ===== Changelog ===== ===== Changelog =====
-  * 09.03 (ora 16:00) - Am publicat etapa 1. +  ​* 27.03 (ora 23:12) - Am publicat etapa 4. 
 +  * 19.03 (ora 10:32) - Am publicat etapa 3. 
 +  * 13.03 (ora 08:10) - Am publicat etapa 2. 
 +  ​* 09.03 (ora 15:30) - Am publicat etapa 1. 
  
  
pp/26/teme/racket-counters.1773045219.txt.gz · Last modified: 2026/03/09 10:33 by mihaela.balint
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0