Open27

trying 4ever-clojure

むらむーむらむー

Problem 29, Get the Caps

https://4clojure.oxal.org/#/problem/29

((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 43, Reverse Interleave

https://4clojure.oxal.org/#/problem/43

(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 50, Split by Type

単純にtypeでgroup-byすると、マップになる

https://4clojure.oxal.org/#/problem/50

(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

https://4clojure.oxal.org/#/problem/53

(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 60, Sequence Reductions

https://4clojure.oxal.org/#/problem/60

(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 65, Black Box Testing

https://4clojure.oxal.org/#/problem/65

(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)))

いい方法が思い浮かばなかったので、解答例を参考にした