Strona główna » Poradniki » Logomocja » LOGIA » Logia 1998/99 - Etap I
 

Logia 1998/99 - Etap I

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

Zadanie 1

Napisz procedurę bez parametrów o nazwie PARKIET, która narysuje na ekranie możliwie duży rysunek parkietu przedstawiony niżej:

Obrazek 1 do zadania 1

Pojedynczy element

Zadanie można podzielić na dwa mniejsze podzadania. Pierwsze z nich to napisanie procedury, która będzie rysowała jeden element. Za element można tu przyjąć jeden z 16 identycznych fragmentów. Ze względu na fakt, że szare, obrócone kwadraty łączą elementy dopuszcza się rysowanie go dwa razy w celu uproszczenia kodu. Procedura PARKIET_el rozpoczyna rysowanie elementu od jego środka i do tego punktu żółw wraca co ułatwia napisanie procedury nadrzędnej. Kod wykonuje kolejno:

  1. oto PARKIET_el :a
  2.   lw 45
  3.   powtórz 4[
  4.     pod
  5.     np :a*pwk(2)
  6.     opu

(1.) Parametr :a określa rozmiar krótszego boku najmniejszego prostokątu w elemencie. (2.) Obrót w kierunku rysowania (3.) pierwszego z czterech identycznych fragmentów. (4. - 6.) Przesunięcie żółwia do najbliższego rogu kwadratu podzielonego na prostokąty.

  1.     lw 45
  2.     powtórz 4[
  3.       niech "n npw
  4.       powtórz 2[
  5.         np :a*4
  6.         pw 90
  7.         np :a*:n
  8.         pw 90
  9.       ]
  10.     ]

(7.) Ustawienie żółwia do rysowania, a następnie (8.) narysowanie czterech prostokątów. (9. - 15.) Prostokąty są rysowane jako prostokąty o stałej wysokości i zwiększające się szerokości.

  1.     pw 45
  2.     pod
  3.     ws :a*pwk(2)
  4.     opu
  5.     wielokąt[
  6.       ukm "jasnoszary
  7.       np (:a*pwk(2))
  8.       pw 45
  9.       np (:a*2)
  10.       pw 135
  11.       np (:a*pwk(2))
  12.       lw 90
  13.       np (:a*pwk(2))
  14.       pw 135
  15.       np (:a*2)
  16.       pw 45
  17.       np (:a*pwk(2))
  18.       pw 135
  19.     ]

(17.) Po narysowaniu prostokątów żółw zostaje obrócony, aby narysował wzór koło prostokątów. (18. - 20.) Korekcja ustawienia i (21. - 35.) narysowanie szarej figury leżącej nabliżej środka elementu.

  1.     pw 45
  2.     np :a*4
  3.     lw 45
  4.     wielokąt[
  5.       ukm "jasnoszary
  6.       powtórz 4[
  7.         np (:a*pwk(2))
  8.         pw 90
  9.       ]
  10.     ]
  11.     pw 45
  12.     ws :a*4
  13.     pw 45
  14.   ]
  15.   pw 45
  16. już

(36. - 38.) Następnie rysowany jest kwadrat na końcu wzoru. Biały element jest pomijany jako, że wszystkie jego boki są narysowane w trakcie rysowania innych figur i nie wymaga on kolorowania. (39. - 45.) narsysowanie kwadratu na końcu wzoru. (46. - 48.) Powrót do środka figury i (49.) zakończenie iteracji. (49.) Ustawienie żółwia do pozycji z której rozpoczął procedure.

Cały parkiet

Kod głównej procedury PARKIET:

  1. oto PARKIET
  2.   niech "h 460
  3.   niech "a :h/42
  4.   pod
  5.   ws :h/2
  6.   pw 90
  7.   ws :h/2
  8.   lw 90
  9.   opu
  10.   powtórz 4[
  11.     np :h
  12.     pw 90
  13.   ]

