平均が最小の部分行列を見つける


21

整数のnm列の行列が与えられます。ここで、n、m> 3です。あなたの仕事は、平均値が最も低い3行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

これはので、各言語で最も短いコードが優先されます。最初の言語より短くなくても、既に使用されている言語で回答を投稿することをお勧めします。


また、必ずしも隣接していない行と列との挑戦持つように興味深いものになるだろう
ルイスMendo

いいえ、自分で進めてください:
ルイスメンドー

数学的な意味またはデータ型の意味で整数を意味しますか?つまり、整数の浮動小数点数の行列を取ることができますか?
デニス

数学的な意味。それは私がここで学んだ一つのことで、それはあなたがさまざまな言語でのデータ・タイプ...についての仮定を行うことができるということです
Stewieグリフィン

甘い、それはバイトを節約します。明確にしてくれてありがとう。
デニス

回答:



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アトキン

1
+3\⁺€F÷9Ṃ数バイト節約します。
デニス

@Dennis Wow、それは本当に+3\最初に処理され、重複は次のようになり+3\€ますか?それが起こることを期待していなかった
マイル

1
パーサーは基本的にスタックベースです。\ポップ3+してクイックリンクをプッシュし+3\その後、クイックリンクをポップし、2つのコピーをプッシュする最上位のコピーをポップし、マッピングバージョンをプッシュします。
デニス


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

パイソン293の 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はタプルのリストを受け取り再帰関数(またはマトリックス表す任意の他の割出し可能2D反復可能であるMの)再帰的平均の最小の計算3×3の左上隅の部分行列およびfはに再帰的に適用Mなし最初の行と最初の列のないM。

f(M) 次のことを行います。

  • Mの行が3行未満の場合M[2:]、空のリストになり、fが返されます。

    最初の実行ではn> 3であるため、イニシャルは空のリストを返すことができないことに注意してください。

  • 場合Mは三列を有している以上、M[2:]非空であり、したがってtruthyので、右側のコードはand次の三つの値の最小値を返す、実行されます。

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

    M[:3]利回りの最初の3行Mzip(*...)転置の行と列は、(タプルのリストが得られる)、 sum(...,())(ので、この作品のすべてのタプルを連結する+連結です)、そしてsum(...)/99つの整数の結果リストの平均を計算します。

    f(M[1:])

    最初の行を削除してfMに再帰的に適用します。

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

    行と列を転置し、結果の最初の行を削除します(したがってMの最初の列は、結果にfを再帰的に適用します。

再帰呼び出しで以前に削除されたレイヤーは常に行であるため、Mに十分な行があるかどうかをテストするだけで十分であることに注意してください。

最後に、いくつかの再帰呼び出しが返さ[]れることが問題になると予想されるかもしれません。ただし、Python 2では、nが数値でAが反復可能の場合、比較n < ATrueを返すため、1つ以上の数値と1つ以上の反復可能要素の最小値を計算すると、常に最小の数値が返されます。


3

J、21バイト

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

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

Jにサブアレイ上で動作する適切な方法は、第三の(使用する_3カットの)形手段は動詞適用する大きさの各完全サブアレイ上のアレイのを。それを使用するソリューションでは、あと1バイトしか必要ありませんが、より大きな配列でははるかに効率的です。;.x (u;._3) yuxy

[:<./@,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は、複数の不均衡な括弧で視聴者の注意をそらすことになっています。[またはを使用する必要がありました|:)
マイル

2

ゼリー、18 バイト

milesの回答で使用されているように、n単位の累積加算を使用するトリックを逃しました-最初の行全体+3\を11に置き換えることができます。

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

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

すべての連続したサブリストを走査し、長さ3と合計(ベクトル化)のサブリストのみを保持するフィルターを実行し、結果のリストごとに繰り返して、3×3のサブマトリックスすべての合計を取得し、最終的にそれらを1つのリストにフラット化し、 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は3つの隣接するスライスを圧縮しzip(*s)、それぞれの転置、を横切って合計関数をマッピングします。これにより、単一列のすべての高さの3つのスライスが合計されます。

名前のない関数は、ヘルパー関数を呼び出し、結果に対して再度ヘルパー関数を転置して呼び出します。次に、それぞれの最小値と結果の最小値を見つけ、それを除算し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()メソッドが。より素朴なアプローチよりも、たった12バイトを節約するのにかなりの時間がかかりました。(まだ、おそらくもっと短い方法があります。)

非再帰バージョン、103バイト

ニールの助けを借りて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私はそれがに近いもの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だったと思うが、私の最初の試みは実際にはそれよりも大きかったと思う。
アーナルド

いいですね、バイトを削り取ることができました: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
ニール

@ニールクール。これは、との1以上のバイトを保存することができます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
アルノー


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