เมทริกซ์ตามลำดับ“ สแลช”


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 สำหรับตัวเลขใด ๆ ได้หรือไม่?
Jo King

2
@JoKing ไม่ต้องเริ่มต้นที่ 1
Luis felipe De jesus Munoz

5
ที่เกี่ยวข้องอย่างใกล้ชิด
AdmBorkBork

1
@LuisfelipeDejesusMunoz บางทีคำที่ดีกว่าสำหรับการสั่งซื้อคือ "diagonals"? โดยส่วนตัวฉันจะเรียกมันว่า "ซิกแซก" เพราะมันทำให้ฉันนึกถึงบทพิสูจน์ซิกแซกของคันทอร์ แต่นั่นอาจทำให้สับสน
mbomb007

2
@ LuisfelipeDejesusMunoz anti-diagonal เป็นคำศัพท์สำหรับ diagonal อื่น ๆ
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+ ไบต์ คุณช่วยเพิ่มคำอธิบายได้ไหม?
Luis felipe De jesus Munoz

3
พระเจ้าเจ้ากรรมเดนนิส นอกจากนี้งานที่ดี
นิตย์

6
ว้าวมันมีความเกี่ยวข้องอย่างใกล้ชิด นั่นเป็นเหมือนการเชื่อมโยงครั้งแรกในคำตอบไมล์ พิจารณา upvoting ทั้งสองอย่าง :)
user202729

1
ฉันคิดว่าอาจเป็นไปได้ที่จะทำเช่นนี้ด้วย<atom><atom>¥þแต่ฉันไม่พบชุดค่าผสมที่เหมาะสม oþ++þอยู่ใกล้ แต่ไม่ได้ไปถึงจุดนั้น
dylnan

1
@akozi จนถึงดีมาก [1, 2, 3, 4, 5, 6]ดัชนีของอาร์เรย์เรียงเป็น เรียงลำดับอาร์เรย์นี้โดยใช้คีย์ที่แผนที่1เพื่อ[1, 1], 2ไป[1, 2], 3ไป[2, 1]ฯลฯ เป็นหลักพบนี้ดัชนีของแต่ละคู่จาก array เรียงตามจำนวนเงินในการเรียง-lexicographically อาร์เรย์
เดนนิส


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
คุณช่วยเพิ่มคำอธิบายได้ไหม?
Luis felipe De jesus Munoz

1
@LuisfelipeDejesusMunoz เพิ่ม หากมีสิ่งใดไม่ชัดเจนแจ้งให้เราทราบและฉันจะพยายามอธิบายให้ชัดเจน
Giuseppe

1
rank(x,1,"f")คือ 2 order(order(x))ไบต์สั้นกว่า
nwellnhof

@nwellnhof โอ้ดีมาก แต่การใช้rank(x,,"l")ก็จะกำจัดtเช่นกัน
Giuseppe

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
Jo King


5

J , 15 ไบต์

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

-4 ไบต์เพิ่มเติมสำหรับการแก้ปัญหานี้ด้วยไมล์ ขอบคุณ!

ลองออนไลน์!

J , 22 19 ไบต์

-3 ไบต์ขอบคุณ FrownyFrog!

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

ลองออนไลน์!

การใช้งานโซลูชันเจลลี่ที่ยอดเยี่ยมของ Dennis ใน J

คำอธิบาย:

