Napisz procedurę jednoparametrową LAS :lista, rysującą na ekranie las na podstawie zdania podanego jako parametr:
Rysunek powinien wykorzystywać cały ekran. Wszystkie drzewa mają mieć tę samą szerokość. Odległości pomiędzy pniami sąsiednich drzew powinny być jednakowe. Wysokość pnia drzewa powinna być wprost proporcjonalna do liczby liter w słowie opisującym dane drzewo. Poziome podłoże jest elementem tworzonego rysunku. Lista opisująca las może zawierać od jednego do dziesięciu niepustych słów składających się jedynie z małych liter alfabetu łacińskiego.
Podczas tego zadania zalecam utworzenie dwóch procedur i funkcji. Pierwsz procedura będzie zarządzać wielkości i będzie wywoływać drugą, która z kolei narusyje pojedyncze pełne drzewo. Zadaniem funkcji będzie sprawdzić czy dana litera jest samogłoską.
Funkcja samogłoska? będzie przyjmować jeden argument - literę do sprawdzenia, a jako wynik zwróći prawdę / fałsz czy to samogłoska czy nie:
Przejdźmy teraz do procedury pomocniczej LAS_pom rysującej drzewo. Będziemy jej przekazywać trzy argumenty: :słowo - określi jakie słowo ma przedstawić drzewom, :szer - określi szerokość pojedynczej gałęzi oraz :odl_gal - określi jaka powinna być odległość pomiędzy parą gałęzi:
(2.) Dla każdego znaku w słowie: (3.) Określamy wstępną długość gałęzi na podstawie parametru :szer. (4.) W przypadku, gdy litera nie jest samogłoską to (5.) zmniejszamy długość gałęzi :a o połowę. (7. - 13.) Rysujemy gałąź po jednej i drugiej stronie. (15.) Cofamy się do punktu z którego zaczęliśmy rysowanie.
Do napisania główna funkcja LAS. Na początku wyliczymy wszystkie wartości potrzebne do narysowania drzewa:
(2.) Na początek ustalamy margines. Dzięki temu łatwiej będzie zmniejszać proporcjonalnie obraz wynikowy. (3.) Obliczamy szerokość i (4.) wysokość obszaru na którym będziemy rysować. (5.) Obliczamy szerokość drzewa. (6. - 11.) W celu obliczenia odległości pomiedzy gałęziami musimy znać jak długie jest najdłuższe słowo. Po znalezieniu maksymalnej wartości możemy wyliczyć (12.) odległość pomiędzy gałęziami.
Druga część procedury to (13. - 17.) ustawienie żółwia w lewym dolnym rogu obrazku i (18. - 26.) narysowanie drzew. Warto tu pamiętać, że procedurze pomocniczej przekazujemy :szer_drzewo / 2 jako argument :szer.
Napisz funkcję PRZESTAW :zdanie, której wartością będzie zdanie zawierające wszystkie słowa zdania podanego jako parametr, ale poprzestawiane tak, aby na początku znajdowały się słowa zawierające literę a (w tej samej kolejności jak na danej liście). Parametrem funkcji może być tylko lista słów składających się jedynie z małych liter alfabetu łacińskiego. Wynik również powinien być listą słów. Poniżej przedstawiamy przykładowe wyniki:
PRZESTAW [ala ma kota i psa] | ma wartość [ala ma kota psa i] |
---|---|
PRZESTAW [hokus pokus abrakadabra] | ma wartość [abrakadabra hokus pokus] |
W zadaniu najprostszym rozwiazaniem jest podzielenie zestawu na dwie listy, a następnie ich scalenie:
(2.) Deklarujemy pustą listę pomocniczą do której będziemy wrzucać elementy, które mają być na początku. (3.) Dla każdego wyrazu na liście: (4.) jeśli zawiera a w sobie to (5.) dopisujemy na koniec :lista_w i (6.) usuwamy ten element z listy. Odejmujemy od npw długość :lista_w, ponieważ lista :zdanie po usunięciu elementu jest mniejsza. (9.) Zwracamy listę scaloną z dwóch list: (kolejno) :lista_w i :zdanie.
Lista liczbowa to taka lista, której każdy element jest liczbą naturalną lub listą liczbową. Na przykład lista [[2 3] 1 [3] [[5 2] 1] 2] jest listą liczbową, bo jej elementy: drugi i piąty (to jest 1 i 2) - są liczbami naturalnymi, a elementy: pierwszy, trzeci i czwarty (to jest [2 3], [3] i [[5 2] 1]) - są listami liczbowymi. Lista pusta też jest listą liczbową.
Jeśli z zapisu listy liczbowej usuniemy wszystkie nawiasy kwadratowe, to otrzymamy skończony ciąg liczb; będziemy je nazywali składnikami listy liczbowej. Liczba składników listy liczbowej na ogół nie jest równa liczbie jej elementów, np. lista podana powyżej ma pięć elementów oraz osiem składników (2, 3, 1, 3, 5, 2, 1, 2).
Dla każdego składnika listy liczbowej określamy jego poziom na tej liście w następujący sposób:
Np. składniki: 2, 3, 1, 3, 5, 2, 1, 2 listy liczbowej [[2 3] 1 [3] [[5 2] 1] 2] mają odpowiednio poziom: 2, 2, 1, 2, 3, 3, 2, 1.
Wagą składnika listy liczbowej nazywamy iloczyn tego składnika przez jego poziom. Wagą listy liczbowej nazywamy sumę wag jej składników, listy puste i listy złożone z list pustych mają wagę zero.
Zdefiniuj funkcję WAGALISTY :lliczb, której wartością jest waga listy liczbowej podanej jako parametr. Zakładamy, że dany parametr funkcji będzie zawsze poprawną listą liczbową i napisane procedury nie musza tego sprawdzać. Oto przykładowe wyniki:
WAGALISTY [[2 3] 1 [3] [[5 2] 1] 2] | ma wartość 42 |
---|---|
WAGALISTY [[] 2 [] [[1]]] | ma wartość 5 |
WAGALISTY [[] []] | ma wartość 0 |
Jest idealne zadania, aby wykorzystać rekurencję. Do funkcji tego typu pierwszym argumentem musi być lista elementów, a drugim poziom. Iterujemy przez wszystkie elementy na liście. W przypadku, gdy element jest liczbą to sumę zwiększamy o iloczyn tego elementu razy poziom. W przeciwnym wypadku, gdy element jest listą to wywołujemy funkcję z tym elementem jako argument :lista, a :poziom zwiększamy o jeden. Wtedy funkcja wygląda następująco:
Jednak zadanie nie przewiduje drugiego argumentu, dlatego funkcja WAGALISTY będzie rozpoczynać rekurencję: