-
Notifications
You must be signed in to change notification settings - Fork 0
/
lists.clj
162 lines (135 loc) · 4.53 KB
/
lists.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
(ns ninety-nine-clojure.lists)
(defn last-builtin ([input] (last input)))
(defn my-last [input]
"P01 (*) Find the last element of a list."
(if (next input)
(recur (next input))
(first input)))
(defn my-butlast [xs]
{:doc "P02 (*) Find the last but one element of a list."
:pre [(seq? xs)]}
(loop [ret (first xs) xs xs]
(if (next xs)
(recur (first xs) (next xs))
ret)))
(defn kth-builtin [n xs] (nth xs n))
(defn kth [n xs]
{:doc "P03 (*) Find the Kth element of a list."
:pre [(seq? xs) (< 0 n)]}
(loop [n n xs xs]
(if (= 0 n)
(first xs)
(recur (- n 1) (next xs))))
)
(defn count-builtin [xs] (count xs))
(defn my-count [xs]
"P04 (*) Find the number of elements of a list."
(loop [num 0 xs xs]
(if (next xs)
(recur (+ num 1) (next xs))
(+ num 1))))
(defn my-count-reduce [xs]
"P04 (*) Find the number of elements of a list."
(reduce (fn [c xs] (inc c)) 0 xs))
(defn my-reverse [xs]
"P05 (*) Reverse a list"
(loop [ret [] xs xs]
(if (empty? xs)
ret
(recur (cons (first xs) ret) (next xs)))))
(defn my-reverse-reduce [xs]
"P05 (*) Reverse a list"
(reduce #(cons %2 %1) '() xs))
(defn palindrome? [xs]
"P06 (*) Find out whether a list is a palindrome."
(= xs (reverse xs)))
(defn flatten-recur
"P07 (**) Flatten a nested list structure."
([xs] (flatten-recur [] xs))
([acc xs]
(if-not
(seq? xs) (conj acc xs)
(if (empty? xs)
acc
(-> (flatten-recur acc (first xs))
(flatten-recur (rest xs)))))))
(defn flatten-destructured
"P07 solution I saw on cchandler's github repo"
[x & tail]
(concat (if (seq? x)
(apply flatten-destructured x)
[x])
(if (nil? tail)
nil
(apply flatten-destructured tail))))
(defn flatten-reduce
"P07 solution I saw on rodnaph's github repo "
[xs]
(reduce #(if (seq? %2)
(concat %1 (flatten-reduce %2))
(concat %1 (list %2)))
'() xs))
(defn compress
"P08 (**) Eliminate consecutive duplicates of list elements."
[xs]
(reduce #(if-not (= (last %1) %2)
(conj %1 %2)
%1)
[]
xs))
(defn pack
"P09 (**) Pack consecutive duplicates of list elements into sublists."
[xs]
(partition-by identity xs))
(defn encode
"P10 (*) Run-length encoding of a list.
Use the result of problem P09 to implement the so-called run-length encoding data compression method. Consecutive duplicates of elements are encoded as tuples (N, E) where N is the number of duplicates of the element E."
[xs]
(map #(list (count %) (first %)) (pack xs)))
(defn encode-modified
"P11 (*) Modified run-length encoding.
Modify the result of problem P10 in such a way that if an element has no duplicates it is simply copied into the result list. Only elements with duplicates are transferred as (N, E) terms."
[xs]
(map #(let [num-elems (count %)
a-elem (first %)]
(if (= 1 num-elems)
a-elem
(list num-elems a-elem))) (pack xs)))
(defn decode
"P12 (**) Decode a run-length encoded list.
Given a run-length code list generated as specified in problem P10, construct its uncompressed version."
[xs]
(flatten (map #(repeat (first %) (second %)) xs)))
(defn encode-direct
"P13 (**) Run-length encoding of a list (direct solution).
Implement the so-called run-length encoding data compression method directly. I.e. don't use other methods you've written (like P09's pack); do all the work directly."
[xs]
(map #(list (count %) (first %)) (partition-by identity xs)))
(defn duplicate
"P14 (*) Duplicate the elements of a list."
[xs]
(reduce #(conj %1 %2 %2 ) [] xs ))
(defn duplicate-n
"P15 (**) Duplicate the elements of a list a given number of times."
[n xs]
(reduce #(concat %1 (repeat n %2 )) '() xs))
(defn drop-every
"P16 (**) Drop every Nth element from a list."
[n coll]
(let [drop-lazily (fn drop-lazily [n coll cnt]
(lazy-seq
(cond
(not (seq coll)) []
(= (mod cnt n) 0) (drop-lazily n (rest coll) (inc cnt))
:else (cons (first coll) (drop-lazily n (rest coll) (inc cnt)))) ))]
(drop-lazily n coll 1))
)
(defn drop-every-2
"P16 (**) Drop every Nth element from a list."
[n coll]
(keep-indexed #(if-not (= (mod (inc %1) n) 0) %2) coll))
(defn drop-every-x [lst n]
"P16 solution from rodnaph"
(->> (partition-all n lst)
(map (partial take (dec n)))
(flatten)))