あなたは、最初からやり直すよりもコードを修正することを好むようです。それでは、あなたのコードを見てみましょう。まず、メインリストのチョッピング:
reverse (take i (reverse xs)) ++ reverse (drop i (reverse xs))
reverse (take i (reverse xs))
リストの最後から要素を取得するようになりましi
たが、これを実現するにはリストを 2 回逆にします
drop (length xs - i) xs
。reverse (drop i (reverse xs)))
同様に、として実装できますtake (length xs - i) xs
。それは私たちに与えます
drop (length xs - i) xs ++ take (length xs - i) xs
リストを\i->[1..n]<=n
と比較するため、コードは意味をなしません。これは機能しません。からまで実行さ
れるループを作成しようとしていると思いますが、これは良い計画です。リスト内包表記を使用して、必要なものを取得しましょう。[1..n]
n
i
1
n
[drop (length xs - i) xs ++ take (length xs - i) xs | i <- [1 .. length xs], i <= n]
しかし、今は 1 からリストの長さまで実行していますが、上記の数字を捨てていますn
。
[drop (length xs - i) xs ++ take (length xs - i) xs | i <- [1..n]]
これはn
を超えることがlength xs
できますが、そこに大きな問題は見られません。最初に確認できます。
ここで を使用
i
しているだけ(length xs - i)
で、実際には
length xs
必要以上に多くの再計算を行っていることにi
注意し1
てください。n
length xs - i
j=length xs -i
j
length xs
length xs - n
[drop j xs ++ take j xs | j <- [length xs,length xs - 1 .. length xs - n]]
たとえば、これは機能します[6,5..1] == [6,5,4,3,2,1]
した方がきれいでしょう
let l = length xs in
[drop j xs ++ take j xs | j <- [l,l - 1 .. l - n]]
またはtake
、算術よりも算数が好きな場合は、次を使用できます。
let l = length xs in
take n [drop j xs ++ take j xs | j <- [l,l - 1 .. 0]]
これには、やりすぎを防ぎ、最初に戻ったときに停止するという追加の利点があります。
関数の名前をからgeneratingListforRightShifting
に変更します。rotationsR
rotationsR n xs = let l = length xs in
take n [drop j xs ++ take j xs | j <- [l,l - 1 ..]]
これは を与えrotationsR 6 [1..4] == [[1,2,3,4],[4,1,2,3],[3,4,1,2],[2,3,4,1],[1,2,3,4]]
ます。
左回転はより簡単に見えます:
rotationsL n xs = take n [drop j xs ++ take j xs | j <- [0..length xs]]
余談: 私は自分自身を助けることができませんでした, 申し訳ありません, そして、私は再び始めました.
私はまだ、そのすべてを毎回落としたり取ったりするのは好きではありません。私はむしろ無限に多くのコピーを並べてxs
(最初のN:cycle xs
tails
rotationsL' n xs = let l = 長さ xs in テイク n . マップ (テイク l) . 尾。サイクル $ xs
遅延評価のため、これまでに限られた量しかcycle xs
計算されませんが、これは実行して実行できrotationsL' 10 [1..4]
ます:
[[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3],[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3],[1,2,3,4],[2,3,4,1]]
そのように適切なローテーションを行うのも良いでしょうが、無限リストの最後から開始して戻る必要があるため、うまくいきません。ただし、リバースを再利用して、必要なものを取り、リバース トリックをもう一度使用しましょう。
rotationsR' n xs = let l = length xs in
take n . map (reverse.take l) . tails . cycle . reverse $ xs
余談: 元のコードにもっと厳密に固執したい場合は、次のことができます。
generatingListforRightShifting n xs =
[reverse (take i (reverse xs)) ++ reverse (drop i (reverse xs)) | i <- [1..n]]