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

Logia 2012/13 Etap II

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

Zadanie 1 (Mozaika)

Nowe budynki w Logianowie będą ozdobione mozaikami układanymi z kwadratowych kafelków w kolorach: czerwonym (c), zielonym (z), czarnym (x), białym (b) i fioletowym (f). Mozaiki są układane na podstawie kolorowych szablonów. Twórca szablonów jest miłośnikiem Juliusza Cezara i postanowił przy ich przygotowywaniu wykorzystać szyfr Cezara, polegający na cyklicznym zastępowaniu każdej kolejnej litery w alfabecie, literą występującą dalej o określoną liczbę pozycji, przy czym jeśli wykraczamy poza alfabet, to kolejne litery bierzemy z początku alfabetu.

Napisz procedurę MOZAIKA :kolory :klucz :wiersz, po wywołaniu której na środku ekranu powstanie rysunek mozaiki, o szerokości 600 lub wysokości 300, opisanej przez parametry:

  • słowo :kolory określa kolory (alfabet) używane w danym szablonie oraz ich kolejność, kolory nie powtarzają się
  • liczba :klucz definiuje sposób zastępowania kolorów i może przyjmować wartości od 0 do 100
  • niepuste słowo :wiersz, które opisuje dolny wiersz mozaiki i może zawierać jedynie kolory wymienione w parametrze :kolory

Każdy kolejny wiersz powstaje przez zaszyfrowanie poprzedniego wiersza. Liczba wierszy jest o jeden większa od długości parametru :kolory. Na przykład dla alfabetu "xfzb i klucza 6, wiersz "xxxfffbbbxxx przechodzi w wiersz "zzzbbbfffzzz.

W tabelce poniżej umieszczono przykłady zastępowania kolorów.

:kolory:kluczprzed zastępieniempo zastąpieniu
"xfzb6czarnyzielony
"xfzb6fioletowybiały
"xfzb6zielonyczarny
"xfzb6białyfioletowy
:kolory:kluczprzed zastępieniempo zastąpieniu
"bzx1białyzielony
"bzx1zielonyczarny
"bzx1czarnybiały

MOZAIKA "xfzb 6 "xxxfffbbbxxx
MOZAIKA "bzx 1 "bzxzb

Rozwiązanie

Na początku ustalmy wartości zmiennych pomocniczych. Po pierwsze rozpoznawanie koloru pisaka będzie odbywać się poprzez wyszukanie pozycji koloru (2.) w zmiennej :nazwyKol. Znaleziony indeks posłuży do wybrania (3.) odpowiedniej nazwy koloru z listy. Następnie (4.) tworzymy zmienną, która będzie przechowywać ile kolorów zostało wybranych (dla uproszczenia zapisu kodu) oraz to (5.) ile będzie faktycznie wierszy miał obraz wynikowy. To samo robimy dla (6.) ilości kolumn. Kolejny etap polega na (7. - 13.) dopasowaniu rozmiaru pojedynczego kwadratu do obszaru rysowania. Potem (14. - 17.) należy przesunąć żółwia w lewy dolny róg rysunku.

  1. oto MOZAIKA :kolory :klucz :wiersz
  2.   niech "nazwyKol "czxbf
  3.   niech "listaKol [czerwony zielony czarny biały fioletowy]
  4.   niech "dlKolory długość :kolory
  5.   niech "poziomów (długość :kolory) + 1
  6.   niech "kolumn (długość :wiersz)
  7.   niech "h 300/:poziomów
  8.   niech "w 600/:kolumn
  9.   jeżeli(:h < :w) [
  10.     niech "a :h
  11.   ][
  12.     niech "a :w
  13.   ]
  14.   pod
  15.   ws :a*:poziomów/2 pw 90
  16.   ws :a*:kolumn/2 lw 90
  17.   opu

