"If I had a nickel for every time I've written "for (i = 0; i < N; i++)" in C I'd be a millionaire."
- Mike Vanier
Taka mała zagadka: Ilu programistów .NET potrzeba, by zabić karalucha?
(odpowiedź na końcu wpisu.).
Problem 27: for the win
Makro to bierze za pierwszy argument wektor powiązań (podobnie jak let i opcjonalnie trzy modyfikatory:
- :let [ powiązania dla dodatkowych zmiennych pomocniczych ]
- :when ( test ) - zmienne w iteracji zostaną przekazane po spełnieniu testu
- :while ( test ) - for zakończy działanie po negatywnym wyniku testu
Powiązania (nie dotyczy :let) muszą być sekwencjami np.: (for [x '(3 4) z [1 2]] (...) ). Elementy sekwencji będą łączone na zasadzie każdy z każdym. To jest dla każdego elementu x zostanie przypisany każdy element z i taka postać przekazana jako parametry do bloku wykonania. Blok wykonania zwraca wartość, z której po każdej iteracji będzie budowana sekwencja. Tak, że for służy do budowania sekwencji na podstawie innych sekwencji.
W teście T1 mam for, które będzie się wykonywać dla każdego x z sekwencji zbudowanej przy pomocy funkcji range). W tym przypadku range zwróci kolekcję liczb od 0 do 39 włącznie z krokiem 1. Iterując po każdym elemencie zostaje sprawdzony warunek :when, który zwraca prawdę jeżeli reszta z dzielenia elementu x kolekcji przez 4 (funkcja rem będzie równa 1. Dzięki temu zostanie zbudowana kolekcja elementów, których reszta z dzielenia przez 4 jest 1. Wynik w ostateczności powinien wyglądać tak: (1 5 9 13 17 21 25 29 33 37).
W teście T2 x jest nieskończoną kolekcją zwróconą przez funkcję iterate. Funkcja ta bierze za pierwszy argument funkcję, a za drugi wartość początkową. Funkcja anonimowa zwraca wartość argumentu powiększonego o 4. Stąd x będzie mieć postać: (0 4 8 12 ... ). Modyfikator :let tworzy zmienną pomocniczą z, która będzie mieć wartość elementu x powiększonego o 1. Modyfikator :while sprawdza, czy z jest mniejsze od 40, jeżeli nie, to kończy działanie for
W teście T3 for iteruje po parach liczb utworzonych poprzez utworzenie kolekcji liczb
(0 1 2 3 ... 19) podzielonej na kolekcję dwuelementowych list : ( (0 1) (2 3) (4 5) .... (18 19) ).
Wynikiem jest lista, której elementy to sumy par liczb.
Pary i większe kolekcje liczb można przypisywać do zmiennych lokalnych w rózny sposób, np:
| (let [ x 1 y 2 ] (+ x y)) | 
| (let [ [x y] '(1 2) ] (+ x y)) | 
| (let [ x (first '(1 2)) y (second '(1 2)) ] (+ x y)) | 
| T1: (= __ (for [x (range 40)            :when (= 1 (rem x 4))]        x))T2: (= __ (for [x (iterate #(+ 4 %) 0)            :let [z (inc x)]            :while (< z 40)]        z))T3: (= __ (for [[x y] (partition 2 (range 20))]        (+ x y)))E1: '(1 5 9 13 17 21 25 29 33 37).E2: [1 5 9 13 17 21 25 29 33 37]. | 
Problem 28: Logical falsity and truth
| T1: (= __ (if-not false 1 0))T2: (= __ (if-not nil 1 0))T3: (= __ (if true 1 0))T4: (= __ (if [] 1 0))T5: (= __ (if [0] 1 0))T6: (= __ (if 0 1 0))T7: (= __ (if 1 1 0)) E1: 1 | 
Problem 29: Map defaults
| (:k {:a 0, :b 1, :c nil} :not_exist) | 
A co jeżeli chcemy utworzyć mapę i nadać kluczom jakaś domyślną wartość?
Zadanie polega na utworzeniu funkcji, która pobierze sekwencję kluczy, wartość domyślną i utworzy z nich mapę. Mapę w najprostszy sposób tworzy się poprzez (hash-map klucz dane) lub {klucz dane}. Wiadomo, że przez elementy sekwencji można iterować przez użycie map lub for. Funkcja map bierze za parametr funkcję, którą stosuje dla każdego elementu sekwencji. Stąd mając domyślą wartość klucza i sekwencję kluczy można zwrócić sekwencję map. Złączyć to można poleceniem conj i funkcją apply lub reduce.
Rozpiszę główne etapy:
1. map ... : ({:a 0} {:b 0} {:c 0})
2. apply conj ... : {:a 0 :b 0 :c 0}
z czego apply tworzy listę w sposób: (conj {:a 0} {:b 0} {:c 0})
reduce: (conj {:a 0} {:b 0}) -> (conj {:a 0 :b 0} {:c 0}) ...
Zadanie:
| (= (__ 0 [:a :b :c]) {:a 0 :b 0 :c 0})(= (__ "x" [1 2 3]) {1 "x" 2 "x" 3 "x"})(= (__ [:a :b] [:foo :bar]) {:foo [:a :b] :bar [:a :b]})E1: #(reduce conj (map (fn [d] {d %1}) %2))E2: #(apply conj (map (fn [d] {d %1}) %2)) | 
Odpowiedź na zagadkę: Dwóch. Jeden trzyma karalucha, by nie uciekł, a drugi instaluje na nim Windows.
 
Brak komentarzy:
Prześlij komentarz