Differences

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

Link to this comparison view

pa:laboratoare:laborator-04 [2021/03/15 10:02]
miruna_elena.banu [Exponențiere pe matrice pentru recurențe liniare]
pa:laboratoare:laborator-04 [2024/04/16 17:38] (current)
radu.nichita
Line 1: Line 1:
-====== Laborator 4: Programare Dinamică (continuare) ====== +====== Laborator 04: Programare Dinamică (2/2) ======
-Responsabili:​ +
-  * [[neatudarius@gmail.com|Darius-Florentin Neațu (2017-2021)]] +
-  * [[radunichita99@gmail.com | Radu Nichita (2021)]] +
-  * [[cristianolaru99@gmail.com | Cristian Olaru (2021)]] +
-  * [[mirunaelena.banu@gmail.com ​ | Miruna-Elena Banu (2021)]] +
-  * [[maraioana9967@gmail.com | Mara-Ioana Nicolae (2021)]] +
-  * [[stefanpopa2209@gmail.com | Ștefan Popa (2018-2020)]] +
- +
-Autori: +
-  * [[neatudarius@gmail.com|Darius-Fforentin Neațu (2018)]] +
-  * [[visanr95@gmail.com|Radu Vișan (2018)]] +
-  * [[cristb@gmail.com|Cristian Banu (2018)]] +
-  * [[razvan.ch95@gmail.com|Răzvan Chițu (2018)]] +
  
 ===== Obiective laborator ===== ===== Obiective laborator =====
Line 102: Line 88:
        * explicație:​ $X =(BC)$ generează $3 * 4 * 5 = 60$ înmulțiri,​ $(AX)$ generează $2 * 3 * 5 = 30$ de înmulțiri        * explicație:​ $X =(BC)$ generează $3 * 4 * 5 = 60$ înmulțiri,​ $(AX)$ generează $2 * 3 * 5 = 30$ de înmulțiri
        
-Rezultatul optim se obține pentru ​cea de a treia parantezare:​ $(AB)C$.+Rezultatul optim se obține pentru ​prima parantezare:​ $(AB)C$.
    
 </​spoiler>​ </​spoiler>​
Line 165: Line 151:
 == Numire recurență === == Numire recurență ===
 $dp[i][j]$ = **numărul minim de înmulțiri scalare** cu care se poate obține produsul $M_i * M_{i+1} * ... *{M_j}$ ​ $dp[i][j]$ = **numărul minim de înmulțiri scalare** cu care se poate obține produsul $M_i * M_{i+1} * ... *{M_j}$ ​
 +
 +Răspunsul la problemă este **dp[1][n]** .
  
 == Găsire recurență == == Găsire recurență ==
Line 186: Line 174:
 <spoiler Implementare C++> <spoiler Implementare C++>
 <code cpp> <code cpp>
-// kInf este valoarea maximă - "​infinitul"​ nostru +// INF este valoarea maximă - "​infinitul"​ nostru 
-const unsigned long long kInf = std::​numeric_limits<​unsigned long long>::​max();​+const auto INF = std::​numeric_limits<​unsigned long long>::​max();​
  
 // T = O(n ^ 3)  // T = O(n ^ 3) 
Line 194: Line 182:
     // dp[i][j] = numărul MINIM înmulțiri scalare cu codare, poate fi calculat produsul     // dp[i][j] = numărul MINIM înmulțiri scalare cu codare, poate fi calculat produsul
     //            matriceal M_i * M_i+1 * ... * M_j     //            matriceal M_i * M_i+1 * ... * M_j
-    vector<​vector<​unsigned long long>> ​ dp(n + 1, vector<​unsigned long long> (n + 1, kInf));+    vector<​vector<​unsigned long long>> ​ dp(n + 1, vector<​unsigned long long> (n + 1, INF));
  
     // Cazul de bază 1: nu am ce înmulți ​     // Cazul de bază 1: nu am ce înmulți ​
Line 242: Line 230:
  
 <​note>​ <​note>​
-**ATENȚIE!** La PA, în general, vom folosi convenția $ expresie \ \%  \ kMod $, care va fi detaliată în capitolul următor din acest laborator. ​+**ATENȚIE!** La PA, în general, vom folosi convenția $ expresie \ \%  \ MOD $, care va fi detaliată în capitolul următor din acest laborator. ​
 </​note>​ </​note>​
  