Dyadic verb, ใช้อาร์กิวเมนต์ซ้ายและขวา (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

@ FronyFrog - แน่นอนฉันรู้สึกงี่เง่ามันน่ารังเกียจมากเลยตอนนี้ ขอขอบคุณ!
Galen Ivanov

1
15 ไบต์$1(+/:@;)</.@i.พร้อมอินพุตเป็นอาร์เรย์[r, c]
ไมล์

@miles: เจ๋งมากขอบคุณ! ฉันพยายาม/.แต่ could't บรรลุผลของคุณ :)
เลน Ivanov

4

APL + WIN, 38 หรือ 22 ไบต์

แสดงพร้อมต์สำหรับคอลัมน์อินพุตจำนวนเต็มจากนั้นแถว:

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

หรือ:

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

ขึ้นอยู่กับการประยุกต์ใช้เกรดขึ้นสองเท่าของ Dennis พลาดว่า :(


1
ขออภัยสำหรับคำถาม แต่มีที่ไหนที่ฉันสามารถทดสอบได้หรือไม่
Luis felipe De jesus Munoz

@Luis felipe De jesus Munoz ไม่มีปัญหา APL + WIN ไม่พร้อมใช้งานในบรรทัด แต่คุณสามารถทดสอบบนเว็บไซต์Dyalogที่tryapl.orgหากคุณแทนที่อักขระ⎕ด้วยจำนวนเต็มที่คุณเลือก
เกรแฮม

4

ภาษา Wolfram (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}]&

ลองออนไลน์!

ลองออนไลน์!


4

APL (Dyalog Unicode) , 14 12 ไบต์

{⍵⍴⍋⍋∊+/↑⍳⍵}

ลองออนไลน์!

-2 ขอบคุณngnเนื่องจากการใช้งานที่ชาญฉลาดของ↑⍳เขา

อ้างอิงจากโซลูชัน 5-Jelly Jelly ของ Dennis


∘.+⌿⍳¨⍵->+/↑⍳⍵
ngn

@ngn ว้าวที่ใช้งานฉลาดของรวมกับ
Erik the Outgolfer


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))
Kevin Cruijssen

ขอบคุณ! import*ฉันควรจะมีความคิดของ ฉันจะไม่เอาชนะคำตอบของเดนนิสดังนั้นฉันจะยึดติดกับ Python 3
สูงสุด


2

Japt , 25 24 ไบต์

สง่างามแทบจะไม่ได้ แต่จะได้งานทำ การทำงานกับข้อมูล 2D ใน Japtize นั้นยุ่งยาก

;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 เพื่อให้เห็นภาพผลลัพธ์ได้ง่ายขึ้นซึ่งจะไม่มีผลกับโซลูชัน
Bit หนึ่งออกขอบคุณไบต์โอลิเวอร์

ลองออนไลน์!


การพูดของ×คุณสามารถแทนที่ด้วย*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 เป็นภาษา tokenized ; โทเค็นทั้งหมดที่ใช้ที่นี่เป็นหนึ่งไบต์นอกเหนือจาก[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
}

บิ๊กขอบคุณเควิน Cruijssenเพราะผมไม่ทราบวิธีการเรียกใช้รหัสของฉันในติ้ว
รหัสบางอย่างเช่นส่วนหัวและส่วนท้ายถูกขโมยจากเขา -> คำตอบของเขา




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

ทูต 45 ไบต์

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

ลองออนไลน์!

แลมบ์ดานิรนามซึ่งมีการสลับพารามิเตอร์ สิ่งนี้สามารถแก้ไขได้สำหรับ +1 ไบต์โดย~ต่อท้ายโปรแกรม ชุดทดสอบทำสิ่งนี้แล้ว

คำอธิบาย

วิธีการนี้จะคล้ายกับคำตอบ Jและคำตอบของวุ้น

แนวคิดแรกคือการสร้างตารางค่า:

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]

จากนั้นเราต้องสับค่าให้ถูกต้องเช่นเดียวกับในคำตอบของเยลลี่ เราสามารถตัดทุก_องค์ประกอบเพื่อทำสิ่งนี้:

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-index ของ 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 คือความยาว ดังนั้นฉันจึงสร้างแถวบนสุดตามรูปแบบนั้น

สำหรับเมทริกซ์ของสลัว (3,4) ให้ a max RoC = 3เราจะเห็นแถวบนสุดของแบบฟอร์ม

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

สมมติว่าสลัว (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)

ลองออนไลน์!


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.