Матриця в "похилому" порядку


23

Дано два додатних числа N >= 2і N <= 100створимо матрицю, яка дотримується таких правил:

  • Перший номер починається з позиції [0,0]
  • Другий номер починається з позиції [0,1]
  • Третє число йде нижче першого номера (позиція [1,0])
  • Наступні цифри йдуть у напрямку "нахил"
  • Діапазон використовуваних чисел є [1, N1 * N2]. Отже, числа переходять від початку 1 до результату множення обох входів.

Вхідні дані

  • Два числа N >= 2і N <= 100. Перше число - це кількість рядків, друге - кількість стовпців.

Вихід

  • Матриця. (Може виводитися у вигляді багатовимірного масиву або рядка з розривами рядків)

Приклад:

Даний 3 and 5вихід:

1   2   4   7   10
3   5   8   11  13
6   9   12  14  15

Дані числа 2 and 2

1   2
3   4

Дано номери 5 and 5

1   2   4   7   11
3   5   8   12  16
6   9   13  17  20
10  14  18  21  23
15  19  22  24  25

Виграє найкоротший код у байтах.


2
Чи можемо ми використовувати 0 індексації для будь-якого числа?
Джо Кінг

2
@JoKing No. Початок в 1.
Луїс феліпе Де ісус Муноз


1
@LuisfelipeDejesusMunoz Можливо, кращим терміном для замовлення є "діагоналі"? Особисто я би назвав це "зигзагом", тому що це нагадує мені доказ Zig-Zag Кантора, але це може заплутати.
mbomb007

2
@LuisfelipeDejesusMunoz антидіагональ - це термін для іншої діагоналі.
qwr

Відповіді:


21

Желе , 6 5 байт

pSÞỤs

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

Як це працює

pSÞỤs  Main link. Left argument: n. Right argument: k

p      Take the Cartesian product of [1, ..., n] and [1, ..., k], yielding
       [[1, 1], [1, 2], ..., [n, k-1], [n, k]].
 SÞ    Sort the pairs by their sums.
       Note that index sums are constant on antidiagonals.
   Ụ   Grade up, sorting the indices of the sorted array of pairs by their values.
    s  Split the result into chunks of length k.

Блін. Міна - 200+ байт. Чи можете ви додати деякі пояснення PLS?
Luis felipe De jesus Munoz

3
Чорт забирай, Деннісе. Також хороша робота.
Ніт

6
Нічого собі, це занадто "тісно пов'язане". Це ідентично першому посиланню у милях відповіді . Розгляньте питання про обидва. :)
користувач202729

1
Я думаю, що це можливо зробити, <atom><atom>¥þале я не можу знайти правильну комбінацію. oþ++þблизько, але не зовсім потрапляє
dylnan

1
@akozi Поки що, так добре. Індекси відсортованого масиву є [1, 2, 3, 4, 5, 6]. сортує цей масив, використовуючи ключ, який відображає 1на [1, 1], 2до [1, 2], 3і [2, 1]т. д. По суті, це знаходить індекс кожної пари з масиву відсортованих за сумою в відсортованому лексикографічно масиві
Денніс


7

R , 101 60 54 байт

function(M,N)matrix(rank(outer(1:M,1:N,"+"),,"l"),M,N)

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

Дякуємо @nwellnhof за пропозицію о rank

Відповідь Порт Денніса .

Стара відповідь, 101 байт:

function(M,N)matrix(unsplit(lapply(split(1:(M*N),unlist(split(x,x))),rev),x<-outer(1:M,1:N,"+")),M,N)

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

splitробить більшу частину роботи тут; можливо, є алгоритм гравця, але це безумовно працює.

Пояснення:

function(M,N){
x <- outer(1:M,1:N,"+")			# create matrix with distinct indices for the antidiagonals
idx <- split(x,x)			# split into factor groups
items <- split(1:(M*N),unlist(idx))	# now split 1:(M*N) into factor groups using the groupings from idx
items <- lapply(items,rev)		# except that the factor groups are
					# $`2`:1, $`3`:2,3, (etc.) but we need
                                        # $`2`:1, $`3`:3,2, so we reverse each sublist
matrix(unsplit(items,x),M,N)		# now unsplit to rearrange the vector to the right order
					# and construct a matrix, returning the value
}

Спробуйте в Інтернеті! - ви можете використовувати обертання printнавколо будь-якої правої частини завдань, <-щоб побачити проміжні результати, не змінюючи остаточний результат, оскільки printповертає свій вхід.


1
Чи можете ви додати деякі пояснення PLS?
Luis felipe De jesus Munoz

1
@LuisfelipeDejesusMunoz додано. Якщо є щось незрозуміле, дайте мені знати, і я спробую уточнити.
Джузеппе

