Permalink
Browse files

P18-P23

  • Loading branch information...
1 parent 9676953 commit dcbf43575245728d8ebc6441322ce98757a73f9f @pavelfatin committed Apr 30, 2012
View
@@ -7,5 +7,5 @@
; Without using "repeat", one-pass concatenation
(defn f2 [n l]
(defn prepend [n x xs]
- (if (= n 0) xs (cons x (prepend (dec n) x xs))))
+ (if (zero? n) xs (cons x (prepend (dec n) x xs))))
(reduce #(prepend n %2 %1) '() (reverse l)))
View
@@ -10,7 +10,7 @@
; Recursion with a counter
(defn f3 [n l]
(if (seq l)
- (if (= n 0)
+ (if (zero? n)
['(), l]
(let [[a b] (f3 (dec n) (rest l))]
[(cons (first l) a), b]))
@@ -20,7 +20,7 @@
(defn f4 [n l]
(loop [k n xs l acc '()]
(if (seq l)
- (if (= k 0)
+ (if (zero? k)
[(reverse acc) xs]
(recur (dec k) (rest xs) (cons (first xs) acc)))
[(reverse acc) '()])))
View
@@ -0,0 +1,43 @@
+; P18 Extract a slice from a list.
+
+; Using "take" and "drop"
+(defn f1 [l i k]
+ (drop (dec i) (take k l)))
+
+; Using "split-at"
+(defn f2 [l i k]
+ (second (split-at (dec i) (first (split-at k l)))))
+
+; Recursion
+(defn f3 [l i k]
+ (if (seq l)
+ (if (> i 1)
+ (f3 (rest l) (dec i) (dec k))
+ (if (pos? k)
+ (cons (first l) (f3 (rest l) 1 (dec k)))
+ '()))
+ '()))
+
+; Tail recursion
+(defn f4 [l i k]
+ (loop [acc '() xs l a i b k]
+ (if (seq xs)
+ (if (> a 1)
+ (recur acc (rest xs) (dec a) (dec b))
+ (if (pos? b)
+ (recur (cons (first xs) acc) (rest xs) 1 (dec b))
+ (reverse acc)))
+ (reverse acc))))
+
+; Filter by index
+(defn f5 [l i k]
+ (map first
+ (filter #(>= (second %) i)
+ (map list l (range 1 (inc k))))))
+
+; Folding
+(defn f6 [l i k]
+ (defn f [acc [x n]]
+ (if (>= n i) (cons x acc) acc))
+ (reverse
+ (reduce f '() (map list l (range 1 (inc k))))))
View
@@ -0,0 +1,23 @@
+; P19 Rotate a list N places to the left.
+
+; Using "split-at"
+(defn f1 [n l]
+ (if (seq l)
+ (let [[a b] (split-at (mod n (count l)) l)]
+ (concat b a))
+ '()))
+
+; Without using "let"
+(defn f2 [n l]
+ (if (seq l)
+ (apply concat
+ (reverse (split-at (mod n (count l)) l)))
+ '()))
+
+; Tail recursion
+(defn f3 [n l]
+ (if (and (seq l) (not (zero? n)))
+ (if (pos? n)
+ (recur (dec n) (concat (rest l) (list (first l))))
+ (recur (inc n) (cons (last l) (drop-last l))))
+ l))
View
@@ -0,0 +1,25 @@
+; P20 Remove the K'th element from a list.
+
+; Using "split-at"
+(defn f1 [n l]
+ (let [[a [x & b]] (split-at (dec n) l)]
+ [(concat a b) x]))
+
+; By index (inefficient)
+(defn f2 [n l]
+ [(concat (take (dec n) l) (drop n l)) (nth l (dec n))])
+
+; Recursion
+(defn f3 [n l]
+ (let [[h & t] l]
+ (if (> n 1)
+ (let [[a b] (f3 (dec n) t)]
+ [(cons h a) b])
+ [t h])))
+
+; Tail recursion
+(defn f4 [n l]
+ (loop [acc '() i n [h & t] l]
+ (if (> i 1)
+ (recur (cons h acc) (dec i) t)
+ [(concat (reverse acc) t) h])))
View
@@ -0,0 +1,23 @@
+; P21 Insert an element at a given position into a list.
+
+; Using "split-at"
+(defn f1 [n x l]
+ (let [[a b] (split-at (dec n) l)]
+ (concat a (cons x b))))
+
+; By index (inefficient)
+(defn f2 [n x l]
+ (concat (take (dec n) l) (cons x (drop (dec n) l))))
+
+; Recursion
+(defn f3 [n x l]
+ (if (= n 1)
+ (cons x l)
+ (cons (first l) (f3 (dec n) x (rest l)))))
+
+; Tail recursion
+(defn f4 [n x l]
+ (loop [i n ys l acc '()]
+ (if (= i 1)
+ (concat (reverse acc) (cons x ys))
+ (recur (dec i) (rest ys) (cons (first ys) acc)))))
View
@@ -0,0 +1,22 @@
+; P22 Create a list containing all integers within a given range.
+
+; Predefined function
+(defn f1 [a b]
+ (range a (inc b)))
+
+; As a sum
+(defn f2 [a b]
+ (reductions + a (repeat (- b a) 1)))
+
+; Recursion
+(defn f3 [a b]
+ (if (<= a b)
+ (cons a (f3 (inc a) b))
+ '()))
+
+; Tail recursion
+(defn f4 [a b]
+ (loop [i a, k b, acc '()]
+ (if (>= k i)
+ (recur i (dec k) (cons k acc))
+ acc)))
View
@@ -0,0 +1,14 @@
+; P23 Extract a given number of randomly selected elements from a list.
+
+; Helper function
+(defn remove-at [n l]
+ (let [[a [x & b]] (split-at n l)]
+ [(concat a b) x]))
+
+; Building a target list while removing items from the source (recursively)
+; Time complexity is O(n^2) in worst and average cases, O(n) - in best case
+(defn f1 [n l]
+ (if (pos? n)
+ (let [i (rand-int (count l)), [xs x] (remove-at i l)]
+ (cons x (f1 (dec n) xs)))
+ '()))
View
@@ -0,0 +1,41 @@
+-- P18 Extract a slice from a list.
+
+-- Using "take" and "drop"
+f1 :: [a] -> Int -> Int -> [a]
+f1 xs i k = drop (pred i) $ take k xs
+
+-- Using "splitAt"
+f2 :: [a] -> Int -> Int -> [a]
+f2 xs i k = snd $ splitAt (pred i) $ fst $ splitAt k xs
+
+-- Recursion
+f3 :: [a] -> Int -> Int -> [a]
+f3 [] _ _ = []
+f3 (x:xs) i k
+ | i > 1 = f3 xs (pred i) (pred k)
+ | k > 0 = x : f3 xs 1 (pred k)
+ | otherwise = []
+
+-- Tail recursion
+f4 :: [a] -> Int -> Int -> [a]
+f4 xs i k = reverse $ f [] xs i k
+ where f acc [] _ _ = acc
+ f acc (x : xs) i k
+ | i > 1 = f acc xs (pred i) (pred k)
+ | k > 0 = f (x : acc) xs 1 (pred k)
+ | otherwise = acc
+
+-- Filter by index
+f5 :: [a] -> Int -> Int -> [a]
+f5 xs i k = fst $ unzip $ filter ((>=i) . snd) $ zip xs [1..k]
+
+-- List comprehension
+f6 :: [a] -> Int -> Int -> [a]
+f6 xs i k = [x | (x, n) <- zip xs [1..k], n >= i]
+
+-- Folding
+f7 :: [a] -> Int -> Int -> [a]
+f7 xs i k = foldr f [] $ zip xs [1..k]
+ where f (x, n) acc
+ | n >=i = x : acc
+ | otherwise = acc
View
@@ -0,0 +1,19 @@
+-- P19 Rotate a list N places to the left.
+
+-- Using "splitAt"
+f1 :: Int -> [a] -> [a]
+f1 _ [] = []
+f1 n xs = let (a, b) = splitAt (mod n $ length xs) xs in b ++ a
+
+-- Without using "let"
+f2 :: Int -> [a] -> [a]
+f2 _ [] = []
+f2 n xs = uncurry (flip (++)) $ splitAt (mod n $ length xs) xs
+
+-- Tail recursion
+f3 :: Int -> [a] -> [a]
+f3 _ [] = []
+f3 0 xs = xs
+f3 n xs
+ | n > 0 = f3 (pred n) (tail xs ++ [head xs])
+ | otherwise = f3 (succ n) (last xs : init xs)
View
@@ -0,0 +1,22 @@
+-- Remove the K'th element from a list.
+
+-- Using "splitAt"
+f1 :: Int -> [a] -> ([a], a)
+f1 n xs = let (a, x:b) = splitAt (pred n) xs in (a ++ b, x)
+
+-- By index (inefficient)
+f2 :: Int -> [a] -> ([a], a)
+f2 n xs = (take (pred n) xs ++ drop n xs, xs !! (pred n))
+
+-- Recursion
+f3 :: Int -> [a] -> ([a], a)
+f3 n (x:xs)
+ | n > 1 = let (a, b) = f3 (pred n) xs in (x : a, b)
+ | otherwise = (xs, x)
+
+-- Tail recursion
+f4 :: Int -> [a] -> ([a], a)
+f4 = f []
+ where f acc n (x:xs)
+ | n > 1 = f (x : acc) (pred n) xs
+ | otherwise = (reverse acc ++ xs, x)
View
@@ -0,0 +1,20 @@
+-- P21 Insert an element at a given position into a list.
+
+-- Using "splitAt"
+f1 :: Int -> a -> [a] -> [a]
+f1 n x ys = let (a, b) = splitAt (pred n) ys in a ++ x : b
+
+-- By index (inefficient)
+f2 :: Int -> a -> [a] -> [a]
+f2 n x ys = take (pred n) ys ++ x : drop (pred n) ys
+
+-- Recursion
+f3 :: Int -> a -> [a] -> [a]
+f3 1 x ys = x : ys
+f3 n x (y:ys) = y : f3 (pred n) x ys
+
+-- Tail recursion
+f4 :: Int -> a -> [a] -> [a]
+f4 = f []
+ where f acc 1 x ys = reverse acc ++ x : ys
+ f acc n x (y:ys) = f (y:acc) (pred n) x ys
View
@@ -0,0 +1,36 @@
+-- P22 Create a list containing all integers within a given range.
+
+import Data.List
+
+-- Predefined function
+f1 :: Int -> Int -> [Int]
+f1 = enumFromTo
+
+-- Range syntax
+f2 :: Int -> Int -> [Int]
+f2 a b = [a..b]
+
+-- A part of an infinite list
+f3 :: Int -> Int -> [Int]
+f3 a b = take (succ b - a) $ iterate succ a
+
+-- Unfolding
+f4 :: Int -> Int -> [Int]
+f4 a b = unfoldr (\n -> if (n <= b) then Just (n, succ (n)) else Nothing) a
+
+-- As a sum
+f5 :: Int -> Int -> [Int]
+f5 a b = scanl (+) a $ replicate (b - a) 1
+
+-- Recursion
+f6 :: Int -> Int -> [Int]
+f6 a b
+ | a <= b = a : f6 (succ a) b
+ | otherwise = []
+
+-- Tail recursion
+f7 :: Int -> Int -> [Int]
+f7 = f []
+ where f acc a b
+ | b >= a = f (b : acc) a (pred b)
+ | otherwise = acc
View
@@ -0,0 +1,15 @@
+-- P23 Extract a given number of randomly selected elements from a list.
+
+import System.Random
+
+-- Building a target list while removing items from the source (recursively)
+-- Time complexity is O(n^2) in worst and average cases, O(n) - in best case
+f1 :: RandomGen g => g -> Int -> [a] -> [a]
+f1 _ 0 _ = []
+f1 g n xs = let (i, g') = randomR (0, length xs - 1) g
+ (xs', x) = rm i xs
+ in x : f1 g' (pred n) xs'
+
+-- Helper function
+rm :: Int -> [a] -> ([a], a)
+rm n xs = let (a, x:b) = splitAt (pred n) xs in (a ++ b, x)
View
@@ -35,7 +35,7 @@
return f4_inner(List.<T>nil(), n, list);
}
- <T> Pair<List<T>, List<T>> f4_inner(List<T> acc, int n, List<T> list) {
+ private <T> Pair<List<T>, List<T>> f4_inner(List<T> acc, int n, List<T> list) {
return list.isEmpty()
? pair(acc.reverse(), List.<T>nil())
: n == 0 ? pair(acc.reverse(), list) : f4_inner(cons(list.head(), acc), n - 1, list.tail());
Oops, something went wrong.

0 comments on commit dcbf435

Please sign in to comment.