Zacznij od implementacji funkcji
def peak(list: List[Int]): Option[Int]
, która zwróci pojedynczy element listy, który jest większy niż jego sąsiedzi, np. peak(List(1, 2, 3, 5, 2))
zwróciłoby Some(5)
, ale już peak(List.range(0, 5))
zwróci None
.Już? Gotowe? Test przechodzi? Zatem kolejne zadanko.
Następnie przejdź do implementacji funkcji
def raisePeak(list: List[Int]): Option[List[Int]]
, która znajdzie "peak" wyżej, ale zwróci nową listę z tym elementem zwiększonym o jeden.Już? Nie za szybko?! :-)
Na pewno dostrzegłeś, że funkcja
raisePeak
znacząco się skomplikowała i to może być ten moment, kiedy zechcesz wejść w świat struktury danych zwanej Zipper. Zanim jednak zdecydujesz się na własną implementację w Scali proponuję zajrzeć do wpisu Zippers in Scala. Ciekawie poprowadzony "wykład", w którym znajdziesz nie tylko rozwiązania tych dwóch problemów powyżej, ale również daje pogląd na problem, który rozwiązują zipper'y."Zippers in Scala" nazwałbym inspirującą lekturą, która kształtuje mój światopogląd scalowy. Mnie natchnął do dalszego zgłębienia tematu zipper'ów. Ktoś już nad tym ślęczał? Jakie wrażenia?
Spoiler: https://gist.github.com/nurkiewicz/5014040
OdpowiedzUsuńTwoja implementacja peak jest bardzo elegancka, nie znałem sliding - tu jest idealne. Natomiast raisePeak nie robi to co ma robić, raisePeak(List(1, 2, 5, 3)) ma zwracać List(1, 2, 6, 3), a Twoja implementacja zwraca Some(List(6))
UsuńCo ma zwrócić peak(List(1, 2, 4, 3, 5, 2))?
OdpowiedzUsuńPowiedzmy, że Some(4), bo w innym przypadku możemy nigdy nie otrzymać odpowiedzi, kiedy lista będzie nieskończona.
Usuń