Clojureの勉強のために、L-99: Ninety-Nine Lisp Problemsを解いてみる。
今回はきり良く2問のみ。Arithmetic終了。
P40 (**) Goldbach's conjecture.
2より大きい偶数を引数に取り、和がその値になる二つの素数を返す関数(ゴールドバッハの予想)を書く。
引数が2または奇数の場合nilを返すようにした。
そうでなければその値までの素数リストを作り、そのfirstとの和が引数の値と一致するものを探す。
あればそれらの二値を返し、なければ素数リストのrestから再度探すように再帰する。
「リストの中から条件に合致する最初の要素を返す」という処理を(first (drop-while #(...) ...))としてみたが、
Haskellのfindのようにもっと簡単に書く方法があっただろうか。
user=> (my-goldbach 28)
(5 23)

user=> (my-goldbach 7)
nil
P41 (**) A list of Goldbach compositions.
先ほど作ったゴールドバッハ関数を利用して、
値の範囲を引数として渡し、その範囲内の偶数に対して和がその値になる二つの素数を返す関数を書く。
また、第三引数を与えた場合、二素数のどちらもその値以上となるもののみ返すようにする。
まず値の範囲をrangeで作り、mapmy-goldbachの結果となる値と元の値のペアを作る。
my-goldbachの結果がnilでないもの(引数が2と奇数の場合)と第三引数以上のもののみフィルタして返すようにした。
my-goldbachが返す素数の二値は昇順となっているのが分かっているため、
比較には(>= (first g) l)のみ行えば条件に合致しているとみなしてよい。
user=> (my-goldbach-list 9 20)
((10 (3 7)) (12 (5 7)) (14 (3 11)) (16 (3 13)) (18 (5 13)) (20 (3 17)))

user=> (my-goldbach-list  1 2000 50)
((992 (73 919)) (1382 (61 1321)) (1856 (67 1789)) (1928 (61 1867)))

Copyright© 2011-2021 Shunsuke Otani All Right Reserved .