Strona główna » Poradniki » Logomocja » LOGIA » Logia 2013/14 Etap II
 

Logia 2013/14 Etap II

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

Zadanie 1 (Szyfr schodkowy)

Kolejnym literom alfabetu łacińskiego odpowiadają obrazki przedstawione na rysunkach poniżej:

Napisz dwuparametrową procedurę/funkcję szyfruj, której efektem wywołania jest rysunek odpowiadający słowu (pierwszemu parametrowi funkcji). Słowo składa się z małych liter alfabetu łacińskiego (od 2 do 20 znaków). Drugi parametr to liczba naturalna (od 2 do 20), oznaczająca wysokość tworzonych schodków. Rysunek powinien być na środku ekranu i mieć kształt schodków, jak w przykładach. Szerokość rysunku wynosi 760 lub wysokość wynosi 480.

szyfruj "dokumentygoogle 5
szyfruj "programowanie 5

Rozwiązanie

Element

Rozpocznijmy omawianie rozwiązanie od rysowania pojedynczego elementu. Jak wynika z rysunku kolejne elementy zielony są rysowane po spirali - w prawo i do środka. Można zauważyć, że przed zmianą kierunku rysowania najpierw trzeba przejść 5, potem 4, 4, 3, 3,.. elementów. Podane wielkości można zapamiętać (2.) na liście. Następnie (3.) zielonych elementów będzie tyle co odległość danej litery od litery a. Następnie przyjmujemy, że (4.) rysujemy pierwszy kwadrat elementu.

  1. oto szyfruj_el :a :c
  2.   niech "lista [5 4 4 3 3 2 2 1 1]
  3.   niech "ile ((ascii :c) - (ascii "a))
  4.   niech "i 1
  5.   powtórz (długość :lista) [
  6.     powtórz (element npw :lista) [
  7.       jeżeli (:i <= :ile) [
  8.         ukm "oliwkowy
  9.       ][
  10.         ukm "biały
  11.       ]
  12.       wielokąt [
  13.         powtórz (4) [np :a pw 90]
  14.       ]
  15.       np :a
  16.       zwiększ "i
  17.     ]
  18.     pw 90 np :a
  19.   ]
  20.   ws :a*3 lw 90
  21.   ws :a*3
  22. już

(5.) Dalsza część kodu polega na pobieraniu kolejnej ilości i (6. - 17.) narysowaniu tylu kwadratów w lini prostej, a potem (18.) obrotu w prawo, aby narysować kolejny fragment. Na koniec (20. - 21.) należy wrócić do punktu wyjścia.

Funkcja główna

Teraz można przejść do głównej procedury. Na początku należy (2. - 10.) wyliczyć rozmiar pojedynczego kwadratu, który będzie narysowany. W tym miejscu należy pamiętać, że trzeba wybrać dopasowanie do określonej wysokości lub szerokości. Potem wystarczy (11. - 14.) przejść do lewego, dolnego rogu rysunku.

  1. oto szyfruj :s :n
  2.   niech "p :n
  3.   niech "wDół "prawda
  4.   niech "aw 760 / (długość :s)
  5.   niech "ah 480 / :n
  6.   jeżeli (:ah < :aw) [
  7.     niech "a :ah
  8.   ][
  9.     niech "a :aw
  10.   ]
  11.   pod
  12.   ws :a*:n/2 pw 90
  13.   ws :a*(długość :s)/2 lw 90
  14.   opu
  15.   powtórz (długość :s) [
  16.     niech "el element npw :s
  17.     powtórz (:n) [
  18.       jeżeli (npw = :p) [
  19.         szyfruj_el :a/5 :el
  20.       ][
  21.         wielokąt [
  22.           ukm "biały
  23.           powtórz 4 [np :a pw 90]
  24.         ]
  25.       ]
  26.       np :a
  27.     ]
  28.     jeżeli (:wDół) [
  29.       zmniejsz "p
  30.       jeśli (:p = 1) [
  31.         niech "wDół "fałsz
  32.       ]
  33.     ][
  34.       zwiększ "p
  35.       jeśli (:p = :n) [
  36.         niech "wDół "prawda
  37.       ]
  38.     ]
  39.     ws :a*:n pw 90
  40.     np :a lw 90
  41.   ]
  42. już

(15.) Dla każdego elementu ze słowa: (16.) pobierz element, (17. - 27.) narysuj wszystkie kwadraty w pionie wstawiając w odpowiednie miejsce kwadrat szyfrujący. Następnie (28. - 38.) odpowiednio wylicz wysokość na której znajduje się kolejny kwadrat szyfrujący. Polega to na tym, że zmienna :wDół określa kierunek przejścia i jeśli dojdziemy do krawędzi to zmieniamy kierunek na przeciwny. Po narysowaniu każdej kolumny (39. - 40.) przejdź do następnej.

Zadanie 2 (Pole robota)

Robot chodzi po płaszczyźnie, w każdym kroku przebywa jednostkową odległość w jednym z czterech podstawowych kierunków: góra, dół, prawo, bądź lewo, które oznaczone są, odpowiednio, literami g, d, p oraz l.

