คดเคี้ยวไปมาเมทริกซ์


43

ในฐานะที่เป็นส่วนหนึ่งของอัลกอริธึมการบีบอัดมาตรฐาน JPEG จะเปิดใช้งานเมทริกซ์เป็นเวกเตอร์ตามแนวต้านของทิศทางสลับ:

ป้อนคำอธิบายรูปภาพที่นี่

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

[1 2 3 4
 5 6 7 8
 9 1 2 3]

ควรให้ผลผลิต

[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]

กฎระเบียบ

10คุณอาจจะคิดว่าองค์ประกอบเมทริกซ์เป็นจำนวนเต็มบวกน้อยกว่า

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ของฟังก์ชันและส่งผลลัพธ์ผ่าน STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

อินพุตเมทริกซ์อาจถูกกำหนดในรูปแบบรายการที่สะดวกไม่คลุมเครือซ้อนหรือรูปแบบสตริงหรือเป็นรายการแบบเรียบพร้อมกับมิติเมทริกซ์ทั้งสอง (หรือแน่นอนว่าเป็นเมทริกซ์หากภาษาของคุณมี)

เวกเตอร์เอาต์พุตอาจอยู่ในรูปแบบรายการแบบแบนหรือแบบสตริงที่สะดวกใด ๆ

ใช้กฎมาตรฐานของ

กรณีทดสอบ

[[1]]                                               => [1]
[[1 2] [3 1]]                                       => [1 2 3 1]
[[1 2 3 1]]                                         => [1 2 3 1]
[[1 2 3] [5 6 4] [9 7 8] [1 2 3]]                   => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 3 4] [5 6 7 8] [9 1 2 3]]                     => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 6 3 1 2] [5 9 4 7 8 3]]                       => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 5 9 6 3 4 7 1 2 8 3]]                         => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1] [2] [5] [9] [6] [3] [4] [7] [1] [2] [8] [3]]   => [1 2 5 9 6 3 4 7 1 2 8 3]

ความท้าทายที่เกี่ยวข้อง


1
อินพุตสามารถเป็นเมทริกซ์จริงใน J หรือไม่? หรือจะต้องเปลี่ยนจากรายการซ้อนเป็นเมทริกซ์เป็นส่วนหนึ่งของฟังก์ชันหรือไม่?
Gareth

4
ถ้าเราใช้เมทริกซ์เป็นอาร์เรย์ 2D เราอาจจะยังคงใช้มิติเป็นอินพุตได้หรือไม่?
xnor

1
@ กาเร็ ธ ใช่คุณสามารถใช้ประเภทเมทริกซ์เป็นอินพุตได้
Martin Ender

1
@ xnor อืมมมมมมมกว่าคนอื่น ฉันรู้สึกว่าการรับข้อมูลซ้ำซ้อนจำนวนมากนั้นจะนำไปสู่การประมวลผลอินพุตล่วงหน้า
Martin Ender

รายการแบบเรียบสามารถอยู่ในลำดับหลักของคอลัมน์ได้ไหมถ้าเป็นภาษาพื้นเมือง
Luis Mendo

คำตอบ:


27

J, 31 30 14 12 11 ไบต์

