W klasie Oli zapanowała moda na kolorowe szlaczki rysowane w zeszytach. Każdy chciał mieć oryginalny szlaczek wymyślony tylko dla siebie. Ola postanowiła przygotować specjalny program do projektowania szlaczków złożonych z kwadratów w dwóch kolorach. Umówiła się z koleżankami, że otrzyma od nich dwie informacje - wysokość szlaczka oraz opis tworzących go kwadratów. Rysunki wydały jej się smutne, więc postanowiła dodać trzeci kolor - czerwony, w ten sposób, że w tych kolumnach rysowanego szlaczka, w których jest najwięcej szarych kwadratów, zastąpiła je kwadratami czerwonymi.
Pomóż Oli projektować szlaczek i napisz procedurę WZOREK :h :s rysującą na środku ekranu szlaczek o szerokości 600 lub wysokości 400, złożony z szarych, czerwonych i białych kwadratów. Parametr :h określa wysokość szlaczka i może przyjmować wartości od 2 do 20. Parametr :s jest słowem opisującym wygląd szlaczka zgodnie z następującymi zasadami:
Ze względu na fakt, że dane są przekazane kolumna po kolumnie od dołu do góry to rysowanie najlepiej rozpocząć od lewego dolnego rogu. Należy tutaj pamiętać, że rysunek może być pionowo lub poziomo zorientowany, więc należy odpowiednio dobrać rozmiar pól.
Rysowanie całego wzorku warto podzielić na dwa etapy. Pierwszy z nich będzie polegał na narysowaniu szaro-białego wzorku na podstawie kodu. Dopiero potem w drugim etapie wystarczy sprawdzić, które kolumny zamalowane na czerwono i w jakiej części. W celu optymalizacji działania programu w trakcie pierwszego etapu warto na bieżąco zliczać ilość szarych pól w każdej kolumnie oraz szukać maksimum.
Początkowo pobieramy (2.) ilość pól i (3.) wyliczamy ile będzie kolumn. Na tej podstawie (4. - 5.) wyliczamy ile by miały kafelki dopasowane na szerokość i wysokość i (6. - 10.) wybieramy mniejszą wartość. Zagwarantuje to, że rysunek zawsze się zmieści w wyznaczonym obszarze 600×400. Po wyliczeniach (11. - 14.) przechodzimy do rysowania szaro-białych pól.
Przed rysowaniem deklarujemy (15.) listę :szarych na którą będą wrzucane ilości szarych pól w kolejnych kolumnach oraz (16.) :maks, która będzie przechowywać największą ilość szarych pól wśród kolumn. (17. - 46.) Rozpoczynamy proces rysowania; (18.) inicjalizujemy licznik :ile, aby zliczyć szare pola i (19.) wyliczamy przesunięcie względem którego będą odczytywane kolejne wartości. Na koniec (42.) dopisujemy kolejną ilość szarych pól na listę i (43. - 54.) sprawdzamy czy nie padła ich nowa, maksymalna ilość.
(47. - 50.) Wracamy do lewego dolnego rogu, aby jeszcze raz narysować, ale tylko nakładając czerwone pola. W tym celu (51. - 77.) ponownie wykonujemy te same polecenia, ale tylko dla kolumn z taką ilością szarych pól jaką wartość ma maksymalna ich ilość. Podczas rysowania kolumny wystarczy szary kolor zamienić na czerwony, a biały pozostawić bez zmian.
Słowo palindrom pochodzi od greckiego słowa palindromeo - biec z powrotem. Palindrom to takie wyrażenie, które jest identyczne, jeśli czytamy je od lewej do prawej i od prawej do lewej, przykładowo: oko, inni, kajak, inniwinni, kobyłamamałybok.
Napisz funkcję ILEP :s, której wartością jest liczba palindromów zawartych w słowie :s, składającym się jedynie z małych liter.
ILEP "kajak | jest 7, bo kajak zawiera palindromy k, a, j, a, k, aja, kajak |
---|---|
ILEP "mama | jest 6, bo mama zawiera palindromy m, a, m, a, mam, ama |
Szukając palindromów zawartych w słowie :s to wiemy, że musi to być ciąg znaków wyjęty z :s, ale nie może być to np. pierwsza i ostatnia litera, ponieważ nie jest to fragment :s. Strategia polega na znalezieniu wszystkich fragmentów od wartości 1 do długości :s używając do tego podwójnej pętli.
Oto przykładowe rozwiązanie:
Na początku (2.) inicjalizujemy :licznik palindromów i (3.) rozpoczynamy poszukiwania fragmentów. (4.) Pierwsza pętla będzie określać długość szukanego fragmentu. Kolejno to będą 1, 2, .. aż do długości :s. (5.) Dla każdej takiej pętli istnieje odpowiednia ilość fragmentów unikalnych. Numer powtórzenia drugiej pętli określa od którego znaku należy wybrać :ile znaków. Dalsza część jest bardzo prosta: (7. - 10.) wybranie odpowieniego fragmentu oraz (11.) sprawdzenie czy wybrany fragment :t jest palindromem. Jeśli jest to (12.) zwiększamy :licznik, który (16.) na koniec zwracamy.
Pionek porusza się po prostokątnej planszy, w każdym ruchu przesuwając się o jedno pole w jednym z czterech kierunków: w lewo, w prawo, w górę, w dół. Poszczególne pola planszy zawierają cyfry.
Napisz funkcję PIONEK :w :p :c, która dla planszy składającej się z :w wierszy, opisanej słowem :p, wyliczy minimalną liczbę ruchów, jaką musi wykonać pionek, aby przejść pomiędzy dwoma polami zawierającymi cyfrę :c. Słowo :p zawiera ciąg cyfr opisujących zawartość kolejnych pól planszy, wierszami, poczynając od lewego górnego pola. Zakładamy, że cyfra :c występuje na planszy co najmniej dwa razy, a także poprawną długość słowa :p.
PIONEK 1 "444474744474 7 | jest 2, patrz rysunek poniżej |
---|
PIONEK 2 "444474744474 7 | jest 1, patrz rysunek poniżej |
---|
PIONEK 3 "532378832375 5 | jest 5, patrz rysunek poniżej |
---|
Przypiszmy każdemu polu na planszy pewna pozycję tj. punkt w którym dana wartość się znajduje. Następnie należy spisać wszystkie pola na których znajduje się wartość :c. Z tak przygotowanej listy można wybrać wszystkie możliwe pary punktów pomiędzy którymi trzeba przejść. Wtedy należy wybrać wśród takich dróg tą o najmniejszej długości.
Wyliczanie przejścia z punktu (x1, y1) do (x2, y2) to dodanie potrzebnych kroków do przejści w pionie i poziomie. Niezależnie od wybranej ścieżki, ale z każdym krokiem zbliżając się do celu to odległość wynosi |x1 - x2| + |y1 - y2|.
Przykładowa funkcja do wyliczenia odległości pomiędzy punktami dla dwóch pewnych punktów :p1 i :p2 reprezentowanych przez dwuelemementową listę wygląda następująco:
Pierwszy etap polega na znalezieniu wszystkich wartości :c występujących w przekazanym kodzie :p. (8.) Dla każdej takiej wartości na listę :pozycje (9.) wrzucana jest dwuelementowa lista opisująca położenie danego pola.
Z kolei w drugiej części porównywane są odległości pomiędzy każda możliwą parą punktów. (13.) Początkowo za odległość potrzebną do przebycia przypisujemy :h + :w czyli najdłuższa możliwa trasa z jednego kąta mapy do drugiego. Podczas wykonywaine kodu (18.) napotkamy ograniczenie, które optymalizuje działanie programu, bo nie sprawdzamy dwa razy odległości pomiędzy pewnymi punktami :p1 i :p2. Ponadto nie porównujemy dwóch taki samych punktów co by skutkowało zawsze odpowiedzią 0.