对2D数组中的行和列进行块排序


15

给定一个2D整数数组,让我们按块对它的行和列进行排序。这意味着您只需要对给定的行或列进行排序,而是将对其进行排序所需的转换应用于2D数组中的所有其他行或列。

规则

  • 输入将是一个2D整数数组和一个1索引整数。如果数字为正,则此整数将表示要排序的行,如果数字为负(或相反,则为整数)将表示要排序的列。示例:给定4x3(行x列)数组,您可以使用-2参数或参数对第三行进行3。第二个参数永远不会为零,其绝对值也不会大于数组的相应维数。
  • 输出还将是一个2D整数数组,并应用了所需的转换来对给定的行或列进行排序。另外,您也可以将阵列写入STDOUT。
  • 输出数组将具有指定的行或列,以升序排列。请注意,当您需要连续交换两个数字时,将交换数字所在的整个列。当您需要在一列中交换两个数字时,数字所在的整行将被交换。
  • 如果相同的数字在要排序的行/列中多次出现,则根据交换值的方式可能会有几种解决方案,只需对要交换的其余行/列进行相应处理。

例子

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是的,请参阅规则的最后一个示例和最后一点。
查理

Answers:




5

Matlab,73 62 47字节

@(m,i){sortrows(m,-i) sortrows(m',i)'}{(i>0)+1}

在线尝试!

-11个字节,感谢@Giuseppe。

-15个字节,感谢@LuisMendo。


4

Japt18 17字节

行为负,列为正

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

在线尝试!


如果U为负数,则此操作失败-但是,以前的17字节版本有效。
毛茸茸的

@Shaggy我的坏人,尽管我仍然可以使用,但根本没有检查
Luis felipe De jesus Munoz

不过,传递函数作为该函数的第一个参数并不是一个坏主意,ß它会自动应用于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

@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没有原生的转置方法,因此我们需要定义一个:

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

Python 2中71 70个字节

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

在线尝试!


如果n为负,则根据column对行进行排序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;
    }

我们将使用两次shift函数,因此函数变量将节省空间。该函数遍历索引数组的水平维度,并将每个水平数组中索引中的每个项目(水平)添加到新的输出数组中-与Arnoud的JS解决方案相同。

现在,排序很简单,通过按索引编号(参数-1)对水平数组进行排序,可以选择在排序前后对数组进行移位。

看到问题是如何具体讨论数组的,我们几次转换为数组(非常浪费)。在编码高尔夫球中使用这种冗长的语言有点傻。


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;
    }

新的全线方法;否定答案仍然按元素索引对数组排序。否则,将创建索引数组的值-索引对的集合并按值排序。这有效地创建了要添加的索引的集合。然后,对于每个阵列,选择预定位置的元素。相当多的代码修整和丑陋,丑陋,丑陋的“默默地吸吮”输入参数的重用,然后就走了……142个字节。

同样,必须严格执行arrays参数,这会增加.ToArray()调用的开销。

135个字节的声明,是吗?C#7.2推断的值元组会额外修剪三个字节,但tio.run不允许。因此,这是我决定发布的答案,以方便验证。


1
好答案。打高尔夫球有一些小东西。(a,s)=>可能是一个烦人的事情a=>s=>(s<0)?不需要括号,-s-1可以是~s在线尝试:137个字节
Kevin Cruijssen

甜!我从来没有想过让该函数返回另一个函数来保存字符,我很惊讶。谢谢!也是公然忽略not运算符和括号的一个很好的例子。我更新了not和括号,但是会给您所有的功能返回功能荣誉。
Barodus

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;}

在线尝试!

伙计们,这个问题对我来说非常令人沮丧,我发布了我的答案,知道我正在忘记一些东西,幸运的是,我们有像Kevin Cruijssen这样的传奇人物在这里帮助我们:)

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];}

在线尝试!


我还没有看过实际的算法,但是您可以通过删除所有方括号并将所有内容放入循环内(包括内部if语句)来节省35个字节。在线尝试:291字节编辑:这里带有空格缩进,因此您可以更清楚地看到我所做的更改。
凯文·克鲁伊森

@KevinCruijssen我知道我缺少什么
X1M4L

另外,由于您正在修改输入数组,因此可以使其成为可循环输入,a->b->而不是(a,b)->除去return-statement。281字节仍然是一个不错的答案。向我+1。我在05AB1E中进行了挑战,但是这次甚至都不会在Java中尝试过。;)
Kevin Cruijssen



1

Kotlin,192字节

{m:Array<Array<Int>>,s:Int->if(s<0){m.sortBy{it[-s-1]}}else{val a=Array(m[0].size){c->Array(m.size){m[it][c]}}
a.sortBy{it[s-1]}
(0..m.size-1).map{r->(0..m[0].size-1).map{m[r][it]=a[it][r]}}}}

在线尝试!



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控制台中正常工作的地方:

红色,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个字节

好极了!第二长字节数!我没有完全失去: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 ...对打开的(活动)工作表上的所有数据进行排序...,该数据可能有问题,但应仅包含已编辑的单元格。

未打高尔夫球:

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

如果您假设活动工作表为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

另外,我认为您可以放心地假设没有.SortFields定义,因此您也可以删除该.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

物理,45字节

Arnauld的JS answer非常相似。

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)))))

啊,apply map list* 2。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.