多次元のダンス


19

チャレンジ

与えられたn整数の次元アレイと第一の順列n自然数、したがってアレイの寸法を並べ替えます。

詳細

この課題は、MATLABに触発されていますpermuteデモンストレーション 順列は整数のリストとして与えられます。たとえば、[1,3,2]1が1にマッピングされ、2が3にマッピングされ、3が2にマッピングされます(ここで、ithエントリは値iがマッピングされます)。ただし、サイクルや関数など、便利な他の形式を使用できます。より便利な場合は、0ベースのインデックスを使用することもできます。

配列は完全な「長方形」m1 x m2 x ... x mn配列であると想定できます(つまり、不規則/ギザギザではないと仮定できます)。

n多くの言語ではネストされた配列の次元数に制限があるため、これは大きすぎないと想定できます。

言語が多次元配列をサポートしていない場合は、配列を表す文字列を入力として使用することもできます。

  • n恒等置換[1,2,3,...,n]を持つ任意の- 次元配列は変更されません。
  • [[10,20,30],[40,50,60]]順列を持つ配列[2,1]はにマッピングされ[[10,40],[20,50],[30,60]]ます。
  • [[[1,2],[3,4]],[[5,6],[7,8]]]順列を持つ配列[2,3,1]はにマッピングされ[[[1,3],[5,7]],[[2,4],[6,8]]]ます。

回答:


13

9

Haskell、168バイト

pは、順列をIntsのリスト、およびIntsの多次元配列を表すネストされたリストを取る(型クラス多相)関数です。

asを呼び出し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リスト(チャレンジの説明とまったく同じ構文)はうまくネストできますが、異なるネストの深さのリストは互換性のないタイプです。また、標準のHaskell解析関数では、解析しようとしている値の型を知る必要があります。

その結果、プログラムに、比較的冗長な型関連の宣言を含める必要があることは避けられないようです。ゴルフパートについては、配列の型に対して多相性を持つPような型classを定義することに決めましたp

一方、TIOのテストハーネスは、解析の問題を回避する方法を示しています。

使い方

  • このアルゴリズムの本質を要約すると、対応する置換インデックスが交換されたときに隣接する次元を入れ替えて、置換リストでバブルソートを実行します。

  • class P a宣言で与えられているように、いずれの場合でもp、順列(常に型[Int])と配列の2つの引数を取ります。

  • 順列はチャレンジの説明の形式で与えることができますが、アルゴリズムの動作方法、インデックスの選択は相対的な順序を除き任意です。(したがって、0ベースと1ベースの両方の作業。)
  • ベースinstance P Intは次元1の配列を処理しますp。1つの次元はそれ自体にのみマップできるため、単純に変更されずに返されます。
  • もう1つinstance P a => P [a]は再帰的に定義され、次元n + 1配列に対して定義するためにp次元nのサブ配列で呼び出します。
    • p(x:r)mfirstはp r、のすべての要素を再帰的に呼び出して、最初の要素を除くすべての次元が互いに相対的に正しくm並べ替えられた結果配列nを提供します。
    • 実行する必要がある残りの順列nはで与えられx:y:z = x:sort rます。
    • の場合x<y、の最初の次元nはすでに正しく配置されており、n単純に返されます。
    • の場合x>y、関数の1番目と2番目の次元をn交換する必要がありtransposeます。最後p(x:z)に、結果のすべての要素に再帰的に適用され、元の最初の次元が正しい位置に転置されるようにします。

3

Python 2、312バイト

これは、順列に0インデックスを使用します

from numpy import*
from itertools import*
z=range
def f(i,r):
	l=array(i).shape;R={b:a for a,b in enumerate(r)};r=len(r);m=eval('['*r+'0'+q('for k in z(l[R[%s]])]',r-1,-1,-1))
	for d in product(*[z(p) for p in l]):exec'm'+q('[d[R[%s]]]',r)+'=i'+q('[d[%s]]',r)
	return m
q=lambda s,*j:''.join(s%(j)for j in z(*j))

オンラインでお試しください!

@Jonathan Frechに感謝-2バイト。


あなたは、呼び出すための括弧を必要としないexec (2つのバイトを保存する)、それはPythonの2の文であるとして、
ジョナサンFRECH

には余分なスペースもありz(p) forます。
ジョナサンフレッチ

1
使用済みmap(z,l)s%jおよびprint301バイト- オンラインで試してみてください!
Mr Xcoder

3

パイソン241の 25バイト

import numpy
numpy.einsum

オンラインでお試しください!

順列ベクトルpは文字列として与えられます。だから、[2,3,1]として与えることができます'bca'

@EriktheOutgolferのおかげで16バイト節約できました!


これは26を超えるディメンションをサポートしていますか?
エリックアウトゴルファー

実際には、52を超えない次元:大文字+小文字。
rahnema1

2

JavaScript(ES6)、136 132バイト

(a,p,v=[],r=[],g=(a,[d,...p],_,h=(r,[i,...v])=>1/v[0]?h(r[i]=r[i]||[],v):r[i]=a)=>1/d?a.map((e,i)=>g(e,p,v[d]=i)):h(r,v))=>g(a,p)&&r

0インデックス。説明:順列を使用して並べ替えられたインデックスのg配列をa構築する配列を再帰的に繰り返します。一度使い果たされると、置換されたインデックスを使用して、結果配列に要素を再帰的に挿入します。vpphr

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.