Strona główna » Poradniki » Logomocja » LOGIA » Logia 2010/11 - Etap I
 

Logia 2010/11 - Etap I

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

Zadanie 1

Napisz procedurę KWADRATY, która na środku ekranu tworzy poniższą figurę. Długość boku zewnętrznego kwadratu wynosi 400.

Rozwiązanie

Całe zadanie zbiega się do rysowania kwadratów w odpowiednim miejscu. Z tego powodu warto napisać funkcję kwadrat, która narysuje kwadrat o środku tam gdzie znajduje się żółw. Procedura przyjmuje jeden argument :a, który określa bok rysowanego kwadratu.

  1. oto kwadrat :a
  2.   pod
  3.   np :a/2 pw 90
  4.   ws :a/2
  5.   opu
  6.   powtórz 4 [
  7.     np :a
  8.     pw 90
  9.   ]
  10.   pod
  11.   np :a/2 lw 90
  12.   ws :a/2
  13.   opu
  14. już

Przyglądając się dalej nietrudno zauważyć, że fragmenty rysunku to kwadraty w kwadracie. Każdy kolejny obrócony o 45 stopni. Procedura zapetlonykwadrat pozwala na narysowanie :ile kwadratów z czego największy będzie miał bok :a z zauważoną prawidłowością.

  1. oto zapetlonykwadrat :a :ile
  2.   niech "k kierunek
  3.   powtórz :ile [
  4.     kwadrat :a
  5.     niech "a (:a*pwk(2))/2
  6.     pw 45
  7.   ]
  8.   skieruj :k
  9. już

Kolejną procedurą pomocniczą jest kwadratyodnogi. Jest to procedura, która ma za zadanie narysować ten sam wzór kwadratu w czterech kierunkach począwszy ze środka. Pozwala to narysować większą część rysunku. Procedura przyjmuje 3 argumenty: :a - odległość w lini prostej do najbliższej ściany kwadratu, :b - rozmiar rysowanego kwadratu oraz :ile - ile kwadratów w sobie ma zostać narysowanych.

  1. oto kwadratyodnogi :a :b :ile
  2.   powtórz 4 [
  3.     pod np :a+:b/2 opu
  4.     zapetlonykwadrat :b :ile
  5.     pod ws :a+:b/2 opu
  6.     pw 90
  7.   ]
  8. już

Ostatnia procedura pomocnicza naokolokwadraty rysuje kwadraty, których się nie da narysować przy pomocy procedury kwadratyodnogi. Są to kwadraty na największym kwadracie i później w kwadracie w niego wpisanym występujące na wszystkich czterech bokach po dwa w równej odległości od siebie oraz ścian bocznych. Procedura przyjmuje 3 argumenty: :a - rozmiar ściany kwadratu na którym są rysowane małe kwadraty, :b - rozmiar rysowanego, małego kwadratu oraz :ile - ile kwadratów w sobie ma zostać narysowanych.

  1. oto naokolokwadraty :a :b :ile
  2.   pod
  3.   ws :a/2 pw 90
  4.   ws :a/2 lw 90
  5.   opu
  6.   powtórz 4 [
  7.     powtórz 2 [
  8.       np :a/3
  9.       pod
  10.       pw 90 np :b/2
  11.       opu
  12.       zapetlonykwadrat :b :ile
  13.       pod
  14.       ws :b/2 lw 90
  15.       opu
  16.     ]
  17.     np :a/3
  18.     pw 90
  19.   ]
  20.   pod
  21.   np :a/2 pw 90
  22.   np :a/2 lw 90
  23.   opu
  24. już

Procedura główna

Teraz na koniec pozostaje powyliczać odpowiednie wielkości i wywołać odpowiednie procedury pomocnicze tak jak w poniższym rozwiązaniu:

  1. oto KWADRATY
  2.   niech "a 400
  3.   zapetlonykwadrat :a 8
  4.   kwadratyodnogi :a/8 :a/12 1
  5.   kwadratyodnogi :a/4 :a/6 3
  6.   naokolokwadraty :a :a/9 2
  7.   pw 45
  8.   niech "b (:a*pwk(2))/2
  9.   kwadratyodnogi :b/4 :b/6 2
  10.   kwadratyodnogi :b/2 :b/3 4
  11.   kwadratyodnogi :b*(5/6) :b/9 1
  12.   naokolokwadraty :b :b/9 1
  13. już

