Strona główna » Poradniki » Logomocja » LOGIA » Logia 2002/03 - Etap II
 

Logia 2002/03 - Etap II

· Etap I · Etap II · Etap III ·
iOryginalna treść zadań jest dostępna pod oficjalnym adresem konkursu LOGIA

Zadanie 1

Zdefiniuj procedurę RYSUJ :s, której daną może być dowolne niepuste słowo utworzone z małych liter alfabetu łacińskiego (bez polskich znaków diakrytycznych) oraz cyfr. Procedura tworzy rysunek złożony z kwadratów oraz dwa razy wyższych prostokątów. Kolejne rysowane figury odpowiadają kolejnym znakom danej. Znaki przedstawiamy jako kwadraty lub prostokąty zgodnie z ich wysokością:

  • cyfrom oraz literom b, d, f, h, k, l, t odpowiadają prostokąty wysunięte do góry,
  • literom g, j, p, q, y - prostokąty wysunięte do dołu,
  • pozostałym literom - kwadraty.

Prostokąty odpowiadające cyfrom wypełniamy kolorem zielonym, figury odpowiadające samogłoskom wypełniamy kolorem czerwonym, zaś spółgłoskom - żółtym. Rysunek powinien mieścić się na ekranie i być możliwie duży, maksymalna długość słowa wynosi 100 znaków.

Poniżej znajdują się przykładowe rysunki uzyskane przez odpowiednie wywołania:

Prostokąty

W celu uproszczenie rysowania prostokątów i nie powielania kodu po kilka razy w głównej procedurze warto napisać procedurę prostokat, która narysuje figurę o zadanych wymiarach :w x :h i wypełni kolorem :kolor.

  1. oto prostokat :w :h :kolor
  2.   wielokąt [
  3.     ukm :kolor
  4.     powtórz 2 [
  5.       np :h
  6.       pw 90
  7.       np :w
  8.       pw 90
  9.     ]
  10.   ]
  11. już

Samogłoski

Dodatkowo w trakcie rysowania kolor, w przypadku małego znaku alfabetu łacińskiego, określa się na podstawie tego czy znak jest samogłoską. Poniżej znajduje się funkcja samogłoska?, która zwraca wartość logiczną czy dany znak :a jest samogłoską:

  1. oto samogłoska? :a
  2.   niech "l [a e i o u y]
  3.   wynik (numel :a :l <> 0)
  4. już

Główna funkcja