(2.) Ustalenie maksymalnej wysokości rysunku i (3.) wyliczenie szerokości pojedynczego, najmniejszego prostokąta na rysunku. (4. - 9.) przesunięcie żółwia w lewy dolny róg rysunku. (10. - 13.) Narysowanie obwódki dookoła rysunku.

  1.   pod
  2.   pw 45
  3.   np :a*6*pwk(2)
  4.   lw 45
  5.   opu
  6.   powtórz 4[
  7.     powtórz 4[
  8.       PARKIET_el :a
  9.       pod
  10.       pw 90
  11.       np :a*10
  12.       lw 90
  13.       opu
  14.     ]
  15.     pod
  16.     pw 90
  17.     ws :a*40
  18.     lw 90
  19.     np :a*10
  20.     opu
  21.   ]
  22. już

(14. - 18.) Przesunięcie żółwia na środek elementu w lewym dolnym rogu, a następnie (19. - 35.) narysowanie 16 identycznych elementów w odpowiedniej odległości od siebie.

Zadanie 2

Napisz procedurę KLEPKA :n, która utworzy na środku ekranu możliwie duży rysunek mozaiki klepek. Parametr :n mówi o ilości elementów w środkowym rzędzie mozaiki. Może on przyjmować wartości od 1 do 10. Oto przykładowe wyniki wywołania procedury KLEPKA dla różnych wartości parametru :n równych 1, 4 oraz 5.

Obrazek 1 do zadania 2

Przykładowe rozwiązanie przewiduje podzielenie zadania na trzy procedury: KLEPKA_el narysuje pojedynczy element o zadanej wielkości, KLEPKA_linia narysuje wyśrodkowaną pośrodku ekranu linię złożoną z pojedynczych elementów, a procedura KLEPKA narysuje odpowiednią ilość linii i przekaże jaką wielkość powinien mieć pojedynczy element.

Element

Pojedynczy element składa się z czterech, szarych oraz identycznych podelementów:

  1. oto KLEPKA_el :a
  2.   powtórz 4[
  3.     wielokąt[
  4.       ukm "jasnoszary
  5.       powtórz 2[
  6.         np :a
  7.         pw 45
  8.         np (:a*pwk(2))
  9.         pw 45
  10.         np :a
  11.         pw 90
  12.       ]
  13.     ]
  14.     pw 90
  15.   ]
  16. już

Linia

Podczas rysowania linii elementów należy pamiętać o prawidłowym wyśrodkowaniu:

  1. oto KLEPKA_linia :a :n
  2.   pod
  3.   pw 90
  4.   ws :a*4*(:n - 1)/2
  5.   opu
  6.   powtórz :n[
  7.     KLEPKA_el :a
  8.     pod
  9.     np :a*4
  10.     opu
  11.   ]
  12.   pod
  13.   ws :a*4*(:n + 1)/2
  14.   opu
  15.   lw 90
  16. już

(1.) Procedura przyjmuje: :a - rozmiar najkrótszego odcinka elementu oraz :n - ile ma być elementów w jednej linii. (2. - 5.) Przesunięcie żółwia na środek pierwszego elementu w linii. (6. - 11.) Narysowanie :n elementów. (12. - 15.) Powrót do miejsca rozpoczęcia procedury z uwzględnieniem, że żółw znajduje się jeden element dalej, ponieważ przesunięcie nastąpiło jeszcze po narysowaniu ostatniego elementu.

Główna procedura

Kod źródłowy głównej funkcji KLEPKA:

  1. oto KLEPKA :n
  2.   niech "h 460
  3.   niech "l (int(:n + 1) / 2)
  4.   niech "a :h / (4 * :n)
  5.   KLEPKA_linia :a :n
  6.   powtórz 2 [
  7.     powtórz :l [
  8.       pod
  9.       np :a * 4
  10.       opu
  11.       KLEPKA_linia :a :n - (2 * npw)
  12.     ]
  13.     wróć
  14.     pw 180
  15.   ]
  16. już

(2.) Ustalenie maksymalnej wysokości rysunku. (3.) Wyliczenie ile linii będzie trzeba narysować po jednej i drugiej stronie lini środkowej. (4.) Wyliczenie rozmiaru na podstawie złożoności najszerszej lini. (5.) Narysowania lini środkowej z elementami, a następnie (6. - 15.) Narysowanie pozostałych lini po obu stronach.

