Permalink
Browse files

P11-P15

  • Loading branch information...
1 parent aa2fd1d commit a1efe056ea90d846f2ecc16dc10e50f7850b90cb @pavelfatin committed Jan 14, 2012
View
@@ -12,4 +12,4 @@
; Folding
(defn f2 [l]
- (reduce (fn [_ b] b) l0))
+ (reduce (fn [_ b] b) l))
View
@@ -7,5 +7,6 @@
; Recursion with "split-with"
(defn f1 [l]
(if (seq l)
- (let [h (first l) t (rest l) [a b] (split-with #(= % h))]
- (cons (cons h a) (f1 b)))))
+ (let [h (first l) t (rest l) [a b] (split-with #(= % h) t)]
+ (cons (cons h a) (f1 b)))
+ '()))
View
@@ -0,0 +1,5 @@
+; P11 Modified run-length encoding.
+
+(defn f1 [l]
+ (defn f [x] (if (= 1 (first x)) (second x) x))
+ (map f l))
View
@@ -0,0 +1,15 @@
+; P12 Decode a run-length encoded list.
+
+; Mapping
+(defn f1 [l]
+ (defn f [x] (if (seq? x) (repeat (first x) (second x)) x))
+ (flatten (map f l)))
+
+; Recursion
+(defn f2 [l]
+ (if (seq l)
+ (let [h (first l) t (rest l)]
+ (if (seq? h)
+ (concat (repeat (first h) (second h)) (f2 t))
+ (cons h (f2 t))))
+ '()))
View
@@ -0,0 +1,23 @@
+; P13 Run-length encoding of a list (direct solution).
+
+; Factory function
+(defn encode [n x]
+ (if (= 1 n) x (list n x)))
+
+; Using "split-with", so there's still some kind of sublists
+(defn f1 [l]
+ (if (seq l)
+ (let [h (first l) t (rest l) [a b] (split-with #(= % h) t)]
+ (cons (encode (inc (count a)) h) (f1 b)))
+ '()))
+
+; Recursion, "look-behind"
+(defn f2 [l]
+ (defn f [n x xs]
+ (if (seq xs)
+ (let [y (first xs) ys (rest xs)]
+ (if (= y x)
+ (f (inc n) y ys)
+ (cons (encode n x) (f 1 y ys))))
+ (list (encode n x))))
+ (if (seq l) (f 1 (first l) (rest l)) '()))
View
@@ -0,0 +1,46 @@
+; P14 Duplicate the elements of a list.
+
+; Recursion
+(defn f1 [l]
+ (if (seq l)
+ (cons (first l)
+ (cons (first l) (f1 (rest l))))
+ '()))
+
+; Direct tail recursion (inefficient)
+(defn f2 [l]
+ (loop [acc '() xs l]
+ (if (seq xs)
+ (recur
+ (concat acc (list (first xs) (first xs)))
+ (rest xs))
+ acc)))
+
+; Tail recursion with "reverse"
+(defn f3 [l]
+ (loop [acc '() xs l]
+ (if (seq xs)
+ (recur
+ (cons (first xs) (cons (first xs) acc))
+ (rest xs))
+ (reverse acc))))
+
+; Direct left folding (inefficient)
+(defn f4 [l]
+ (reduce #(concat %1 (list %2 %2)) '() l))
+
+; Left folding with reverse
+(defn f5 [l]
+ (reduce #(cons %2 (cons %2 %1)) '() (reverse l)))
+
+; Map then flatten
+(defn f6 [l]
+ (flatten (map #(list %1 %1) l)))
+
+; Using "mapcat"
+(defn f7 [l]
+ (mapcat #(list %1 %1) l))
+
+; With "repeat"
+(defn f8 [l]
+ (mapcat #(repeat 2 %) l))
View
@@ -0,0 +1,11 @@
+; P15 Replicate the elements of a list a given number of times.
+
+; Replicate then mapcat
+(defn f1 [n l]
+ (mapcat #(repeat n %) l))
+
+; 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))))
+ (reduce #(prepend n %2 %1) '() (reverse l)))
View
@@ -0,0 +1,10 @@
+-- P11 Modified run-length encoding.
+
+module P11 where
+
+data Entry a = Value a | Sequence Int a deriving Show
+
+f1 :: [(Int, a)] -> [Entry a]
+f1 = map toEntry
+ where toEntry (1, x) = Value x
+ toEntry (n, x) = Sequence n x
View
@@ -0,0 +1,17 @@
+-- P12 Decode a run-length encoded list.
+
+module P12 where
+
+data Entry a = Value a | Sequence Int a deriving Show
+
+-- Using concatMap
+f1 :: [Entry a] -> [a]
+f1 = concatMap toItems
+ where toItems (Value v) = [v]
+ toItems (Sequence n v) = replicate n v
+
+-- Recursion
+f2 :: [Entry a] -> [a]
+f2 [] = []
+f2 ((Value v) : xs) = v : f2 xs
+f2 ((Sequence n v) : xs) = replicate n v ++ f2 xs
View
@@ -0,0 +1,30 @@
+-- P13 Run-length encoding of a list (direct solution).
+
+module P13 where
+
+data Entry a = Value a | Sequence Int a deriving Show
+
+-- Factory function
+makeEntry :: Int -> a -> Entry a
+makeEntry 1 a = Value a
+makeEntry n a = Sequence n a
+
+-- A simple solution, but there's still some kind of sublists
+f1 :: Eq a => [a] -> [Entry a]
+f1 [] = []
+f1 (x:xs) = let (a, b) = span (== x) xs in
+ makeEntry (succ $ length a) x : f1 b
+
+-- Recursion, "look-ahead"
+f2 :: Eq a => [a] -> [Entry a]
+f2 [] = []
+f2 xs = f 1 xs
+ where f n [x] = [makeEntry n x]
+ f n (a:bs@(b:_)) = if a == b then f (succ n) bs else makeEntry n a : f 1 bs
+
+-- Recursion, "look-behind"
+f3 :: Eq a => [a] -> [Entry a]
+f3 [] = []
+f3 (x:xs) = f 1 x xs
+ where f n x [] = [makeEntry n x]
+ f n x (y:ys) = if y == x then f (succ n) y ys else makeEntry n x : f 1 y ys
View
@@ -0,0 +1,42 @@
+-- P14 Duplicate the elements of a list.
+
+-- Recursion
+f1 :: [a] -> [a]
+f1 [] = []
+f1 (x:xs) = x : x : f1 xs
+
+-- Direct tail recursion (inefficient)
+f2 :: [a] -> [a]
+f2 = f []
+ where f acc [] = acc
+ f acc (x:xs) = f (acc ++ [x, x]) xs
+
+-- Tail recursion with "reverse"
+f3 :: [a] -> [a]
+f3 = reverse . f []
+ where f acc [] = acc
+ f acc (x:xs) = f (x : x : acc) xs
+
+-- Right folding
+f4 :: [a] -> [a]
+f4 = foldr (\x xs -> x : x : xs) []
+
+-- Direct left folding (inefficient)
+f5 :: [a] -> [a]
+f5 = foldl (\xs x -> xs ++ [x, x]) []
+
+-- Left folding with reverse
+f6 :: [a] -> [a]
+f6 = reverse . foldl (\xs x -> x : x : xs) []
+
+-- Map with "replicate" then concatenate
+f7 :: [a] -> [a]
+f7 = concat . map (replicate 2)
+
+-- Using concatMap
+f8 :: [a] -> [a]
+f8 = concatMap (\x -> [x, x])
+
+-- Using concatMap with "replicate"
+f9 :: [a] -> [a]
+f9 = concatMap (replicate 2)
View
@@ -0,0 +1,21 @@
+-- P15 Replicate the elements of a list a given number of times.
+
+-- Using concatMap and replicate
+f1 :: Int -> [a] -> [a]
+f1 n xs = concatMap (replicate n) xs
+
+-- With function composition
+f2 :: Int -> [a] -> [a]
+f2 = concatMap . replicate
+
+-- Without "replicate" (folding with concatenation)
+f3 :: Int -> [a] -> [a]
+f3 n = foldr ((++).(rep n)) []
+ where rep 0 _ = []
+ rep n x = x : rep (pred n) x
+
+-- More efficient version (one-pass concatenation)
+f4 :: Int -> [a] -> [a]
+f4 n = foldr (prepend n) []
+ where prepend 0 _ xs = xs
+ prepend n x xs = x : prepend (pred n) x xs
View
@@ -4,7 +4,7 @@
import core.Pair;
import static core.List.*;
-import static core.Pair.pair;
+import static core.Pair.*;
class P10 {
// Recursion
View
@@ -0,0 +1,26 @@
+// P11 Modified run-length encoding.
+
+import core.List;
+import core.Pair;
+
+import static core.List.*;
+import static core.Pair.*;
+
+class P11 {
+ // Recursion, list of objects
+ @SuppressWarnings("unchecked")
+ <T> List f1(List<Pair<Integer, T>> list) {
+ if (list.isEmpty()) return nil();
+ Pair<Integer, T> h = list.head();
+ return cons(h.getA().equals(1) ? h.getB() : h, f1(list.tail()));
+ }
+
+ // Imperative, list of objects
+ @SuppressWarnings("unchecked")
+ <T> List f2(List<Pair<Integer, T>> list) {
+ List acc = nil();
+ for (Pair<Integer, T> each : list)
+ acc = cons(each.getA().equals(1) ? each.getB() : each, acc);
+ return acc.reverse();
+ }
+}
View
@@ -0,0 +1,24 @@
+// P12 Decode a run-length encoded list.
+
+import core.List;
+import core.Pair;
+
+import static core.List.*;
+import static core.Pair.*;
+
+class P12 {
+ // Imperative, list of objects
+ @SuppressWarnings("unchecked")
+ List f1(List list) {
+ List acc = nil();
+ for (Object each : list) {
+ if (each instanceof Pair) {
+ Pair<Integer, Object> pair = (Pair<Integer, Object>) each;
+ acc = concat(List.replicate(pair.getA(), pair.getB()), acc);
+ } else {
+ acc = cons(each, acc);
+ }
+ }
+ return acc.reverse();
+ }
+}
View
@@ -0,0 +1,37 @@
+// P13 Run-length encoding of a list (direct solution).
+
+import core.List;
+
+import static core.List.*;
+import static core.Pair.*;
+
+class P13 {
+ // Imperative, list of objects
+ @SuppressWarnings("unchecked")
+ List f1(List list) {
+ if (list.isEmpty()) return nil();
+
+ List acc = nil();
+ Object x = list.head();
+ int n = 1;
+
+ for (Object each : list.tail()) {
+ if (each.equals(x)) {
+ n++;
+ } else {
+ acc = cons(makeValue(n, x), acc);
+ x = each;
+ n = 1;
+ }
+ }
+
+ acc = cons(makeValue(n, x), acc);
+
+ return acc.reverse();
+ }
+
+ // Factory method
+ private Object makeValue(int n, Object x) {
+ return n == 1 ? x : pair(n, x);
+ }
+}
Oops, something went wrong.

0 comments on commit a1efe05

Please sign in to comment.