pist eine (typklassenpolymorphe) Funktion, die eine Permutation als Liste von Ints und eine verschachtelte Liste als mehrdimensionales Array von Ints verwendet.
Rufen Sie als auf p [2,1] [[10,20,30],[40,50,60]]. Wenn jedoch die Standardeinstellung des Typs nicht erfolgreich ist, müssen Sie möglicherweise eine Typanmerkung wie :: [[Int]](entsprechend verschachtelt) hinzufügen , die den Typ des Ergebnisses angibt.
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]
Probieren Sie es online!
Golf-Herausforderungen mit verschachtelten Arrays beliebiger Tiefe sind in Haskell etwas umständlich, da die statische Typisierung eher stört. Während Haskell-Listen (mit genau der gleichen Syntax wie in der Challenge-Beschreibung) problemlos verschachtelt werden können, sind Listen mit unterschiedlicher Verschachtelungstiefe nicht kompatibel. Für Standard-Parsingfunktionen von Haskell ist es außerdem erforderlich, den Typ des zu analysierenden Werts zu kennen.
Infolgedessen scheint es unvermeidlich, dass das Programm typbezogene Erklärungen enthalten muss, die relativ ausführlich sind. Für den Golf-Teil habe ich mich darauf festgelegt, eine Typklasse zu definieren P, pdie über den Typ des Arrays polymorph sein kann.
In der Zwischenzeit zeigt das Test-Gurtzeug des TIO einen Weg, um das Parsing-Problem zu umgehen.
Wie es funktioniert
Um das Wesentliche dieses Algorithmus zusammenzufassen: Er führt eine Blasensortierung für die Permutationsliste durch und transponiert benachbarte Dimensionen, wenn die entsprechenden Permutationsindizes vertauscht werden.
Wie in der class P aDeklaration angegeben, werden in jedem Fall pzwei Argumente verwendet, eine Permutation (immer vom Typ [Int]) und ein Array.
- Die Permutation kann in der Form in der Herausforderungsbeschreibung angegeben werden, obwohl die Art und Weise, wie der Algorithmus arbeitet, die Auswahl der Indizes bis auf ihre relative Reihenfolge willkürlich ist. (Also sowohl 0- als auch 1-basierte Arbeit.)
- Die Basis
instance P Intbehandelt Arrays der Dimension 1, die peinfach unverändert zurückgegeben werden, da die eine Dimension nur auf sich selbst abgebildet werden kann.
- Die andere
instance P a => P [a]ist rekursiv definiert und ruft pmit Dimension n Subarrays auf, um sie für Dimension n + 1 Arrays zu definieren .
p(x:r)mfirst ruft p rrekursiv jedes Element von auf mund gibt ein Ergebnisfeld an, nin dem alle Dimensionen mit Ausnahme der ersten relativ zueinander korrekt permutiert wurden.
- Die verbleibende Permutation, die durchgeführt werden muss,
nist gegeben durch x:y:z = x:sort r.
- Wenn dies
x<yder Fall nist, nist die erste Dimension von bereits korrekt platziert und wird einfach zurückgegeben.
- Wenn ja
x>y, dann müssen die erste und zweite Dimension ngetauscht werden, was mit der transposeFunktion erledigt wird . Schließlich p(x:z)wird rekursiv auf jedes Element des Ergebnisses angewendet, um sicherzustellen, dass die ursprüngliche erste Dimension an die richtige Position verschoben wird.
exec(zwei Bytes sparen) , da es sich um eine Anweisung in Python 2 handelt.