Перевірте, чи матриця є матрицею Toeplitz


11

Вам буде надано двовимірний масив і число, і вас попросять знайти, чи є дана матриця Toeplitz чи ні.

Формат введення:

Вам буде надана функція, яка буде приймати two-dimensionalматрицю як аргумент.

Формат виводу:

Поверніться 1з функції, якщо матриця - Toeplitz , інакше поверніться -1.

Обмеження:

3 < n,m < 10,000,000

де nкількість рядків, тоді як mбуде кількість стовпців.

Зразок тестового випадку:

Sample Input :
4 
5
6 7 8 9 2
4 6 7 8 9
1 4 6 7 8
0 1 4 6 7 

Sample Output : 
1 

Оцінка балів

Це , тому найкоротша відповідь у байтах виграє.


8
Це хороший виклик, але тут ми віддаємо перевагу меншим вимогам вводу / виводу. Я б запропонував дозволити як програми, так і функції, як за замовчуванням . І щоб дозволити True / False або 1/0 як вихідні дані, або, можливо, будь-які два послідовні різні виходи, як видається, переважні для вирішення проблем.
xnor

15
Крім того, визначення Toeplitz було б добре, як і більше тестових випадків, включаючи не-Toeplitz. Не впевнений, що ви маєте на увазі додавання коду.
xnor

5
Я думаю, ви повинні зменшити максимальне значення n, m . Інакше головна частина цього завдання полягає у пошуку способу обробки матриці 1 терабайт.
Стюі Гріффін

1
Чи завжди елементи матриці будуть невід'ємними цілими числами?
Мартін Ендер

Відповіді:


7

Математика, 42 байти

