This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:03-aplicatii-cu-functii-de-ordin-superior [2015/03/05 13:50] matei.popovici |
laboratoare:03-aplicatii-cu-functii-de-ordin-superior [2016/03/15 10:30] (current) mihai.dumitru2201 [Resurse] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Laborator 3 - Functii de ordin superior. Aplicatii ===== | + | ====== Aplicații cu funcții de ordin superior ====== |
- | ==== Functii de ordin superior `revisited` ==== | + | Responsabili laborator: |
- | Fie doua matrici reprezentate ca liste de liste. In rezolvarea exercitiilor de mai jos, puteti folosi doar functii de ordin superior (impreuna cu take si drop). | + | * [[mihai.dumitru@cti.pub.ro|Dumitru Mihai-Valentin]] |
- | * Implementati o functie care determina linia i dintr-o matrice | + | * [[calin.cruceru@cti.pub.ro|Călin Cruceru]] |
- | * Implementati o functie care determina elementul i,j dintr-o matrice | + | |
- | * Implementati adunarea a doua matrici | + | |
- | * Implementati transpunerea unei matrici | + | |
- | * [Optional] Implementati inmultirea a doua matrici | + | |
- | ==== Imagini ca liste ==== | + | Scopul laboratorului este de a exersa lucrul cu funcții de ordin superior. |
- | O imagine poate fi reprezentata ca o matrice de caractere (numiti in continuare pixeli). Consideram ca avem trei tipuri de pixeli: '.', '*', ' ' | + | |
+ | ===== Recapitulare ===== | ||
+ | |||
+ | O **funcție de ordin superior** este //o funcție care primește ca argument sau returnează o funcție//. | ||
+ | |||
+ | <code haskell> | ||
+ | applyTwice f x = f (f x) | ||
+ | adder x = (+x) | ||
+ | </code> | ||
+ | |||
+ | ==== Folduri ==== | ||
+ | Două funcții de ordin superior foarte importante sunt foldurile pe liste: ''foldl'' și ''foldr''. Aceasta combină, în mod recursiv, elementele unei liste cu o valoare default, pentru a obține un rezultat. | ||
+ | |||
+ | |||
+ | <code haskell> | ||
+ | foldr (:) [] l -- intoarce o lista identica cu l | ||
+ | foldl (flip (:)) [] l -- intoarce inversul listei l | ||
+ | </code> | ||
+ | |||
+ | <note> | ||
+ | O variantă importantă a lui ''foldl'' este ''foldl%%'%%'', care se găsește în modulul ''Data.List''. | ||
+ | |||
+ | <code> | ||
+ | Prelude> import Data.List | ||
+ | Prelude Data.List> :t foldl' | ||
+ | foldl' :: (a -> b -> a) -> a -> [b] -> a | ||
+ | </code> | ||
+ | |||
+ | Puteți citi [[https://wiki.haskell.org/Foldr_Foldl_Foldl'|aici]] despre diferențele dintre aceste trei folduri. | ||
+ | |||
+ | |||
+ | </note> | ||
+ | |||
+ | O vizualizare utilă: | ||
+ | {{:laboratoare:fold-visualization.png?800|}} | ||
+ | |||
+ | Tipurile acestor funcții sunt: | ||
+ | |||
+ | <code> | ||
+ | Prelude> :t foldr | ||
+ | foldr :: (a -> b -> b) -> b -> [a] -> b | ||
+ | Prelude> :t foldl | ||
+ | foldl :: (a -> b -> a) -> a -> [b] -> a | ||
+ | </code> | ||
+ | |||
+ | <note tip> | ||
+ | Nu trebie să rețineți pe de rost tipurile. Încercați să înțelegeți ce exprimă și de ce sunt așa. | ||
+ | </note> | ||
+ | |||
+ | Alte funcții de ordin superior des întâlnite: ''map'', ''filter'', ''zipWith'', ''flip''. | ||
+ | |||
+ | |||
+ | ===== Exerciții ===== | ||
+ | |||
+ | 1. Fie două matrici reprezentate ca liste de liste. În rezolvarea exercițiilor de mai jos, puteți folosi doar funcții de ordin superior (împreună cu ''take'' și ''drop''). | ||
+ | |||
+ | Implementați funcții care să returneze: | ||
+ | |||
+ | * linia ''i'' dintr-o matrice | ||
+ | * elementul ''(i, j)'' dintr-o matrice | ||
+ | * suma a două matrici | ||
+ | * transpusa unei matrici | ||
+ | * produsul a două matrici | ||
+ | |||
+ | |||
+ | 2. O imagine poate fi reprezentată ca o matrice de caractere (numiți, în continuare, "pixeli"). Considerăm că avem trei tipuri de pixeli: ''%%'%%.%%'%%'', ''%%'%%*%%'%%'', ''%%'%% %%'%%'' | ||
+ | |||
+ | Implementați următoarele funcții: | ||
+ | * flip orizontal, flip vertical, rotație de 90 în sens trigonometric și invers trigonometric | ||
+ | * negativul (''%%'%%*%%'%%'' si ''%%'%%.%%'%%'' devin ''%%'%% %%'%%'', iar ''%%'%% %%'%%'' devine ''%%'%%*%%'%%'') | ||
+ | * scalarea unei imagini cu ''x'' unități | ||
+ | * alipirea a două imagini (cu aceeași înălțime) pe orizontală | ||
+ | * alipirea a două imagini (cu aceeași lungime) pe verticală | ||
+ | * crop orizontal de la de la coloana ''x'' la coloana ''y'' | ||
+ | * crop vertical de la linia ''x'' la linia ''y'' | ||
+ | * Implementați suprapunerea unei imagini peste o alta (având aceeași dimensiune) | ||
+ | |||
+ | |||
+ | ===== Resurse ====== | ||
+ | |||
+ | Puteți folosi următoarea imagine pentru a vă testa funcțiile. | ||
+ | |||
+ | <code haskell> | ||
+ | l1=" ***** ** ***** ** " | ||
+ | l2=" ****** **** ****** **** " | ||
+ | l3=" ** * * *** ** * * *** " | ||
+ | l4=" * * * *** * * * *** " | ||
+ | l5=" * * ** * * ** " | ||
+ | l6=" ** ** ** ** ** ** " | ||
+ | l7=" ** ** ** ** ** ** " | ||
+ | l8=" **** ** * **** ** * " | ||
+ | l9=" * *** ** * * *** ** * " | ||
+ | l10=" ** ******* ** ******* " | ||
+ | l11=" ** ****** ** ****** " | ||
+ | l12=" ** ** ** ** " | ||
+ | l13=" ** ** ** ** " | ||
+ | l14=" ** ** ** ** " | ||
+ | l15=" ** ** ** ** ** ** " | ||
+ | l16="*** * * *** * * " | ||
+ | l17=" *** * *** * " | ||
+ | l18=" ****** ****** " | ||
+ | l19=" *** *** " | ||
+ | |||
+ | img = [l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19] | ||
+ | |||
+ | </code> | ||
+ | |||
+ | ===== Solutii laborator ==== | ||
+ | - [[https://github.com/Programming-Paradigms/Labs/archive/master.zip | Solutii laborator 3]] | ||
+ | - Puteți, alternativ, să folosiți următorul repository git [[https://github.com/Programming-Paradigms/Labs]] pentru a descărca soluțiile și a le sincroniza, ulterior. |