Strona główna » Poradniki » Logomocja » LOGIA » Logia 1995/96 - Etap I
 

Logia 1995/96 - Etap I

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

Zadanie 1

Napisz procedurę POSADZKA rysowania posadzki dokładnie takiej jak poniżej.

Obrazek 1 do zadania 1

Zadanie podzielimy na dwie procedury: pomocnicza będzie rysować pojedynczą figurę. Z kolei główna funkcja wyśrodkuje odpowiednio rysunek i wywoła funkcję pomocniczą.

Figura składa się z trójkątów równobocznych. Możemy wyszczególnić w niej część, która powtarza się dwa razy. Zakładamy, że całą figurę wpisujemy w kwadrat, dlatego na początek przesuwamy do góry o .

  1. oto POSADZKA_pom :a
  2.   pod np (:a*pwk(3))/2 opu
  3.   wielokąt[
  4.       ukm "szary
  5.       powtórz 3[
  6.         pw 30
  7.         np :a
  8.         pw 60
  9.         np :a
  10.         lw 120
  11.         np (2*:a)
  12.         pw 120
  13.         np :a
  14.         lw 60
  15.         np :a
  16.         pw 90
  17.       ]
  18.   ]
  19.   pod ws (:a*pwk(3))/2 opu
  20. już

(1.) Funkcja pomocnicza przyjmuje argument :a. Określa on długość boku pojedynczego trójkąta. (2.) Przesuwamy z podniesionym pisakiem na pozycję od której zaczynamy rysować. (3.) Do rysowania używamy funkcji wielokąt: (4.) określamy kolor wypełnienia i (5.) trzy razy (6. - 16.) rysujemy identyczne części. Na koniec (19.) wracamy do punktu wyjścia.

Pozostaje teraz napisać funkcję główną POSADZKA. Będziemy z niej wywoływać funkcję pomocniczą:

  1. oto POSADZKA
  2.   niech "a 420 / 17
  3.   pod
  4.   ws (:a*17/2*pwk(3))/2
  5.   pw 90
  6.   ws :a*8
  7.   lw 90
  8.   opu
  9.   powtórz 4[
  10.     powtórz (5 - npw)[
  11.       POSADZKA_pom :a
  12.       pod
  13.       pw 90
  14.       np :a*4
  15.       lw 90
  16.       opu
  17.     ]
  18.     pod
  19.     lw 90
  20.     np :a*(4*(5 - npw) - 2)
  21.     pw 90
  22.     np (:a*4*pwk(3))/2
  23.     opu
  24.   ]
  25.   wróć
  26. już

(1.) Procedura POSADZKA nie przyjmuje parametrów. (2.) Ustalamy długość najmniejszego trójkąta. (Można tu wstawić konkretną wartość). (3. - 8.) Przesuwamy żółwia przy podniesionym pisak w lewy, dolny róg rysunku. (9.) Będziemy rysować 4 rzędy wzoru, a w każdym rzędzie (10.) o jeden mniej symbol. W i-tym rzędzie mamy 5-i symboli. (11.) Rysujemy wzór i (12. - 16.) przesuwamy się w prawo z podniesionym pisakiem, aby móc narysować kolejny. Po zakończeniu rysowania całego rzędu (18. - 23.) przesuwamy pisak do rzędy wyżej do początku rzędu.

Zadanie 2

Siatka trójkątów o stopniu złożoności n to duży trójkąt równoboczny podzielony na mniejszych (jednostkowych) trójkątów równobocznych.

Rysunek przedstawia trzy siatki równoboczne o złożoności 1, 2 oraz 3. Siatki trójkątów są przykładami figur jednobieżnych, można je narysować bez odrywania ołówka od papieru, kreśląc każdy jednostkowy odcinek dokładnie raz.

Napisz procedurę SIATKA :n rysowania w sposób jednobieżny takich trójkątnych siatek o dowolnym stopniu złożoności.

Po wywołaniu procedury SIATKA z dowolną wartością parametru :n od 1 do 10 żółw powinien wykreślić na ekranie możliwie duży rysunek siatki o złożoności :n. Powinien zacząć i skończyć kreślenie w wybranym rogu siatki i przebiec dokładnie jeden raz przez każdy jednostkowy odcinek siatki.

Obrazek 1 do zadania 2

