p
è una funzione (tipo classe polimorfica) che prende una permutazione come un elenco di Int
s, e un elenco nidificato che rappresenta un array multidimensionale di Int
s.
Chiama come p [2,1] [[10,20,30],[40,50,60]]
, tuttavia se il default del tipo non riesce, potrebbe essere necessario aggiungere un'annotazione del tipo come :: [[Int]]
(nidificato in modo appropriato) fornendo il tipo di risultato.
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]
Provalo online!
Le sfide del golf con matrici annidate di profondità arbitraria sono un po 'imbarazzanti in Haskell, perché la tipizzazione statica tende a intralciarsi. Mentre gli elenchi di Haskell (con la stessa sintassi esatta nella descrizione della sfida) possono essere nidificati bene, gli elenchi con diverse profondità di annidamento sono di tipo incompatibile. Inoltre, le funzioni standard di analisi di Haskell richiedono la conoscenza del tipo di valore che si sta tentando di analizzare.
Di conseguenza, sembra inevitabile che il programma debba includere dichiarazioni relative al tipo, che sono relativamente dettagliate. Per la parte golfizzata, ho deciso di definire una classe di tipo P
, tale da p
poter essere polimorfica rispetto al tipo di array.
Nel frattempo, il cablaggio di test del TIO mostra un modo per aggirare il problema di analisi.
Come funziona
Riassumendo l'essenza di questo algoritmo: esegue un ordinamento a bolle nell'elenco delle permutazioni, trasponendo le dimensioni vicine quando vengono scambiati gli indici di permutazione corrispondenti.
Come indicato dalla class P a
dichiarazione, in ogni caso, p
accetta due argomenti, una permutazione (sempre di tipo [Int]
) e una matrice.
- La permutazione può essere data nella forma nella descrizione della sfida, sebbene il modo in cui l'algoritmo funziona, la scelta degli indici è arbitraria, ad eccezione del loro ordine relativo. (Quindi funzionano sia a 0 che a 1).
- La base
instance P Int
gestisce le matrici della dimensione 1, che p
ritorna semplicemente invariata, poiché l'unica dimensione può essere mappata solo su se stessa.
- L'altro
instance P a => P [a]
è definito in modo ricorsivo, chiamando p
con dimensione n subarrays per definirlo per matrici dimensione n + 1 .
p(x:r)m
prima chiama in p r
modo ricorsivo su ogni elemento di m
, dando un array di risultati n
in cui tutte le dimensioni tranne la prima sono state permutate correttamente l'una rispetto all'altra.
- La permutazione rimanente su cui deve essere eseguita
n
è data da x:y:z = x:sort r
.
- In
x<y
tal caso, la prima dimensione di n
è già posizionata correttamente e n
viene semplicemente restituita.
- Se
x>y
, allora la prima e la seconda dimensione n
devono essere scambiate, il che viene fatto con la transpose
funzione. Infine, p(x:z)
viene applicato in modo ricorsivo a ogni elemento del risultato, assicurando che la prima dimensione originale venga trasposta nella posizione corretta.
exec
(salvare due byte) , in quanto è una dichiarazione in Python 2.