2D配列の行と列のブロックソート


15

整数の2D配列が与えられた場合、その行と列をブロックで並べ替えましょう。つまり、特定の行または列を並べ替えるだけで、並べ替えに必要な変換を2D配列の他のすべての行または列に適用できます。

ルール

  • 入力は、整数の2D配列と1インデックス付き整数になります。この整数は、数値が正の場合にソートされる行を表し、数値が負の場合にソートされる列を表します(または、必要に応じて逆になります)。例:(4x3行x列)配列を指定すると、2番目の列を-2引数で、または3番目の行を引数でソートでき3ます。この2番目の引数はゼロになることはなく、その絶対値は配列の対応する次元より大きくなることはありません。
  • 出力は、指定された行または列をソートするために必要な変換が適用された整数の2D配列にもなります。または、STDOUTに配列を書き込むこともできます。
  • 出力配列には、指定された行または列が昇順でソートされます。行の2つの数字を交換する必要がある場合、数字が配置されている列全体が交換されることに注意してください。また、列内の2つの数字を交換する必要がある場合、数字が配置されている行全体が交換されます。
  • 並べ替えられる行/列に同じ番号が複数回現れる場合、値を交換する方法に応じていくつかの解決策があり、交換される残りの行/列に応じてそれを行うだけです。

Positive indices for rows and negative indices for columns

[5  8  7  6                                  [1  3  2  4
 1  3  2  4   order by -3 (3rd column)  -->   9  6  3  0
 9  6  3  0]                                  5  8  7  6]

[5  8  7  6                                  [9  6  3  0
 1  3  2  4   order by -4 (4th column)  -->   1  3  2  4
 9  6  3  0]                                  5  8  7  6]

[5  8  7  6                                  [5  7  8  6
 1  3  2  4     order by 2 (2nd row)  -->     1  2  3  4
 9  6  3  0]                                  9  3  6  0]

[5  8  7  6                                  [6  7  8  5
 1  3  2  4     order by 3 (3rd row)  -->     4  2  3  1
 9  6  3  0]                                  0  3  6  9]

[1  2                                    [1  2     [3  2
 3  2]   order by -2 (2nd column)  -->    3  2] or  1  2]  (both are valid)

[7  5  9  7                                  [5  7  7  9     [5  7  7  9
 1  3  2  4     order by 1 (1st row)  -->     3  1  4  2  or  3  4  1  2
 9  6  3  0]                                  6  9  0  3]     6  0  9  3]

これはなので、各言語の最短コードが勝つかもしれません!


これはサンドボックスから来ます。
チャーリー

整数表現を変更できますか?行が負で列が正ですか?
ルイスフェリペデジェススムニョス

1
@LuisfelipeDejesusMunozはい、質問で述べられています。
チャーリー

行/列に重複した数字を含めることはできますか?
ケビンクルーイッセン

@KevinCruijssenはい、ルールの最後の例と最後のポイントを参照してください。
チャーリー

回答:





4

Japt18 17バイト

行の場合は負、列の場合は正

>0?VñgUÉ:ßUa Vy)y

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


U負の場合、これは失敗します-ただし、以前の17バイトバージョンは動作します。
シャギー

@シャギー私の悪い、私はそれがとにかく動作するだろうが、まったくチェックし
ませんでした

ただし、最初の引数として関数を渡すとß、自動的に適用されUます。リテラル文字列を渡そうとすると問題が発生する可能性がありますが、とにかくさらなる調査のためにGitHubリポジトリに提案を投稿してください。
シャギー

4

05AB1E25 24 14 バイト

diø}Σ¹Ä<è}¹diø

なんと-10に感謝バイト@Emigna

正の整数入力を使用して行をソートし、負の列を使用します。

オンラインで試すか、、すべてのテストケースを確認してください

説明:

di }      # If the (implicit) integer input is positive:
  ø       #  Swap the rows and columns of the (implicit) matrix input
          #   i.e. 3 and [[5,8,7,6],[1,3,2,4],[9,6,3,0]]
          #    → [[5,1,9],[8,3,6],[7,2,3],[6,4,0]]
Σ    }    # Sort the rows of this matrix by:
 ¹Ä       #  Take the absolute value of the input
          #   i.e. -3 → 3
   <      #  Decreased by 1 to make it 0-indexed
          #   i.e. 3 → 2
    è     #  And index it into the current row
          #   i.e. [5,8,7,6] and 2 → 7
          #   i.e. [5,1,9] and 2 → 9
          #  i.e. [[5,1,9],[8,3,6],[7,2,3],[6,4,0]] sorted by [9,6,3,0]
          #   → [[6,4,0],[7,2,3],[8,3,6],[5,1,9]]
          #  i.e. [[5,8,7,6],[1,3,2,4],[9,6,3,0]] sorted by [7,2,3]
          #   → [[1,3,2,4],[9,6,3,0],[5,8,7,6]]
