This shows you the differences between two versions of the page.
|
pp:26:teme:racket-supermarket [2026/03/25 16:39] mihaela.balint |
pp:26:teme:racket-supermarket [2026/03/26 08:55] (current) mihaela.balint |
||
|---|---|---|---|
| Line 40: | Line 40: | ||
| (stream-cons 7 empty-stream))) | (stream-cons 7 empty-stream))) | ||
| </code> | </code> | ||
| - | și, după cum știm din comportamentul constructorului stream-cons, apelul recursiv al funcției rotate este întârziat. | + | și, conform comportamentului constructorului ''stream-cons'', apelul recursiv al funcției ''rotate'' este întârziat. |
| - | Dacă ulterior vom accesa restul acestui flux, vom evalua noul apel al lui rotate și vom obține un rezultat de forma ''%%(stream-cons 2 (rotate ....))%%'', etc. | + | 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 dezvoltarea simulatorului în fișierul **supermarket.rkt**. | + | După ce ați finalizat implementarea TDA-ului, continuați implementarea în fișierul **etapa4.rkt**. |
| - | Simulatorul trebuie să modeleze toate situațiile de la etapa anterioară, plus situația în care o casă este închisă. | + | 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: | + | |
| - | <code lisp> | + | Exemplu pentru ''ITEMS = 5'': |
| - | (serve '((ana 7) (mia 2) 5 (ion 8) (close 2) (delay 1 10) (dan 2) 3 (ensure 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 1)) | ||
| (list (empty-counter 2) (empty-counter 3))) | (list (empty-counter 2) (empty-counter 3))) | ||
| - | </code> pentru ITEMS = 5: | + | </code> |
| - | * observăm că avem o casă fast (o vom numi C1) și 2 case slow (le vom numi C2 și C3) | + | * avem o casă fast (o numim ''C1'') și două case slow (le numim ''C2'' și ''C3'') |
| - | * pentru a ilustra starea caselor vom folosi: | + | * când ilustrăm starea caselor: |
| - | * reprezentarea unui counter ca o colecție de index, tt, et și queue (deși în această etapă aveți libertatea să modificați structura, dacă doriți) | + | * o casă este o colecție de ''index'', ''tt'', ''et'' și ''queue'' (dar puteți modifica structura, dacă doriți) |
| - | * reprezentarea elementelor unui flux între acolade (altfel ar trebui să scriem #<stream>, ceea ce nu este tocmai informativ) | + | * vizualizăm elementele fluxurilor între acolade (în loc să scriem ''#<stream>'', ceea ce nu este tocmai informativ) |
| - | * primele 2 cereri distribuie cei 2 clienți astfel: | + | * primele două cereri distribuie cei doi clienți astfel: |
| - | * ana la C2 => ''%%C2 = (counter 2 7 7 (queue {(ana . 7)} '() 1 0))%%'' | + | * ''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))%%'' | + | * ''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, dar aici sunt în stiva left pentru că s-a efectuat o rotație, necesară pentru menținerea invariantului |left| ≥ |right| | + | * 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 caselor trebuie să fie: | + | * 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))%%'' | + | * ''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))%%'' | + | * 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))%%'' | + | * ''C3'' a rămas cum era: goală și neîntârziată => ''%%C3 = (counter 3 0 0 (queue {} '() 0 0))%%'' |
| - | * ion se așază la C3 => ''%%C3 = (counter 3 8 8 (queue {(ion . 8)} '() 1 0))%%'' | + | * următoarele două cereri distribuie cei doi clienți astfel: |
| - | * C2 este închisă => nu poate primi clienți noi, dar funcționează normal până la golirea cozii | + | * ''ion'' la ''C3'' => ''%%C3 = (counter 3 8 8 (queue {(ion . 8)} '() 1 0))%%'' |
| - | * C1 este întârziată cu 10 minute => ''%%C1 = (counter 1 10 10 (queue {} '() 0 0))%%'' | + | * ''dan'' la ''C2'' => ''%%C2 = (counter 2 8 2 (queue {(ana . 7)} '((dan . 6)) 1 1))%%'' |
| - | * dan se așază la C3 => ''%%C3 = (counter 3 10 8 (queue {(ion . 8)} '((dan . 2)) 1 1))%%'' | + | * ''C2'' se închide => ''ana'' rămâne la ''C2'', iar ''dan'' se mută la ''C3'' |
| - | * C2 avea tt-ul mai mic, însă C2 este închisă, deci s-a ales între C1 și C3 | + | * => ''%%C2 = (counter 2 2 2 (queue {(ana . 7)} '() 1 0))%%'' și nu mai primește clienți |
| - | * apoi trec 3 minute, după care situația caselor trebuie să fie: | + | * => ''%%C3 = (counter 3 14 8 (queue {(ion . 8)} '((dan . 6)) 1 1))%%'' |
| - | * întârzierea de la C1 s-a consumat parțial => ''%%C1 = (counter 1 7 7 (queue {} '() 0 0))%%'' | + | * ''C1'' este întârziată cu ''15'' minute => ''%%C1 = (counter 1 15 15 (queue {} '() 0 0))%%'' |
| - | * ana a ieșit de la C2, care a rămas goală => ''%%C2 = (counter 2 0 0 (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))%%'' |
| - | * la C3 au trecut 3 minute => ''%%C3 = (counter 3 7 5 (queue {(ion . 8)} '((dan . 2)) 1 1))%%'' | + | * ''C2'' are ''tt'' mai mic, însă ''C2'' este închisă, deci se alege între ''C1'' și ''C3'' |
| - | * ensure compară media timpilor totali ai caselor deschise cu 5 | + | * ''C2'' se deschide, fără să producă alte modificări |
| - | * tt1 + tt3 = 7 + 7 = 14 => ttmed = 14 / 2 > 5 | + | * apoi trec ''2'' minute, după care situația este: |
| - | * tt2 nu participă la medie întrucât C2 este închisă | + | * întârzierea de la ''C1'' s-a consumat parțial => ''%%C1 = (counter 1 13 13 (queue {} '() 0 0))%%'' |
| - | * se adaugă o casă slow goală (C4) => ttmed = 14 / 3 ≤ 5 (deci ne oprim aici cu adăugarea) | + | * ''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> | ||