6年前に出された問題なのですが、面白そうだし、未だに @cielavenir さんが異なる言語で回答を出し続けているようなので、その様子を見て、私もやってみたくなりました。
言語は Uncle Bob が最近注目しているらしい Clojure にしてみました。
「多段階選抜」の問題はここです。
(改変)solve-1
で うっかり solve-1
で再起してしまっていたので、recur
に改めました。
(defn square? [n]
(let [sq (Math/floor (Math/sqrt n))]
(== (* sq sq) n)))
(defn cube? [n]
(let [cb (Math/floor (Math/cbrt n))]
(== (* cb cb cb) n)))
(defn numbers
([] (numbers 1))
([n] (lazy-seq (cons n (numbers (inc n))))))
(defn drop-before [test coll]
(let [f (fn [test coll]
(let [a (first coll)
bs (rest coll)]
(if (test (first bs))
(recur test bs)
(cons a (drop-before test bs)))))]
(lazy-seq (f test coll))))
(defn drop-after [test coll]
(lazy-seq
(let [a (first coll)
bs (rest coll)]
(cons a
(if (test a)
(drop-after test (rest bs))
(drop-after test bs))))))
(defn drop-nth [n coll]
(lazy-cat (take (dec n) coll) (drop-nth n (drop n coll))))
(defn solve-1 [cs coll]
(if (empty? cs)
coll
(let [c (first cs)
cs (rest cs)]
(recur
cs
(case c
\s (drop-before square? coll)
\S (drop-after square? coll)
\c (drop-before cube? coll)
\C (drop-after cube? coll)
\h (drop 100 coll)
(drop-nth (- (long c) 48) coll))))))
(defn solve [cmds]
(let [cs (seq cmds)
ns (numbers)
answer (->> (solve-1 cs ns)
(take 10)
(clojure.string/join ","))]
(println answer)))
(solve "ss6cc24S")
(solve "4scC3hh982Cc5s")