¹di       # And if the integer input was positive:
   ø      #  Swap the rows and columns back again now that we've sorted them
          #   i.e. 3 and [[6,4,0],[7,2,3],[8,3,6],[5,1,9]]
          #    → [[6,7,8,5],[4,2,3,1],[0,3,6,9]]
          # (And implicitly output the now sorted matrix)

1
私が得たdiø}Σ¹Ä<è]¹diøので、私は別の答えを投稿していないよ、あなたのサブセットです。
エミグナ

@Emigna Dang、あなたはそれをとても簡単に見せます。私はそれを見たので、私は私がそれについて自分で考えていなかったと信じることができませんが、それは同時に独創的です。ありがとう!おかげでなんと10バイトも節約できました。
ケビンクルイッセン

4

JavaScript(ES6)、90バイト

t=m=>m[0].map((_,x)=>m.map(r=>r[x]))
f=(m,k)=>k<0?m.sort((a,b)=>a[~k]-b[~k]):t(f(t(m),-k))

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

どうやって?

JSにはネイティブな転置方法がないため、1つ定義する必要があります。

t = m =>              // given a matrix m[]
  m[0].map((_, x) =>  // for each column at position x in m[]:
    m.map(r =>        //   for each row r in m[]:
      r[x]            //     map this cell to r[x]
    )                 //   end of map() over rows
  )                   // end of map() over columns

メイン機能:

f = (m, k) =>         // given a matrix m[] and an integer k
  k < 0 ?             // if k is negative:
    m.sort((a, b) =>  //   given a pair (a, b) of matrix rows, sort them:
      a[~k] - b[~k]   //     by comparing a[-k - 1] with b[-k - 1]
    )                 //   end of sort
  :                   // else:
    t(f(t(m), -k))    //   transpose m, call f() with -k and transpose the result

k=2

M=(587613249630)t(M)=(519836723640)f(t(M),2)=(519723836640)f(M,2)=t(f(t(M),2))=(578612349360)

3

MATL、17バイト

y0>XH?!]w|2$XSH?!

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

または、すべてのテストケースを確認します

説明

y       % Implicit inputs: number n, matrix M. Duplicate from below: pushes n, M, n
0>      % Greater than 0?
XH      % Copy into clipboard H
?       % If true
  !     %   Transpose matrix. This way, when we sort the rows it will correspond
        %   to sorting the columns of the original M
]       % End
w       % Swap: moves n to top
|       % Absolute value
2$XS    % Two-input sortrows function: sorts rows by specified column
H       % Push contents from clipboard H
?       % If true
  !     %   Transpose again, to convert rows back to columns
        % Implicit end
        % Implicit display


2

パイソン271の 70バイト

f=lambda m,n:n<0and sorted(m,key=lambda l:l[~n])or zip(*f(zip(*m),-n))

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


場合はn負である、行は列に基づいてソートされていますn

それ以外の場合、マトリックスは転置され、同じ方法でソートされ、再び転置されます。



1

C#(.NET Core)、186バイト

(x,y)=>{Func<int[][],int[][]>shift=a=> a[0].Select((r,i)=>a.Select(c=>c[i]).ToArray()).ToArray();return y>0?shift(shift(x).OrderBy(e=>e[y-1]).ToArray()):x.OrderBy(e=>e[-y-1]).ToArray();}

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

ゴルフをしていない:

    private static int[][] Blocksort0a(int[][] array, int sortingInstruction)
    {
        Func<int[][], int[][]> shift = a => a[0].Select((r, i) => a.Select(c => c[i]).ToArray()).ToArray();

        sortingInstruction++;

        array = sortingInstruction < 0 ? 
        shift(shift(array).OrderBy(e => e[-sortingInstruction]).ToArray()) 
             : 
        array.OrderBy(e => e[sortingInstruction]).ToArray();

        return null;
    }

シフト関数は2回使用するため、関数変数はスペースを節約します。この関数は、インデックスの配列の水平次元を反復処理し、各水平配列のそのインデックスのすべてのアイテムを新しい出力配列に(水平方向に)追加します-ArnoudのJSソリューションとほぼ同じです。

順序付けは簡単になりました。インデックスの番号(引数-1)で水平配列を並べ替え、オプションで並べ替えの前後に配列をシフトします。

質問が配列について具体的に語っている様子を見て、数回配列に変換します(非常に、非常に無駄です)。このような冗長な言語をコードゴルフheheで使用するのは少しばかげていると感じます。