Mając napisany kod pomocniczy napisanie funkcji RYSUJ jest o wiele prostsze. Ze względu na fakt, że RYSUJ to funkcja pierwotna i nie można jej nadpisać to została ona zapisana jako RYSUJ2.

  1. oto RYSUJ2 :s
  2.   niech "w 700
  3.   niech "h 460
  4.   niech "a :w / (długość :s)
  5.   jeśli (:a > :h/3)[niech "a :h / 3]

Na początek należy wyliczyć szerokość kwadratu na podstawie (2.) szerokości strony oraz (3.) wysokości. (4.) Najpierw szerokość jest wyliczany z szerokości, ale należy pamiętać, że dla długości mniejszej, równej 3 długość :a może wyjść za duża i dlatego (5.) należy ewentualnie wykonać poprawkę względem wysokości.

  1.   niech "elz [a b c d e f g h i j k l m n o p q r s t u v w x y z]
  2.   niech "elna [3 1 3 1 3 1 2 1 3 2 1 1 3 3 3 2 2 3 3 1 3 3 3 3 2 3]
  3.   pod
  4.   ws :a/2 pw 90
  5.   ws :a*((długość :s)/2) lw 90
  6.   opu

Strategia rysowania liter opiera się na listach (6.) :elz i (7.) :elna. Mianowicie dla każdej litery o indeksie i na liście :elz na drugiej liście pod tym samym indeksie znajduje się cyfra określająca styl rysowanego prostokąta (1 - wysunięty prostokąt do góry, 2 - prostokąt w dół oraz 3 - kwadrat). (8. - 11.) Przesuń żółwia na początek rysowania.

  1.   powtórz (długość :s) [
  2.     niech "z element npw :s
  3.     jeżeli (liczba? :z) [
  4.       prostokat :a 2*:a "zielony
  5.     ][
  6.       jeżeli (samogłoska? :z) [
  7.         niech "kolor "czerwony
  8.       ][
  9.         niech "kolor "żółty
  10.       ]
  11.       wybierz (element (numel :z :elz) :elna) [
  12.         1 [prostokat :a 2*:a :kolor]
  13.         2 [ws :a prostokat :a 2*:a :kolor np :a]
  14.         3 [prostokat :a :a :kolor]
  15.       ]
  16.     ]
  17.     pod
  18.     pw 90 np :a
  19.     lw 90
  20.     opu
  21.   ]
  22. już

(12.) Dla każdego znaku: (13.) pobierz znak. Następnie (14.) jeśli to liczba to (15.) narysuj odpowiedni prostokąt. (16.) W przeciwnym wypadku: (17. - 21.) określ kolor figury i (22. - 27.) wybierz odpowiedni styl, aby narysować figurę odpowiadającą znakowi. (28. - 31.) Po narysowaniu litery przesuń w prawo o odległość :a.

Zadanie 2

Zdefiniuj funkcję LC :s, której daną może być dowolne słowo składające się z par litera-cyfra (np. "a5z3x0y2), a wynikiem - słowo składające się wyłącznie z liter, w którym każdej kolejnej parze litera-cyfra danego słowa odpowiada ciąg tylu identycznych liter, jaka jest wartość cyfry występującej bezpośrednio po literze.

LC "a3n5z1jest "aaannnnnz
LC "x7y0a1z2z1c4jest "xxxxxxxazzzcccc

Przykładowe rozwiązanie to rozwiązanie rekurencyjne, które opiera się na fakcie, że wyraz :s składa się z par litera-cyfra. Mianowicie jeśli drugi znak to cyfra to tyle razy dopisujemy ją na końcu :s i wywołujemy ponownie funkcję LC z nową wartością :s. Rekurencja kończy się kiedy na drugiej pozycji nie ma cyfry.

  1. oto LC :s
  2.   jeśli (nie liczba? element 2 :s)[ wynik :s ]
  3.   powtórz (element 2 :s) [
  4.     niech "s nak pierw :s :s
  5.   ]
  6.   wynik LC bezPierw bezPierw :s
  7. już

(2.) Jeśli na drugiej pozycji nie ma cyfry to zwróć :s. W przeciwnym wypadku (3. - 4.) odkoduj pierwszą parę i (5.) wywołaj funkcję ze zmienioną wartością :s. Bardzo ważne, aby pamiętać, aby usunąć z :s odkodowaną parę litera-cyfra.

Uwaga: takie rozwiązanie jest krótkie i poprawne, ale należy pamiętać, że program mógłby się zapętlić, gdyby umożliwić wstawianie par cyfra-cyfra.

Zadanie 3

Zdefiniuj funkcję KOD :s, której daną może być dowolne niepuste słowo składające się jedynie z małych liter alfabetu łacińskiego. Wynikiem funkcji jest słowo, utworzone z danego słowa według następujących zasad:

  • pierwszy i ostatni znak nie ulegają zmianie,
  • z każdej sekwencji kolejnych spółgłosek są pozostawione tylko skrajne, pozostałe pomijamy,
  • każda samogłoska (o ile nie jest pierwszym lub ostatnim znakiem słowa) jest powielona.

KOD "abrakadabrajest "abraakaadaabra
KOD "skrzynkajest "szyynka
KOD "warsztatjest "waartaat

W celu napisania krótkiego i efektywnego kodu warto sobie zdać sprawę, że pierwszą i ostatnią literę należy przepisać bez zmian tj. w pętli iterującej po słowie nie uwzględniać ich w jakikolwiek sposób. Ponadto skrajne spółgłoski można odnaleźć poprzez sprawdzenie czy obok nich występuje samogłoska. Oczywiście można to też rozwiązać porównując czy dana litera jest otoczona poprzez spółgłoski.

  1. oto KOD :s
  2.   niech "w pierw :s
  3.   powtórz ((długość :s) - 2) [
  4.     niech "z element (npw + 1) :s
  5.     jeżeli (samogłoska? :z)[
  6.       niech "w nak (słowo :z :z) :w
  7.     ][
  8.       jeśli(LUB samogłoska? element npw :s samogłoska? element (npw + 2) :s) [
  9.         niech "w nak :z :w
  10.       ]
  11.     ]
  12.   ]
  13.   wynik (słowo :w ost :s)
  14. już

(2.) Utwórz zmienną do której będą dopisywane kolejne części tekstu wynikowego. Przypisz jej pierwszą literę słowa :s. (3.) Dla każdego znaku prócz pierwszego i ostatniego: (4.) pobierz odpowiedni znak. (5.) Jeśli pobrany znak to samogłoska to (6.) zawsze dopisz do wyniku dwa takie znaki. (7.) Jednak w przypadku samogłoski przed (9.) dopisaniem (8.) upewnij się, że obok niej występuje samogłoska. Na koniec (12.) dopisz ostatni znak do wyniku.