2Boole[#==ToeplitzMatrix[#&@@@#,#&@@#]]-1&

Mathematica не має вбудованої системи, щоб перевірити, чи є щось матрицею Toeplitz, але у неї є вбудований для її створення. Таким чином, ми генеруємо одне з першого стовпця ( #&@@@#) та першого рядка ( #&@@#) введення та перевіряємо, чи він рівний вводу. Для перетворення True/ Falseрезультату в 1/ -1ми використовуємо Boole(надати 1або 0), а потім просто перетворюємо результат за допомогою 2x-1.


6

Октава , 30 байт

Я припускаю, що мені не доведеться обробляти матриці 1,000,000x1,000,000, як сказано в виклику. Це працює для матриць, які не перевищують доступну пам'ять (у моєму випадку менше 1 ТБ).

@(x)x==toeplitz(x(:,1),x(1,:))

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

Це приймає матрицю xяк вхідний і створює матрицю Toeplitz на основі значень першого стовпця та першого рядка. Потім він перевірить рівність кожного елемента матриць. Якщо всі елементи рівні, то вхід - це матриця Toeplitz.

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

Редагувати:

Щойно помітив суворий формат виводу:

Це працює на 41 байт. З цієї версії може бути поле на байт-два, але я сподіваюся, що правила виведення трохи будуть послаблені.

@(x)2*(0||(x==toeplitz(x(:,1),x(1,:))))-1


5

05AB1E , 11 байт

Œ2ùvy`¦s¨QP

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

Пояснення

Œ             # get all sublists of input
 2ù           # keep only those of length 2
   v          # for each such pair
    y`        # split to separate lists
      ¦       # remove the first element of the second list
       s¨     # remove the last element of the first list
         Q    # compare for equality
          P   # product of stack

4

Haskell , 43 байти

f(a:b:t)|init a==tail b=f$b:t|1>0= -1
f _=1

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


Данг, знову ускладнюючи це. Цікаво, що я розумію, що це до 39 байт з правдою / фальшивим висновком, тож якби Toeplitz = Falseбуло дозволено, я міг би побити його на один байт.
Ørjan Johansen

3

Математика, 94 байти

l=Length;If[l@Flatten[Union/@Table[#~Diagonal~k,{k,-l@#+1,l@#[[1]]-1}]]==l@#+l@#[[1]]-1,1,-1]&

вхід

{{6, 7, 8, 9, 2}, {4, 6, 7, 8, 9}, {1, 4, 6, 7, 8}, {0, 1, 4, 6, 7}}

ще один, заснований на алгоритмі Стіві Гріффіна

Математика, 44 байти

If[#==#[[;;,1]]~ToeplitzMatrix~#[[1]],1,-1]&

2
Вам потрібно визначитися s? Ви не можете просто використовувати #замість цього?
Не дерево

так! ти правий!
J42161217

3

Java 7, 239 233 220 113 байт

int c(int[][]a){for(int i=a.length,j;i-->1;)for(j=a[0].length;j-->1;)if(a[i][j]!=a[i-1][j-1])return -1;return 1;}

-107 байт після підказки щодо використання більш ефективного алгоритму завдяки @Neil .

Пояснення:

Спробуйте тут.

int c(int[][]a){                // Method with integer-matrix parameter and integer return-type
  for(int i=a.length,j;i-->1;)  //  Loop over the rows (excluding the first)
    for(j=a[0].length;j-->1;)   //   Loop over the columns (excluding the first)
      if(a[i][j]!=a[i-1][j-1])  //    If the current cell doesn't equal the one top-left of it:
        return -1;              //     Return -1
                                //   End of columns loop (implicit / single-line body)
                                //  End of rows loop (implicit / single-line body)
  return 1;                     //  Return 1
}                               // End of method

що таке R & c у першій функції?
Міккі Джек

@MickeyJack Рядки та стовпці ( r= nі c= mякщо ви порівнюєте це із завданням).
Кевін Круїссен

Ви не повинні передавати масив як параметр функції? Крім того, існує набагато ефективніший алгоритм для цього, який би скоротив ваш байт приблизно на 50%.
Ніл

1
@KevinCruijssen Просто перевірте, чи всі елементи не в першому рядку чи стовпці рівні елементу по діагоналі вгору та зліва від нього.
Ніл

1
Ах, ви навіть повинні скористатися -->оператором!
Ніл

3

Haskell , 51 байт

t приймає список списків цілих чисел і повертає ціле число.

t m=1-sum[2|or$zipWith((.init).(/=).tail)=<<tail$m]

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

Це могло бути 39 або 38 байт із результатами трити / хибності.

Ідея використовувати initнадихнула відповідь Еміньї 05AB1E, яка використовує дуже подібний метод; до цього я використовував вкладені блискавки.

Як це працює

  • zipWith((.init).(/=).tail)=<<tailє безточковою формою \m->zipWith(\x y->tail x/=init y)(tail m)m.
  • Це поєднує кожну пару послідовних рядів рядків m, перевіряючи, чи перший з вилученим першим елементом відрізняється від другого з другим вилученим елементом.
  • orПотім комбінує перевірки для всіх пар рядків.
  • 1-sum[2|...] перетворює вихідний формат.


2

Рубін , 54 байти

->a,b,m{m.reduce{|x,y|x[0..-2]==y[1,b]?y:[]}.size<=>1}

Точно, як зазначено, можна отримати більше гольфу, якщо буде прийнято гнучке введення / виведення.

Пояснення:

Ітерайте матрицю і порівняйте кожен рядок із лінією вгорі, зміщеною на одну праворуч. Якщо вони різні, використовуйте порожній масив для наступної ітерації. Зрештою, поверніть -1, якщо остаточний масив порожній, або 1, якщо він принаймні 2 елементи (оскільки найменша матриця 3x3, це справедливо, якщо всі порівняння повертаються як істинні)

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


Приємне використання <=>для обчислення результату!
Ніл

Як щодо того, |(*x,_),y|щоб вам не потрібно нарізати x?
Стефан Похман


1

Пітона, 108

r=range
f=lambda x,n,m:all([len(set([x[i][j] for i in r(n) for j in r(m) if j-i==k]))==1 for k in r(1-n,m)])

Зовсім не ефективна, оскільки вона торкається кожного n+mразу під час фільтрування по діагоналях. Потім перевіряє, чи існує більше одного унікального елемента на діагональ.


1

Аксіома, 121 байт

f(m)==(r:=nrows(m);c:=ncols(m);for i in 1..r-1 repeat for j in 1..c-1 repeat if m(i,j)~=m(i+1,j+1)then return false;true)

m має бути матрицею якогось елемента, що дозволяє ~ =; ungolf це

f m ==
  r := nrows(m)
  c := ncols(m)
  for i in 1..(r - 1) repeat
    for j in 1..(c - 1) repeat
      if m(i,j)~=m(i + 1,j + 1)     then return(false)
  true

1

Сітківка , 148 байт

m(1`\d+
$*#
1`#\n\d+\n
@
+`(#*)#@([^#\n]*(#*)\n)(.*)$
$1# $2$1@$4 #$3
@

+`##
# #
+(+s`^(\d+)\b(.*)^\1\b
$1$2#
s`.*^\d.*^\d.*
-1
)%`^[^- ]+ ?

\s+
1

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

N × M вхідна матриця

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

спочатку перетворюється на матрицю N × (N + M-1) шляхом вирівнювання діагоналей таким чином:

# # # 6 7 8 9 2 0
# # 4 6 7 8 9 2 #
# 1 4 6 7 8 9 # #
0 1 4 6 7 8 # # #

а потім перший стовпець повторно перевіряється, щоб він містив єдине унікальне число, і видаляється, якщо це так. Матриця - Toeplitz, якщо вихід порожній.


О, це не працює з від’ємними числами, треба це виправити :)
eush77

1

MATL , 11 байт

T&Xd"@Xz&=v

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

Безпосередньо "побудуйте матрицю Toeplitz і перевірте її", яку використовують в перших кількох відповідях, якось мені здається нудною (і, схоже, це було б у будь-якому випадку на 1 байт довше). Тому я пішов на метод "перевірка кожної діагоналі містить лише одне унікальне значення".

T&Xd - Витягніть діагоналі введення та створіть з ними нову матрицю у вигляді стовпців (набивання нулями за потреби)

" - повторіть через стовпці цього

@Xz - натисніть на змінну ітерації (поточний стовпець) та видаліть із неї (підкладки) нулі

&=- перевірка рівності трансляції - це створює матрицю з усіма 1s (truthy), якщо всі інші значення рівні одна одній, інакше матриця містить деякі 0s, що є хибним

v - об'єднати значення результатів разом, щоб створити один кінцевий вектор результату, який є або truthy (всі 1s), або фальсі (деякі 0s)



0

Clojure, 94 байти

#(if(=(+ %2 %3 -1)(count(set(for[Z[zipmap][i r](Z(range)%)[j v](Z(range)r)][(- i j)v]))))1 -1)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.