Clojureの勉強のために、L-99: Ninety-Nine Lisp Problemsを解いてみる。
まだコードがぎこちない気がするが…徐々に慣れていきたい。とにかく今は数をこなしてみよう。
P06 (*) Find out whether a list is a palindrome.
回文かどうかを判定する。
文字列を前半部と後半部を反転したものとを比較して、等しければ回文とみなすようにすればいいか。
(map list word1 word2)は他の言語でいうzip関数のようなことをしたかったが、
該当する関数が見当たらなかったのでword1,word2の各要素をそれぞれリストにすることで代用した。
最初、#(= (first %) (second %))のところで==で比較しようとしてハマった…。
数値なら==、数値を含む全ての型なら=で同値かどうかを調べる、ということで良いのかな。
take, dropsplit-atに書き換えてみた。簡潔に書けるかと思ったけど、あまり変わらずか…。
後から気づいたが、map listzipmapで代用できそうなので、やってみた。
P07 (**) Flatten a nested list structure.
問題文の(*)の数が難易度を表しているらしく、初のレベル2といったところか。
組み込み関数のflattenを使わずに書くと、こんな感じかな。
my-flattenの引数を分配束縛し、先頭要素をxに、残りの要素をxsに、引数全体をlstに束縛している。
xがネストしたリストであればconcatで要素を連結し、リストでなければconsで先頭に追加する、というように処理を分けた。
特に難しいことはしていないつもりだが、懸念点としてはこの再帰の呼び出し方では末尾再帰(recurを呼ぶやり方)にできず、
もっと効率の良い書き方があるのかもしれない…。
P08 (**) Eliminate consecutive duplicates of list elements.
連続した重複要素を除いたリストを作る。
まず、要素を一つずつ調べて一つ前の要素と同じでなければリストに追加していく解き方。
次に、drop-while関数を使って先頭要素と同じ要素を除いたリストを作っていく解き方。
更に、fnで無名関数を作ってその場で呼んでいる箇所を、loopで書き直してみた。
こちらのほうが冗長ではなく良さそうだ。
P09 (**) Pack consecutive duplicates of list elements into sublists.
連続した重複要素をまとめたリストを作る。
p08-3.cljに少し手を加えて解けた。
take-whileして残りをdrop (count y)している箇所をsplit-withで書き換えてみた。
また、partition-byで書き換えてみた。こちらは凄く簡潔になった。
P10 (*) Run-length encoding of a list.
連続した重複要素の個数と要素の組のリストを作る。
p09-2.cljに更に手を加えて解けた。
p09-3.cljに手を加えて書いたのがこちら。

Copyright© 2011-2021 Shunsuke Otani All Right Reserved .