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

Logia 2004/05 - Etap I

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

Zadanie 1

Napisz bezparametrową procedurę DYWAN, która tworzy na środku ekranu rysunek przedstawiony poniżej. Wysokość rysunku powinna wynosić 300 pikseli.

Strategia

Zauważmy, że obrazek składa się z 15 identycznych fragmentów, dlatego warto wyodrębnić następujący fragment rysunku:

aby uprościć pisanie kodu. Zadanie to realizuje funkcja DYWAN_pom. Co prawda polecenie jasno określa, że wysokość rysunku to 300 pikseli, więc można by przyjąć szerokość i wysokość kwadratu na 100, ale dodatkowy parametr :a pozwala na ewentualne powiększenie rysunku.

  1. oto DYWAN_pom :a
  2.   niech "b :a/4
  3.   pod
  4.   np :a/2 pw 90
  5.   np :a/2 pw 90
  6.   opu

Środek rysowanego fragmentu będzie tam gdzie stoi żółw, więc: (1.) obliczamy szerokość małego kwadratu i (2. - 6.) przesuwamy się w prawy, górny róg rysunku. Następnie obramowanie składa się z czterech identycznych fragmentów (kwadratu i trójkąta).

  1.   powtórz 4[
  2.     ukp "niebieski11
  3.     ukm "niebieski11
  4.     wielokąt[
  5.       powtórz 4[
  6.         np :b
  7.         pw 90
  8.       ]
  9.     ]
  10.     pod np :b opu
  11.     ukp "oliwkowy4
  12.     ukm "oliwkowy4
  13.     wielokąt[
  14.       np (:a - 2*:b)
  15.       pw 135
  16.       np ((:a - 2*:b)/(pwk(2)))
  17.       pw 90
  18.       np ((:a - 2*:b)/(pwk(2)))
  19.     ]
  20.     pod np :a - :b pw 90 opu
  21.   ]

(7.) W każdej iteracji: (8. - 15.) narysuj mały kwadrat, (16.) przejdź o szerokość kwadratu. (17. - 25.) Narysuj trójkąt i (26.) ustaw żółwia do następnej iteracji.

  1.   pod
  2.   np :a/2 pw 90
  3.   np :a/2 pw 90
  4.   np :b pw 135 opu
  5.   ukp "niebieski11
  6.   ukm "niebieski11
  7.   wielokąt[
  8.     powtórz 4[
  9.       np ((:w - 2*:a)/(pwk(2)))
  10.       pw 90
  11.     ]
  12.   ]
  13.   pod lw 135 ws :b opu
  14.   ukp "czarny
  15. już

(28. - 31.) Przejdź do górnego rogu środkowego rombu na rysunku, (32. - 39.) narysuj go i (40.) wróć na środek rysunku. (41.) Zmień kolor pisaka na domyślny.

Główna procedura

  1. oto DYWAN
  2.   niech "a 100
  3.   pod
  4.   lw 90 np :a * 2
  5.   pw 90 ws :a
  6.   opu
  7.   powtórz 3 [
  8.     powtórz 5 [
  9.       DYWAN_pom :a
  10.       pod
  11.       pw 90 np :a
  12.       lw 90
  13.       opu
  14.     ]
  15.     pod
  16.     pw 90 ws :a * 5
  17.     lw 90 np :a
  18.     opu
  19.   ]
  20. już

(2.) Ustal rozmiar wyszczególnionego wcześniej fragmentu. (3. - 6.) Przesuń na środek lewego dolnego symbolu. (7.) Narysuj trzy rzędy po (8.) pięć symboli: (9.) narysuj fragment i (10. - 13.) przejdź do obszaru obok. Po narysowaniu wiersza: (15. - 18.) przejdź do pierwszego obszaru w wierzszu wyżej.

Zadanie 2

Figury przedstawione na rysunku poniżej to przykłady tak zwanych sześciokątnych plastrów, o różnych stopniach złożoności: 1, 2 oraz 4.

Napisz procedurę PLASTER :n rysowania na środku ekranu plastrów o dowolnym stopniu złożoności :n.Po wywołaniu procedury PLASTER z dowolną wartością parametru :n, nie mniejszą niż 1 i nie większą niż 6, na ekranie powinien powstać rysunek plastra o złożoności :n.

Strategia

