kernelp4nic
5/9/2014 - 4:46 AM

Clojure learning

Clojure learning

(defproject toto "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.5.1"]])
;
; The Joy of Clojure
;

; usamos "when" si no tenemos condicion de else
(defn print-down-from [x]
    (when (pos? x)
        (println x)
        (recur (dec x))))

;
(defn sum-down-from [sum x]
    (if (pos? x)
        ; "x" es positivo, hacemos tail rec
        (recur (+ sum x) (dec x))
        ; "x" ya no es positivo (else) retornamos "sum"
        sum))

;
(defn sum-down-from [initial-x]
    ; inicializamos "sum" y "x"
    ; cuando "recur" llama al "loop"
    ; estos parametros se vuelven a inicializar
    ; con los que "recur" pasó
    (loop [sum 0, x initial-x]
        (if (pos? x)
            ; "recur" siempre vuelve para atras
            ; hasta que encuentra un "loop" o un "fn"
            (recur (+ sum x) (dec x))
            ; "sum" es el valor de retorno de todo el loop
            sum)))

(defn absolute-value [x]
  (if (pos? x)
    x           ; "then"
    (- x)))     ; "else"

; destructuring
; guys-whole-name -> ["Seba" "Martin" "Moreno"]
(let [[f-name m-name l-name] guys-whole-name]
          (str l-name ", " f-name " " m-name))

; seq
(defn print-seq [s]
  (when (seq s)
    (prn (first s))
    (recur (rest s))))


(defn l [s]
  ( nth (count s)))

; walk a macro