Zadanie z pozoru jest proste. Jednak brak możliwości przesunięcia po tej samej linii dwa razy znacznie utrudnia całe zadanie. Niemniej warto zauważyć, że siatkę możemy rysować rzędami. W każdym rzędzie rysujemy odpowiednią ilość trójkątów, ale nie rysujemy podstaw, a w przypadku ostatniego trójkąta rysujemy tylko jeden bok. Potem przechodzimy do rysowania kolejnego rzędu itd. Na koniec rysunek musimy uzupełnić dwoma liniami prawy bok oraz podstawę. W ten sposób działa poniższy kod:

  1. oto SIATKA :n
  2.   niech "h_max 400
  3.   niech "a (2*:h_max/:n)/pwk(3)
  4.   pod
  5.   ws :h_max/2
  6.   pw 90
  7.   ws :h_max/2
  8.   opu
  9.   powtórz (:n)[
  10.     powtórz (:n - npw)[
  11.       lw 60
  12.       np :a
  13.       pw 120
  14.       np :a
  15.       lw 60
  16.     ]
  17.     lw 60
  18.     np :a
  19.     lw 120
  20.     np :a*(:n - npw)
  21.     pw 180
  22.   ]
  23.   pw 60
  24.   np :a*:n
  25.   pw 120
  26.   np :a*:n
  27. już

(1.) Procedura SIATKA zgodnie z zadaniem przyjmuje parametr :n określający złożoność siatki. (2.) Ustalamy maksymalną wysokość figury (ułatwi powiększanie / zmniejszanie rozmiaru rysunku). (3.) Wyliczamy bok :a pojedynczego trójkąta. Korzystamy tu z przekształcenia wzoru na wysokość trójkąta równobocznego: . (3. - 8.) Przesuwamy żółwia w lewy, dolny róg rysunku. (9.) Będziemy rysować :n rzędów. (10.) Z kolei w i-tym rzędzie narysujemy (11. - 15.) :n - i trójkątów podstaw, (17., 18.) tylko jeden bok trójkąta, a (19.) następnie obracamy się i (20.) przechodzimy na początek kolejnego rzędu. Tam z kolei (21.) obracamy się, aby być tak samo ustawionym jak na początku rysowania poprzedniego rzędu. Po zakończeniu pętli głównej (23. - 26.) rysujemy ostatnie dwa boki.

Zadanie 3

Wielokąty przedstawione na rysunku to tak zwane spiroboki o różnych stopniach złożoności: 1, 4 oraz 13.

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

Obrazek 1 do zadania 3