Zadanie 2

Napisz procedurę RYBA:ile, która tworzy rysunki ryb składających się z głowy, ogona oraz :ile par ości. Szerokość rysunku wynosi 550. Parametr :ile może przyjmować wartości od 1 do 15. Środek ekranu leży w połowie wysokości i w połowie szerokości rysunku.

RYBA 1
RYBA 2

Idea rozwiązania

Na potrzeby rozwiązania opracowany został system zapisu kroków dla żółwia. Jak można zauważyć żółw rysując cały czas porusza się po linii prostej i czasem wykonuje skęt w prawo lub lewo. W zaproponowanym rozwiązaniu generowana jest lista kroków złożona z liter L, P oraz C. Dla każdego polecenia wykonywany jest ruch do przodu, ale dla litery L żółw na końcu narysowanej lini skręca w lewo, a dla P w prawo. Dla ostatniej litery (jak również każdej innej) program wykona tylko krok do przodu.

Przykładowo w celu narysowania oka ryby należy zapisać PPPP, albo LLLL. Gdybyśmy jednak chcieli narysować ość ryby dla wartości 1 to odpowiada temu kod LPLPLPCPLPLLC. Tego typu pozwoli na uproszczenie pisanego kodu i jego łatwiejszą modyfikację.

Rozwiązanie

W pierwszej części należy wygenerować kod dla górnej części rysunku. Później program automatycznie dołączy kod dla dolnej części.

  1. oto RYBA :ile
  2.   niech "w 550
  3.   niech "kroki "PLPLPCCCPLPLC
  4.   powtórz (:ile) [
  5.     niech "rozmiar :ile + 3 - npw
  6.     powtórz (:rozmiar) [
  7.       niech "kroki (słowo :kroki "LP)
  8.     ]
  9.     niech "kroki (słowo :kroki "CP)
  10.     powtórz (:rozmiar - 1) [
  11.       niech "kroki (słowo :kroki "PL)
  12.     ]
  13.     niech "kroki (słowo :kroki "LC)
  14.   ]
  15.   niech "kroki (słowo :kroki "CCLPLCPLCPLCPPCCPLCCPLC)
  16.   niech "kroki (słowo :kroki "C wspak :kroki "C)

(2.) Ustal szerokość rysunku o (3.) narysuj górną część głowy. Potem (4. - 14.) dla każdej kolenej ości wygeneruj kod rysunku. (15.) Po zakończeniu generowania ości dorysuj ogon (górną część). Ważny moment jest w linijce (16.) kiedy dodanie wspak zapisanych poleceń generuje kod dla dolnej części kodu. Pomiędzy polecenia zostały wpisane polecenie "C" jako korekta łączenia obu części.

  1.   niech "a :w / (16 + 4*:ile)
  2.   pod
  3.   lw 90 np :w/2
  4.   pw 90
  5.   opu
  6.   niech "dl długość :kroki
  7.   powtórz (:dl) [
  8.     np :a
  9.     wybierz element npw :kroki
  10.     [
  11.       P [pw 90]
  12.       L [lw 90]
  13.       C []
  14.     ]
  15.   ]
  16.   pod
  17.   np :a*2 pw 90
  18.   np :a*3
  19.   opu
  20.   powtórz 4 [
  21.     np :a
  22.     pw 90
  23.   ]
  24. już

W drugiej części ryba zostaje narysowana. Początkowo jest to (17.) wyliczenie długości rysowanych odcinków, a potem (18. - 21.) przejście do głowy ryby. Następnie (22. - 31.) intepretowane są kolejne polecenia wygenerowanego przez pierwszą część procedury. Na koniec (32. - 39.) należy pamiętać o dorysowaniu brakującego oka rybie.

Zadanie 3

Napisz procedurę PIRAMIDA:n :bok, która tworzy piramidy takie, jak na rysunkach poniżej. Wartość parametru :n określa liczbę cegieł na najniższym poziomie oraz liczbę poziomów i może przyjmować wartości od 1 do 20. Parametr :bok określa długość boku trójkąta równobocznego i może przyjmować wartości od 100 do 500.

