Open27
trying 4ever-clojure
Problem 29, Get the Caps
((fn [word] (apply str (filter #(Character/isUpperCase %) word))) "HeLlO, WoRlD!")
これだと、Could not resolve symbol: Character/isUpperCase
となってしまう
なので愚直な感じにした
(fn [word] (apply str (filter #(contains? (set "ABCDEFGHIJKLMNOPQRSTUVWXYZ") %) word)))
containsはsetに変換してから使う必要がある
Problem 30, Compress a Sequence
reduce #(if (= (last %1) %2) %1 (conj %1 %2)) []
他の解答例も見てみたけど、reduce使うのが一番シンプルっぽい
Problem 31, Pack a Sequence
partition-by identity
全然検討つかなくてChatGPTに聞いた。
そしたら関数をpartition-by
の関数を教えてくれた。
こんな関数あるんだなあ。
Problem 32, Duplicate a Sequence
reduce #(concat %1 (take 2 (repeat %2))) []
Problem 33, Replicate a Sequence
(fn [list n]
(reduce #(concat %1 (take n (repeat %2))) [] list))
Problem 39, Interleave Two Seqs
(fn [a-list b-list]
(flatten (map #(list %1 %2) a-list b-list)))
- mapに渡せるシーケンスは2つ以上も可能
- これを直接やってくれる、interleaveという関数もある
Problem 40, Interpose a Seq
(fn [divider a-seq]
(reduce
#(conj %1 divider %2)
[(first a-seq)]
(rest a-seq)))
- interposeはこれをやってくる関数
Problem 41, Drop Every Nth Item
(fn [dropped-seq target]
(keep-indexed #(when (not= (mod (inc %1) target) 0) %2) dropped-seq))
filter-indexed的なメソッドを探したら代わりに見つかったのがkee-indexed
elseでnullを返すケースは、ifよりもwhenを使った方が良さそう
Problem 42, Factorial Fun
(fn [n] (reduce * 1 (range 1 (inc n))))
Problem 43, Reverse Interleave
(fn [a-seq size]
(map
(fn [x] (filter #(= (mod % size) x) a-seq))
(range size)))
これだと、最初の例の出力が((2 4 6) (1 3 5))
と逆になってしまう
なので、Problem 42 を参考に、keep-indexed
を使う形に
(fn [a-seq size]
(map
(fn [x] (keep-indexed #(when (= (mod %1 size) x) %2) a-seq))
(range size)))
Problem 44, Rotate Sequence
(fn [n a-seq]
(as-> (mod n (count a-seq)) index
(concat
(subvec (vec a-seq) index)
(subvec (vec a-seq) 0 index))))
Problem 46, Flipping out
(fn [f] (fn [& args] (apply f (reverse args))))
applyする必要がある
Problem 49, Split a sequence
(fn [pos a-seq]
(list (subvec a-seq 0 pos) (subvec a-seq pos)))
Problem 50, Split by Type
単純にtypeでgroup-byすると、マップになる
(group-by type [1 :a 2 :b 3 :c])
> {java.lang.Long [1 2 3], clojure.lang.Keyword [:a :b :c]}
これをvaluesだけのシーケンスにすればいいから
(fn [a-seq] (vals (group-by type a-seq)))
Problem 53, Longest Increasing Sub-Seq
(fn [a-seq]
(as-> a-seq result
(reduce
#(let [last-sub-seq (last %1)]
(if (= (last last-sub-seq) (dec %2))
(assoc %1 (dec (count %1)) (conj last-sub-seq %2))
(conj %1 [%2])))
[[(first result)]]
(rest result))
(reduce #(if (< (count %1) (count %2)) %2 %1) [] result)
(if (< (count result) 2) [] result)))
Problem 54, Partition a Sequence
(fn [size a-seq]
(filter
#(>= (count %) size)
(vals (group-by #(quot % size) a-seq))))
Problem 55, Count Occurences
(fn [a-seq]
(as-> a-seq result
(group-by identity result)
(into {} (map #(hash-map (first %) (count (second %))) result))))
Problem 56, Find Distinct Items
reduce
#(if (contains? (set %1) %2) %1 (conj %1 %2))
[]
Problem 58, Function Composition
(fn [& functions]
(fn [& args]
(reduce
(fn [result f] (f result))
(apply (last functions) args)
(rest (reverse functions)))))
Problem 59, Juxtaposition
(fn [& functions]
(fn [& args]
(map #(apply % args) functions)))
Problem 60, Sequence Reductions
(fn my-reductions
([a-fn a-seq] (my-reductions a-fn (first a-seq) (rest a-seq)))
([a-fn acc a-seq]
(lazy-seq
(if (empty? a-seq)
[acc]
(let [result (a-fn acc (first a-seq))]
(cons acc (my-reductions a-fn result (rest a-seq))))))))
最初はreduce使おうとしていたけど、reduceはlazyなseqを返さないからうまく行かず。。
試行錯誤してもうまくいかず、最後は解答例を参考に。
Problem 61, Map Construction
(fn [keys values]
(into {} (map #(hash-map %1 %2) keys values)))
Problem 62, Re-implement Iteration
(fn my-iterate [f x]
(lazy-seq
(cons x (my-iterate f (f x)))))
Problem 63, Group a Sequence
(fn [grouping-fn a-seq]
(reduce
(fn [acc current]
(let [group (grouping-fn current)]
(assoc acc group (vec (conj (acc group) current)))))
{}
a-seq))
Problem 65, Black Box Testing
(fn [a-seq]
(let [empty-seq (empty a-seq)
foo-bar-seq (conj empty-seq [:foo :bar])]
(cond
(= :bar (:foo foo-bar-seq)) :map
(= (count foo-bar-seq) (count (conj foo-bar-seq [:foo :bar]))) :set
(= :bar (first (conj foo-bar-seq :bar))) :list
(= :bar (last (conj foo-bar-seq :bar))) :vector
:else :unknown)))
いい方法が思い浮かばなかったので、解答例を参考にした
Problem 66, Greatest Common Divisor
(fn [x y]
(apply max (filter
#(and (= 0 (mod x %)) (= 0 (mod y %)))
(range 1 (inc (min x y))))))
Prime Numbers
(fn [size]
(take size (filter
(fn [num]
(and
(< 1 num)
(empty? (filter
(fn [divisor] (= 0 (mod num divisor)))
(range 2 (inc (quot num 2)))))))
(range))))