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

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
Emigna
источник
4

Haskell , 43 байта

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

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

XNOR
источник
Черт, снова усложняю это. Любопытно, что я получаю это до 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]&
J42161217
источник
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

PHP, 70 байт

<?=!preg_match('/\[([\d,]+?),\d+\],\[\d+,(?!\1)/',json_encode($_GET));
user63956
источник
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раз при фильтрации по диагонали. Затем проверяет, есть ли более одного уникального элемента на диагонали.

DenDenDo
источник
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
RosLuP
источник
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
источник
О, это не работает с отрицательными числами, это нужно исправить :)
eush77
1

MATL , 11 байт

T&Xd"@Xz&=v

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

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

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

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

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

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

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

sundar - Восстановить Монику
источник
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)
NikoNyrh
источник