Zadanie 3

Napisz procedurę z parametrem STOSIK :ileKart, która utworzy możliwie duży rysunek pliku kartek. Parametr :ileKart mówi ile kartek ma zostać narysowanych, może on się zmieniać w granicach od 1 do 30. Odległość między skrajnymi kartkami jest stała i równa długości boku kartki. Druga krawędź kartki jest rysowana kreską tej samej długości co krawędź przednia oraz jako nachylona do linii poziomej pod kątem 450. Rysunki przedstawiają wyniki wywołania: STOSIK 1, STOSIK 2 i STOSIK 20.

Obrazek 1 do zadania 3

Istnieją dwa możliwe rozwiązania tego zadania. Pierwsze z nich, które jest podane jako przykładow korzysta z funkcji wielokąt, która rysując kolejną kartkę zamalowywuje kartkę niżej. Drugie rozwiązanie trudniejsze w wykonaniu polega na narysowaniu kartki na wierzchu, a następnie narysowaniu tylko krawędzi pozostałych kartek.

Pojedyncza kartka

Jedna kartka to romb o kącie przy podstwie 45 stopni:

  1. oto STOSIK_karta :a
  2.   pw 45
  3.   wielokąt[
  4.     ukm "biały
  5.     powtórz 2[
  6.       np :a
  7.       pw 45
  8.       np :a
  9.       pw 135
  10.     ]
  11.   ]
  12.   lw 45
  13. już

Stosik kart

  1. oto STOSIK :ilekart
  2.   niech "h 460
  3.   niech "w 600
  4.   niech "a :w/(1 + 0.5*pwk(2))
  5.   niech "r 0
  6.   jeśli (:ilekart <> 1)[
  7.     niech "r (:h - :a/2*pwk(2)) / (:ilekart - 1)
  8.   ]
  9.   pod
  10.   ws :h/2
  11.   pw 90
  12.   ws :w/2
  13.   lw 90
  14.   opu
  15.   powtórz :ilekart[
  16.     STOSIK_karta :a
  17.     pod
  18.     np :r
  19.     opu
  20.   ]
  21. już

Ustalenie maksymalnej (2.) wysokości i (3.) szerokości. (4.) Następnie należy wyliczyć bok kartki. (5.) Domyślnie odległość pomiędzy kolejnymi kartkami to 0. (6.) Właściwą odległość pomiędzy nimi należy obliczyć tylko wtedy, gdy leży więcej niż jedna kartka. Inaczej dojdzie do próby dzielenia przez 0. (7.) Podczas wyliczania odległości pomiędzy kartkami należy pamiętać o odjęciu od :h wysokości rombu o boku :a. (9. - 14.) Ustawienie żółwia w lewym dolnym rogu rysunku i (15. - 22.) narysowanie wszystkich kart.

Zadanie 4

Napisz procedurę WINDA :ilePięter :naKtórymJest :naKtórymMy, która da w wyniku jeden z czterech rysunków przedstawiających drzwi od windy:

  1. przez drzwi widać wnętrze windy,
  2. przez drzwi widać przeciwwagę,
  3. przez drzwi widać linę windy lub przeciwwagi,
  4. przez drzwi widać pustą ścianę.

Parametry oznaczają:

  • :ilePięter - ile pięter ma budynek (wartości od 1 do 20, uwaga: 1 oznacza dwie kondygnacje: parter i pierwsze piętro),
  • :naKtórymJest - na którym piętrze stoi winda (wartości od 0 do :ilePięter, 0 oznacza parter),
  • :naKtórymMy - na którym piętrze patrzymy na drzwi (wartości od 0 do :ilePięter, 0 oznacza parter).

Zakładamy, że jeśli winda jest na ostatnim piętrze, to przeciwwaga znajduje się na parterze i jest ona połączona z windą liną o stałej długości. Oto schematyczne rysunki, ich wygląd może zostać zmieniony, ważne aby nie pozostawiały wątpliwości, z którym z przypadków mamy do czynienia.

