Перевірте, чи матриця є матрицею 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.