查找具有最小均值的子矩阵


21

您会得到一个n×m的整数矩阵,其中n,m> 3。您的任务是找到均值最低的3-by-3子矩阵,然后输出该值。

规则和说明:

  • 整数将为非负数
  • 可选的输入和输出格式
  • 输出必须精确到至少2个十进制小数点(如果不是整数)
  • 子矩阵必须由连续的行和列组成

测试用例:

35    1    6   26   19   24
 3   32    7   21   23   25
31    9    2   22   27   20
 8   28   33   17   10   15
30    5   34   12   14   16
 4   36   29   13   18   11 

Minimum mean: 14

100    65     2    93
  3    11    31    89
 93    15    95    65
 77    96    72    34

Minimum mean: 46.111

1   1   1   1   1   1   1   1
1   1   1   1   1   1   1   1
1   1   1   1   1   1   1   1
1   1   1   1   1   1   1   1

Minimum mean: 1

4   0   0   5   4
4   5   8   4   1
1   4   9   3   1
0   0   1   3   9
0   3   2   4   8
4   9   5   9   6
1   8   7   2   7
2   1   3   7   9

Minimum mean: 2.2222

这是因此每种语言中最短的代码将获胜。我鼓励人们以已经使用的语言发布答案,即使它的长度不小于第一个。


不一定必须具有连续的行和列的挑战也很有趣
Luis Mendo

不,请继续:-)
路易斯·门多

您是在数学意义上还是在数据类型意义上表示整数,即我们可以采用整数浮点矩阵吗?
丹尼斯

数学意义上的。我在这里学到的一件事是,您可以对各种语言的数据类型进行假设...
Stewie Griffin

甜蜜的,节省了一个字节。感谢您的澄清。
丹尼斯

Answers:



11

果冻11 9字节

+3\⁺€F÷9Ṃ

由于@ Dennis节省了2个字节。

在线尝试!

说明

+3\⁺€F÷9Ṃ  Main link. Input: 2d matrix
+3\        Reduce overlapping sublists of size 3 by addition
   ⁺€      Repeat previous except over each row
     F     Flatten
      ÷9   Divide by 9
        Ṃ  Minimum

1
哦,> _ <当然是:D
乔纳森·艾伦

我会对无果冻的果冻版本感兴趣,因为它具有许多有用的功能。
J Atkin

1
+3\⁺€F÷9Ṃ保存几个字节。
丹尼斯

@Dennis Wow,真的是+3\先处理重复项+3\€吗?没想到会发生这种情况
英里

1
解析器本质上是基于堆栈的;\弹出3+推送快速链接+3\弹出快捷链接并推送两个副本,然后弹出最高的副本并推送映射版本。
丹尼斯


8

MATL13 9字节

3thYCYmX<

@ rahnema1的答案端口。

在线尝试!

怎么运行的

考虑输入

[100 65  2 93;
   3 11 31 89;
  93 15 95 65;
  77 96 72 34]

举个例子。

3th   % Push [3 3]
      % STACK: [3 3]
YC    % Input matrix implicitly. Convert 3x3 sliding blocks into columns
      % STACK: [100   3  65  11;
                  3  93  11  15;
                 93  77  15  96;
                 65  11   2  31;
                 11  15  31  95;
                 15  96  95  72;
                  2  31  93  89;
                 31  95  89  65;
                 95  72  65  34]
Ym    % Mean of each column
      % STACK: [46.1111 54.7778 51.7778 56.4444]
X<    % Minimum of vector. Display implicitly
      % STACK: [46.1111]

7

Mathematica,37 35字节

感谢@MartinEnder 2个字节!

