Arantium Maestum

プログラミング、囲碁、読書の話題

アルゴリズム

Clojureで動的計画法を使ってKnapsack Problemを解いてみる

Project Eulerの31問と同じような動的計画法を使ったナップサック問題の解き方。 m kgまで入るカバンと、n個のモノがある。 モノiはx-i kgでy-i円の価値がある。 カバンに入り、価値の合計が最大になるモノの組み合わせは何か。 まずはデータ構造の定義。 (d…

Clojureでアルゴリズムまとめ

ソート selection sort insertion sort bubble sort 1/ 2/ 3 merge sort 1 2 quick sort bucket sort radix sort

Clojureで基数ソート

Radix Sortとも。 バケツソートのバケツ数を制限して、そのかわり複数回走らせることで すでにバケツソートを書いたので実装は比較的楽。 (defn radix-sort [xs] (let [bucket-count 100 buckets (into [] (repeat bucket-count [])) max-item (apply max xs…

Clojureでバケツソート

正の整数のシーケンスxsをO(n+m)時間でソートする方法としてBucket Sortがある。 0からxsの最大値mまで番号が付けられているvector of vectorを作成して、xsの全要素を一つずつ対応するvectorに入れていく。あとはconcatするだけ。 (defn bucket-sort [xs] (…

clojureでバブルソート3

あやぴーさんのご指摘を参考に、バブルソートをいろいろ(主に名前を)いじってみる。 最終的にはremainingのdestructuringを後に遅らせた方が、実際に使うところの近くで定義されるのでわかりやすいんじゃないか、ということに。 (def max-min (juxt max mi…

Clojureでバブルソート2

そういえばClojureのsequenceはvectorじゃない場合は大抵countがO(n)だった。 bubble-sortでO(n)回bubbleを呼び、bubble内でO(n)回再帰して、その中でO(1)の作業だったはずが、(cond (>= i (count xs)))でもう一回O(n)の作業を入れていたのでO(n3)になる。 …

Clojureでバブルソート

とりあえず書きなぐったもの。 (defn bubble [xs i] (loop [left [] x1 (first xs) [x2 & right :as xs] (rest xs)] (cond (>= i (count xs)) (doall (concat left [x1] xs)) :else (let [[maxx minx] ((juxt max min) x1 x2)] (recur (conj left minx) maxx…

Clojureでインサーションソート

例によってソート実装。これは面白かった。 とりあえず書いてみたのは以下のコード: (defn insert [x sorted] (let [[heads tails] (split-with #(<= % x) sorted)] (concat heads [x] tails))) (defn insertion-sort [xs] (loop [[head & tail :as unsorte…

Clojureでセレクションソート

まあとりあえず。 (defn selection-sort [xs] (loop [unsorted xs, sorted []] (if (empty? unsorted) sorted (let [unsorted-indexed (map vector (range) unsorted) [min-i min-v] (apply min-key second unsorted-indexed) [heads [_ & tails]] (split-at…

Clojureでクイックソート

書いてみる。 まずはletの中にベタ書き。 (defn quick-sort [col] (if (>= 1 (count col)) col (let [i (rand-int (count col)) pivot (nth col i) heads (take i col) tails (drop (inc i) col) col2 (concat heads tails) lesser (filter #(< % pivot) col…

Clojureでマージソート2

とりあえずiterate版も貼っておく。 (defn merge ([col] col) ([[head1 & rest1 :as col1] [head2 & rest2 :as col2]] (cond (some empty? [col1 col2]) (concat col1 col2) (< head1 head2) (lazy-seq (cons head1 (merge rest1 col2))) :else (lazy-seq (c…

Clojureでマージソート

なんとなくやってみた。 (defn merge ([col] col) ([[head1 & rest1 :as col1] [head2 & rest2 :as col2]] (cond (some empty? [col1 col2]) (concat col1 col2) (< head1 head2) (lazy-seq (cons head1 (merge rest1 col2))) :else (lazy-seq (cons head2 (…

Alex Martelli版エラトステネスの篩をClojureで書いてみた

素数算出アルゴリズムで最も有名なものは多分エラトステネスの篩だろう。発見した素数の倍数を消していく(篩にかけていく)ことによって、残った数の中で最小のものが素数だとわかる。そのプロセスを繰り返していくことで、一定のn以下のすべての素数が効率…