Strona główna » Poradniki » Logomocja » LOGIA » Logia 2004/05 - Etap II
 

Logia 2004/05 - Etap II

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

Zadanie 1

Zdefiniuj procedurę GRAFKOD :liczba, której daną może być dowolna liczba całkowita dodatnia. Procedura przedstawia liczbę w postaci graficznej, zgodnie z następującymi zasadami:

  • wszystkie słupki mają identyczną szerokość,
  • każdej cyfrze odpowiada słupek o odpowiedniej wysokości, wszystkie słupki mają wysokość będącą wielokrotnością wysokości słupka odpowiadającego cyfrze 1,
  • cyfrze 0 odpowiada słupek o wysokości zero - czyli poziomy odcinek,
  • słupki odpowiadające cyfrom stojącym na parzystych pozycjach w liczbie są skierowane ku górze, zaś odpowiadające cyfrom na pozycjach nieparzystych - ku dołowi,
  • każdy słupek rysowany jest z pozycji żółwia, dla której y=0.

Rysunek powinien mieścić się na ekranie i być możliwie duży, kodowana liczba może mieć maksymalnie 100 cyfr.

Rysunki poniżej przedstawiają efekty wywołań: GRAFKOD 4236, GRAFKOD 11001 oraz GRAFKOD 912345678909876543219.

Obrazek 1 do zadania 1

W przypadku tego zadania warto na początek ustalić maksymalny rozmiar rysunku. Za rozmiar roboczy można przyjąć obszar o wielkości 700x460. Wiedząc, że największa cyfra to 9 to maksymalnie w kolumnie musi się zmieścić 18 odcinków, dlatego można bezpiecznie przyjąć, że odległość pomiędzy pionowymi kreskami nie może przekroczyć 25. Oczywiście należy pamiętać, aby tę szerokość ewentualnie zmniejszyć jeśli wpisana liczba jest bardzo długa.

  1. oto GRAFKOD :liczba
  2.   niech "max_a 25
  3.   niech "w 700
  4.   niech "n długość :liczba
  5.   niech "a :w / :n
  6.   jeśli (:a > :max_a) [
  7.     niech "a :max_a
  8.   ]
  9.   pod
  10.   lw 90 np (:n * :a) / 2
  11.   lw 90
  12.   opu

(2.) Ustal maksymalną odległość pomiędzy pionowymi kreskami oraz (3.) szerokość obszaru roboczego. (4.) Zapamiętaj ile jest cyfr w wprowadzonej liczbie i na podstawie tej wartości (5.) oblicz szerokość jednej kolumny. (6.) Jeśli odległość jest większa niż maksymalna wartość to (7.) zmień ją na maksymalną. Następnie przejdź (9. - 12.) w lewy koniec rysunku w celu rozpoczęcia rysowania.

  1.   powtórz (:n) [
  2.     niech "k (element npw :liczba)
  3.     jeżeli (reszta npw 2 = 1) [
  4.       np :k * :a
  5.       lw 90
  6.       np :a
  7.       lw 90
  8.       np :k * :a
  9.     ][
  10.       np :k * :a
  11.       pw 90
  12.       np :a
  13.       pw 90
  14.       np :k * :a
  15.     ]
  16.   ]
  17. już

(13.) Dla każdej z cyfr: (14.) pobierz cyfrę i (15.) w zależności od tego czy kolumna być rysowana w dół czy w górę wybierz odpowiedni fragment kodu. W przypadku rysowania kolumny do dołu (16. - 20.) skręty będą wyoknywane w lewo, a w przypadku rysowania kolumny do góry (22. - 26.) w prawo.

Zadanie 2

Zdefiniuj funkcję POWIEL :słowo :liczba, której danymi są dowolne słowo i dowolna liczba całkowita nieujemna. Wynikiem funkcji jest słowo z powielonymi literami. Każda litera jest powielona tyle razy, jaka jest wartość cyfry na tej samej pozycji w liczbie. Jeśli liczba jest krótsza (tzn. ma mniej cyfr, niż słowo liter), to dla kolejnych liter na pozycjach dalszych niż długość liczby - brane są ponownie cyfry od początku liczby.

POWIEL "krokodyl 123jest "krroookoodddyll
POWIEL "lis 2005jest "ll

Całe zadania się do pobierania kolejnych liter z słowa i kolejnych cyfr z liczby. W tym drugim przypadku należy zastosować funkcję reszta, aby wybierać cyfry z liczby cyklicznie.

  1. oto POWIEL :słowo :liczba
  2.   niech "w "
  3.   niech "n długość :liczba
  4.   powtórz (długość :słowo) [
  5.     niech "e element npw :słowo
  6.     niech "i element ((reszta (npw - 1) :n) + 1) :liczba
  7.     powtórz (:i) [
  8.       niech "w nak :e :w
  9.     ]
  10.   ]
  11.   wynik :w
  12. już