1

C#(.NET Core)142 / 139 138/135バイト(およびKevinによる別の-1)

(a,s)=>s<0?a.OrderBy(e=>e[~s]).ToArray():a.Select(f=>a[s-1].Select((v,j)=>new{v,j}).OrderBy(e=>e.v).Select(e=>f[e.j]).ToArray()).ToArray()

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

ゴルフをしていない:

    private static int[][] Blocksort0b(int[][] array, int sortingInstruction)
    {
        if (sortingInstruction < 0) { return array.OrderBy(e => e[-sortingInstruction - 1]).ToArray(); }
        var rowIndices = array[sortingInstruction - 1].Select((value, index) => (value, index)).OrderBy(e => e.value);
        var newRow = new int[array[0].Length];
        for (var i = 0; i < array.Length; i++)
        {
            int horizontalIndexer = 0;
            foreach (var e in rowIndices)
            {
                newRow[horizontalIndexer++] = array[i][e.index];
            }
            array[i] = newRow.ToArray();
        }
        return array;
    }

新しいオールインラインアプローチ。否定的な答えは、要素のインデックスで配列を並べ替えます。そうでない場合、value-index-pairのコレクションがarray-at-indexから作成され、値でソートされます。これにより、追加する必要のあるインデックスのコレクションが効果的に作成されます。次に、各配列について、所定の位置の要素が選択されます。コードのかなりのトリミングと見苦しい、見苦しい、見苦しい**静かにすすり泣く**入力パラメータの再利用が必要です。

繰り返しになりますが、配列引数は厳密に適用され、.ToArray()呼び出しにかなりのオーバーヘッドが追加されます。

135バイトの要求、え?!C#7.2の推論した値タプルは追加の3バイトを削除しますが、tio.runは許可しません。そのため、これは簡単な確認のために投稿することにした回答です。


1
いい答え。ゴルフにはいくつかの小さなことがあります。(a,s)=>カレーになりますa=>s=>(s<0)?括弧を必要としない、と-s-1することができ~sオンラインで試してください:137バイト
ケビンクルーイッセン

甘い!文字を保存するために関数にさらに別の関数を返させることはできませんでしたが、うれしい驚きです。ありがとう!また、not演算子と括弧を露骨に見落としているという強い事例です。notとかっこを更新しましたが、function-returning-functionのすべての名誉を残します。
バロドゥス

1

Java(OpenJDK 8)、326バイト

(a,b)->{int l=a.length,w=a[0].length,k,m,t,i;if(b>0){for(i=0;i<w;i++){for(k=1;k<(w-i);k++){if(a[b-1][k-1]>a[b-1][k]){for(m=0;m<l;m++){t=a[m][k];a[m][k]=a[m][k-1];a[m][k-1]=t;}}}}}else{b*=-1;for(i=0;i<l;i++){for(k=1;k<(l-i);k++){if(a[k-1][b-1]>a[k][b-1]){for(m=0;m<w;m++){t=a[k][m];a[k][m]=a[k-1][m];a[k-1][m]=t;}}}}}return a;}

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

まあみんな、この質問は私にとって非常にイライラさせられました、そして私は何かを忘れていましたが、幸運にもケビン・クルーッセンのような伝説があります:)

Java(OpenJDK 8)、281バイト

a->b->{int l=a.length,w=a[0].length,k,m,t,i;if(b>0)for(i=0;i<w;i++)for(k=0;++k<w-i;)for(m=0;a[b-1][k-1]>a[b-1][k]&m<l;a[m][k]=a[m][k-1],a[m++][k-1]=t)t=a[m][k];else for(b*=-1,i=0;i<l;i++)for(k=0;++k<l-i;)for(m=0;a[k-1][b-1]>a[k][b-1]&m<w;a[k][m]=a[k-1][m],a[k-1][m++]=t)t=a[k][m];}

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


私はまだ実際のアルゴリズムを見ていませんが、すべてのブラケットを削除し、ループ内にすべてを入れることで35バイトを節約できます(内部if文を含む)。オンラインで試してください:291バイト編集:ここにスペースのインデントを付けて、私が行った変更をより明確に確認できるようにします。
ケビンクルイッセン

@KevinCruijssen私は何かが足りないと知っていました
-X1M4L

さらに、input-arrayを変更しているため、-statementのa->b->代わりにそれをカリー化入力として(a,b)->削除returnできます。281バイトでもいい答えです。私から+1。05AB1Eでチャレンジしましたが、今回はJavaでも挑戦しませんでした。;)
ケビンクルーイッセン





1

190の 185バイト