Napisz funkcję poler, której parametrem jest słowo określające trasę robota, a wynikiem – pole najmniejszego prostokąta, o pionowych i poziomych bokach, zawierającego całą trasę.

poler "ggdpjest 2
poler "lllgpddddjest 12

Rozwiązanie

Wyznaczenie najmniejszego pola polega na wyznaczeniu jak daleko robota zajdzie w każdym z czterech kierunków. W tym celu przyjmijmy, że (2. - 7.) wszystkie wartości początkowo wynoszą zero.

  1. oto poler :trasa
  2.   niech "xmin 0
  3.   niech "xmax 0
  4.   niech "ymin 0
  5.   niech "ymax 0
  6.   niech "x 0
  7.   niech "y 0
  8.   powtórz (długość :trasa) [
  9.     wybierz (element npw :trasa) [
  10.       g [
  11.         zwiększ "y
  12.         jeśli (:y > :ymax) [
  13.           niech "ymax :y
  14.         ]
  15.       ]
  16.       d [
  17.         zmniejsz "y
  18.         jeśli (:y < :ymin) [
  19.           niech "ymin :y
  20.         ]
  21.       ]
  22.       p [
  23.         zwiększ "x
  24.         jeśli (:x > :xmax) [
  25.           niech "xmax :x
  26.         ]
  27.       ]
  28.       l [
  29.         zmniejsz "x
  30.         jeśli (:x < :xmin) [
  31.           niech "xmin :x
  32.         ]
  33.       ]
  34.     ]
  35.   ]
  36.   wynik (:xmax - :xmin)*(:ymax - :ymin)
  37. już

Potem (9. - 34.) w zależności od kierunku przesunięcia aktualizujemy aktualną pozycję robota (x, y) i jeśli zmieni się któryś z parametrów min/max to go zmieniamy. Na koniec (36.) należy zwrócić iloczyn różnic dla każdej współrzędnej pomiędzy wartością maksymalną i minimalną.

Zadanie 3 (Gwiazda)

Gwiazdowo ma promienistą strukturę ulic, co powoduje, że z każdej dzielnicy istnieje tylko jedna droga do Centrum. Każdy mieszkaniec zna drogę i koszt dojazdu ze swojej dzielnicy do Centrum. Są one zakodowane słowem składającym się z par złożonych z litery oznaczającej dzielnicę i cyfry określającej koszt przejazdu kolejnego odcinka. Na przykład, jeśli takim kodem jest D3E5J8, to odczytujemy, że łączny koszt dojazdu z D do Centrum to 3+5+8=16.

Napisz dwuparametrową funkcję kosp, której wynikiem jest minimalny koszt zorganizowania spotkania dwóch mieszkańców miasta (czyli łączny koszt ich dojazdu do określonej dzielnicy). Oba parametry są słowami, oznaczającymi drogę i koszt dojazdu do Centrum, odpowiednio, każdego z dwóch mieszkańców.

kosp "D3E5J8 "H3I2E4J6jest 8 (wyjaśnienie rys. 1)
kosp "A3T5U6 "B4G1Y4jest 23 (wyjaśnienie rys. 2)
rys. 1
rys. 2

Strategia

Zadanie można podzielić na dwie części: pierwsza z nich polega na wyznaczeniu miejsca spotkania, a druga na zsumowaniu wartości przebycia z punktu początkowego do drugiego. Wynik końcowy to suma wartości przejazdu jednego i drugiego mieszkańca do wyznaczonego wcześniej punktu docelowego.

Rozwiązanie

Miejsce spotkania

W celu wyznaczenia miejsca spotkanie należy sprawdzić, który element się powtarza na obu opisanych trasach. Realizuje to poniższy kod:

  1. oto kosp_spotkanie :trasa1 :trasa2
  2.   powtórz (długość :trasa1)/2 [
  3.     niech "i 2*npw - 1
  4.     niech "el element :i :trasa1
  5.     jeśli (numel :el :trasa2 > 0) [
  6.       wynik :el
  7.     ]
  8.   ]
  9.   wynik "
  10. już

Koszt przejazdu

Funkcja kosp_sumuj sumuje koszt przejazdu z punktu początkowego do punktu spotkania.

  1. oto kosp_sumuj :trasa :stop
  2.   niech "suma 0
  3.   powtórz (długość :trasa)/2 [
  4.     niech "i 2*npw
  5.     jeśli (element :i-1 :trasa = :stop) [
  6.       wynik :suma
  7.     ]
  8.     niech "suma :suma + (element :i :trasa)
  9.   ]
  10.   wynik :suma
  11. już

Funkcja główna

Główna funkcja kosp to zaledwie dwie linijki, ponieważ w pierwszej wyznaczamy punkt docelowy spotkania, a w drugiej sumujemy koszt przejazdu dla każdego z mieszkańców.

  1. oto kosp :trasa1 :trasa2
  2.   niech "cel kosp_spotkanie :trasa1 :trasa2
  3.   wynik (kosp_sumuj :trasa1 :cel) + (kosp_sumuj :trasa2 :cel)
  4. już