Zadania do wykładu o domknięciach
Uniwersytet Gdański - Instytut Matematyki - Zakład Informatyki - Strona domowaPerl: programowanie - domknięcia
- Napisz program obliczający pierwiastki trójmianu kwadratowego w taki sposób, aby wykorzystać w nim funkcje różnego przeznaczenia: wczytujące współczynniki, obliczające deltę oraz pierwiastki itp. Niezależnie od liczby napisanych funkcji, stwórz mechanizm, dzięki któremu będzie wiadomo, ile razy każda z nich została wywołana. Na zakończenie programu (może w bloku END?) oprócz wyników powinna zostać wypisana statystyka wykonań funkcji.
- Napisz generator liczb pseudolosowych zwracający funkcję myRand nie wymagającą podania argumentów. Kolejne wywołania funkcji powinny dawać różne liczby pseudolosowe z przedziału [0,1).
- Sprawdź na ile losowe są wyniki zwracane przez twoją funkcję generując np. 1e5 liczb i obliczając ich średnią.
- Porównaj średnią uzyskaną ze swoich liczb ze średnią uzyskaną z uśrednienia 1e5 liczb generowanych przez perlową funkcję rand losującą liczby z dokładnie tego samego przedziału.
- Wygeneruj 1000 funkcji, które będą inicjowane różnymi zarodkami losowymi, i dla każdej z nich wykonaj 1e5 losowań w celu określenia podobnej średniej. Czy istnieją jakieś przypadki, gdy twoje funkcje są "mniej" losowe?
- Napisz generator funkcji szyfrujących. Generator ten powinien otrzymać wszystkie wymagane dane do szyfrowania, poza tekstem, a zwrócić referencję do kodu, który wywołany jako funkcja powinien pobierać jako argument tekst do szyfrowania, a zwracać zaszyfrowany tekst. Oczywiście należy także napisać generator funkcji odszyfrowującej. Obie referencje do kodu mogą być zwracane razem jako para, jeżeli korzystają ze wspólnych prywatnych danych swojego środowiska, ale można także wygenerować funkcje całkowicie osobne, korzystające ze swoich własnych środowisk. Algorytm szyfrowania można wybrać dowolny.
- Używając domknięć, wygeneruj funkcję mytime, której wartością będzie zawsze czas w sekundach od epoch, z tym, ze przesunięty o podaną przy tworzeniu domknięcia wartość. Takiej funkcji można użyć potem np. jako licznika, który odlicza w przód albo w tył:
my $mytime1 = GenerujTimer(time()); # domknięcie poda upływ czasu od momentu swojej definicji my $mytime2 = GenerujTimer(time+100); # odliczanie czasu do tyłu przez 100 sekund
- (1+1p) *Analogicznie jak w poprzednim zadaniu z liczbami zespolonymi, zaprogramuj ich obsługę używając wyłącznie domknięć. Wykorzystaj w tym celu jedną funkcję, która otrzymywać będzie informację, co należy zrobić, na przykład tak:
use strict; use myComplex; # implementacja liczb zespolonych przy uzyciu domkniec my $cplx = GenerateComplex(1,2); # liczba 1+2i dana jako funkcja obslugi # operacje na liczbie wykonywane sa wylacznie przez funkcje: print $cplx->('re'); # wypisuje czesc rzeczywista print $cplx->('im'); # wypisuje czesc urojona print $cplx->(); # wypisuje liczbe w formie re+im my $cplx2 = $cplx->('add',1,0); # dodanie liczby 1+0i (uwaga - zwracane jest nowe domkniecie!) print $cplx->('add', $cplx2 )->(); # wypisanie sumy liczb zespolonych (uwaga, to jest 'tricky')
W powyższych przykładach wygenerowano funkcję anonimową będącą domknięciem dla prywatnych danych 1 i 2. Funkcja ta zwrócona jest przez referencję do kodu i zapisana w skalarze $cplx, dzięki któremu można mieć dostęp do danych zamkniętych w domknięciu. Funkcja analizuje swój pierwszy parametr i zależnie od niego podejmuje odpowiednie akcje na swoich prywatnych danych z domknięcia. Od analizy parametrów zależy tutaj wszystko. Dla chętnych ustalam deadline na to zadanie do dnia 20070428:2359 - rozwiązania zawierające pełną dokumentację, moduł oraz kody przykładowych zastosowań (napisane ze strict) przysłane przed punktem deadline'u mogą otrzymać dodatkowy punkt bonusowy. :) W takim przypadku moduł powinien domyślnie eksportować funkcję GenerateComplex, a same liczby zespolone muszą obsługiwać co najmniej sumę, różnicę, wypisywanie części oraz całości, iloczyn i iloraz liczb. Liczby podawane do funkcji mają być podane jako składowe w postaci pary liczb (re,im) lub jako domknięcie w postaci referencji do kodu (ustalenie rodzaju danych przekazanych do funkcji nie powinno być problemem dla tych, którzy chodzą na wykłady lub zaznajomili się z operatorem ref). Wszyscy, którzy doprogramują ponad to jakieś dodatkowe funkcje związane z liczbami zespolonymi, mogą otrzymać drugi bonusowy punkt :)
[c] Piotr Arłukowicz, materiały z tej strony udostępnione są na licencji GNU.