Druga część kodu przedstawia rysowanie kolejnych poziomów rysunku. Na początku każdego poziomu (19. - 29.) rysowany jest aktualny wiersz. Potem (30. - 31.) należy przejść na następny poziom. W każdej iteracji pozostaje jeszcze (32. - 40.) przygotować następny wiersz. Początkowo jest on przechowywany w tymaczasowej zmiennej :s, aby potem go przepisać do zmiennej :wiersz na podstawie której wartości rysowane są kolejne poziomy rysunku.

  1.   powtórz (:poziomów) [
  2.     powtórz (:kolumn) [
  3.       niech "nrKol numel (element npw :wiersz) :nazwyKol
  4.       wielokąt [
  5.         ukm (element :nrKol :listaKol)
  6.         powtórz 4 [
  7.           np :a pw 90
  8.         ]
  9.       ]
  10.       pw 90 np :a
  11.       lw 90
  12.     ]
  13.     pw 90 ws :a*:kolumn
  14.     lw 90 np :a
  15.     niech "s "
  16.     powtórz (:kolumn) [
  17.       niech "el element npw :wiersz
  18.       niech "poz numel :el :kolory
  19.       niech "poz reszta ((:poz - 1) + :klucz) :dlKolory
  20.       niech "t element (:poz + 1) :kolory
  21.       niech "s (słowo :s :t)
  22.     ]
  23.     niech "wiersz :s
  24.   ]
  25. już

Zadanie 2 (Ślimak)

Napisz funkcję KIEDY :x :y :z, której wynikiem będzie liczba określająca, którego dnia ślimak znajdzie się na szczycie dziesięciometrowego słupa. Ślimak pierwszego dnia startuje u podstawy słupa. Każdego dnia wspina się o :x centymetrów. Każdej nocy osuwa się o :y centymetrów, chyba że natrafi na półkę - wtedy zatrzymuje się na niej. Półki znajdują się co :z centymetrów, licząc od podstawy słupa. Zakładamy, że :x jest większe od :y.

KIEDY 300 100 100jest 4
KIEDY 5 3 2jest 250

Rozwiązanie

Rozwiązanie polega na zastosowaniu nieskończonej pętli oraz liczników, które będą pamiętać (3.) ile dni już upłynęło oraz (2.) gdzie znajduje się ślimak (tj. jakiej wysokości).

  1. oto KIEDY :x :y :z
  2.   niech "ile 0
  3.   niech "dni 0
  4.   dopóki [:ile < 1000][
  5.     zwiększ "dni
  6.     niech "ile :ile + :x
  7.     niech "półka (int(:ile/:z))*:z
  8.     niech "ile :ile - :y
  9.     jeśli (:ile < :półka) [
  10.       niech "ile :półka
  11.     ]
  12.   ]
  13.   wynik :dni
  14. już

(4.) W pętli dopóki ślimak nie osiągnie szczytu: (5.) rozpoczynamy dzień i (6.) symulujemy wspinaczke do góry. Następnie (7.) obliczamy pozycje najbliższej półki. Po wyliczeniu możemy (8.) opuścić ślimaka w dół o :y cm, ale (9.) sprawdzamy czy według obliczeń ślimak nie minął półki. Jeśli tak to (10.) ustalamy jego wysokość na pozycję półki. Na koniec (13.) zwracamy ile :dni ślimak wędrował na szczyt.

Zadanie 3 (Pascal)

Trójkąt Pascala to trójkątna tablica liczb, skonstruowana w następujący sposób: na dwóch bokach trójkąta znajdują się jedynki, liczby wewnątrz trójkąta są sumą dwóch najbliższych liczb położonych w wierszu powyżej.

Ola podaje Antkowi dwie liczby: numer wiersza oraz pozycję w obrębie wiersza. Zadaniem Antka jest podanie odpowiedniej liczby w trójkącie Pascala. Pomóż Antkowi i napisz funkcję PASCAL :w :p. Parametr :w określa numer wiersza i może przyjmować wartości od 1 do 2000. Parametr :p określa pozycję liczby w wierszu i może przyjmować wartości od 1 do 4, a także od :w-3 do :w, przy czym :w nie jest mniejsze od :p.

PASCAL 5 3 jest 6
PASCAL 10 7 jest 84

Rozwiązanie

Wartości trójkąta Pascala można wyliczać ze wzoru rekurencyjnego. Każdy wyraz trójkąta to suma elementów znajdujących się nad nim na prawo oraz lewo. Dokładne informacje można znaleźć w artykule o Trójkącie Pascala. Poniższy kod to zastosowanie wspomnianej wskazówki:

  1. oto PASCAL :w :p
  2.   jeżeli (LUB (:p = 1) (:p = :w)) [
  3.     wynik 1
  4.   ][
  5.     wynik (PASCAL :w-1 :p-1) + (PASCAL :w-1 :p)
  6.   ]
  7. już