Wieś Logianów postanowiła nawozić swoje pola zgodnie z zasadami rolnictwa precyzyjnego. Za pomocą specjalnych kombajnów zbożowych wyposażonych w mierniki plonów zebrano dane o wysokości zbiorów w różnych częściach logianowskich pól. Następnie opracowano wyniki na komputerze, tworząc barwne mapy plonów. Na podstawie mapy plonów stosuje się zabiegi nawożenia roślin polegające na tym, że te części pola, które mogą wydać większy plon otrzymują odpowiednio wyższe nawożenie, natomiast te, które mają mniejszy potencjał otrzymują odpowiednio mniej. Przyjęto trzy poziomy nawożenia: I - minimalne nawożenie, II - średnie, III - najwyższe.
Każde pole ma wymiary :n na :n jednostek. Dzielimy je na prostokątne obszary, ze względu na poziom nawożenia. Położenie oraz poziom nawożenia obszaru określamy za pomocą pięcioelementowej listy liczb całkowitych. Cztery pierwsze liczby wyznaczają przeciwległe narożniki obszaru i mogą przyjmować wartości z zakresu od 0 do :n, piąta liczba określa poziom nawożenia, może przyjmować wartości z zakresu od 1 do 3. Na przykład lista [0 0 1 2 3] oznacza najwyższy stopień nawożenia górnego lewego kwadratu pola i kwadratu poniżej.
Napisz funkcję ILEN :n :mapa, która wyliczy, jakie części logianowskich pól obejmuje każdy ze stosowanych poziomów nawożenia. Parametr :n określa wielkość pola i może przyjmować wartości od 1 do 10, parametr :mapa jest listą złożoną z list określających położenie oraz poziom nawożenia obszarów. Zakładamy, że wszystkie obszary, które nie są wymienione na liście wymagają minimalnego nawożenia, na liście nie ma też sprzecznych danych. Wynikiem funkcji jest trójelementowa lista liczb określających powierzchnię objętą I, II oraz III poziomem nawożenia.
ILEN 4 [[0 0 4 4 2]] | jest [0 16 0] |
---|---|
ILEN 3 [[0 0 1 1 3][2 2 3 3 2]] | jest [7 1 1] |
ILEN 4 [[0 0 1 2 2][0 1 3 2 2][3 3 4 4 3]] | jest [11 4 1] |
Na początku należy zadeklarować tablicę, która będzie pamiętać jaki poziom nawożenia wymaga każde z pól. Następnie dla każdego określonego obszaru aktualizowane są odpowiednie pola. Na koniec wystarczy wtedy sprawdzić ile razy występuje, która wartość w tablicy, aby uzyskać wynik.
(2.) Tablica dwuwymiarowa jest dla prostoty przetrzymywana jako jednowymiarowa i (3. - 5.) jest ona na początku deklarowana samymi wartościami 1, ponieważ jest to minimalny poziom nawożenia:
(6.) Następnie dla każdego pola: (7. - 12.) pobieramy odpowiednie dane z kolejnego elementu tj. współrzędne początkowe (xp, yp), końcowe (xk, yk) oraz poziom nawożenia pz. Do zapełniania odpowiednich pól została wykorzystana (13. - 23.) podwójna pętla, która przechodzi po kolejnych polach wskazanego obszaru. (17.) Jeśli dane pole ma mniejszy stopień nawożenia niż wskazany to jest (18.) on aktualizowany. Na koniec (25. - 30.) zliczane jest ile jest jakich poziomów nawożenia.
Szyfrujemy słowo zapisując je w formie ślimaka (druga litera nad pierwszą, trzecia po prawej stronie drugiej, czwarta pod trzecią itd. dookoła), a następnie czytamy wierszami od lewej do prawej. Na przykład zapisane w formie ślimaka słowo "abcdefghijklmnopqrstuvwxy odczytamy jako "yjklmxibcnwhadovgfeputsrq.
Napisz funkcję SZYFR :słowa, której daną jest lista słów do zaszyfrowania, a wynikiem jest lista zaszyfrowanych słów według przedstawionego sposobu.
SZYFR [abc defg hijkl] | jest [bca efdg ijhkl] |
---|---|
SZYFR [konkurs logia] | jest [onkksru oglia] |
Szyfrowanie w formia ślimaka opiera się na zasadzie rysowania spirali. Oznacza to, że kolejno przed skrętem w prawo idzie się kolejno 1, 1, 2, 2, 3, 3, 4, 4, ... pól do przodu. Jednak, aby móc poruszać wskaźnik pola po spirali należy mieć jaką planszę - może to być dwuwymiarowa tablica. Dla każdej kolejnej litery będzie wyliczana nowa pozycja i w tym miejscu zostanie umieszczony znak. Na koniec wystarczy przeczytać kolejne wiersze tablicy, aby odczytać wynik.
(3.) Dla każdego słowa przekazanego na liscie słów: (4.) pobieramy kolejny wyraz i (5. - 8.) szukamy takiego boku tablicy dwuwymiarowej tak, aby wszystkie znaki się zmieściły. Następnie (9. - 12.) całą tablicę wypełniamy znakami spacji - później będą one ignorowane podczas odczytywania wyniku. Jest to ważne, ponieważ zwykle znalezione wymiary tablicy są w stanie pomieścić więcej znaków niż ma rozważane słowo. Przed przejściem do uzupełniania tablicy pozostało teraz (13. - 19.) przygotować listę liczb co ile kroków należy skręcić w prawo.
Początkowym (20.) miejscem zapisu jest środek tablicy dwuwymiarowej. Jest to możliwe, ponieważ jej bok zawsze jest nieparzysty. (21.) Dodatkowo zadeklarowane zostały możliwe przesunięcia oraz (22.) które przesunięcie jest aktualnie używane. Na początku (23.) wybieramy, że tylko jedno pole ma zostać zapisane. (24.) Dopóki będą znaki do zapisania to: (25. - 26.) zastąp odpowiednie miejsce w tablicy kolejnym znakiem i (28. - 36.) sprawdź czy nie trzeba odbić w prawo. Warunkiem jest (29.) brak kroków do wykonania. Na koniec iteracji należy pamiętać, aby (37.) zmienić wybrane pole i (38.) usunąć zapisany znak. Na koniec (40. - 45.) zapisane znaki są odczytywane kolejno z tablicy i (46.) zaszyfrowane słowo zostaje dopisane na listę wynikową.
Asia kontynuuje badanie liczb pierwszych. Przeglądając encyklopedię znalazła następującą definicję: "Liczbami pierwszymi lustrzanymi nazywamy pary różnych liczb pierwszych, z których jedna powstaje przez zapisanie cyfr drugiej w odwrotnej kolejności. Dwucyfrowe lustrzane liczby pierwsze to 13 i 31, 17 i 71, 37 i 73, 79 i 97.". Asia zauważyła, że po sklejeniu dwóch lustrzanych liczb pierwszych otrzymuje liczby będące palindromami (nie zmieniają się, gdy ich cyfry zapiszemy w odwrotnej kolejności): 1331, 1771, 3773, 9779. Asia postanowiła poszukać więcej takich liczb.
Pomóż Asi wyszukać sześciocyfrowe liczby palindromiczne, z których każda powstała przez sklejenie pary trzycyfrowych liczb pierwszych lustrzanych. Napisz funkcję LLLP :n, która zbuduje uporządkowaną rosnąco listę złożoną z :n najmniejszych sześciocyfrowych liczb palindromicznych. Zakładamy, że :n nie przekracza liczby wszystkich sześciocyfrowych liczb palindromicznych.
LLLP 0 | jest [] |
---|---|
LLLP 2 | jest [107701 113311] |
W celu rozwiązania zadania najpierw zostaną wyznaczone wszystkie liczby pierwsze trzycyfrowe i na ich podstawie zostaną wyliczone liczby sześciocyfrowe. Po posortowaniu zostanie przepisane jedynie :n pierwszych liczb na listę wynikową.
Do sprawdzenia czy liczba jest pierwsza została napisana specjalna funkcja czyPierwsza, która dla podanej liczby :a zwraca czy wartość logiczną, która określa czy należy ona do zbioru liczb pierwszych.
Z kolei w głównej funkcji (2. - 4.) możemy wykluczyć, gdy :n = 0, ponieważ wtedy zawsze jest zwracana pusta lista. Jeśli jednak :n jest większe od 0 to (5. - 14.) szukamy wszystkich trzycyfrowych liczb pierwszych, a na listę (9. - 11.) zapisujemy gotowe liczby sześciocyfrowe. Używany jest do tego wzór w linijce (10.). Kolejny etap polega na (15.) posortowaniu i (16. - 19.) przepisaniu tylko pierwszych :n wyrazów.
W pewnym mieście, przy pewnym przystanku, pomiędzy godziną 5 a 23, zatrzymują się autobusy dwóch linii autobusowych, o numerach 1 i 2. Autobusy obu linii kursują nie częściej niż co dziesięć minut, a pomiędzy kolejnymi odjazdami autobusów tej samej linii mija parzysta liczba minut.
Rozkład odjazdów jest podany w postaci listy dwuelementowych list i opisuje chronologicznie odjazdy autobusów z dokładnością do jednej minuty. Każda dwuelementowa lista zawiera numer linii i czas odjazdu. Czas odjazdu jest trzycyfrową lub czterocyfrową liczbą, której dwie ostatnie cyfry określają minutę, a pozostałe określają godzinę odjazdu.
Wobec spodziewanego przyjazdu do miasta wielu turystów, prezydent miasta podjął decyzję, że pomiędzy każdymi dwoma odjazdami autobusów tej samej linii pojawi się kolejny, w równym odstępie czasowym od dotychczasowych autobusów tej linii.
Napisz funkcję NRJ :rj, która dla danego rozkładu odjazdów :rj wyliczy nowy rozkład odjazdów, po uwzględnieniu decyzji prezydenta.
Zakładamy, że zarówno dotychczasowy, jak i nowy rozkład odjazdów są tak ułożone, aby w każdej minucie z przystanku odjeżdżał co najwyżej jeden autobus - jeśli pewien dodatkowy odjazd miałby mieć miejsce o tej samej godzinie i minucie, w której odjeżdża z przystanku inny autobus, to odjazd dodatkowego autobusu powinien być o minutę przyspieszony lub opóźniony.
NRJ [[1 700][2 707][1 720]] | jest [[1 700][2 707][1 710][1 720]] |
---|---|
NRJ [[1 701][2 710][1 715][2 720]] | jest [[1 701][1 708][2 710][2 714][1 715][2 720]] albo [[1 701][1 708][2 710][1 715][2 716][2 720]] |
Wyliczanie czasu pomiędzy dwoma czasami jest problematyczne, ponieważ należy obliczyć różnicę minut pomiędzy dwoma czasami, podzielić na dwa i uzyskany wynik dodać do wcześniejszej godziny. Zadanie to można uprościć poprzez możliwość przeliczenia dowolnej godziny na ilość minut, która upłynęła od północy.
W celu poszerzenia rozkładu wystarczy podzielić aktualny rozkład na rozkład każdej z linii. Następnie każdy rozkład rozszerzamy niezależnie tak, aby był posortowany. Mając tak przygotowane nowe rozkłady wystarczy wybierać z każdej listy wcześniejszą godzinę i dopisać do niej numer linii. W przypadku, gdy nie ma mniejszego czasu to znaczy, że są równe i należy je oddzielić o minutę.
Funkcja naMinuty pozwala na zamianę dowolnej godziny na ilość minut, które upłynęły od północy.
Funkcja naCzas konwertuje ilość minut z powrotem na czas z zachowaniem formatu ustalonego w zadaniu.
Funkcja rozszerz dla każdej kolejnej pary czasów przyjazdu autobusu wylicza czas pośredni, a na sam koniec zwraca posortowany rozkład.
Funkcja NRJ rozpoczyna działanie od (2. - 12.) podziału rozkładu na czasy przyjazdu dla każdej z linii, a nastepnie (13. - 14.) na dodaniu dodatkowych kursów.
Dalsza część programu polega na (15. - 30.) wybieraniu wcześniejszego czasu z obu rozkładów, a następnie wstawieniu go w poprawnej formie tj. numer linii i czas przyjazdu. Oczywiście należy pamiętać, że (31. - 38.) po zakończeniu tego fragmentu kody jeden z rozkładów nie będzie pusty, dlatego dla jednego i drugiego należy przepisać pozostałe przyjazdy.