Strona główna » Poradniki » Logomocja » LOGIA » Logia 2017/18 Etap I
 

Logia 2017/18 Etap I

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

Zadanie 1

Napisz bezparametrową procedurę/funkcję rama, po wywołaniu której na środku ekranu powstanie rysunek taki, jak poniżej. Wysokość rysunku wynosi 490.

rama

Rozwiązanie

Domyślnie rozmiar pisaka żółwia to 1. Jego zwiększenie spowoduje narysowanie grubszej linii, ale nie będzie ona kwadratowa, a okrągła. Z tego powodu warto napisać własną funkcję do rysowania kreski. W przykładowym rozwiązaniu nazywa się rama_np i przyjmuje dwa argumenty: :n - ile kroków ma wykonać żółw oraz :a - jaki jest rozmiar rysowanego kwadratu.

  1. oto rama_np :n :a
  2.   pod
  3.   ws :a/2 pw 90
  4.   ws :a/2 lw 90
  5.   opu
  6.   powtórz :n [
  7.     wielokąt [
  8.       ukm "czerwony3
  9.       ukp "czerwony3
  10.       powtórz 4 [
  11.         np :a pw 90
  12.       ]
  13.     ]
  14.     pod np :a opu
  15.   ]
  16.   pod
  17.   ws :a/2 pw 90
  18.   np :a/2 lw 90
  19.   opu
  20. już

Początkowo żółw przesuwa się na lewy, dolny róg pierwszego kwadratu, a nastepnie rysuje :n kolejnych kwadratów w kierunku w którym jest ustawiony żółw. Po zakończeniu wraca na środek ostatnio narysowanego kwadratu.

Teraz narysowanie przedstawionego wzorku staje się o wiele prostsze - można się skupić jedynie na wydaniu polecenia narysowania paru kwadratów i obrotu. Obliczana zmienna :a określa rozmiar małego kwadratu.

  1. oto rama
  2.   niech "a 490/49
  3.   pod
  4.   ws 245-:a/2 pw 90
  5.   ws 245-:a/2 lw 90
  6.   powtórz 4 [
  7.     niech "poczatek poz
  8.     pod
  9.     np :a*2 pw 90
  10.     np :a*2 lw 90
  11.     opu
  12.     powtórz 4 [
  13.       rama_np 5 :a pw 90
  14.     ]
  15.     pod
  16.     np :a*2 pw 90
  17.     np :a*2 lw 90
  18.     opu
  19.     rama_np 1 :a
  20.     pod
  21.     ustalPoz :poczatek
  22.     opu
  23.     rama_np 9 :a pw 90
  24.     rama_np 7 :a lw 90
  25.     powtórz 3 [
  26.       niech "poczatek poz
  27.       rama_np 5 :a lw 90
  28.       rama_np 5 :a pw 90
  29.       rama_np 5 :a pw 90
  30.       rama_np 7 :a lw 90
  31.       rama_np 4 :a
  32.       pod
  33.       ustalPoz :poczatek
  34.       pw 90 np :a*2
  35.       lw 90
  36.       opu
  37.       rama_np 7 :a lw 90
  38.       rama_np 5 :a lw 90
  39.       rama_np 5 :a pw 90
  40.       rama_np 5 :a pw 90
  41.       rama_np 9 :a pw 90
  42.       rama_np 7 :a lw 90
  43.     ]
  44.     rama_np 3 :a lw 90
  45.     rama_np 7 :a pw 90
  46.     rama_np 9 :a pw 90
  47.     opu
  48.   ]
  49. już

Cały rysunek składa się z czeterech identycznych części. Z kolei środki boków mają ten sam wzór powtórzony dokładnie trzy razy. Zauważenie tego znacznie skraca długość kodu.

Zadanie 2

Napisz jednoparametrową procedurę/funkcję flaga, po wywołaniu której na ekranie powstanie rysunek taki, jak poniżej. Parametr określa liczbę kolumn tworzących flagę i może przyjmowaćwartości od 2 do 14. Wielkość zielonych i żółtych elementów jest stała, a długość najkrótszego odcinka na ich boku wynosi 8.

Rysunek pomocniczy
flaga 2
flaga 3
flaga 4

Rozwiązanie

