# pavelfatin/ninety-nine

P18-P23

1 parent 9676953 commit dcbf43575245728d8ebc6441322ce98757a73f9f committed Apr 30, 2012
 @@ -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)))
 @@ -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) '()])))
 @@ -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))))))
 @@ -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))
 @@ -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])))
 @@ -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)))))
 @@ -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)))
 @@ -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))) + '()))
 @@ -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
 @@ -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)
 @@ -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)
 @@ -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
 @@ -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
 @@ -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)
 @@ -35,7 +35,7 @@ return f4_inner(List.nil(), n, list); } - Pair, List> f4_inner(List acc, int n, List list) { + private Pair, List> f4_inner(List acc, int n, List list) { return list.isEmpty() ? pair(acc.reverse(), List.nil()) : n == 0 ? pair(acc.reverse(), list) : f4_inner(cons(list.head(), acc), n - 1, list.tail());