Проверьте, является ли матрица Теплица


11

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

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

Вам будет предоставлена ​​функция, которая будет принимать two-dimensionalматрицу в качестве аргумента.

Выходной формат:

Возврат 1из функции, если матрица Тёплица , иначе возврат -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
Кроме того, было бы неплохо определение Теплица, так как было бы больше тестовых случаев, в том числе и не тепловых. Не уверен, что вы имеете в виду при добавлении кода.
— xnor

5
Я думаю, что вы должны уменьшить максимальное значение n, м . В противном случае основная часть этой задачи состоит в том, чтобы найти способ обработки матрицы размером 1 терабайт.
— Стьюи Гриффин

1
Будут ли матричные элементы всегда неотрицательными целыми числами?
— Мартин Эндер

Ответы:


7

Mathematica, 42 байта

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

Mathematica не имеет встроенной проверки того, является ли матрица Теплица, но она имеет встроенную функцию для ее генерации. Таким образом, мы генерируем один из первого столбца ( #&@@@#) и первого ряда ( #&@@#) ввода и проверяем, равен ли он входу. Чтобы преобразовать True/ Falseresult в 1/ -1мы используем Boole(чтобы дать 1или 0), а затем просто преобразовать результат с помощью 2x-1.


6

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

Я предполагаю, что мне не нужно обрабатывать матрицы 1 000 000 x 1 000 000, как сказано в задаче. Это работает для матриц, которые не превышают доступную память (в моем случае менее 1 ТБ).

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

Попробуйте онлайн!

Он принимает матрицу в xкачестве входных данных и создает матрицу Теплица на основе значений в первом столбце и первой строке. Затем он проверит каждый элемент матриц на равенство. Если все элементы равны, то вход является матрицей Теплица.

На выходе будет матрица с теми же размерами, что и на входе. Если на выходе есть какие-либо нули, то это считается ошибкой 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был разрешен, я мог бы побить его одним байтом.
— Орджан Йохансен

3

Mathematica, 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}}

еще один, основанный на алгоритме Стьюи Гриффина

Mathematica, 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, это верно, если все сравнения возвращают true)

Попробуйте онлайн!


Хорошее использование <=>для вычисления результата!
— Нил

Как насчет того, |(*x,_),y|чтобы вам не нужно нарезать ломтики x?
— Stefan Pochmann


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 должна быть матрицей некоторого элемента, который позволяет ~ =; раскрутить это

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 # # #

а затем первый столбец повторно проверяется на наличие единственного уникального номера и удаляется, если это так. Матрица Тёплица, если на выходе ничего нет.


О, это не работает с отрицательными числами, это нужно исправить :)
— eush77

1

MATL , 11 байт

T&Xd"@Xz&=v

Попробуйте онлайн!

Простой метод «построить матрицу Теплица и проверить его», который используют первые несколько ответов, почему-то мне показался скучным (и, похоже , в любом случае это было бы на 1 байт длиннее). Поэтому я выбрал метод «проверить, что каждая диагональ содержит только одно уникальное значение».

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

" - перебрать столбцы этого

@Xz - нажать переменную итерации (текущий столбец) и удалить из нее (заполнение) нули

&=- проверка равенства вещания - это создает матрицу со всеми единицами (правда), если все оставшиеся значения равны друг другу, в противном случае матрица содержит несколько нулей, что неверно

v - объединить значения результатов вместе, чтобы создать один конечный вектор результата, который будет либо истинным (все 1 с), либо ложным (некоторые 0)



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.