Strona główna » Poradniki » Logomocja » LOGIA » Logia 2012/13 Etap I
 

Logia 2012/13 Etap I

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

Zadanie 1

Napisz procedurę PLECIONKA, która tworzy na środku ekranu rysunek plecionki taki, jak obok. Wysokość rysunku wynosi nie mniej niż 400.

Rozwiązanie

Zaproponowane rozwiązanie poniżej korzysta z trzech procedur. Pierwsza z nich PLECIONKA_el rysuje jeden, pojedynczy element na rysunku. Rozmiarem rysunku można sterować przy pomocy parametru :a, który określa długość najkrótszego odcinka.

  1. oto PLECIONKA_el :a
  2.   wielokąt [
  3.     ukm "oliwkowy
  4.     powtórz 3 [
  5.       np :a pw 60
  6.       np (:a*2) lw 60
  7.       np (:a*2) pw 120
  8.     ]
  9.   ]
  10. już

Kolejne spotrzeżenie, które ma uprościć wykonanie zadania jest fakt, że w środku rysunku zostało narysowanych sześć takich elementów. Zostały one ustawione w kółko, a dokładniej można powiedzieć, że mają dokładnie po jednym wspólnym wierzchołku z sześciokątem. Bardzo ważnym faktem jest to, że po obróceniu fragmanetu o 60º dalej jest takim samym fragmentem (powstaje przystająca figura). Obracanie oczywiście można powtórzyć dowolną ilość razy. Tego typu fragment rysuje procedura PLECIONKA_fragment:

  1. oto PLECIONKA_fragment :a
  2.   pod
  3.   lw 30 np :a
  4.   pw 60
  5.   opu
  6.   powtórz (6) [
  7.     PLECIONKA_el :a
  8.     pw 60 np :a
  9.   ]
  10.   pod
  11.   lw 60 ws :a
  12.   pw 30
  13.   opu
  14. już

Jak można zauważyć to na rysunku takich sześciokątów jest 7. Co więcej jeśli by je obrysować jak najmniejszą figurą to wyjdzie ... duży sześciokąt. Oznacza to, że w każdym jego rogu można rozpocząć rysowanie fragmentu. Niektóre z elementów będą przez to rysowane 2 razy. Nie trzeba później rysować środkowego elementu, ponieważ zostanie on narysowany w trakcie rysowania zewnętrznych fragmentów. Ostateczny kod procedury głównej PLECIONKA:

  1. oto PLECIONKA
  2.   niech "a 30
  3.   pw 30
  4.   powtórz 6 [
  5.     pod
  6.     np :a*4 lw 30
  7.     opu
  8.     PLECIONKA_fragment :a
  9.     pod
  10.     pw 30 ws :a*4
  11.     pw 60
  12.     opu
  13.   ]
  14.   lw 30
  15. już

Rozmiar narysowanego rysunku można sterować przy pomocy zmiennej :a, która jest deklarowana na samym początku procedury głównej. Domyślniej jest to wartość 30, ponieważ wtedy grafika końcowa spełnia założenia zadania.

Zadanie 2

Napisz procedurę RAMKI:ile, która tworzy na środku ekranu rysunek składający się z :ile ramek, taki, jak w przykładach. Parametr :ile może przyjmować wartości od 1 do 9. Szerokość zewnętrznej ramki wynosi 480. Szerokość każdej kolejnej ramki stanowi 16/21 szerokości ramki ją obejmującej.

Rysunek pomocniczy
RAMKI 1
RAMKI 8

Rozwiązanie