1
rank(x,1,"f")на 2 байти коротше order(order(x)).
nwellnhof

@nwellnhof О, дуже приємно, але використання rank(x,,"l")також позбудеться цього t.
Джузеппе

6

Java 10, 121 120 109 105 байт

m->n->{var R=new int[m][n];for(int i=0,j,v=0;i<m+n;)for(j=++i<n?0:i-n;j<i&j<m;)R[j][i-++j]=++v;return R;}

-11 байт завдяки @ OlivierGrégoire .
-4 байти завдяки @ceilingcat .

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

Пояснення:

m->n->{                // Method with two integer parameters and integer-matrix return-type
  var R=new int[m][n]; //  Result-matrix of size `m` by `n`
  for(int i=0,j,       //  Index integers, starting at 0
          v=0;         //  Count integer, starting at 0
      i<m+n;)          //  Loop as long as `i` is smaller than `m+n`
    for(j=++i<n?0      //   Set `j` to 0 if `i+1` is smaller than `n`
               :i-n;   //   or to the difference between `i` and `n` otherwise
        j<i&j<m;)      //   Inner loop `j` until it's equal to either `i` or `m`,
                       //   so basically check if it's still within bounds:
      R[j][i-++j]=++v; //    Add the current number to cell `j, i-(j+1)`
  return R;}           //  Return the result-matrix

Я зрозумів, що це спочатку стовпці, а потім рядки.
Luis felipe De jesus Munoz

@Luis Я думаю, що це звичайно взяти координати як x,y/width,height
Джо Кінг,


5

J , 15 байт

$1(+/:@;)</.@i.

Ще 4 байти для цього рішення в милях. Спасибі!

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

J , 22 19 байт

-3 байти завдяки FrownyFrog!