Rysowanie spirali to w rzeczywistości rysowanie odcinków prostopadłych do siebie. Pierwszy z nich ma długość :a, a każdy kolejny jest większy od poprzedniego o długość najmniejszego odcinka. Rysowanie spirali można rozdzielić na dwie części. Pierwsze z nich polega na narysowaniu "zewnętrznych" krawędzi - wtedy obracamy żółwia za każdym razem o . Z kolei drugą pętla będzie rysować "wewnętrzne" krawędzie. Tym razem z kolei będziemy obracać o i zmniejszać krawędzie. Pętle musimy uzupełnić kilkoma dodatkowymi kreskami. Zadanie to realizuje poniższy kod:

  1. oto SPIROBOK :n
  2.   niech "w 460/(:n+1)
  3.   jeśli (:w > 40)[niech "w 40]
  4.   np :w
  5.   pw 90
  6.   niech "a :w*2
  7.   powtórz (:n-1)[
  8.     np :a
  9.     niech "a :a + :w
  10.     pw 90
  11.   ]
  12.   np :a-:w
  13.   pw 90
  14.   np :w
  15.   pw 90
  16.   niech "a :w*(:n - 1)
  17.   powtórz :n[
  18.     np :a
  19.     lw 90
  20.     niech "a :a - :w
  21.   ]
  22.   pw 90
  23.   np :w
  24. już

(2.) Ustalamy wysokość pomiędzy dwoma liniami równoległymi. (3.) Ustalamy, że odległość ta nigdy nie będzie większa niż 40. W przypadku, gdy tak jest to zmieniamy :w na 40. (4.) Rysujemy linię uzupełniającą o długości :w i (5.) obracamy żółwia w prawo. (6.) Zmienna :a będzie przechowywać aktualną długość rysowanej linii. (7. - 11.) Rysujemy :n - 1 linii z których każda kolejna jest dłuższa o :w i jest prostopadła do poprzedniej. W tym przypadku za każdym razem skręcamy w prawo o . (12.) Rysujemy drugą taką samą linie jak ostatni. (W tym momencie znajdujemy się na zakończeniu spirali.) (13.) Rysujemy kolejny najkrótszy odcinek, długości :w, a następnie (16.) będziemy rysować linie wewnętrzne. W każdej iteracji linia jest mniejsza o :w, prostopadła do poprzedniej, a żółw skręca za każdym razem w lewo o . (17. - 21.) Rysujemy :n takich linii. Na koniec (22.) skręcamy w prawo i (23.) dorysowujemy ostatni fragment. (24.) Rysunek został zakończony.

Zadanie 4

Rysunek przedstawia mapę rzędu 3.

Obrazek 1 do zadania 4

Mapa rzędu n jest kwadratową siatką kropek, utworzoną z 2n+1 poziomych rzędów po 2n+1 kropek w każdym rzędzie. Środkowe punkty na zachodniej, północnej, wschodniej i południowej krawędzi mapy oznaczamy odpowiednio literami W, N, E oraz S.

Trzeba ułożyć trasę WNESW, to znaczy taką trasę, która spełnia następujące warunki:

  1. składa się z jednostkowych poziomych i pionowych odcinków, łączących sąsiednie punkty na mapie zaczyna się w punkcie W następnie biegnie do N, do E, do S i wraca do W,
  2. ma minimalną długość.

Rysunek przedstawia 4 różne trasy WNESW na mapie rzędu 3.

Obrazek 2 do zadania 4

Napisz procedurę TRASA :n, która dla dowolnej wartości parametru :n nie mniejszej niż 1 i nie większej niż 6:

  • rysuje na ekranie mapę rzędu :n,
  • wykreśla na niej w sposób losowy trasę WNESW.

Procedurę należy napisać w taki sposób, aby każda trasa WNESW (tj. spełniająca warunki 1, 2 i 3) mogła być efektem jej wykonania.

Podczas rozwiązywania tego zadania należy pamiętać, że podczas przechodzenia z dowolnego kierunku świata na drugi wykonamy maksymalnie 2*:n razy z czego pionowo przesuniemy się :n razy. Poziomo przesuniemy się tyle samo razy. Zadanie podzielimy na dwie części: procedura główna narysuje siatką oraz wypisze kierunki świata i uruchomi procedurę pomocniczą, która wylosuje trasę.

  1. oto TRASA_pom :a :max
  2.   niech "P 0
  3.   niech "S 0
  4.   dopóki[(I nie (:P = :max) nie (:S = :max) )][
  5.     jeżeli ((losowa 2) = 0)[
  6.           np :a
  7.           zwiększ "P
  8.         ][
  9.           pw 90
  10.           np :a
  11.           lw 90
  12.           zwiększ "S
  13.       ]
  14.   ]
  15.   dopóki[:P < :max][np :a zwiększ "P]
  16.   dopóki[:S < :max][pw 90 np :a lw 90 zwiększ "S]
  17. już

(1.) Funkcja pomocnicza TRASA_pom przyjmuje dwa argumenty: :a - pozioma odległość pomiędzy dwoma punktami, :max - określa ile kresek pionowych i poziomych rysujemy. (2., 3.) Określamy licznik przesunięć pionowo (P) / poziomo (S). (4.) Dopóki oba liczniki są mniejsze od :max (5.) losujemy kierunek przesunięcia. Jeśli wylosowana liczba to 0 to (6., 7.) wykonujemy poziomą linię i zwiększamy licznik :P. W przeciwnym przypadku (9. - 11.) rysujemy pionową kreskę i tym razem (12.) zwiększamy licznik :S. Kiedy choć jeden licznik osiągnie wartość :max. (15., 16.) Sprawdzamy, których kresek brakuje i je dorysowujemy. W rzeczywistości wykonana zostanie dokładnie tylko jedna z pętli dopóki.

W funkcji głównej TRASA możemy wyszczególnić trzy części: podpisanie kierunków świata, rysowanie siatki i rysowanie wylosowanej trasy.

  1. oto TRASA :n
  2.   niech "a 400 / (:n*2)
  3.   pod
  4.   ustalPoz (lista 0 (:a*:n+20))
  5.   piszTekst "S
  6.   ustalPoz (lista 0 (-:a*:n-20))
  7.   piszTekst "N
  8.   ustalPoz (lista (:a*:n+20) 0)
  9.   piszTekst "E
  10.   ustalPoz (lista (-:a*:n-20) 0)
  11.   piszTekst "W
  12.   wróć

Na początek (2.) wyliczamy odległość :a. Jest to odległość pomiędzy dwoma najbliższymi punktami. (3.) Podnosimy pisak. (4. - 11.) Dla każdego kierunku świata ustalamy odpowiednio pozycję żółwia i wypisujemy kierunek. Po zakończeniu (12.) wracamy na środek ekranu.

  1.   wróć
  2.   ws :a*:n
  3.   pw 90
  4.   ws :a*:n
  5.   lw 90
  6.   powtórz (:n*2 + 1)[
  7.       powtórz (:n*2)[
  8.           kropka 1
  9.           np :a
  10.       ]
  11.       kropka 1
  12.       ws :a*:n*2
  13.       pw 90
  14.       np :a
  15.       lw 90
  16.   ]
  17.   lw 90
  18.   np :a*(:n+1)
  19.   opu

Przed narysowaniem siatki (13. - 16.) przesuwamy żółwia w lewy, dolny róg rysunku i (17. - 27.) rysujemy siatkę. Kropki stawiamy przy pomocy kropka. Po zakończeniu rysowania siatki znajdujemy się w prawym dolnym rogu, dlatego (28. - 30.) musimy wrócić na środek dolnej krawędzi.

  1.   powtórz 4[
  2.       TRASA_pom :a :n
  3.       pw 90
  4.   ]
  5. już

W ostatniej części (31.) rysujemy cztery (32.) wylosowane trasy. Na koniec rysowania trasy skręcamy o .