Przyglądając się rysunkowi RAMKI 1 należy zauważyć, że składa się on z czterech identycznych fragmentów. Jest to grafika podobna do tej przedstawionej na rysunku pomocniczym, ale bez elementu z prawej lub lewej. Innymi słowy cały obrazek można narysować w czterech iteracjach rysując ten sam fragment. Procedura RAMKI_ramka przyjmuje jeden argument :szer, który określa szerokość aktualnie rysowanej ramki. Procedura rysuje rysunek pośrodku miejsca, gdzie żółw rozpoczyna rysowanie.

  1. oto RAMKI_ramka :szer
  2.   niech "a :szer/21
  3.   pod
  4.   ws :szer/2 pw 90
  5.   ws :szer/2 lw 90
  6.   opu
  7.   powtórz 4 [
  8.     wielokąt [
  9.       ukm "zielony2
  10.       ukp "zielony2
  11.       pod
  12.       powtórz 2 [
  13.         np (:a*4)
  14.         powtórz 2 [
  15.           pw 45
  16.           np (:a*pwk(2)) lw 90
  17.           np (:a*pwk(2)) pw 45
  18.         ]
  19.         np (:a*5)
  20.         powtórz 2 [
  21.           pw 45
  22.           np (:a*pwk(2)) lw 90
  23.           np (:a*pwk(2)) pw 45
  24.         ]
  25.         np (:a*4) pw 90
  26.         np (:a*2) pw 90
  27.       ]
  28.     ]
  29.     pod
  30.     np :szer pw 90
  31.     opu
  32.   ]
  33.   ukp "czarny
  34.   pod
  35.   np :szer/2 pw 90
  36.   np :szer/2 lw 90
  37.   opu
  38. już

(2.) Oblicz długość najkrószego odcinka. Potem (3. - 5.) przejdź w lewy, dolny róg rysunku. Narysuj (7. - 32.) cztery takie same fragmenty. Za każdym razem na koniec iteracji (29. - 31.) przesuwając się do kolejnego rogu. Na koniec (33.) przywróć czarny kolor pisaka i (34. - 37.) wróć tam skąd zostało rozpoczęte rysowania.

Teraz pozostaje jedynie wywoływać w procedurze RAMKI procedurę RAMKI_ramka z odpowiednimi parametrami. Innymi słowy główna procedura (3. - 6.) to pętla, która w każdej iteracji (4.) rysuje ramkę o aktualnej szerokości (początkowo :szer = 480) i (5.) oblicza następną szerokość.

  1. oto RAMKI :ile
  2.   niech "szer 480
  3.   powtórz (:ile) [
  4.     RAMKI_ramka :szer
  5.     niech "szer :szer*16/21
  6.   ]
  7. już

Zadanie 3

Burmistrz miasta Logianów, planując wiele inwestycji, zlecił Działowi Architektury wykonanie wizualizacji. Wokół budynków mają zostać ułożone dwukolorowe chodniki z kostek takich, jak na rysunku wyżej. Niektóre kostki należy przeciąć na pół tak, by powstał prostokątny chodnik.

Napisz procedurę CHODNIK:ilek :iler, która tworzy rysunek prostokątnego chodnika ułożonego z szarych i różowych kostek. Parametr :ilek oznacza liczbę kolumn ułożonych z różowych kostek. Parametr :iler oznacza liczbę różowych kostek potrzebnych do ułożenia jednej kolumny. Oba parametry mogą przyjmować wartości od 1 do 20. Wysokość rysunku wynosi 400 lub szerokość 600.

Rysunek pomocniczy
CHODNIK 1 2
CHODNIK 4 5

Rozwiązanie

Pierwszy etap wykonania rysunku polega na obliczeniu szeokości kostki oraz jej wyśrodkowania na stronie. Tutaj należy najpierw obliczyć długość odcinka, która wynika zarówno z wysokości jak i szerokości obszaru rysowania. Potem należy oczywiście wybrać mniejszą wartość i przyjąć ją za parametr szerokości :a, który będzie oznaczał najkrótszy odcinek elementu kostki.

  1. oto CHODNIK :ilek :iler
  2.   niech "h 400/(6*:iler)
  3.   niech "w 600/(10*:ilek)
  4.   jeżeli(:h < :w) [
  5.     niech "a :h
  6.   ][
  7.     niech "a :w
  8.   ]
  9.   pod
  10.   ws (:a*6*:iler/2) pw 90
  11.   ws (:a*10*:ilek/2) lw 90
  12.   opu