[:;<@|.`</.

. มีขนาดใหญ่เกินไป.

ใช้เมทริกซ์เป็นอินพุต

คำอธิบาย

J มีความได้เปรียบที่นี่ มีคำสั่งที่เรียกว่าเฉียง ( /.) ซึ่งใช้เส้นเอียงในทางกลับกันและใช้คำกริยากับพวกเขา ในกรณีนี้ฉันใช้ gerund เพื่อใช้คำกริยาสองคำสลับกัน: <( box ) และ<@|.( reverse and box) จากนั้นเป็นเพียงเรื่องของการแกะกล่องทุกอย่างที่ใช้;( ทำลาย )


26
J เป็นภาษาเดียวที่ทำให้ฉันรู้สึกว่าฉันต้องการปริญญาภาษาอังกฤษขั้นสูงเพื่อทำความเข้าใจ
Alex A.

2
@AlexA btw คำว่า "command" ควรเป็น "adverb"
อดัม

11

Pyth, 24 23 21 20 19 18 17 ไบต์

ssm_W=!Td.T+LaYkQ

รุ่น 17 ไบต์อื่น: ssuL_G=!T.T+LaYkQ

                Q  input
           +L      prepend to each subarray...
             aYk   (Y += ''). Y is initialized to [], so this prepends [''] to
                     the first subarray, ['', ''] to the second, etc.
                   ['' 1  2  3  4
                    '' '' 5  6  7  8
                    '' '' '' 9  1  2  3]
         .T        transpose, giving us
                   ['' '' ''
                    1  '' ''
                    2  5  ''
                    3  6  9
                    4  7  1
                    8  2
                    3]
  m_W=!Td          black magic
 s                 join subarrays together
s                  join *everything* on empty string (which means ''s used for
                     padding disappear)

ขอขอบคุณ@FryAmTheEggmanสำหรับไบต์, @Jakubeสำหรับ 2 ไบต์และ@isaacgสำหรับไบต์!

คำอธิบายของ "มนต์ดำ" พาดพิงถึงเหนือ: m_W=!Tdโดยพื้นฐานแล้วตรงกันข้ามทุก ๆ subarray มันทำได้โดยการจับคู่_W=!Tผ่านแต่ละ subarray Wเป็นแอปพลิเคชั่นที่มีเงื่อนไขดังนั้นจึงเป็น_s (กลับรายการ) subarrays ทั้งหมดที่=!Tเป็นจริง Tเป็นตัวแปร preinitialized ถึงสิบ (truthy) และวิธีการ=!T (T = !T)ดังนั้นจึงสลับค่าของตัวแปรที่เริ่มต้นความจริงและส่งกลับค่าใหม่ซึ่งหมายความว่ามันจะสลับกันระหว่างการคืนค่าความเท็จความจริงความผิดความจริง ... (ให้เครดิตแก่ Jakube สำหรับความคิดนี้)

ชุดทดสอบที่นี่


11

เยลลี่, 24 19 15 13 11 ไบต์

pS€żị"¥pỤị⁵

รับจำนวนแถวจำนวนคอลัมน์และรายการแฟล็กเป็นอาร์กิวเมนต์บรรทัดคำสั่งที่แยกต่างหาก

ลองออนไลน์!

มันทำงานอย่างไร

pS€żị"¥pỤị⁵  Main link. Argument: m (rows), n (columns), A (list, flat)

p            Compute the Cartesian product [1, ..., m] × [1, ..., n]. This yields
             the indices of the matrix M, i.e., [[1, 1], [1, 2], ..., [m, n]].
 S€          Compute the sums of all index pairs.
       p     Yield the Cartesian product.
      ¥      Dyadic chain. Arguments: Sums, Cartesian product.
    ị"       For each index pair in the Cartesian product, retrieve the coordinate
             at the index of its sum, i.e., map [i, j] to i if i + j is odd and to
             j if i + j is even.
   ż         Zip the sums with the retrieved indices.
       Ụ     Sort [1, ..., mn] by the corresponding item in the resulting list.
        ị⁵   Retrieve the corresponding items from A.

Tsk ฉันไม่แน่ใจว่าฉันจะทำให้ฉันสั้นลงได้ไหม : -S
Gareth

ไม่ได้หมายความว่าฉันจะไม่ลอง ...
Gareth

ทำไม Jelly ถึงยังไม่ได้รับการสืบทอดเฉียง ฉันขอแนะนำ glyphs APL และได้ไหม หรืออาจจะสแกนดิเนเวียøและǿ?
อดัม

7

MATL , 28 27 ไบต์

tZyZ}:w:!+-1y^7MGn/*-X:K#S)

ที่ดัดแปลงมาจากคำตอบของฉันที่นี่ แนวคิดทั่วไปคือการสร้างอาร์เรย์ 2 มิติที่มีขนาดเดียวกันกับอินพุตที่เต็มไปด้วยค่าที่เพิ่มขึ้นในลำดับเดียวกันกับเส้นทางซิกแซก จากนั้นเวอร์ชันที่เป็นเส้นตรง (แบน) ของอาร์เรย์นั้นจะถูกจัดเรียงและดัชนีของการเรียงลำดับนั้นจะถูกเก็บไว้ สิ่งเหล่านี้เป็นดัชนีที่จำเป็นต้องใช้กับอินพุตเพื่อสร้างเส้นทางซิกแซก

อินพุตอยู่ในรูปแบบ

[1 2 3; 5 6 4; 9 7 8; 1 2 3]

คำอธิบาย

ลองออนไลน์!

t       % input 2D array. Duplicate
ZyZ}    % get size as length-2 vector. Split into two numbers: r, c
:       % range [1,2,...,c] as a row vector
w:!     % swap, range [1;2;...;r] as a column vector
+       % add with broadcast. Gives a 2D array
-1      % push -1
y^      % duplicate previous 2D array. Compute -1 raised to that
7M      % push [1;2;...;r] again
Gn/     % divide by input matrix size, that is, r*c
*       % multiply
-       % subtract
X:      % linearize 2D array into column array
K#S     % sort and push the indices of the sorting. Gives a column vector
)       % index input matrix with that column vector

4

Matlab, 134 ไบต์

ฉันแค่พยายามทำให้ดีที่สุดเพื่อย่อรหัสของฉันใน Matlab เช่นโทรเลข

function V=z(M)
[m,n]=size(M);
a=(1:m)'*ones(1,n);
b=ones(m,1)*(1:n);
A=a+b-1;
B=a-b;
C=(A.^2+(-1).^A.*B+1);
[~,I]=sort(C(:));
V=M(:);
V=V(I)';

หมายเหตุ:

  1. Mเป็นm×nเมทริกซ์
  2. aและbทั้งสองเมทริกซ์มีขนาดเท่าMกันแต่ละแถวaประกอบด้วยตัวเลขเท่ากับจำนวนแถวในขณะที่แต่ละคอลัมน์ของbเท่ากับจำนวนคอลัมน์ ดังนั้นa+ เป็นเมทริกซ์ที่มีองค์ประกอบเท่ากับยอดรวมของแถวและจำนวนคอลัมน์คือbmatrix(p,q)=p+q
  3. ดังนั้นA(p,q)=p+q-1; B(p,q)=p-qและ
  4. Cมีการระบุทางคณิตศาสตร์เป็นสมการด้านล่าง Zigzagifiedly matrix ที่เพิ่มขึ้น ด้วยสมการเมทริกซ์ที่เพิ่มขึ้นซิกแซกจะทำตามที่แสดงด้านล่าง
C =
     1     2     6     7
     3     5     8    14
     4     9    13    18
    10    12    19    25
  1. Cระบุลำดับขององค์ประกอบของ M ในผลลัพธ์ซิกแซก จากนั้น[~,I]=sort(C(:));ส่งคืนคำสั่งซื้อเช่นIดังนั้นจึงV=V(I)'เป็นผลลัพธ์

ใช่ฉันเพิ่งพบมันตอนนี้ฉันอัปเดต
Guoyang Qin

@AlexA ขอบคุณอเล็กซ์ สำหรับฉันยังใหม่กับสิ่งนี้และฉันต้องการย่อให้สั้นที่สุดเท่าที่จะเป็นไปได้ แต่ทำให้มันเป็นตัวอย่าง ตอนนี้ฉันได้แก้ไขรหัสของฉันแล้ว
Guoyang Qin

ดูดี. โพสต์แรกที่ดี! :)
อเล็กซ์ A.

3

JavaScript (SpiderMonkey 30+), 99 ไบต์

x=>[for(y of[...x,...x[0]].keys())for(z of Array(y+1).keys())if(a=x[y%2?z:y-z])if(b=a[y%2?y-z:z])b]

ทดสอบใน Firefox 44 รับอินพุตเป็นอาร์เรย์ 2D


3

Python 2, 84 ไบต์

lambda N,w,h:[N[i*w+s-i]for s in range(w+h+1)for i in range(h)[::s%2*2-1]if-1<s-i<w]

แจงคำตอบ Nimi ของ รับอาเรย์แบนที่มีความกว้างและความสูงที่กำหนด xsot บันทึกไบต์


88 ไบต์:

lambda M,w,h:[M[i]for i in sorted(range(w*h),key=lambda i:(i/w+i%w,-i*(-1)**(i/w+i%w)))]

รับอาเรย์แบนที่มีความกว้างและความสูงที่กำหนด เรียงลำดับพิกัด 2D ที่สอดคล้องกัน(i/w,i%w)ในลำดับซิกแซกของการเพิ่มผลรวมเพื่อรับ diagonals, tiebroken โดยการเพิ่มหรือลดค่าแถวขึ้นอยู่กับว่าแถวบวกคอลัมน์เป็นเลขคี่หรือคู่


ว่าถ้าเงื่อนไขสามารถสั้นลงอีก
xsot

@ xsot จับที่ดี
xnor

3

Haskell, 79 78 73 ไบต์

(m#h)w=[m!!(y*w+x-y)|x<-[0..h+w],y<-g!!x$[0..x],y<h,x-y<w]
g=reverse:id:g

การป้อนข้อมูลที่เป็นรายการที่แบนที่มีจำนวนแถวและคอลัมน์เช่น->( [1,2,6,3,1,2,5,9,4,7,8,3] # 2) 6[1,2,5,9,6,3,4,7,1,2,8,3]

มันทำงานอย่างไร: เดินผ่านพิกัด x และ y ของเมทริกซ์ ( hแถว, wคอลัมน์) ในลูปซ้อนกันสองลูป:

  | 0 1 2 3 4 5 6 7 8    outer loop               Index is y*w+x-y, i.e.
--+------------------    x from 0 to h+w          the elements are accessed
0 | 1 2 6 3 1 2                                   in the following order:
1 | 5 9 4 7 8 3
2 |                                               1 2 4 6  8 10 
3 |                                               3 5 7 9 11 12
4 |
5 |
6 |
7 | inner loop:
8 | y from 0 to x

เช่นจากบน / ขวาลงล่าง / ซ้ายข้ามจากดัชนีที่ถูกผูกไว้ ( yและxต้องตอบสนองy<hและx-y<w) เมื่อxแม้แต่คำสั่งของภายในวงจะกลับ: yไปจากการx 0ฉันทำเช่นนี้โดยการเลือกฟังก์ชั่นการแก้ไขสำหรับ y ที่หลากหลาย[0..x]ซึ่งเป็นองค์ประกอบของ x TH[reverse,id,reverse,id,...]

แก้ไข: @xnor จัดเรียงลูปและบันทึกอีก 5 ไบต์ ขอบคุณ!


g=id:reverse:gผมคิดว่าคุณสามารถทำได้
xnor

parens บน multication สามารถตัดได้โดยการปัญหา:(y-x)*w (m#h)w=[m!!(x*w+y-x)|y<-[0..h+w],x<-g!!y$[0..y],x<h,y-x<w] g=reverse:id:gการแปลเป็น Python จะช่วยประหยัด 3 ตัวอักษรจากสิ่งที่ฉันมี
xnor

1

Python 2 + NumPy, 122 ไบต์

ฉันยอมรับมัน. ฉันทำงานไปข้างหน้า น่าเสียดายที่วิธีการเดียวกันนี้ไม่สามารถแก้ไขได้อย่างง่ายดายเพื่อแก้ไขความท้าทายที่เกี่ยวข้องอีก 2 รายการ ...

import numpy
def f(m):w=len(m);print sum([list(m[::-1,:].diagonal(i)[::(i+w+1)%2*-2+1])for i in range(-w,w+len(m[0]))],[])

รับอาร์เรย์ numpy เป็นอินพุต ส่งออกรายการ

ลองออนไลน์

คำอธิบาย:

def f(m):
    w=len(m)    # the height of the matrix, (at one point I thought it was the width)
    # get the anti-diagonals of the matrix. Reverse them if odd by mapping odd to -1
    d=[list(m[::-1,:].diagonal(i)[::(i+w+1)%2*-2+1])for i in range(-w,w+len(m[0]))]
            # w+len(m[0]) accounts for the width of the matrix. Works if it's too large.
    print sum(d,[]) # join the lists

แลมบ์ดามีความยาวเท่ากัน:

import numpy
lambda m:sum([list(m[::-1,:].diagonal(i)[::(i+len(m)+1)%2*-2+1])for i in range(-len(m),len(m)+len(m[0]))],[])

1

Python 3, 131 118 115 107 ไบต์

ขึ้นอยู่กับ Principe เดียวกับฉันคำตอบของความท้าทายของ Deusovi

ฉันคิดว่าเราไม่สามารถมีศูนย์ในอินพุท matrice ได้

e=enumerate
lambda s:[k for j,i in e(zip(*[([0]*n+i+[0]*len(s))for n,i in e(s)]))for k in i[::j%2*2-1]if k]

คำอธิบาย

มันทำงานอย่างไร :

            pad with 0      transpose    remove 0    reverse line           concatenate 
                                                     with even index
1 2 3       1 2 3 0 0        1 0 0        1            1                
4 5 6   --> 0 4 5 6 0    --> 2 4 0    --> 2 4     -->  2 4              -->  1 2 4 7 5 3 6 8 9
7 8 9       0 0 7 8 9        3 5 7        3 5 7        7 5 3             
                             0 6 8        6 8          6 8               
                             0 0 9        9            9

ผล

>>> [print([i,f(i)]) for i in [[[1]], [[1, 2], [3, 1]], [[1, 2, 3, 1]], [[1, 2, 3], [5, 6, 4], [9, 7, 8], [1, 2, 3]], [[1, 2, 3, 4], [5, 6, 7, 8], [9, 1, 2, 3]], [[1, 2, 6, 3, 1, 2], [5, 9, 4, 7, 8, 3]], [[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]], [[1], [2], [5], [9], [6], [3], [4], [7], [1], [2], [8], [3]]]]
# [input,                                                          output]
[[[1]],                                                            [1]]
[[[1, 2], [3, 1]],                                                 [1, 2, 3, 1]]
[[[1, 2, 3, 1]],                                                   [1, 2, 3, 1]]
[[[1, 2, 3], [5, 6, 4], [9, 7, 8], [1, 2, 3]],                     [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 1, 2, 3]],                       [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 6, 3, 1, 2], [5, 9, 4, 7, 8, 3]],                         [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]],                           [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1], [2], [5], [9], [6], [3], [4], [7], [1], [2], [8], [3]],     [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]

ควรreverse even lineจะreverse odd linesเป็นอย่างไร
nwp

@nwp ดัชนีเริ่มต้นที่ 0 ^^
Erwan

อาคุณกำลังพูดถึงหมายเลขบรรทัดไม่ใช่ความยาวของบรรทัด ฉันสับสนเหล่านั้นขอโทษ
nwp

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