P06 (*) Find out whether a list is a palindrome.
回文かどうかを判定する。文字列を前半部と後半部を反転したものとを比較して、等しければ回文とみなすようにすればいいか。
(map list word1 word2)
は他の言語でいうzip
関数のようなことをしたかったが、該当する関数が見当たらなかったのでword1,word2の各要素をそれぞれリストにすることで代用した。
最初、
#(= (first %) (second %))
のところで==
で比較しようとしてハマった…。数値なら
==
、数値を含む全ての型なら=
で同値かどうかを調べる、ということで良いのかな。take, drop
をsplit-at
に書き換えてみた。簡潔に書けるかと思ったけど、あまり変わらずか…。後から気づいたが、
map list
をzipmap
で代用できそうなので、やってみた。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に手を加えて書いたのがこちら。