p
adalah (tipe kelas polimorfik) fungsi mengambil permutasi sebagai daftar Int
s, dan daftar bersarang mewakili array multidimensi Int
s.
Sebutlah sebagai p [2,1] [[10,20,30],[40,50,60]]
, namun jika jenis default tidak berhasil, Anda mungkin harus menambahkan anotasi jenis seperti :: [[Int]]
(bersarang dengan tepat) memberikan jenis hasil.
import Data.List
class P a where p::[Int]->[a]->[a]
instance P Int where p _=id
instance P a=>P[a]where p(x:r)m|n<-p r<$>m,y:z<-sort r=last$n:[p(x:z)<$>transpose n|x>y]
Cobalah online!
Tantangan bermain golf dengan array bersarang dari kedalaman arbitrer agak canggung di Haskell, karena pengetikan statis cenderung menghalangi. Sementara daftar Haskell (dengan sintaks yang sama persis seperti pada deskripsi tantangan) dapat disarangkan dengan baik, daftar kedalaman bersarang yang berbeda adalah jenis yang tidak kompatibel. Selain itu, fungsi parsing Haskell standar memerlukan mengetahui jenis nilai yang Anda coba parsing.
Akibatnya, tampaknya tak terhindarkan bahwa program perlu menyertakan deklarasi terkait tipe, yang relatif bertele-tele. Untuk bagian golf, saya memutuskan untuk mendefinisikan kelas tipe P
, sehingga p
bisa polimorfik atas jenis array.
Sementara itu, harness pengujian TIO menunjukkan cara untuk mengatasi masalah parsing.
Bagaimana itu bekerja
Untuk meringkas inti dari algoritma ini: Ia melakukan semacam gelembung pada daftar permutasi, mentransposisi dimensi tetangga ketika indeks permutasi yang sesuai bertukar.
Seperti yang diberikan oleh class P a
deklarasi, dalam setiap contoh, p
membutuhkan dua argumen, permutasi (selalu bertipe [Int]
) dan array.
- Permutasi dapat diberikan dalam bentuk dalam deskripsi tantangan, meskipun cara algoritme bekerja, pemilihan indeks bersifat arbitrer, kecuali untuk urutan relatifnya. (Jadi pekerjaan berbasis 0- dan 1-.)
- Basis
instance P Int
menangani array dimensi 1, yang p
hanya mengembalikan tidak berubah, karena satu dimensi hanya dapat dipetakan ke dirinya sendiri.
- Yang lain
instance P a => P [a]
didefinisikan secara rekursif, memanggil p
dengan dimensi dan sub- array untuk mendefinisikannya untuk dimensi dan array 1 .
p(x:r)m
panggilan pertama p r
secara rekursif pada setiap elemen m
, memberikan array hasil n
di mana semua dimensi kecuali yang pertama telah diijinkan dengan benar relatif satu sama lain.
- Permutasi yang tersisa yang perlu dilakukan
n
diberikan oleh x:y:z = x:sort r
.
- Jika
x<y
kemudian dimensi pertama n
sudah ditempatkan dengan benar, dan n
hanya dikembalikan.
- Jika
x>y
, maka dimensi pertama dan kedua n
perlu ditukar, yang dilakukan dengan transpose
fungsi. Akhirnya p(x:z)
diterapkan secara rekursif untuk setiap elemen hasil, memastikan dimensi pertama asli ditransformasikan ke posisi yang tepat.
exec
(menyimpan dua byte) , karena ini adalah pernyataan dengan Python 2.