(2.) Ustal zmienną przechowującą wynik na puste słowo. (3.) Pobierz ile cyfr ma :liczba i (4.) dla każdej litery: (5.) zapamiętaj literę, (6.) wybierz odpowiednią cyfrę. Następnie (7.) w zależności od wybranej cyfry (8.) dodaj tyle razy zapamiętaną literę do tekstu wynikowego. Na koniec (11.) zwróć zmienną :w.

Zadanie 3

Zdefiniuj procedurę POSADZKA :s :w, która dla całkowitych, dodatnich danych :s i :w rysuje na środku ekranu posadzkę o szerokości :s i wysokości :w. Posadzka składa się z możliwie najmniejszej liczby kwadratowych kafelków o całkowitoliczbowych długościach boków. Kafelki nie różnią się rozmiarem i występują w jednym z dwóch kolorów, dowolnie wybranych, ale różnych od koloru tła. Kafelki mające wspólny bok mają różne kolory.

Rysunek poniżej przedstawiają efekty wywołania POSADZKA 700 80 i POSADZKA 700 70, POSADZKA 150 250.

Obrazek 1 do zadania 3

Rozmiar kafelków.

W zadaniu jest mowa, aby kafelków było jak najmniej, a ich boki miały długość całkowitoliczbową. Oznacza to, że zarówno szerokość jak i wysokość rysunku powinny być wielokrotnościami rozmiaru. Jednym z najprostszych sposobów na rozwiązanie tego problemu jest znalezienione Najmniejszego Wspólnego Dzielnika dla podanych wartości :s i :w. Poniżej znajduje się algorytm realizujący Algorytm Euklidesa, który pozwala znaleźć NWD dla dowolnych dwóch liczb całkowitych dodatnich.

  1. oto nwd :a :b
  2.   niech "c 0
  3.   dopóki [:b <> 0][
  4.     niech "c reszta :a :b
  5.     niech "a :b
  6.     niech "b :c
  7.   ]
  8.   wynik :a
  9. już

Jego dokładnie wyjaśnienie można znaleźć tutaj. Warto oczywiście zauważyć, że jeśli liczby są względnie pierwsze to rozmiar kafelków wyniesie 1.

Kod

Procedura rozpoczyna działanie od wyznaczenia potrzebnych wartości:

  1. oto POSADZKA :s :w
  2.   niech "nwd nwd :s :w
  3.   niech "hn :w / :nwd
  4.   niech "wn :s / :nwd
  5.   pod
  6.   ws :w / 2 pw 90
  7.   ws :s / 2 lw 90
  8.   niech "kolory ["ciemnozielony4 "oliwkowy]

(2.) Oblicz rozmiar kafelka, a następnie ile (3.) będzie kafelków wzwyż i (4.) wszerz. Następnie (5. - 7.) przejdź w lewy dolny róg rysunku. (8.) Ustal jakie kolory będą miały kafelki. Są one zgodnie z zadaniem dowolne, dlatego mogą być jak w przykładowym rozwiązaniu: w odcieniu zielonego koloru.

  1.   powtórz (:hn) [
  2.     niech "kolori reszta npw 2
  3.     powtórz (:wn) [
  4.       niech "kolori reszta (:kolori + 1) 2
  5.       ukm element (:kolori+1) :kolory
  6.       ukp element (:kolori+1) :kolory
  7.       wielokąt [
  8.         powtórz 4 [
  9.           np :nwd
  10.           pw 90
  11.         ]
  12.       ]
  13.       pw 90 np :nwd
  14.       lw 90
  15.     ]
  16.     lw 90 np :s
  17.     pw 90 np :nwd
  18.   ]
  19.   opu
  20.   ukp "czarny
  21. już

(9.) Narysuj :hn wierszy. (10.) Każdy kolejny wiersz zaczyna się innym kolorem, dlatego wybieramy odpowiedni indeks koloru biorąc resztę z dzielenia numeru wiersza przez 2. (11.) Rozpoczyamy rysowanie kwadracików: (12.) przed narysowaniem każdego kwadratu zmieniamy kolor na przeciwny i ustalamy (13.) kolor malowania i (14.) pisaka. (15. - 20.) Rysujemy kwadrat i (21. - 22.) przechodzimy do kwadratu obok na prawo. Po narysowaniu wiersza (24. - 25.) przechodzimy do pierwszego kwadratu wiersz wyżej. Na koniec (27. - 28.) przywracamy domyślne ustawienia pisaka i koloru pisaka.