Obrazek 1 do zadania 4

W trakcie rozwiązywania należy opierać się na fakcie, że odważnik znajduje się na piętrze wyliczonym ze wzoru :ilePięter - :naKtórymJest.

  1. oto WINDA :ilePięter :naKtórymJest :naKtórymMy
  2.   niech "h 460
  3.   pod
  4.   ws :h/2
  5.   pw 90
  6.   ws :h/4
  7.   lw 90
  8.   opu
  9.   powtórz 2[
  10.     np :h
  11.     pw 90
  12.     np :h/2
  13.     pw 90
  14.   ]

(2.) Ustalenie wysokości rysunku. Wszystko inne będzie ustalane względem tej wielkości. (3. - 9.) Przesunięcie żółwia w lewy dolny róg. (10. - 14.) Narysowanie obramówki drzwi.

  1.   wróć
  2.   pod
  3.   lw 90
  4.   np :h/4-:h/12
  5.   okrąg :h/24
  6.   wróć
  7.   pod
  8.   pw 90
  9.   ws :h/8
  10.   lw 90
  11.   opu
  12.   wielokąt[
  13.     ukm "jasnoszary
  14.     powtórz 2[
  15.       np (:h/2*0.98)
  16.       pw 90
  17.       np (:h/4)
  18.       pw 90
  19.     ]
  20.   ]
  21.   wróć
  22.   jeśli (:naKtórymJest = :naKtórymMy)[
  23.     pod

(15.) Powrót na środek rysunku i (16. - 18.) przesunięcie, aby (19.) narysować klamke. (20.) Ponowny powrót, aby (22. - 26.) przesunąć ponownie żółwia i (27. - 36.) dorysować okienko w drzwiach, które domyślnie będzie szare. (37.) Powrót na środek.

  1.     np :h/4
  2.     lw 90
  3.     ukm "biały
  4.     zam
  5.     opu
  6.     powtórz 2[
  7.       np :h/10
  8.       pw 90
  9.       np :h/20
  10.       pw 90
  11.       np :h/10
  12.     ]
  13.     stop
  14.   ]
  15.   jeśli (:ilePięter - :naKtórymJest = :naKtórymMy)[

(38.) Jeśli jesteśmy na tym samym piętrze to widzimy winde. Wtedy (39. - 51.) Rysujemy odpowiednie wypełnienie okna. Uprzednio należy pamiętać o zamalowaniu okna na biało (domyślnie jest szare). (52.) Kończymy wykonywanie, aby nie rozpatrywać innych przypadków.

  1.     powtórz 4[
  2.       pod
  3.       np :h/20
  4.       opu
  5.       lw 90
  6.       np :h/8
  7.       ws :h/4
  8.       np :h/8
  9.       pw 90
  10.     ]
  11.     pod
  12.     np :h/20
  13.     opu
  14.     ugp 5
  15.     np (:h/2*0.98 - :h/4 - 2.5)
  16.     ugp 1
  17.     stop
  18.   ]

(53.) Jeśli widzimy odważnik to: (54. - 69.) należy narysować odpowiedni rysunek w oknie i (70.) zatrzymać wykonywania procedury.

  1.   jeśli (LUB :ilePięter - :naKtórymJest < :naKtórymMy :naKtórymJest < :naKtórymMy)[
  2.     ugp 5
  3.     np (:h/2*0.98 - 2.5)
  4.     ugp 1
  5.     stop
  6.   ]
  7. już

(71.) Jeśli nie widzimy, ani windy, ani odważnika, a znajdujemy się powyżej chociaż jednego z nich to zobaczymy linkę windy. (72. - 74.) Wtedy należy ją narysować i (75.) zatrzymać sprawdzanie dalszych warunków.

W przypadku, gdy w procedure warunek nie zostanie spełniony oznacza to, że przez okno nic nie widać. Nie wymaga to dodatkowego przypadku, ponieważ okno jest już domyślnie zamalowane na szaro.