o modülo operatörü eksik çünkü sen arkadaşının kod çalışmıyor - yani rotasyon etrafında "sarma" değildir. Carsten'in kodu çalışır (onun kodu, listeyi kendi başına istifleyerek ve sonra uygun dilimi alarak çalışır; yığıldığı için "sarılır"); İşte bir alternatif. Bu sadece the array rotation problem.
import Data.List (splitAt)
import Data.Tuple (swap)
rotate :: Int -> [a] -> [a]
rotate k xs = uncurry (++) $ swap $ splitAt (k `mod` length xs) xs
Biz ikiye liste bölünmüş - ve
mod
rotasyonu,
swap
sırt için ön etkinleştirmek ve bunları birbirine eklemek için.
swap
, tuple üzerinde çalışır (
splitAt
döndürür).
uncurry
, yalnızca iki ayrı bağımsız değişken yerine bir dizi üzerinde çalışacak şekilde liste birleştirmeyi (
++
) zorlar.
a -> b -> c
türünün bir işlevini
(a, b) -> c
türüne dönüştürür.
Bazı testler-- forM_
, her satırı sırayla basmak için bir for döngüsü gibi kullanılır.
import Control.Monad (forM_)
main = do
let img = ["XX XX",
" X ",
"XX XX"]
putStrLn "Up is positive"
forM_ (rotate 1 img) print
putStrLn "Down is negative"
forM_ (rotate (-1) img) print
şu çıktıyı verir: sen, pozitif/negatif değerler kullanmak yerine bir Up
/Down
veri türünü yaratabilir istiyorsa
Up is positive
" X "
"XX XX"
"XX XX"
Down is negative
"XX XX"
"XX XX"
" X "
. Örneğin.
data Direction = Up | Down
rotate :: Direction -> Int -> [String] -> [String]
rotate d k xs = . . .
Eğer şimdiye kadar denedim neyi gösterebilir olabilir? – duffn
@duffn - Bu problemle ilgili bazı problemleri bilen bir arkadaşla çalıştım. O ----------- hareket n olarak = kafa ts ile geldi: (hs ++ kuyruk ts) Burada (hs, ts) = splitAt n ---------- ama onun işe yaramasını istemediğim sessiz değil. – evian1
Nasıl çalışmasını istersiniz? – Carsten