"The Grid. A digital frontier. I tried to picture clusters of information as they move through the computer. What did they look like? Ships? Motorcycles? Were the circuits like freeways? I kept dreaming of a world I thought I’d never see. And then, one day, I got in." — Tron: Legacy

2012-12-08

Clojure Easy 2


"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
                             (recur (inc c) 
                                    (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
             (recur (inc c) (conj acc c)))))

Brak komentarzy:

Prześlij komentarz