func[b n][t: func[a][c: length? a/1 a: to[]form a
d: copy[]loop c[append/only d extract a c take a]d]d: does[if n > 0[b: t b]]d
m: absolute n sort/compare b func[x y][x/(m) < y/(m)]d b]

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

説明:

f: func [ b n ] [
    t: func [ a ] [                            ; helper transpose function 
        c: length? a/1                         ; c is the length of the rows
        a: to-block form a                     ; flatten the list
        d: copy []                             ; an empty block (list)
        loop c [                               ; do as many times as the number of columns  
            append/only d extract a c          ; extract each c-th element (an entire column)
                                               ; and append it as a sublist to d
            take a                             ; drop the first element
        ] 
        d                                      ; return the transposed block (list of lists)
    ]
   d: does [ if n > 0 [ b: t b ] ]             ; a helper function (parameterless) to transpose 
                                               ; the array if positive n
   d                                           ; call the function  
   m: absolute n                               ; absolute n
   sort/compare b func[ x y ] [ x/(m) < y/(m) ]; sort the array according to the chosen column 
   d                                           ; transpose if positive n
   b                                           ; return the array  
]

私の実際のソリューションの長さは175バイトですが、TIOでは機能しません。ここでは、Redコンソールでnormalylを使用しています。

、175バイト

func[b n][d: does[if n > 0[c: length? b/1 a: to-block form b
t: copy[]loop c[append/only t extract a c take a]b: t]]d
m: absolute n sort/compare b func[x y][x/(m) < y/(m)]d b]

0

VBA(Excel)、205バイト

わーい!2番目に長いバイトカウント!私は完全に失われませんでした:D

ゴルフ:

Sub d(a)
With ActiveSheet.Sort
  .SortFields.Clear
  .SortFields.Add Key:=IIf(a<0,ActiveSheet.Columns(Abs(a)),ActiveSheet.Rows(Abs(a)))
  .SetRange ActiveSheet.UsedRange
  .Orientation=IIf(a<0,1,2)
  .Apply
End With
End Sub

これにより、UsedRange ...を使用して開いている(アクティブな)ワークシート上のすべてのデータが並べ替えられます。

UnGolfed:

Sub d(a)
  'Clear any Sort preferences that already exists
  ActiveSheet.Sort.SortFields.Clear
  'Use the column if A is negative, the row if A is positive
  ActiveSheet.Sort.SortFields.Add Key:=IIf(a < 0, ActiveSheet.Columns(Abs(a)), ActiveSheet.Rows(Abs(a)))
  'Set the area to sort
  ActiveSheet.Sort.SetRange ActiveSheet.UsedRange
  'Orient sideways if sorting by row, vertical if by column
  ActiveSheet.Sort.Orientation = IIf(a < 0, xlTopToBottom, xlLeftToRight)
  'Actually sort it now
  ActiveSheet.Sort.Apply
End Sub

activesheetがsheet1であると仮定した場合、これを169バイトに減らすことができますSub d(a) With Sheet1.Sort .SortFields.Clear .SortFields.Add IIf(a<0,Columns(Abs(a)),Rows(Abs(a))) .SetRange Sheet1.UsedRange .Orientation=(a<0)+2 .Apply End With End Sub
Taylor Scott

また、.SortFieldsDefined がないと安全に想定できるので.Sortfields.Clear、同様に行を削除できると思います。
テイラースコット

0

Perl 6、43バイト

{($!=$_>0??&[Z]!!*[])o*.sort(*[.abs-1])o$!}

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

カリー化された機能。

説明

{                                         } # Block returning function composed of
                                       o$!  # 1. Apply $! (transpose or not)
                     o*.sort(*[.abs-1])     # 2. Sort rows by column abs(i)-1
     $_>0??&[Z]                             # 3. If i > 0 transpose matrix
               !!*[]                        #    Else identity function
 ($!=               )                       #    Store in $!

0

Physica、45バイト

ArnauldのJS回答に非常に似ています

F=>n;m:n<0&&Sort[->u:u{~n};m]||Zip@F#Zip@m#-n

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

使い方?

より詳細で視覚的な説明は、リンクされた回答にあります。

F=>n;m:           // Create a function F that takes two arguments, n and m.
       n<0&&      // If n < 0 (i.e. is negative)
Sort[->u{~n};m]   // Sort the rows u of m by the result of the function u[~n].
                  // In short, sort by indexing from the end with n.
||    F#Zip@m#-n  // Else, apply F to Zip[m] and -n. Uses a new feature, binding.
  Zip@            // And transpose the result.


0

Clojure、91バイト

(fn f[A i](if(< i 0)(sort-by #(nth %(- -1 i))A)(apply map list(f(apply map list A)(- i)))))

Argh、apply map list* 2。

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