Żółty oraz zielony element na rysunku to w rzeczywistości to ta sama figura, ale obrócone są względem siebie o 180 stopni. Pierwszy etap polega na napisaniu metody, która pozwoli na rysować figurę w wybranym przez użytkownika kolorze. Przyjmuje się zgodnie z zadaniem, że bok jednego kwadratu wynosi 8 jednostek.

  1. oto flaga_pom :kolor
  2.   pod
  3.   np 8
  4.   opu
  5.   wielokąt [
  6.     ukm :kolor
  7.     np 16 pw 90
  8.     np 8 lw 90
  9.     np 8 pw 90
  10.     np 32 pw 90
  11.     np 8 lw 90
  12.     np 8 pw 90
  13.     np 8 pw 90
  14.     np 8 lw 90
  15.     np 8 pw 90
  16.     np 8 pw 90
  17.     np 16 lw 90
  18.     np 16 lw 90
  19.     np 8 lw 90
  20.     np 8 pw 90
  21.     np 8 pw 90
  22.     np 8 lw 90
  23.     np 8 pw 90
  24.     np 8 pw 90
  25.     np 8 lw 90
  26.   ]
  27.   pod
  28.   ws 8
  29.   opu
  30. już

Do narysowania jednej kolumny elementów zostanie wykorzystana pętla oraz operacja modulo (tj. reszta z dzielenia). W zależności od parzystości numeru powtórzenia rysujemy zielony bądż żółty element i odpowiednio przesuwamy żółwiem, ale zawsze ustawiamy na koniec żółwia w lewym, dolnym rogu następnej rysowanej figury.

  1. oto flaga_kol :n
  2.   niech "poczatek poz
  3.   powtórz (:n) [
  4.     jeżeli (reszta npw 2 = 1)[
  5.       flaga_pom "zielony3
  6.       pod np 40 opu
  7.     ][
  8.       pod
  9.       np 32 pw 90
  10.       np 48 pw 90
  11.       opu
  12.       flaga_pom "żółty
  13.       pod
  14.       np 8 pw 90
  15.       np 48 pw 90
  16.       opu
  17.     ]
  18.   ]
  19.   pod
  20.   ustalPoz :poczatek
  21.   opu
  22. już

Warto zauważyć, że żółw kończy procedurę w tym samym miejscu co ją zaczyna. Dla uproszczenia powrotu ustalana jest z powrotem pozycja wejściowa.

Mając napisaną funkcję do rysowania kolumn z elementami można przejść do napisania głównej funkcji flaga. Na początek określamy szacunkowe rozmiary figury (ciężko otrzymać dokładne) i przesuwamy żółwia w lewy, dolny róg rysunku i rozpoczynamy rysowanie kolejnych kolumn i odpowidniego przesuwania żółwia.

  1. oto flaga_kol :n
  2.   niech "poczatek poz
  3.   powtórz (:n) [
  4.     jeżeli (reszta npw 2 = 1)[
  5.       flaga_pom "zielony3
  6.       pod np 40 opu
  7.     ][
  8.       pod
  9.       np 32 pw 90
  10.       np 48 pw 90
  11.       opu
  12.       flaga_pom "żółty
  13.       pod
  14.       np 8 pw 90
  15.       np 48 pw 90
  16.       opu
  17.     ]
  18.   ]
  19.   pod
  20.   ustalPoz :poczatek
  21.   opu
  22. już

Zadanie 3

W Turtlandii można płacić monetami o nominałach będących potęgami 3 – 1, 3, 9, 27, ..., itd. Napisz jednoparametrową funkcję ile, której parametrem jest kwota, a wynikiem minimalna liczba monet potrzebnych do zapłacenia tej kwoty. Parametr może przyjmować wartości od 1 do 1 000 000.

ile 293
ile 644

Rozwiązanie

Do rozwiązania tego zadania należy znaleźć jak największą potęgą liczby 3, którą będzie można odjąć od aktualnej kwoty. Następnie tą kwotę odejmujemy tyle ile się da i dzielimy wartość monety o 3 i powtarzamy odejmowanie. W ten sposób gwarantowane jest to, że zostanie użyte jak najmniej monet. Oto przykładowy kod:

  1. oto ile :n
  2.   niech "moneta 1
  3.   niech "ilosc 0
  4.   dopóki[:moneta <= :n][
  5.       niech "moneta :moneta*3
  6.   ]
  7.   dopóki[:moneta > 1][
  8.     niech "moneta :moneta/3
  9.     dopóki[:moneta <= :n][
  10.       niech "n :n - :moneta
  11.       zwiększ "ilosc
  12.     ]
  13.   ]
  14.   wynik :ilosc
  15. już

Ciekawostka: wyznaczenie ile monet potrzeba to w rzeczywistości sumowanie cyfr w systemie trójkowym czyli takim, gdzie występują cyfry 0, 1, 2. Przykładowo 29 to w zapisie trójkowym 1002 (gdyż 1·34 + 2·30 = 29). Suma cyfr liczby 1002 daje 3.