「スラッシュ」順のマトリックス


23

2つの正の数N >= 2を与えN <= 100、次の規則に従う行列を作成します。

  • 最初の番号は位置から始まります [0,0]
  • 2番目の番号は位置から始まります [0,1]
  • 3番目の番号が最初の番号(位置[1,0])より下になります
  • 次の数字は「スラッシュ」方向に移動します
  • 使用される番号の範囲は[1, N1 * N2]です。したがって、数値は1から始まり、両方の入力の乗算結果になります。

入力

  • 2つの数字N >= 2N <= 100。最初の数は行の量、2番目の数は列の量です。

出力

  • マトリックス。(多次元配列または改行付き文字列として出力できます)

例:

与えられた数字の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番号は1から開始しなければなりません
ルイス・フェリペ・デ・イエス・ムニョス


1
@LuisfelipeDejesusMunozおそらく注文のより良い用語は「対角線」ですか?個人的には、これを「ジグザグ」と呼びます。これは、カンターのジグザグ証明を思い出させるからです。
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バイト以上です。説明を追加できますか?
ルイスフェリペデジェススムニョス

3
神はそれを気にする、デニス。また、良い仕事。
NIT

6
うわー、それはあまりにも「密接に関連している」。それはマイルの回答の最初のリンクと同じです。両方の投票を検討してください。:)
user202729

1
これを行うことは可能かもしれ<atom><atom>¥þませんが、適切な組み合わせが見つかりません。oþ++þ近くにいるが、そこにたどり着くことができません
ディルナン

1
@akoziこれまでのところ、とても良い。ソートされた配列のインデックスは[1, 2, 3, 4, 5, 6]です。この配列は、マッピングキー用いてソートする1には[1, 1]2[1, 2]3[2, 1]本質的に等、これはソート-辞書アレイにソート・バイ・和アレイからの各対のインデックスを見つける
デニス・


7

R101 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
説明を追加できますか?
ルイスフェリペデジェススムニョス

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;}

@OlivierGrégoireのおかげで-11バイト。@ceilingcatの
おかげで-4バイト。

オンラインでお試しください。

説明:

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

これは最初に列を取り、次に行を取ることに気付きました。
ルイスフェリペデジェススムニョス

@ルイス座標をとるのは慣習だと思うx,y/width,height
ジョーキング


5

J、15バイト

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

このソリューションの場合、マイル単位で-4バイト増加します。ありがとう!

オンラインでお試しください!

J22 19バイト

FrownyFrogのおかげで-3バイト!

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

オンラインでお試しください!

Jでのデニスの素晴らしいJellyソリューションの実装

説明:

二項動詞、左と右の引数(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

[:>:@/:@/:@, テーブルを平坦化し、リストを2回評価し、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
$1(+/:@;)</.@i.配列として入力された15バイト[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問題ありません。APL + WINはオンラインでは使用できませんが、⎕文字を選択した整数に置き換えれば、tryapl.orgのDyalog Webサイトでテストできます。
グラハム

4

Wolfram言語(Mathematica)73 67バイト

上の行の要素を数える: Min[j+k,#2]~Sum~{k,i-1}

現在の行以下の要素をカウントします。 Max[j-k+i-1,0]~Sum~{k,i,#}

テーブルに入れて1を追加します。

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

更新:マトリックス内の通常指定された位置の前にあるすべての位置を、2次元でたった1つの合計でカウントするより短い方法があることに気付きました。

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

オンラインでお試しください!

オンラインでお試しください!




2

Python 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*。デニスの答えに勝るものはないので、Python 3に固執します
。– maxb


2

Japt25 24バイト

エレガントではありませんが、仕事は完了です。Japtで2Dデータを操作するのは難しいです。

;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にフラグを追加しましたが、ソリューションには影響しません。Oliverに
感謝します。

オンラインでお試しください!


いえば×、あなたは置き換えることができ*V
オリバー

1
@Oliverそして、私はショートカットが便利だと思っていましたが、一般的なユースケースではありませんでした。どうもありがとう!
NIT


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バイト以外の1バイトです。

注: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でコードを実行する方法がわからなかったため、Kevin Cruijssenに感謝します。ヘッダーやフッターなどのコードが彼から盗まれます。->彼の答え


1
119バイト:tio.run/...
無知の実施例


1

PHP、115バイト

かなり怠zyなアプローチ。おそらく最短ではありません。

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;}

無名関数、パラメーターとして幅と高さを取り、2次元行列を返します

オンラインで試す



1

アタッシュ、45バイト

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

オンラインでお試しください!

パラメータが切り替えられる匿名ラムダ。これは~、プログラムの先頭に追加することにより、+ 1バイトで修正できます。テストスイートは既にこれを実行しています。

説明

このアプローチは、J回答およびJelly回答に似ています

最初のアイデアは、値のテーブルを生成することです:

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

これにより、両方の入力パラメーターの範囲を使用して追加テーブルが生成されます。inputの[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の回答のアプローチを使用して、配列を(つまり、並べ替えられた値のインデックスを返す)を2回評価できます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]

次に、ゼリーの回答のように、値を正しく切り刻む必要があります。これを行うためにすべての_要素をカットできます。

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

次に、Attacheの0インデックスを補正する必要があります+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バイト

だから私はこれを奇妙な方法でやった。配列の形成方法には2つのパターンがあることに気付きました。

1つ目は、最上部の行パターンに、各項が1-> hから増加する差がある方法です。ここで、hは高さ、lは長さです。そのため、そのパターンに基づいて一番上の行を作成します

dim(3,4)の行列の場合max RoC = 3、フォームの一番上の行が表示されます。

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

代わりにdim(3,9)を与えると、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

2番目のパターンは、行が互いにどのように変化するかです。マトリックスを考慮した場合:

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)

オンラインでお試しください!


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.