Podane zadanie można rozwiązać na wiele sposobów. Przyjęte rozwiązanie przyjmuje, że zadanie jest podzielone na trzy procedury: PLASTER_pom, który rysuje sześciokąt o tej samej orientacji niezależnie od obrotu żółwia. Druga to PLASTER_kolo, która rysuje n-tą otoczkę wokół dotychczas narysowanego rysunku. Z kolei główna procedura sprowadza się do ustawiania miejsca rozpoczęcia rysowania przez PLASTER_kolo.

Sześciokąt

  1. oto PLASTER_pom :h
  2.   niech "a :h/pwk(3)
  3.   niech "kierunek ż1'kierunek
  4.   pod
  5.   skieruj 0
  6.   ws :h/2
  7.   lw 90
  8.   ws :a/2
  9.   opu
  10.   powtórz 6 [
  11.     np :a
  12.     pw 60
  13.   ]
  14.   pod
  15.   np :a/2
  16.   pw 90
  17.   np :h/2
  18.   skieruj :kierunek
  19.   opu
  20. już

(1.) Procedura przyjmuje jeden argument :h, który określa wysokość sześciokąta. Na podstawie tej wartości (2.) wyliczany jest bok sześciokąta. (3.) Zapamiętaj kierunek żólwia i (4. - 9.) przejdź do rysowania sześciokąta pamiętając, że procedura rysuje sześciokąt prawidłowo tylko wtedy, gdy (5.) żółw jest ustawiony pionowo. (10. - 13.) Narysuj sześciokąt. (14. - 19.) Powróć do środka sześciokąta pamiętając, aby (18.) ustawić na koniec ten sam kierunek co żółw miał na rozpoczęciu.

Rysowanie kolejnych otoczek

Pomińmy przypadek rysowania środkowego sześciokątu. Każda następna otoczka składa się z 6·:n sześciokątów. Warto jednak zauważyć, że można je narysować dzieląc na 6 lini po :n sześciokątów. Zadanie to realizuje procedura PLASTER_kolo:

  1. oto PLASTER_kolo :n :h
  2.   jeśli :n = 1[
  3.     PLASTER_pom :h
  4.     stop
  5.   ]
  6.   powtórz 6[
  7.     pw 30
  8.     powtórz (:n - 1)[
  9.       PLASTER_pom :h
  10.       pod
  11.       np :h
  12.       opu
  13.     ]
  14.     pw 30
  15.   ]
  16. już

(1.) Funkcja przyjmuje dwa argumenty :n - numer warstwy i :h - wysokość sześciokąta. W przedstawionym rozwiązaniu dla wykluczonego przypadku dla :n = 1 (2. - 4.) procedura rysuje tylko sześciokąt i kończy działanie. Jednak w pozostałych przypadkach (6.) sześć razy: (7.) obraca żółwia w kierunku rysowania kolejnych sześciokątów: (8. - 13.) rysuje je, przechodząc za każdym razem do przodu. (14.) Na koniec każdej grupki skręca ponownie w prawo.

Główna procedura

  1. oto PLASTER :n
  2.   niech "h 460/(2*:n - 1)
  3.   powtórz (:n) [
  4.     pw 90
  5.     PLASTER_kolo npw :h
  6.     lw 90
  7.     pod
  8.     skieruj 0
  9.     np :h
  10.     opu
  11.   ]
  12. już

(2.) Wyznacz największą możliwa wysokość sześciokąta, aby rysunek się zmieścił. (3.) Następnie :n razy: (4.) przygotuj żółwia do rysowania kółka skręcając w prawo, (5.) narysuj koło (warstwe), (6.) obróć z powrotem i (7. - 10.) przejdź do następnej warstwy.

Zadanie 3

Napisz bezparametrową procedurę OKO, która tworzy losowy rysunek złożony z sześciu okręgów. Największy okrąg ma średnicę 300 pikseli. Każdy kolejny jest wewnętrznie styczny z poprzednim i zmniejszony w skali od dwóch trzecich do pięciu szóstych. Również punkty styczności są wybierane losowo. Na rysunku poniżej widzimy przykładowe efekty dwóch wywołań procedury OKO.

Strategia

Przed napisaniem kodu warto zastanowić się nad dwoma problemami: stycznością kół oraz zmniejszaniem ich średnicy. Mianowicie styczność kół można uzyskać poprzez wyliczenie różnicy średnic poprzedni narysowanego koła i rysowanego następnie. Podzielone przez dwa oznacza odległość jaką można przejść w dowolnym kierunku, aby koła były styczne.