Line 519: Line 507:
       * o înmulțire de matrice patrătică de dimensiune KMAX are $KMAX^3$ operații       * o înmulțire de matrice patrătică de dimensiune KMAX are $KMAX^3$ operații
     * această metodă este eficientă când $KMAX << n$ (KMAX este mult mai mic decât n)     * această metodă este eficientă când $KMAX << n$ (KMAX este mult mai mic decât n)
-  * ** complexitatea spațială **: $S = O(KMAX^3)$  +  * ** complexitatea spațială **: $S = O(KMAX^2)$  
-    * explicație  +**Observație!** În ultimele calcule nu am șters constanta KMAX, întrucât apare la puterea a 2-a! $KMAX = 1000$ implică $KMAX^= 10^6$, valoare care nu mai poate fi ignorată în practică ($KMAX^2$ poate fi comparabil cu n).
-      * este nevoie să stocăm câteva matrice +
-**Observație!** În ultimele calcule nu am șters constanta KMAX, întrucât apare la puterea a 3-a! $KMAX = 100$ implică $KMAX^= 10^6$, valoare care nu mai poate fi ignorată în practică ($KMAX^3$ poate fi comparabil cu n).+
  
 === Gardurile lui Gigel (optimizare) === === Gardurile lui Gigel (optimizare) ===
Line 531: Line 517:
 == Exponențiere rapidă == == Exponențiere rapidă ==
   * $ k = 4 $   * $ k = 4 $
-  * $S_4 = (dp[1], dp[2], dp[3], dp[4]) = (1, 1, 1, 4)$+  * $S_4 = (dp[1], dp[2], dp[3], dp[4]) = (1, 1, 1, 2)$
   * $S_i = (dp[i-3], dp[i-2], dp[i-1], dp[i])$   * $S_i = (dp[i-3], dp[i-2], dp[i-1], dp[i])$
   * Răspunsul se află efectuând operația $S_n = S_4 * C^{n - 4}$, unde C are următorul conținut:  ​   * Răspunsul se află efectuând operația $S_n = S_4 * C^{n - 4}$, unde C are următorul conținut:  ​
Line 629: Line 615:
  
 <spoiler Comparație solutii (studiu de caz pentru curioși)>​ <spoiler Comparație solutii (studiu de caz pentru curioși)>​
-În arhiva ** demo-lab04.zip ** găsiți o sursă completă în care se realizează:​+Pe git găsiți o sursă completă în care se realizează:​
   * o verificare a faptului că cele 2 implementări (** gardurile_lui_Gigel** și **garduri_rapide**) produc aceleași rezultate   * o verificare a faptului că cele 2 implementări (** gardurile_lui_Gigel** și **garduri_rapide**) produc aceleași rezultate
   * un benchmark în care cele 2 implementări sunt comparate   * un benchmark în care cele 2 implementări sunt comparate
-    * pe sistem uzual (laptop) s-au obținut următoarele rezulate:+    * pe un sistem uzual (laptop) s-au obținut următoarele rezulate:
 <code bash> <code bash>
 test case: varianta simplă test case: varianta simplă
Line 649: Line 635:
 </​spoiler>​ </​spoiler>​
    
-===== Exercitii ​=====+===== Exerciții ​=====
 <​note>​ <​note>​
 Scheletul de laborator se găsește pe pagina [[https://​github.com/​acs-pa/​pa-lab/​tree/​main/​skel/​lab04|pa-lab::​skel/​lab04]]. Scheletul de laborator se găsește pe pagina [[https://​github.com/​acs-pa/​pa-lab/​tree/​main/​skel/​lab04|pa-lab::​skel/​lab04]].
 </​note>​ </​note>​
 === DP or math? === === DP or math? ===
-Fie un sir de **numere naturale strict pozitive**. ​Cate **subsiruri** (submultimi ​nevide) au suma numerelor **para**?+Fie un șir de **numere naturale strict pozitive**. ​Câte **subșiruri** (submulțimi ​nevide) au suma numerelor **pară**?
  
 <​note>​ <​note>​
-**subsir** (**subsequence** ​in engleza) pentru un vector ** v **inseamna ​un alt vector $u = [v[i_1], v[i_2],..., v[i_k]]]$ unde $i_1 < i_2 < ... < i_k$.+**subșir** (**subsequence** ​în engleză) pentru un vector **v** înseamnă ​un alt vector $u = [v[i_1], v[i_2],..., v[i_k]]]$ unde $i_1 < i_2 < ... < i_k$.
 </​note>​ </​note>​
  
  
 Task-uri: Task-uri:
-  * Se cere o **solutie ​folosind DP**. +  * Se cere o **soluție ​folosind DP**. 
-  * Inspectand recurenta gasita ​la punctul precedent, ​incercati sa inlocuiti ​cu o **formula matematica**. +  * Inspectând recurența gasită ​la punctul precedent, ​încercați să înlocuiți ​cu o **formulă matematică**. 
-  * Care este **complexitatea** pentru fiecare ​solutie ​(timp + spatiu)? Care este mai buna? De ce? :D+  * Care este **complexitatea** pentru fiecare ​soluție ​(timp + spațiu)? Care este mai bună? De ce? :D
  
-Deoarece rezultatul poate fi prea mare, se cere **restul ​impartirii** lui la $1000000007$ ($10^9 + 7$).+Deoarece rezultatul poate fi prea mare, se cere **restul ​împărțirii** lui la $1000000007$ ($10^9 + 7$).
  
-Pentru punctaj maxim pentru ​aceasta problema, este necesar ​sa rezolvati ​toate subpunctele (ex. nu folositi ​direct formula, ​gasiti ​mai intai recurenta ​DP). Trebuie ​sa implementati ​**cel putin** solutia ​cu DP.+Pentru punctaj maxim pentru ​această problemă, este necesar ​să rezolvați ​toate subpunctele (ex. nu folosiți ​direct formula, ​găsiți ​mai întâi recurența ​DP). Trebuie ​să implementați ​**cel puțin** soluția ​cu DP.
  
  
Line 676: Line 662:
 |v|2|6|4| |v|2|6|4|
  
-Raspuns: $7$+Răspuns: $7$
  
-Explicatie: Toate subsirurile ​posibile sunt+Explicație: Toate subșirurile ​posibile sunt
   * $[2]$   * $[2]$
   * $[2, 6]$   * $[2, 6]$
Line 686: Line 672:
   * $[6, 4]$   * $[6, 4]$
   * $[4]$   * $[4]$
-Toate subsirurile ​de mai sus au suma para.+Toate subșirurile ​de mai sus au suma pară.
 </​spoiler>​ </​spoiler>​
  
Line 695: Line 681:
 |v|2|1|3| |v|2|1|3|
  
-Raspuns: $3$+Răspuns: $3$
  
-Explicatie: Toate subsirurile ​posibile sunt+Explicație: Toate subșirurile ​posibile sunt
   * $[2]$   * $[2]$
   * $[2, 1]$   * $[2, 1]$
Line 706: Line 692:
   * $[3]$   * $[3]$
  
-Subsirurile ​cu suma para sunt: $[2]$, $[2, 1, 3]$, $[1, 3]$.+Subșirurile ​cu sumă pară sunt: $[2]$, $[2, 1, 3]$, $[1, 3]$.
  
 </​spoiler>​ </​spoiler>​
Line 716: Line 702:
 |v|3|2|1| |v|3|2|1|
  
-Raspuns: $3$+Răspuns: $3$
  
-Explicatie: Toate subsirurile ​posibile sunt+Explicație: Toate subșirurile ​posibile sunt
   * $[3]$   * $[3]$
   * $[3, 2]$   * $[3, 2]$
Line 727: Line 713:
   * $[1]$   * $[1]$
  
-Subsirurile ​cu suma para sunt: $[3, 2, 1]$, $[3, 1]$, $[2]$.+Subșirurile ​cu sumă pară sunt: $[3, 2, 1]$, $[3, 1]$, $[2]$.
  
 </​spoiler>​ </​spoiler>​
Line 734: Line 720:
 Morala: există probleme pentru care găsim o soluție cu DP, dar pentru care pot exista și alte soluții mai bune (am ignorat citirea/​afișarea). Morala: există probleme pentru care găsim o soluție cu DP, dar pentru care pot exista și alte soluții mai bune (am ignorat citirea/​afișarea).
  
