簡単な答えは「はい」です。ClojureはJava配列を直接操作できるため、直接翻訳は非常に簡単です。
(for [k (range 1 (count a))
y (range 1 b)]
(if (< y (aget a (dec k)))
(aset knap k (dec y) (aget knap (dec k) (dec y))
(if (> y (aget a (dec k)))
(aset knap k (dec y) (max (aget knap (dec k) (dec y))
(aget knap (dec k) (+ (- y 1 (aget a (dec k)))
(aget c (dec k))))
(aset knap k (dec y) (max (aget knap (dec k) (dec y))
(aget c (dec k))))))))))
これは、ループと実行する作業を組み合わせているため、あまり理想的なClojureではありません。このループの要素を分離すると、結果のコードははるかにクリーンになり、正しく表示されやすくなります。
ささいな最初のステップとして、ループを「作業」から分離すると、次のようになります。
(defn edit-array [k y]
(if (< y (aget a (dec k)))
(aset knap k (dec y) (aget knap (dec k) (dec y))
(if (> y (aget a (dec k)))
(aset knap k (dec y) (max (aget knap (dec k) (dec y))
(aget knap (dec k) (+ (- y 1 (aget a (dec k)))
(aget c (dec k))))
(aset knap k (dec y) (max (aget knap (dec k) (dec y))
(aget c (dec k))))))))))
(for [k (range 1 (count a)) y (range 1 b)]
(edit-array k y))
次に、replから編集配列をテストし、それが機能することを自分自身に納得させることができます(そしておそらく単体テストを作成します)。edit-arrayその後、もっと詳しく調べて、これを個別にテストしやすいステップに分割できるかどうかを判断したいと思うかもしれません。おそらく、配列を変更する代わりに機能的なスタイルを使用するようにこれを変更することができます。ここでは、この線形計画法ソリューションが解決するように設計された元の問題を理解していないことを認めなければならないため、特定の問題から離れます。
(defn finished? [row] ... determine if we have reached the final state ...)
(defn next-row [current-row]
(for [y (range 1 (count current-row)]
... code to produce a new vector based on the previous one ...))
(take-while #(not (finished? %) (iterate next-row (initial-state)))
Idomatic Clojureコードがどのように見えるかの基本的な概念は、問題を単純な(1つのことだけを行う)抽象化に分解し、それらを構成して主要な問題を解決することです。もちろん、これは常に目前の問題に合うように調整する必要があります。