Problem drugi dotyczący zmniejszania można sprawdzić do bardzo prostego warunku. Jeśli wartość ma być pomiędzy dwoma ułamkami to wystarczy ich różnicę pomnożyć przez liczbę z zakresu (0, 1), a następnie dodać mniejszy ułamek do wyniku.

Kod

  1. oto OKO
  2.   niech "d 300
  3.   niech "maxl 10
  4.   powtórz 6 [
  5.     okrąg :d
  6.     niech "mn 2/3 + (5/6 - 2/3)*((losowa :maxl) / :maxl)
  7.     pod
  8.     skieruj losowa 360
  9.     np (:d - :d*:mn)/2
  10.     niech "d :d*:mn
  11.     opu
  12.   ]
  13. już

(1.) Początkowa średnica oka i (2.) zakres losowania liczb do losowego zmniejszania rozmiarów średnicy. (Im większy zakres tym więcej różnych mnożników można uzyskać.) (8.) Skieruj żółwia w dowolną stronę i (9.) przejdź o wcześniej wspomnianą różnicę średnic podzieloną na dwa. (10.) Oblicz nową średnicę. Wymienione instrukcje należy powtórzyć zgodnie z zadaniem 6 razy.

Zadanie 4

Napisz procedurę POSADZKA :n :m, która tworzy możliwie duże rysunki mozaiki, jak w przykładach poniżej, w których dana :n określa liczbę poziomych pasów, a dana :m liczbę pionowych pasów. Dane :n i :m to liczby całkowite nie mniejsze niż 1 i nie większe niż 10.

Oto przykłady efektów wywołania POSADZKA 3 8 i POSADZKA 4 2:

Napisz procedurę PIRAMIDA :lp, która tworzy na środku ekranu możliwie duży rysunek piramidy o danej liczbie pięter :lp z zakresu od 1 do 6.

Strategia

Zadanie zostało podzielone na dwie procedury. Funkcja pomocnicza będzie rysować pełną kolumne, a główna procedura odpowiednio przygotuje dane, aby rysunek został narysowany prawidłowo. Funkcja pomocnicza na początek. Funkcja przyjmuje trzy argumenty: :h - wysokość fragmentu, :w - szerokość fragmentu oraz :m - z ilu poziomów składa się fragment. Procedura rysuje fragment tak, aby środek rysowanego rysunku znalazł się tam gdzie stoi żółw.

    Pierwsza część procedury polega na (2.) obliczeniu krótszego boku żółtego trójkąta, a potem jego (3.) przeciwprostokątną. (4. - 6.) Przesuń lewy dolny róg rysunku tak, aby żółw podczas rozpoczęcia procedury wyznaczał środek fragmentu. (7. - 16.) Narysuj tylne, żółte tło.

      Następnie (17. - 20.) przejdź w prawo o wyliczony bok :a i (21. - 36.) narysuj wzorek poprzez (24.) powtózenie dwa razy ząbków i górnego odcinka. (37. - 40.) Na koniec wróć do punktu wyjściowego.

      Główna procedura

      1. oto POSADZKA :n :m
      2.   niech "h 460
      3.   niech "w 700
      4.   pod
      5.   niech "od_w :w/:m
      6.   jeśli (:h/:n > :od_w)[
      7.     niech "h :od_w * :n
      8.   ]
      9.   pw 90 ws :od_w * ((:m - 1) / 2)
      10.   lw 90
      11.   powtórz (:m) [
      12.     POSADZKA_pom :h :od_w :n
      13.     pod
      14.     pw 90 np :od_w
      15.     lw 90
      16.     opu
      17.   ]
      18. już

      (2. - 3.) Ustal maksymalny rozmiar rysunku. (4.) Podnieś pisak i (5.) oblicz szerokość fragmentów na podstawie maksymalnej szerokości. Bardzo ważne, aby sprawdzić (6.) czy przypadkiem nie spowoduje to nachodzenie na siebie prawej i lewej strony rysunku czyli czy górny odcinek pomiędzy żółtymi trójkątami jest równy conajmniej 0. Jeśli nie to (7.) należy dostosować wysokość obrazka do wyliczonej szerokości rysunku. (9.) Przejdź do pierwszego fragmentu od lewej i (10.) ustaw żółwia pionowo. (11.) Wykonaj :m razy: (12.) narysuj fragment i (13. - 16.) przejdź do fragmentu obok.