-In problemele de numaratexista ​o **sansa** buna sa putem gasi (si) o formula matematicacare poate fi implementata intr-un mod mai eficient ​decat recurenta ​DP. +În problemele de număratexistă ​o **șansă** bună să putem si (și) o formulă matematicăce poate fi implementată într-un mod mai eficient ​decât ​recurență ​DP. 
 </​note>​ </​note>​
  
 <spoiler Hint> <spoiler Hint>
-Cate subsiruri ​au suma **impara**?+Câte subșiruri ​au suma **impară**?
 </​spoiler>​ </​spoiler>​
  
 <​hidden>​ <​hidden>​
-<​spoiler ​Solutie+<​spoiler ​Soluție
-Problema este preluata ​de [[https://​infoarena.ro/​problema/​azerah|aici]]. ​Solutia ​se gaseste ​[[https://​www.infoarena.ro/​onis-2015/​solutii-runda-1#​azerah|aici]].+Problema este preluată ​de [[https://​infoarena.ro/​problema/​azerah|aici]]. ​Soluția ​se găsește ​[[https://​www.infoarena.ro/​onis-2015/​solutii-runda-1#​azerah|aici]].
 </​spoiler>​ </​spoiler>​
 </​hidden>​ </​hidden>​
  
-=== Expresie ​booleana ​=== +=== Expresie ​booleană ​=== 
-Se da o expresie ​booleana corecta ​cu n termeni. Fiecare din termeni poate fi unul din stringurile **true**, **false**, **and**, **or**, **xor**.+Se dă o expresie ​booleană corectă ​cu n termeni. Fiecare din termeni poate fi unul din stringurile **true**, **false**, **and**, **or**, **xor**.
  
-Numarati ​modurile ​in care se pot aseza paranteze astfel ​incat rezultatul ​sa fie **true**. Se respecta ​regulile de la logica ​(tabelele de adevar ​pentru ​operatiile ​**and**, **or**, **xor**).+Numărați ​modurile ​în care se pot așeza ​paranteze astfel ​încât ​rezultatul ​să fie **true**. Se respectă ​regulile de la logică ​(tabelele de adevăr ​pentru ​operațiile ​**and**, **or**, **xor**).
  
-Deoarece rezultatul poate fi prea mare, se cere **restul ​impartirii** lui la $1000000007$ ($10^9 + 7$).+Deoarece rezultatul poate fi prea mare, se cere **restul ​împărțirii** lui la $1000000007$ ($10^9 + 7$).
  
 <​note>​ <​note>​
-In schelet vom codifica cu valori de tip char cele 5 stringuri:+În schelet vom codifica cu valori de tip char cele 5 stringuri:
   * **false**: '​F'​   * **false**: '​F'​
   * **true**: '​T'​   * **true**: '​T'​
Line 762: Line 748:
   * **xor**: '​^'​   * **xor**: '​^'​
  
-Functia ​pe care va trebui ​sa implementati ​voi va folosi variabilele **n** (numarul ​de termeni) ​si ** expr** (vectorul cu termenii expresiei).+Funcția ​pe care va trebui ​să implementați ​voi va folosi variabilele **n** (numărul ​de termeni) ​și **expr** (vectorul cu termenii expresiei).
 </​note>​ </​note>​
  
  
 <spoiler Exemplu 1> <spoiler Exemplu 1>
-$n = 5$ si $expr = ['​T',​ '&',​ '​F',​ '​^',​ '​T'​]$ (expr = [** true and false xor true**])+$n = 5$ și $expr = ['​T',​ '&',​ '​F',​ '​^',​ '​T'​]$ (expr = [** true and false xor true**])
  
-Raspuns: $2$+Răspuns: $2$
  
-ExplicatieExista ​2 moduri corecte de a paranteza expresia astfel ​incat sa obtinem ​rezultatul **true** (1).+ExplicațieExistă ​2 moduri corecte de a paranteza expresia astfel ​încât să obținem ​rezultatul **true** (1).
   * $ T&(F^T) $   * $ T&(F^T) $
   * $ (T&F)^T $   * $ (T&F)^T $
Line 777: Line 763:
  
 <spoiler Hint> <spoiler Hint>
-    Complexitate temporală ​dorita ​este $O(n ^ 3)$.+    Complexitate temporală ​dorită ​este $O(n ^ 3)$.
     ​     ​
-    ​Optional, se pot defini ​functii ajutatoare ​precum **is_operand**,​ **is_operator**,​ **evaluate**.+    ​Opțional, se pot defini ​funcții ajutătoare ​precum **is_operand**,​ **is_operator**,​ **evaluate**.
 </​spoiler>​ </​spoiler>​
  
 <note tip> <note tip>
-Pentru rezolvarea celor doua probleme ​ganditi-va la ce scrie in sectiunea ​[[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-04?&#​sfaturireguli| Sfaturi / Reguli]]. Pentru fiecare dintre cele doua probleme facem o **partitionare dupa un anumit criteriu**.+Pentru rezolvarea celor două probleme ​gândiți-vă la ce scrise în secțiunea ​[[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-04?&#​sfaturireguli| Sfaturi / Reguli]]. Pentru fiecare dintre cele două probleme facem o **partiționare după un anumit criteriu**.
  
  
-Pentru problema** DP or math?​** ​partitionam ​toate subsirurile dupa critieriul **paritatii ​sumei subsirului** (cate sunt pare/​impare).\\  +Pentru problema **DP or math?​** ​partiționăm ​toate subșirurile după critieriul **parității ​sumei subșirului** (câte sunt pare/​impare).\\  
-Pentru problema **expresie ​booleana** partitionam ​**toate ​parantezarile ​posibile ​dupa rezultatul lor** (cate dau true/​false).+Pentru problema **expresie ​booleană** partiționăm ​**toate ​parantezările ​posibile ​după rezultatul lor** (câte dau true/​false).
  
 </​note>​ </​note>​
 === Bonus === === Bonus ===
-Asistentul va alege una dintre problemele din sectiunea ​Extra.+Asistentul va alege una dintre problemele din secțiunea ​Extra.
  
 <spoiler Hint> <spoiler Hint>
-Recomandam sa ** NU** fie una din cele 3 probleme de la Test PA 2017. Recomandam sa le incercati dupa ce recapitulati acasa DP1 si DP2, pentru a verifica ​daca cunostintele ​acumulate sunt la nivelul ​asteptat.+Recomandăm să **NU** fie una dintre ​cele 3 probleme de la Test PA 2017. Recomandăm să le incercați după ce recapitulați acasă ​DP1 și DP2, pentru a verifica ​dacă cunoștințele ​acumulate sunt la nivelul ​așteptat.
 </​spoiler>​ </​spoiler>​
  
 === Extra === === Extra ===
-<​spoiler ​Extraterestrii+<​spoiler ​Extratereștrii
-Rezolvati ​problema [[https://​www.hackerrank.com/​contests/​test-practic-pa-2017-v1-plumbus/​challenges/​test-1-extraterestrii +Rezolvați ​problema [[https://​www.hackerrank.com/​contests/​test-practic-pa-2017-v1-plumbus/​challenges/​test-1-extraterestrii 
-extraterestrii]] de la Test PA 2017.+extratereștrii]] de la Test PA 2017.
 </​spoiler>​ </​spoiler>​
  
-<​spoiler ​Secvente+<​spoiler ​Secvențe
-Rezolvati ​problema [[https://​www.hackerrank.com/​contests/​test-practic-pa-2017-v1-plumbus/​challenges/​test-1-secvente +Rezolvați ​problema [[https://​www.hackerrank.com/​contests/​test-practic-pa-2017-v1-plumbus/​challenges/​test-1-secvente 
-Secvente]] de la Test PA 2017.+Secvențe]] de la Test PA 2017.
 </​spoiler>​ </​spoiler>​
  
