"The computing scientist’s main
challenge is not to get confused by the complexities of his own
making."
--- E. W. Dijkstra
Czas na kolejną część
zagadek ze strony 4clojure.com.
Problem 9: Fibonacci
Sequence
Zadanie polega na napisaniu
funkcji, która zwróci n pierwszych elementów ciągu Fibonacci.
Funkcja w E1 bierze za
parametr szukaną liczbę elementów ciągu. Dla pierwszego i
drugiego elementu zwracane są wartości bezpośrednio. Dla dalszych
obliczane są kolejne elementy na podstawie dwóch pierwszych
elementów listy acc. W pętli
zwiększany jest licznik c i dodawana do początku listy acc suma
dwóch poprzednich elementów. Trzeba pamiętać, że funkcja conj
dodaje elementy do list od lewej strony, dlatego aby uzyskać
poprawną odpowiedź trzeba acc
odwrócić przed zwrotem. Odpowiedź E2 jest z wykorzystaniem
wektora.
T1:
(=
(__
3) '(1
1 2))
T2:
(=
(__
6) '(1
1 2 3 5 8))
T3:
(=
(__
8)
'(1
1 2 3 5 8 13 21))
E1:
(fn
fiblist [n]
(let
[a '(1)
b '(1 1)]
(cond
(=
n 1) a
(=
n 2)
b
:else
(loop
[c 2 acc b]
(if
(>=
c n)
(reverse
acc)
(recur
(inc
c)
(conj
acc (+
(first
acc)
(second
acc)))))))))
E2 : (fn
fiblist [n]
(let
[a [1] b [1 1]]
(cond
(=
n 1) a
(=
n 2)
b
:else
(loop
[c 2 acc b]
(if
(>=
c n)
acc
acc
(recur
(inc
c)
(conj acc (+ (acc (- c 1)) (acc (- c 2))))))))))
(conj acc (+ (acc (- c 1)) (acc (- c 2))))))))))
Problem 10: Maximum value
Zadanie polega na napisaniu funkcji,
która zwróci parametr o największej wartości.
Haczyk: nie można użyć funkcji max i
max-key.
Zanim podam wynik wyjaśnię na przykładzie jak to jest z przekazywaniem argumentów do funkcji:
=> ((fn f [a b & more] more) 1 2 3 4)
(3
4)
=>
((fn
f [a & more] more)
1 2 3 4)
(2
3 4)
=>
((fn
f [& more] more)
1 2 3 4)
(1
2 3 4)
Przed znakiem & argumenty przypisywane są jak leci 1 do a, 2 do b, itd. Po znaku & reszta argumentów traktowana jest jako lista. W przypadku braku identyfikatorów przed & wszystkie argumenty traktowane są jako lista. Oczywiście a, b, more i args mogą mieć dowolne nazwy.
T1:
(=
(__
1 8 3 4)
8)
T2:
(=
(__
30 20) 30)
T3:
(=
(__
45 67 11)
67)
E1:(fn
maxx [& args]
(loop
[e (first
args)
re (rest
args)
mx e]
(if
(empty?
re)
mx
(recur
(first
re)
(rest
re)
(if
(>
e mx)
e mx)))))
Problem 11: Get the Caps
Zadanie: Znaleźć funkcję, która z
podanego łańcucha znaków zwróci łańcuch zawierający tylko
wielkie litery. Łańcuchy tekstowe w Clojure to zwykłe String z
Javy, więc będą na nich działać funkcje z Javy. Aby dostać
listę wielkich liter trzeba przefiltrować tekst za pomocą funkcji
filter, którą następnie
trzeba złączyć w napis przy użyciu funkcji str
i apply.
T1:
(=
(__
"HeLlO, WoRlD!")
"HLOWRD")
T2:
(empty?
(__
"nothing"))
T3:
(=
(__
"$#A(*&987Zf")
"AZ")
E1:
#(apply
str (filter
(fn
[c] (Character/isUpperCase
c))
%))
Problem 12: Intro to some
Należy podać wynik działania funkcji
some. Funkcja ta bierze za
pierwszy parametr funkcję, która zwraca logiczną prawdę lub fałsz
, oraz kolekcję, której elementy będą przekazywane do tej
funkcji. Jeżeli wynikiem działania funkcji będzie true
to zostanie zwrócony pierwszy element dla którego warunek został
spełniony.
T1:
(=
__ (some
#{2 7 6} [5 6 7 8]))
T2:
(= __ (some
#(when
(even?
%) %)
[5 6 7 8]))
E1:
6
Problem 13: Duplicate a sequence
Zadanie polega na napisaniu funkcji,
która powtórzy elementy sekwencji dwukrotnie.
T1:
(=
(__
[1 2 3])
'(1 1 2 2 3
3))
T2:
(=
(__
[:a :a
:b :b])
'(:a
:a :a
:a :b
:b :b
:b))
T3:
(=
(__
[[1 2] [3 4]])
'([1 2] [1
2] [3 4] [3 4]))
E1:
#(if
(empty?
%1) []
(loop
[a (first
%1) r (rest
%1) ac [a
a]]
(if
(empty?
r) ac
(let
[s (first
r)]
(recur
s (rest
r)
(conj
ac s s))))))
E2:
#(interleave
%1 %1)
Problem 14: Implement range
Zadanie polega na napisaniu
odpowiednika funkcji range .
T1:
(=
(__
1 4)
'(1
2 3))
T2:
(=
(__
-2 2) '(-2
-1 0 1))
T3:
(=
(__
5 8)
'(5
6 7))
E1:
(fn
[s e]
(loop
[c s acc []]
(if
(>= c e)
acc
acc
(recur
(inc
c)
(conj
acc c)))))
Brak komentarzy:
Prześlij komentarz