Min@BlockMap[Mean@*Mean,#,{3,3},1]&

说明

Min@BlockMap[Mean@*Mean,#,{3,3},1]&
    BlockMap[                    ]&  (* BlockMap function *)
                        #            (* Divide the input *)
                          {3,3}      (* Into 3x3 matrices *)
                                1    (* With offset 1 *)
             Mean@*Mean              (* And apply the Mean function twice to
                                        each submatrix *)
Min                                  (* Find the minimum value *)

非常非常光滑!
格雷格·马丁

5

Python 2中93 81 80 79个字节

f=lambda M:M[2:]and min(sum(sum(zip(*M[:3])[:3],()))/9,f(M[1:]),f(zip(*M)[1:]))

在线尝试!

怎么运行的

f是一个递归函数,它接收一个元组列表(或表示矩阵M的任何其他可索引2D迭代对象)并递归计算左上角3×3子矩阵的均值的最小值,而f递归应用于M,而没有它的第一行,M则没有第一列

f(M) 执行以下操作。

  • 如果M少于三行,M[2:]则为空列表,f返回。

    请注意,由于在第一次运行中n> 3,所以初始值不能返回空列表。

  • 如果M具有三行或更多行,M[2:]则为非空,因此为真,因此and执行右边的代码,并返回以下三个值中的最小值。

    min(sum(sum(zip(*M[:3])[:3],()))/9

    M[:3]产生M的前三行,zip(*...)转置行和列(产生一个元组列表),sum(...,())连接所有元组(这是有效的,因为+是串联的),并sum(...)/9计算得到的九个整数列表的平均值。

    f(M[1:])

    递归地将f应用于M并删除其第一行。

    f(zip(*M)[1:])

    转置行和列,删除结果的第一行(因此M的第一列,然后将f递归地应用于结果。

请注意,递归调用中先前删除的层将始终是一行,因此测试M是否具有足够的行将总是足够的。

最后,人们可能希望返回一些递归调用[]会成为问题。但是,在Python 2中,只要n是一个数字并且A是一个可迭代的,比较n < A将返回True,因此,计算一个或多个数字的最小值和一个或多个可迭代的值将始终返回最低的数字。


3

J,21字节

[:<./@,9%~3+/\3+/\"1]

在线尝试!

在J中对子数组进行操作的正确方法是使用_3cut 的第三种()形式,;.其中x (u;._3) y将动词应用于数组u大小x的每个完整子数组上y。使用的解决方案仅需要1个字节,但在较大的阵列上效率更高。

[:<./@,9%~3 3+/@,;._3]

在线尝试!

说明

[:<./@,9%~3+/\3+/\"1]  Input: 2d array M
                    ]  Identity. Get M
                  "1   For each row
              3  \       For each overlapping sublist of size 3
               +/          Reduce by addition
          3  \         For each overlapping 2d array of height 3
           +/            Reduce by addition
       9%~             Divide by 9
[:    ,                Flatten it
  <./@                 Reduce by minimum

1
我喜欢[]它们的外观匹配,但实际上却不匹配。
林恩

1
@Lynn请稍等,这是不对的。J应该用多个不平衡的括号分散观众的注意力。应该使用a [|:)
英里

2

果冻,18 字节

错过了答案,如英里数在答案中所使用的,使用n值累积减少加法-整个第一行可以替换+3\为11。

ẆµL=3µÐfS€
ÇÇ€FṂ÷9

在线尝试!

遍历所有连续的子列表,过滤以仅保留长度为3的子列表,然后对其求和(向量化),然后对每个结果列表重复,以获取所有3×3子矩阵的总和,最后将其平整为一个列表,并取最小值和除以9(构成该最小和的元素数)。


我喜欢过滤子列表的想法。如果该子列表的大小取决于计算值,则很有用。
英里



1

Python 2,96字节

h=lambda a:[map(sum,zip(*s))for s in zip(a,a[1:],a[2:])]
lambda a:min(map(min,h(zip(*h(a)))))/9.

测试用例在Repl.it

带有列表列表的未命名函数a-矩阵的行。

辅助函数h在三个相邻的切片之间滑动,并在zip(*s)每个的转置上映射求和函数。这导致将所有高度的三列单列求和。

未命名的函数调用辅助函数,对结果再次转置并调用辅助函数,然后找到每个的最小值和结果的最小值,然后将其除以9.得出平均值。


1

JavaScript(ES6),107 98 96字节

该函数计算行上的三元组的总和,然后调用自身以对列执行相同的操作,并跟踪最小值M

f=m=>m.map((r,y)=>r.map((v,x)=>M=(z[x<<9|y]=v+=r[x+1]+r[x+2])<M?v:M),z=[M=1/0])&&m[1]?f([z]):M/9

JS对于这种东西有点冗长,并且缺少本机zip()方法。我花了很多时间通过一种更幼稚的方法来保存十几个字节。(但是,可能存在一个更短的方法。)

非递归版本,103字节

在Neil的帮助下节省了2个字节

m=>m.map((r,y)=>y>1?r.map((v,x)=>[..."12345678"].map(i=>v+=m[y-i%3][x+i/3|0])&&(M=v<M?v:M)):M=1/0)&&M/9

测试用例


我对您所谓的天真的方法感兴趣,因为我可以用一种合理的纯方法做到的最好是113个字节:(a,b=a.map(g=a=>a.slice(2).map((e,i)=>a[i]+a[i+1]+e)))=>eval(`Math.min(${b[0].map((_,i)=>g(b.map(a=>a[i])))})`)/9
尼尔(Neil)

@Neil我认为这很接近m=>m.map((r,y)=>r.map((v,x)=>[..."12345678"].map(i=>v+=(m[y+i/3|0]||[])[x+i%3])&&(M=v<M?v:M)),M=1/0)&&M/9,尽管我认为我的首次尝试实际上比这更大。
Arnauld

不错,尽管我可以剃掉一个字节:m=>m.map((r,y)=>y>1&&r.map((v,x)=>[..."12345678"].map(i=>v+=m[y-i%3][x+i/3|0])&&(M=v<M?v:M)),M=1/0)&&M/9
尼尔

@尼尔酷。这样一来,您就可以再节省一个字节m=>m.map((r,y)=>y>1?r.map((v,x)=>[..."12345678"].map(i=>v+=m[y-i%3][x+i/3|0])&&(M=v<M?v:M)):M=1/0)&&M/9
Arnauld

1

05AB1E21 16字节

2FvyŒ3ùO})ø}˜9/W

在线尝试!

说明

2F         }       # 2 times do:
  v     }          # for each row in the matrix
   yŒ3ù            # get all sublists of size 3
       O           # reduce by addition
         )ø        # transpose matrix
            ˜      # flatten the matrix to a list
             9/    # divide each by 9
               W   # get the minimum

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.