Line 811: Line 797:
  
 <spoiler PA Country> <spoiler PA Country>
-Rezolvati ​problema [[https://​www.hackerrank.com/​contests/​test-practic-pa-2017-v2-meeseeks/​challenges/​test-2-pa-country-medie+Rezolvați ​problema [[https://​www.hackerrank.com/​contests/​test-practic-pa-2017-v2-meeseeks/​challenges/​test-2-pa-country-medie
 | PA Country]] de la Test PA 2017. | PA Country]] de la Test PA 2017.
 </​spoiler>​ </​spoiler>​
Line 819: Line 805:
    
 <spoiler iepuri> <spoiler iepuri>
-Rezolvati ​pe infoarena problema [[http://​infoarena.ro/​problema/​iepuri| iepuri]].+Rezolvați ​pe infoarena problema [[http://​infoarena.ro/​problema/​iepuri| iepuri]].
  
-Hint: Exponentiere logaritmica ​pe matrice+Hint: Exponențiere logaritmică ​pe matrice
  
-Solutie:+Soluție:
   * $dp[0] = X; dp[1] = Y; dp[0] = Z; $   * $dp[0] = X; dp[1] = Y; dp[0] = Z; $
   * $dp[i] = (A * dp[i-1] + B * dp[i-2] + C * dp[i-3]) \ \% \ 666013$   * $dp[i] = (A * dp[i-1] + B * dp[i-2] + C * dp[i-3]) \ \% \ 666013$
  
-Pentru punctaj maxim, pentru fiecare test se foloseste ecuatia matriceala atasata.+Pentru punctaj maxim, pentru fiecare test se folosește ecuația matriceală atașată.
 Complexitate:​ $O(T * log(n))$. Complexitate:​ $O(T * log(n))$.
  
Line 834: Line 820:
  
 <spoiler Minimum Path Sum> <spoiler Minimum Path Sum>
-Rezolvati ​pe leetcode problema [[https://​leetcode.com/​problems/​minimum-path-sum/​description/#​| Minimum Path Sum]].+Rezolvați ​pe leetcode problema [[https://​leetcode.com/​problems/​minimum-path-sum/​description/#​| Minimum Path Sum]].
 </​spoiler>​ </​spoiler>​
  
  
-<​spoiler ​Lacusta+<​spoiler ​Lăcusta
-Rezolvati ​pe infoarena problema [[http://​infoarena.ro/​problema/​Lacusta| ​Lacusta]].+Rezolvați ​pe infoarena problema [[http://​infoarena.ro/​problema/​Lacusta| ​Lăcusta]].
 </​spoiler>​ </​spoiler>​
  
  
 <spoiler Suma4> <spoiler Suma4>
-Rezolvati ​pe infoarena problema [[http://​infoarena.ro/​problema/​Suma4|Suma4]].+Rezolvați ​pe infoarena problema [[http://​infoarena.ro/​problema/​Suma4|Suma4]].
 </​spoiler>​ </​spoiler>​
  
-<​spoiler ​Subsir+<​spoiler ​Subșir
-Rezolvati ​pe infoarena problema [[https://​www.infoarena.ro/​problema/​subsir|subsir]].+Rezolvați ​pe infoarena problema [[https://​www.infoarena.ro/​problema/​subsir|subșir]].
 </​spoiler>​ </​spoiler>​
  
-<​spoiler ​2sah+<​spoiler ​2șah
-Rezolvati ​pe infoarena problema [[https://​infoarena.ro/​problema/​2sah | 2sah]].+Rezolvați ​pe infoarena problema [[https://​infoarena.ro/​problema/​2sah | 2șah]].
  
-Hint:   Exponentiere logaritmica ​pe matrice+Hint: Exponențiere logaritmică ​pe matrice
  
-descrie detaliata ​se afla in [[http://​olimpiada.info/​oji2015/​index.php?​cid=arhiva | arhiva OJI 2015]].+descriere detaliată ​se află în [[http://​olimpiada.info/​oji2015/​index.php?​cid=arhiva | arhiva OJI 2015]].
 </​spoiler>​ </​spoiler>​
  
Line 865: Line 851:
 ===== Referințe ===== ===== Referințe =====
  
-[0] Capitolul ​**Dynamic Programming** ​din **Introductions ​to Algorithms** de către T. H. Cormen, ​C. E. Leiserson, ​R. L. Rivest, C. Stein +[0] Chapter ​**Dynamic Programming**, “Introduction ​to Algorithms”, Thomas ​H. Cormen, ​Charles ​E. Leiserson, ​Ronald ​L. Rivest ​and Clifford ​Stein 
 + 
 [1] [[http://​infoarena.ro/​problema/​podm]] [1] [[http://​infoarena.ro/​problema/​podm]]
  
pa/laboratoare/laborator-04.1615795362.txt.gz · Last modified: 2021/03/15 10:02 by miruna_elena.banu
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