W celu narysowania chodnika skorzystamy z pewnej sztuczki. Pisanie dodatkowej funkcji do rysowania połowy kostki może okazać się mało wygodne i podczas konkursu mogłoby zabraknąć czasu. Tutaj nie trzeba rysować szarej kostki, a wystarczy różową, ponieważ po jej narysowaniu zostaną obrysowane kontury szarej. Jednak należy pamiętać, że szary kolor sam się nie pojawi i należy narysować najpierw szare prostokąty na których zostanie narysowana szara kostka. Na koniec przechodzimy do punktu skąd zostaną narysowane kostki.

  1.   powtórz (:iler) [
  2.     wielokąt [
  3.       ukm "szary11
  4.       powtórz 2 [
  5.         np (:a*6) pw 90
  6.         np (:a*10*:ilek) pw 90
  7.       ]
  8.     ]
  9.     np :a*6
  10.   ]
  11.   pod
  12.   ws :a*6*:iler pw 90
  13.   np :a*3 lw 90
  14.   opu

Narysowanie różowych kostek polega na tym, że najpierw rysujemy obramowanie wszystkie kostek w danej kolumnie, a dopiero potem dorysowywujemy dodatkowe linie, które symbolizują łączenia kostek.

  1.   powtórz (:ilek) [
  2.     wielokąt [
  3.       ukm "różowy11
  4.       powtórz 2 [
  5.         powtórz (:iler) [
  6.           np :a lw 45
  7.           np (:a*pwk(2)) pw 45
  8.           np (:a*2) pw 45
  9.           np (:a*pwk(2)) lw 45
  10.           np :a
  11.         ]
  12.         pw 90 np (:a*4)
  13.         pw 90
  14.       ]
  15.     ]
  16.     pod
  17.     lw 90 np :a
  18.     pw 90 np :a*3
  19.     opu
  20.     powtórz (:ilek) [
  21.       opu
  22.       pw 90 np :a*6
  23.       ws :a*6 lw 90
  24.       pod
  25.       np :a*6
  26.     ]
  27.     pod
  28.     ws :a*6*(:ilek+0.5) pw 90
  29.     np :a*11 lw 90
  30.     opu
  31.   ]
  32. już

Zadanie 4

Napisz funkcję KIEDY:x :y, której wynikiem będzie liczba określająca, którego dnia mały żuczek znajdzie się na szczycie dziesięciometrowego słupa. Żuczek w dzień wspina się o :x centymetrów, w nocy osuwa się o :y centymetrów. Załóż, że :x >:y.

KIEDY 300 100jest 5
KIEDY 4 2jest 499

Rozwiązanie

W celu obliczenia ile dni będzie szedł żuczek można skorzystać z wzoru. Mianowicie wiemy, że żuczek dziennie przebywa :x - :y cm. Wiemy też, że ostatniego dnia jest gwarantowane wejście o :x cm, więc musimy dowiedzieć się kiedy osiągnie co najmniej wysokość 1000 - :x. Można tego dokonać dzieląc to wyrażenie przez dzienny odcinek, który przebywa. Uwaga! Należy pamiętać, że później ten wynik należy zaokrąglić w górę, aby poznać faktyczną ilość dni spędzonych na wspinaniu. Funkcja główna to zaledwie jeden wzór:

  1. oto KIEDY :x :y
  2.   wynik wgóre((1000 - :x) / (:x - :y) + 1)
  3. już

Z kolei funkcja wgóre przyjmuje jeden argument :a i zwraca argument zaokrąglony w górę. Oto kod:

  1. oto wgóre :a
  2.   jeżeli (int :a < :a)[
  3.     wynik (int :a) + 1
  4.   ][
  5.     wynik :a
  6.   ]
  7. już