PIRAMIDA 2 300
PIRAMIDA 3 100
PIRAMIDA 4 200

Rozwiązanie

W trakcie rysowania pirmiady należy pamiętać, że cegiełka ma wysokość równą wysokości trójkąta równobocznego podzielonego przez :n + 1, a podstawa cegiełki ma długość równą bokowi trójkąta równobocznego podzielonego przez :n + 1. Ponadto wszystkie połówki białych trójkątów mają podstawę równą połowie podstawy cegiełek.

  1. oto PIRAMIDA :n :bok
  2.   niech "h (:bok*pwk(3))/2
  3.   pod
  4.   ws :h/2 lw 90
  5.   np :bok/2
  6.   opu
  7.   powtórz 3 [
  8.     pw 120
  9.     np :bok
  10.   ]
  11.   niech "a :bok / (:n + 1)
  12.   niech "b :h / (:n + 1)
  13.   pw 180
  14.   np :a/2
  15.   lw 90
  16.   powtórz (:n) [
  17.     niech "ile :n - npw + 1
  18.     powtórz (:ile) [
  19.       wielokąt [
  20.         ukm "zielony4
  21.         powtórz 2 [
  22.           np :b
  23.           pw 90
  24.           np :a
  25.           pw 90
  26.         ]
  27.       ]
  28.       pw 90 np :a
  29.       lw 90
  30.     ]
  31.     np :b lw 90
  32.     np :a * (:ile - 0.5)
  33.     pw 90
  34.   ]
  35. już

(2.) Wylicz wysokość trójkąta. Następnie (3. - 6.) przesuń żółwia i (7. - 10.) narysuj obramowanie piramidy. Potem wylicz (11.) podstawę oraz (12.) wysokość cegiełek. (13. - 15.) Przejdź do pierwsze cegiełki od lewej na dole piramidy. Narysuj (16.) :n poziomów (17.) za każdym razem zmniejszając ilość cegiełek o jeden. (18. - 30.) narysuj odpowiednią ilość cegiełek w wierszu i (31. - 33.) przejdź do wiersza wyżej.

Zadanie 4

Napisz procedurę DYWAN:n, która na środku ekranu tworzy kwadratowe dywany o boku długości 400, takie, jak na rysunkach poniżej. Parametr :n określa stopień złożoności wzoru dywanu i może przyjmować wartości od 1 do 30.

DYWAN 4
DYWAN 5

Rozwiązanie

Podczas rozwiązywanie zadania najpierw narysować tło, a następnie kombinować jak narysować żółte elementy. Dodatkowo warto zauważyć, że najkrószy bok elementu ma wymiar równy szerokości całego rysunku podzielonego przez 3·:n + 1, gdzie :n to stopień złożoności wzoru dywanu. Jest to spowodowane faktem, że każdy kolejny element jest na zakładkę o 1 z poprzednim.

  1. oto DYWAN :n
  2.   niech "w 400
  3.   pod
  4.   ws :w/2 lw 90
  5.   np :w/2 pw 90
  6.   opu
  7.   wielokąt [
  8.     ukm "zielony5
  9.     powtórz 4 [
  10.       np :w
  11.       pw 90
  12.     ]
  13.   ]
  14.   niech "el 3 * :n + 1
  15.   niech "a :w / :el
  16.   np :a
  17.   powtórz (:n) [
  18.     powtórz (:n) [
  19.       wielokąt [
  20.         ukm "żółty6
  21.         powtórz 4 [
  22.           np :a pw 90
  23.           np :a lw 90
  24.           np (2*:a) pw 90
  25.         ]
  26.       ]
  27.       pod
  28.       pw 90 np :a*3
  29.       lw 90
  30.       opu
  31.     ]
  32.     pod
  33.     lw 90 np :a*(:el - 1)
  34.     pw 90 np :a*3
  35.     opu
  36.   ]
  37. już

(2.) Ustal szerokość rysunku. Następnie (3. - 6.) przejdź do (7. - 13.) narysowania tła. Potem (14.) oblicz ile jest elementów i na tej podstawie (15.) jakiej długości jest najkrótszy odcinek. (16.) Przejdź do rysowania elementów. Narysuj (17.) :n poziomów po (18.) :n elementów.