(use 'clojure.walk)
(macroexpand-all 'codigo)

; Factorial
(defn fact[x]
  ((fn [n so_far]
    (if (<= n 1)
        so_far
        (recur (dec n) (* so_far n)))) x 1))
;
; 4clojure.com
;

; stupid keyboard:
;  < >

(= [:a :b :c] (list :a :b :c) (vec '(:a :b :c)) (vector :a :b :c))
(= 20 ((hash-map :a 10, :b 20, :c 30) :b))
(= 8 ((fn add-five [x] (+ x 5)) 3))
(= ((fn d [x] (* x 2)) 2) 4)
(= ((fn [name] ( str "Hello, " name "!" )) "Dave") "Hello, Dave!")
(= '(6 7 8) (map #(+ % 5) '(1 2 3)))
(= '(6 7) filter #(> % 5) '(3 4 5 6 7))

;----------------------------------------------
;
; #19 - Write a function which returns the last element in a sequence.
;
;(= ___ [1 2 3 4 5]) 5)

(fn l [s]
  ( nth s (- (count s) 1 )))

;
; guilespi
;
;(fn [s]
;  (let [p (rest s)]
;  (if (empty? p)
;      (first s)
;       (recur p))))

; pcl / nikelandjelo / daowen
; (fn [x] (first (reverse x)))
; #(first (reverse %))
; reduce #(-> %2)

;----------------------------------------------
;
; #20 - Write a function which returns the second to last element from a sequence.
;(= ___ [1 2 3 4 5]) 4)

((defn l [s]
 ( nth s (- (count s) 2 )))

; Other solutions
;
; (fn [x] (first (rest (reverse x))))
; #(last (butlast %))
; #(nth (reverse %1) 1)


;----------------------------------------------
;
; #21 - Write a function which returns the Nth element from a sequence.
;(= (__ '(4 5 6 7) 2) 6)

(defn _nth [s at]
  (loop [i 0, r s]
    (if (= i at)
      (first r)
      (recur (+ i 1) (rest r)))))

(_nth [1 2 3] 3)

;(fn [s n]
;  (first (drop n s)))

; guilespi
;
; (fn [s, index]
;   (if (= index 0)
;       (first s)
;       (recur (rest s) (- index 1))))


;----------------------------------------------
;
; #22 - Write a function which returns the total number of elements in a sequence.
;
; (= (__ '(1 2 3 3 1)) 5)

(defn seq-length [s]
  (loop [sum 0, r s]
    (if (seq r)
      (recur (+ sum 1) (rest r))
      sum)))

; others
;
; (fn [s]
; (reduce + (map (constantly 1) s)))

;
; pcl's solution:
;
; reduce (fn [m i] (+ m 1)) 0


;----------------------------------------------
;
; #23 - Write a function which reverses a sequence.
; (= (__ [1 2 3 4 5]) [5 4 3 2 1])

(defn r [s]
 "reverse the collection passed as parameter"
 (into () s ))

; guilespi
; (fn [s]
;   (loop [se s resto []]
;   (if (empty? se)
;        resto
;        (recur (rest se) (cons (first se) resto)))))


;----------------------------------------------
; # 24 Write a function which returns the sum of a sequence of numbers.
; (= (__ [1 2 3]) 6)
;
(defn sum-seq [s]
  (loop [sum 0, r s]
    (if (seq r)
      (recur (+ (first r) sum) (rest r))
      sum)))

;(for [x [1 2]] (+ x 1))

;----------------------------------------------
; # 25 - Write a function which returns only the odd numbers from a sequence.
; (= (__ #{1 2 3 4 5}) '(1 3 5))
(defn get-odds [s]
 (for [x s :when (odd? x)] x))

;----------------------------------------------
; # 26 - Write a function which returns the first X fibonacci numbers.
; (= (__ 6) '(1 1 2 3 5 8))

(defn fib [n]
 (loop [v [1 1]]
  (if (= (count v) n) v ; return vector
    (recur (conj v (+ (last v) (nth v (- (count v) 2))) )))))

; guilespi
;#(take % (map (fn fib [x]
;   (cond
;    (= x 0) 0
;    (= x 1) 1
;    :else (+ (fib (- x 1)) (fib (- x 2)))
;    )
;   ) (iterate inc 1)))

;----------------------------------------------
; # 27 - Write a function which returns true if the given sequence is a palindrome.
; (false? (__ '(1 2 3 4 5)))
; (true? (__ "racecar"))

(defn p?[s]
 ; recursive palindrome detection
 (cond  (<= (count s) 1) true
        (= (first s) (last s))
            (recur (butlast (rest s)))
        :else false))

;
;(defn is-palindrome? [s]
; (= (seq s) (reduce conj () s)))
;
;#(= (seq %) (reverse %))

;----------------------------------------------
; 28 - Write a function which flattens a sequence.
; forbidden: flatten
;
;(= (__ '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6))
;(= (__ ["a" ["b"] "c"]) '("a" "b" "c"))

(defn flat [s]
  (let [l (first s) r (next s)]
    (concat
      (if (sequential? l)
        (flat l)
        [l])
      (when (sequential? r)
        (flat r)))))

;(defn flt [s]
;   (if (sequential? s)
;     (mapcat flt s)
;     (list s)))

; guilespi
; (fn flat [lst]
; (lazy-seq
;   (if (empty? lst) lst
;       (let [[x & xs] lst]
;         (if (coll? x)
;           (concat (flat x) (flat xs))
;           (cons x (flat xs)))))))

; daowen's
; (fn flat [x] (if (coll? x) (mapcat flat x) [x]))

;----------------------------------------------
; 29 - Write a function which takes a string and returns a new string containing only the capital letters.
;(= (__ "HeLlO, WoRlD!") "HLOWRD");
;(empty? (__ "nothing"))

(defn upper [s]
 (apply str (filter #(Character/isUpperCase %) s)))

; #(apply str (re-seq #"[A-Z]" %))


;----------------------------------------------
; 30 - Write a function which removes consecutive duplicates from a sequence.
;
;(= (apply str (__ "Leeeeeerrroyyy")) "Leroy")
;(= (__ [1 1 2 3 3 2 2 3]) '(1 2 3 2 3))

(defn dupes [s]