pявляє собою (поліморфний клас класу) функцію, що приймає перестановку як список Ints, і вкладений список, що представляє багатовимірний масив Ints.
Зателефонуйте як p [2,1] [[10,20,30],[40,50,60]], однак, якщо типова помилка типу не вдається, вам, можливо, доведеться додати анотацію типу, наприклад :: [[Int]](вкладеного належним чином), надаючи тип результату.
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]
Спробуйте в Інтернеті!
Проблеми з гольфом із вкладеними масивами довільної глибини в Хаскеллі трохи незручні, оскільки статичний набір тексту, як правило, перешкоджає. Хоча списки Haskell (з точно таким же синтаксисом, як і в описі виклику) можуть вкладатись чудово, списки різної глибини вкладення несумісні. Крім того, для стандартних функцій розбору Haskell потрібно знати тип значення, яке ви намагаєтеся розібрати.
Як результат, видається неминучим необхідність програми включати декларації, що стосуються типу, які є відносно багатослівними. Щодо гольф-частини, я зупинився на визначенні класу типу P, такого, який pможе бути поліморфним щодо типу масиву.
Тим часом, тестовий джгут TIO показує спосіб подолати проблему розбору.
Як це працює
Підсумовуючи суть цього алгоритму: Він виконує сортування бульбашок у списку перестановок, переносячи сусідні розміри при заміні відповідних індексів перестановки.
Як зазначено в class P aдекларації, у будь-якому випадку pбереться два аргументи, перестановка (завжди типу [Int]) та масив.
- Перестановку можна навести у формі опису виклику, хоча спосіб роботи алгоритму вибір індексів довільний, за винятком їх відносного порядку. (Отже, робота на основі 0 і 1).
- База
instance P Intобробляє масиви розмірності 1, які pпросто повертаються незмінними, оскільки один вимір може бути відображений лише для себе.
- Інший
instance P a => P [a]визначається рекурсивно, викликаючи pрозмірність n підматрив, щоб визначити його для розмірності n + 1 масивів.
p(x:r)mПерший p rрекурсивно викликає кожен елемент m, даючи масив результатів, nв якому всі розміри, крім першого, перестановлені правильно відносно один одного.
- Інша перестановка, яку потрібно виконати
n, задається x:y:z = x:sort r.
- Якщо
x<yтоді перший вимір nрозміщений вже правильно, nвін просто повертається.
- Якщо
x>y, тоді перший і другий вимір nпотрібно замінити, що робиться за допомогою transposeфункції. Нарешті p(x:z), застосовується рекурсивно до кожного елемента результату, забезпечуючи перенесення вихідного першого виміру у потрібне положення.
exec(збереження двох байтів) , оскільки це твердження в Python 2.