,$[:>:@/:@/:@,+/&i.

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

Реалізація фантастичного рішення Дженіса в Дж.

Пояснення:

Дієдичне дієслово, бере аргумент зліва і справа (mfn)

+/&i. створює списки 0..m-1 і 0..n-1 і складає для них таблицю додавання:

   3 +/&i. 5
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6

[:>:@/:@/:@, згладжує таблицю та класифікує список удвічі та додає до нього 1:

   3 ([:>:@/:@/:@,+/&i.) 5
1 2 4 7 10 3 5 8 11 13 6 9 12 14 15

,$ перетворює список назад у таблицю mxn:

   3 (-@],\[:>:@/:@/:@,+/&i.) 5
1 2  4  7 10
3 5  8 11 13
6 9 12 14 15

1
-@],\,$для −3 байт.
FrownyFrog

@FrownyFrog - Звичайно, я відчуваю себе дурним, це так огидно зараз. Дякую!
Гален Іванов

1
15 байт $1(+/:@;)</.@i.із введенням у вигляді масиву[r, c]
миль

@miles: Дуже круто, дякую! Я намагався, /.але не зміг досягти вашого результату :)
Гален Іванов,

4

APL + WIN, 38 або 22 байти

Підказки для цілого стовпця введення та рядка:

m[⍋+⌿1+(r,c)⊤m-1]←m←⍳(c←⎕)×r←⎕⋄(r,c)⍴m

або:

(r,c)⍴⍋⍋,(⍳r←⎕)∘.+⍳c←⎕

заснований на подвійному застосуванні Денніса на підвищення рівня. Пропустив це :(


1
Вибачте за запитання, але десь я можу його перевірити?
Luis felipe De jesus Munoz

@Luis felipe De jesus Munoz Немає проблем. APL + WIN недоступний в режимі он-лайн, але ви можете протестувати його на веб-сайті Dyalog на tryapl.org, якщо замінити you символів на ваші цілі числа.
Грем

4

Мова Вольфрама (Mathematica) , 73 67 байт

Порахуйте елементи в рядках вище: Min[j+k,#2]~Sum~{k,i-1}

Порахуйте елементи на поточному рядку та нижче: Max[j-k+i-1,0]~Sum~{k,i,#}

Помістіть у таблицю і додайте 1. Voila:

1+Table[Min[j+k,#2]~Sum~{k,i-1}+Max[j-k+i-1,0]~Sum~{k,i,#},{i,#},{j,#2}]&

Оновлення: я зрозумів, що існує коротший спосіб підрахунку всіх позицій попереду нормально заданої позиції в матриці з лише однією сумою за двома вимірами:

Table[1+Sum[Boole[s-i<j-t||s-i==j-t<0],{s,#},{t,#2}],{i,#},{j,#2}]&

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

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




2

Пітон 3 , 164 байти

from numpy import*
r=range
def h(x,y):
 a,i,k,j=-array([i//y+i%y for i in r(x*y)]),1,2,0
 while j<x+y:a[a==-j],i,k,j=r(i,k),k,k+sum(a==~j),j+1
 a.shape=x,y;return a

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

Це, безумовно, не найкоротше рішення, але я подумав, що це весело.


from numpy import*а опускання обох n.трохи коротше. Крім того, ви можете скинути місце на ) for. А перехід на Python 2 дозволяє перейти return aна print a(у Python 3 це було б те саме число байтів print(a)).
Кевін Кройсейсен

Спасибі! Я мав би подумати import*. Я ніколи не
переможу


2

Japt , 25 24 байт

Навряд чи елегантний, але виконує роботу. Робота з двовимірними даними в Japt - хитра.

;N×Ç<U©Ap[] A®Ê<V©Zp°T
A

;                      // Set alternative default vars where A is an empty array.
 N×Ç                   // Multiply the inputs and map the range [0..U*V).
    <U                 // If the current item is less than the second input,
      ©Ap[]            // add a new empty subarray into A.
            A®         // Then, for each item in A,
              Ê<V      // if its length is less than the first input,
                 ©Zp°T // Add the next number in the sequence to it.
A                      // Output the results, stored in A.

Я додав -Qпрапор у TIO для легшої візуалізації результатів, це не впливає на рішення.
Відкусив один байт завдяки Оліверу .

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


Якщо говорити ×, ви можете замінити *V на .
Олівер

1
@Oliver І ось я був, думаючи, що ярлик зручний, але це не звичайний випадок використання. Дуже дякую!
Ніт


2

TI-Basic, 76 байт

Prompt A,B
{A,B🡒dim([A]
1🡒X
For(E,1,B+A
For(D,1,E
If D≤A and E-D<B
Then
X🡒[A](D,E-D+1
X+1🡒X
End
End
End
[A]

Запрошує ввести користувач і повертає матрицю в Ansта друкує її.

TI-Basic - це токенізована мова ; всі використовувані тут жетони є одним байтом, окрім [A]якого є 2 байти.

Примітка: TI-Basic (принаймні, на TI-84 Plus CE) підтримує лише матриці розміром до 99x99, як і ця програма.

Пояснення:

Prompt A,B        # 5 bytes, prompt for user input
{A,B🡒dim([A]      # 9 bytes, make the matrix the right size
1🡒X               # 4 bytes, counter variable starts at 1
For(E,1,B+A       # 9 bytes, Diagonal counter, 1 to A+B-1, but we can over-estimate since we have to check later anyway.
For(D,1,E         # 7 bytes, Row counter, 1 to diagonal count
If D≤A and E-D<B  # 10 bytes, Check if we are currently on a valid point in the matrix
Then              # 2 bytes, If so,
X🡒[A](D,E-D+1     # 13 bytes, Store the current number in the current point in the matrix
X+1🡒X             # 6 bytes, Increment counter
End               # 2 bytes, End dimension check if statement
End               # 2 bytes, End row for loop
End               # 2 bytes, End dimension for loop
[A]               # 2 bytes, Implicitly return the matrix in Ans and print it


2

Java (JDK 10) , 142 131 байт

X->Y->{var A=new int[X][Y];int E=1;for(int y=0;y<Y+X-1;y++)for(int x=0;x<X;x++){if(y-x<0|y-x>Y-1)continue;A[x][y-x]=E++;}return A;}

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

Пояснення:

X->Y->{                            // Method with two integer parameters and integer-matrix return-type
    var A=new int[X][Y];           // The Matrix with the size of X and Y
    int E=1;                       // It's a counter
        for(int y=0;y<Y+X-1;y++)   // For each column plus the number of rows minus one so it will run as long as the bottom right corner will be reached
            for(int x=0;x<X;x++){  // For each row
                if(y-x<0|y-x>Y-1)  // If the cell does not exist becouse it's out of range
                    continue;      // Skip this loop cycle
                A[x][y-x]=E++;     // Set the cell to the counter plus 1
            }
    return A;                      // Return the filled Array
}

Велика подяка Кевіну Крейсейну за те, що я не знав, як запустити свій код на tio .
У нього викрадений якийсь код, як заголовок і колонтитул. -> Його відповідь


1
119 байт: tio.run/…
Втілення


1

PHP, 115 байт

досить ледачий підхід; певно, не найкоротший з можливих.

function($w,$h){for(;$i++<$h*$w;$r[+$y][+$x]=$i,$x--&&++$y<$h||$x=++$d+$y=0)while($x>=$w|$y<0)$y+=!!$x--;return$r;}

анонімна функція, приймає ширину та висоту в якості параметрів, повертає 2d матрицю

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



1

Attache , 45 байт

{Chop[Grade//2<|Flat!Table[`+,1:_2,1:_],_]+1}

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

Анонімні лямбда, де перемикаються параметри. Це можна виправити за 1 байт, попередньо додавши ~до програми. Тестовий набір це вже робить.

Пояснення

Цей підхід схожий на відповідь J та відповідь Jelly .

Перша ідея полягає у створенні таблиці значень:

Table[`+,1:_2,1:_]

Це створює таблицю додавання, використовуючи діапазони обох вхідних параметрів. Для введення [5, 3]це дає:

A> Table[`+,1:3,1:5]
 2 3 4 5 6
 3 4 5 6 7
 4 5 6 7 8

Потім ми це згладжуємо Flat!:

A> Flat!Table[`+,1:3,1:5]
[2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]

Використовуючи підхід у відповіді J, ми можемо оцінити масив (тобто повернути індекси відсортованих значень) двічі, за допомогою Grade//2:

A> Grade//2<|Flat!Table[`+,1:3,1:5]
[0, 1, 3, 6, 9, 2, 4, 7, 10, 12, 5, 8, 11, 13, 14]

Потім нам потрібно правильно порубати значення, як у відповіді Jelly. Для цього ми можемо вирізати всі _елементи:

A> Chop[Grade//2<|Flat!Table[`+,1:3,1:5],5]
 0 1  3  6  9
 2 4  7 10 12
 5 8 11 13 14

Тоді нам просто потрібно компенсувати 0-індексацію Attache +1:

A> Chop[Grade//2<|Flat!Table[`+,1:3,1:5],5]+1
 1 2  4  7 10
 3 5  8 11 13
 6 9 12 14 15

І таким чином ми маємо результат.


1

Python 3 , 259 байт

Тому я зробив це дивним чином. Я помітив, що у способі формування масиву було дві схеми.

Перший - це те, як шаблон верхнього ряду має різницю між кожним членом, що збільшується від 1 -> h, де h - висота, а l - довжина. Тому я будую верхній ряд на основі цього шаблону

Для матриці dim (3,4), що дає A, max RoC = 3ми побачимо верхній рядок форми

1, (1+1), (2+2), (4+3) = 1, 2, 4, 7

Припустимо, замість того, що dim (3,9), що дає a, max RoC = 3ми побачимо верхній рядок

`1, (1+1), (2+2), (4+3), (7+3), (10+3), (13+3), (16+3), (19+3) = 1, 2, 4, 7, 10, 13, 16, 19, 22

Другий візерунок - це те, як змінюються між собою рядки. Якщо ми розглянемо матрицю:

1   2   4   7   11
3   5   8   12  16
6   9   13  17  20
10  14  18  21  23
15  19  22  24  25

і віднімаємо кожен рядок із нижнього рядка (ігноруючи додатковий рядок), який ми отримуємо

2 3 4 5 5
3 4 5 5 4
4 5 5 4 3
5 5 4 3 2

Побачивши цю матрицю, ми можемо помітити, що ця матриця є послідовністю, 2 3 4 5 5 4 3 2де в кожному рядку є 5 членів цього шаблону, зміщених на 1 для кожного рядка. Дивіться нижче для візуального.

         |2 3 4 5 5| 4 3 2
       2 |3 4 5 5 4| 3 2
     2 3 |4 5 5 4 3| 2
   2 3 4 |5 5 4 3 2|

Отже, щоб отримати остаточну матрицю, ми беремо перший створений нами рядок і виводимо цей рядок, доданий із 5 необхідними умовами цього шаблону.

Цей візерунок завжди матиме характер початку 2-> max valueта кінця, max value -> 2де max value = min(h+1, l)та, скільки разів з’явиться максимальне значення, appearances of max = h + l -2*c -2деc = min(h+1, l) - 2

Тож в цілому виглядає мій метод створення нових рядків

1  2  3  7  11 +      |2 3 4 5 5|4 3 2  = 3  5  8  12 16

3  5  8  12 16 +     2|3 4 5 5 4|3 4 2  = 6  9  13 17 20

6  9  13 17 20 +   2 3|4 5 5 4 3|4 2    = 10 14 18 21 23

10 14 18 21 23 + 2 3 4|5 5 4 3 2|       = 15 19 22 24 25

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

o,r=len,range
def m(l,h):
 a,t=[1+sum(([0]+[x for x in r(1,h)]+[h]*(l-h))[:x+1]) for x in r(l)],min(l,h+1);s,c=[x for x in r(2,t)],[a[:]]
 for i in r(h-1):
  for j in r(o(a)):
   a[j]+=(s+[t]*(l+h-2*(t-2)-2)+s[::-1])[0+i:l+i][j]
  c+=[a[:]]
 for l in c:print(l)

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


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