Знайдіть підматрицю з найменшим середнім


21

Вам дана n-на- матриця цілих чисел, де 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

Це тому найкоротший код на кожній мові виграє. Я закликаю людей публікувати відповіді мовами, які вже використовуються, навіть якщо вона не коротша за першу.


Також було б цікаво зробити виклик з необов’язково суміжними рядами та стовпцями
Луїс Мендо

Ні, продовжуйте самі :-)
Луїс Мендо

Ви маєте на увазі цілі числа в математичному сенсі або типу даних, тобто, чи можемо ми взяти матрицю інтегральних плавців?
Денніс

Математичний сенс. Це одне, чого я тут дізнався, це те, що ви можете робити припущення про типи даних різними мовами ...
Стюі Гріффін

Солодке, що економить байт. Дякуємо за уточнення.
Денніс

Відповіді:



11

Желе , 11 9 байт

+3\⁺€F÷9Ṃ

Збережено 2 байти завдяки @ Dennis .

Спробуйте в Інтернеті!

Пояснення

+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

MATL , 13 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

Математика, 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 - рекурсивна функція, яка приймає список кортежів (або будь-який інший 2D ітерабельний індексатор, який представляє матрицю M ) і рекурсивно обчислює мінімум середнього значення підматриці 3 × 3 у верхньому лівому куті і f застосовується рекурсивно до M без її перший рядок та М без першого стовпця.

f(M) робить наступне.

  • Якщо M має менше трьох рядків, M[2:]це порожній список, який повертається f .

    Зауважте, що оскільки n> 3 у першому запуску, початковий не може повернути порожній список.

  • Якщо M має три рядки або більше, M[2:]він не порожній і, таким чином, truthy, тому код праворуч 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 - це використання третьої ( _3) форми cut, ;.де 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 повинен відволікати глядачів з кількома незбалансованими дужками. Повинні були використати [або |:)
милі

2

Желе , 18 байт

Пропущено хитрість, яку використовують милі у своїй відповіді , використовувати n-розумне кумулятивне зменшення додавання - весь перший рядок можна замінити +3\на 11.

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

Спробуйте в Інтернеті!

Проходить усі суміжні підсписи, фільтрує, щоб зберегти лише ті, що мають довжину 3 та суми (які векторні), потім повторюється для кожного результуючого списку, щоб отримати суми всіх 3-х підматриць і, нарешті, вирівняє їх в один список, приймає мінімум та ділиться на 9 (кількість елементів, що становлять цю мінімальну суму).


Мені подобається ідея фільтруючих підспісок Корисно, якщо розмір цього списку залежав від обчисленого значення.
милі

2

Pyth, 19 байт

chSsMsMs.:R3C.:R3Q9

Програма, яка приймає введення списку списків і друкує результат.

Тестовий набір

Як це працює

[Пояснення, що надходить пізніше]



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 байти

Збережено 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.
Ніл

@Neil Cool. Це дозволяє зберегти ще один байт за допомогою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
Арнольд


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.