Diamondize a Matrix


20

รับเมทริกซ์เอาท์พุทเป็นตัวแทนของเมทริกซ์ที่องค์ประกอบด้านบนซ้ายอยู่ด้านบนการต่อต้านเส้นทแยงมุมคือแถวกลางและองค์ประกอบด้านล่างขวาอยู่ที่ด้านล่าง

ตัวอย่างเช่นพิจารณาเมทริกซ์ต่อไปนี้:

1 2 3
4 5 6
7 8 9

เมทริกซ์รุ่นเพชรนี้คือ:

  1
 4 2
7 5 3
 8 6
  9

อินพุตและเอาต์พุต

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

เมทริกซ์จะมีจำนวนเต็มบวกเท่านั้น

เมทริกซ์อินพุตไม่จำเป็นต้องเป็นจตุรัส

เมทริกซ์อินพุตจะมีอย่างน้อย 1 × 1

กรณีทดสอบ

Input:  [[1]]
Output: [[1]]

Input:  [[1,2],[3,4]]
Output: [[1],[3,2],[4]]

Input:  [[1,2,3],[4,5,6]]
Output: [[1],[4,2],[5,3],[6]]

Input:  [[11,2,5],[3,99,3],[4,8,15],[16,23,42]]
Output: [[11],[3,2],[4,99,5],[16,8,3],[23,15],[42]]

เกณฑ์การให้คะแนน

นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ



ที่เกี่ยวข้อง / ทั่วไป (ไม่คิดว่ามันเป็นล่อลวงเพราะมันอนุญาตเรย์เรย์และต้องมีการหมุนหลายรอบ 45 องศา)
Martin Ender

คำตอบ:


19

J, 7 ไบต์

<@|./.

นี่เป็นคำกริยาที่ไม่มีชื่อซึ่งใช้เมทริกซ์และส่งกลับรายการของ antidiagonals:

   input =. i.3 4
   input
0 1  2  3
4 5  6  7
8 9 10 11

   <@|./. input
┌─┬───┬─────┬─────┬────┬──┐
│0│4 1│8 5 2│9 6 3│10 7│11│
└─┴───┴─────┴─────┴────┴──┘

ทดสอบที่นี่

คำอธิบาย

  • /.เป็นในตัวของ J ที่จะใช้ฟังก์ชั่นการต่อต้านเส้นทแยงมุมแต่ละอัน แต่น่าเสียดายที่การต่อต้าน diagonals เหล่านี้ได้รับในลำดับตรงกันข้ามกับสิ่งที่เราต้องการที่นี่
  • ใน<@|.เราใช้ครั้งแรก|.ที่ย้อนกลับการต่อต้านในแนวทแยงและจากนั้น<ไปที่กล่อง (ซึ่งเป็นวิธีเดียวที่จะกลับอาร์เรย์ ragged ใน J เนื่องจากอาร์เรย์ปกติมักจะเป็นรูปสี่เหลี่ยมผืนผ้าเสมอดังนั้น antidiagonals จะเต็มไปด้วยเลขศูนย์)

นั่นมันบ้าและสวยงาม ฉันจะใช้เวลาในการเรียนรู้ภาษานี้สักวัน
เครื่องจักรโหยหา

5

Python ขนาด 91 ไบต์

e=enumerate
lambda M:[[r[n-i]for i,r in e(M)if-1<n-i<len(r)][::-1]for n,_ in e(M[1:]+M[0])]

ทดสอบบนIdeone


Python + NumPy, 69 ไบต์

import numpy
lambda M:map(M[::-1].diagonal,range(1-len(M),len(M[0])))

คาดหวังอาร์เรย์ 2D NumPy เป็นอินพุตและส่งคืนรายการของอาร์เรย์ NumPy ทดสอบบนIdeone


4

เยลลี่ขนาด 7 ไบต์

ṚŒDṙZL$

ลองออนไลน์!

คำอธิบาย

Ṛ         Reverse the matrix vertically.
 ŒD       Get its diagonals. However these start from 
          the main diagonal, not the corners.
    ZL$   Get the width of the input matrix.
   ṙ      Rotate the list of diagonals left by that many 
          places to obtain the correct order.

ไม่รู้จัก Jelly แต่นั่นไม่ใช่ 7 ไบต์หากต้องการตัวถูกดำเนินการ unicode
Guidobot

5
@Guidobot Jelly ใช้หน้ารหัสที่กำหนดเองที่เข้ารหัสอักขระ 256 ตัวแต่ละตัวที่มันเข้าใจว่าเป็นไบต์เดียว
Dennis

4

Mathematica, 58 56 ไบต์

a=Length;Reverse@#~Diagonal~b~Table~{b,1-a@#,a@#&@@#-1}&

ฟังก์ชั่นไม่ระบุชื่อใช้เวลาอาร์เรย์ที่ซ้อนกัน


คุณสามารถบันทึกเป็นหนึ่งเดียวกับLength[#]ที่เป็น \[Transpose]และอาจจะอีกจาก Lengthaliasing
Sp3000

หรือLength@#&@@#สำหรับ ASCII ที่จำนวนไบต์เดียวกันเท่านั้น
Martin Ender

3

CJam, 17 ไบต์

{eeSf.*::+W%zSf-}

บล็อก (ฟังก์ชัน) ที่ไม่มีชื่อซึ่งคาดว่าเมทริกซ์บนสแต็กและแทนที่ด้วย antidiagonals

ทดสอบที่นี่

สิ่งนี้ (ค้นพบโดย Sp3000) ใช้ได้กับจำนวนไบต์เดียวกัน:

{_,,Sf*\.+W%zSf-}

คำอธิบาย

นี่คือตัวอย่างที่อธิบายได้ดีที่สุด พิจารณาอินพุต:

[[0  1  2  3]
 [4  5  6  7]
 [8  9 10 11]]

ee    e# Enumerate matrix, turning each row [x ... z] into [i [x ... z]] where
      e# i is the vertical index from the top.

[[0 [0  1  2  3]]
 [1 [4  5  6  7]]
 [2 [8  9 10 11]]]

Sf.*  e# Replace each i with a string of i spaces.

[[""   [0  1  2  3]]
 [" "  [4  5  6  7]]
 ["  " [8  9 10 11]]]

::+   e# Prepend these strings to the rows.

[[0  1  2  3]
 ['  4  5  6  7]
 ['  '  8  9 10 11]]   e# Note that each '  corresponds to a space character.

W%    e# Reverse the rows.

[['  '  8  9 10 11]
 ['  4  5  6  7]
 [0  1  2  3]]

z     e# Zip/transpose.

[[ '  '  0]
 [ '  4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

Sf-   e# Remove spaces from each row.

[[ 0]
 [ 4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

3

Python 2, 88 87 ไบต์

lambda L:[filter(None,x)[::-1]for x in map(None,[],*[i*[0]+r for i,r in enumerate(L)])]

เติม 0s, zip จากนั้นลบองค์ประกอบที่ผิดพลาด ส่งคืนรายการของสิ่งอันดับ สิ่งนี้ใช้map(None,...)เพื่อดำเนินการzip_longest (การใส่จุดหายไปด้วยNone) และfilter(None,...)เพื่อลบองค์ประกอบที่ผิดพลาด

น่ารำคาญเราต้องเพิ่ม[]แถวพิเศษลงในmapเพื่อรับประกันว่าจะส่งคืนรายการของ tuples เนื่องจากmap(None,*[[1]])ส่งคืน[1]แทนที่จะ[(1,)]เป็นเมทริกซ์ 1x1 แถวพิเศษจะถูกตัดออกโดยfilterแม้ว่า

(ขอบคุณ @Dennis สำหรับ -1 ไบต์)


3

ทับทิม, 68 66 ไบต์

ฟังก์ชั่นไม่ระบุชื่อ

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • เนื่องจากวิธีการทำงานของเครื่องหมายแดงฉันจึงสามารถบันทึก 2 ไบต์ได้โดยการเพิ่มอาร์เรย์

2

Mathematica, 60 ไบต์

#&@@@#&/@GatherBy[Join@@MapIndexed[List,#,{2}],Tr@*Last]&

โดยที่เป็นอักขระ Unicode ซึ่ง Mathematica อ่านว่าเป็น postfix\[Transpose]ดำเนินการ

นี่นานกว่าโซลูชัน Mathematica อื่น ๆ แต่ฉันคิดว่าฉันจะโพสต์เพราะไม่ได้ใช้ Diagonalsตัวและใช้วิธีการที่แตกต่างอย่างสิ้นเชิง

คำอธิบาย

MapIndexed[List,#,{2}]

นี่เป็นครั้งแรกที่สลับเมทริกซ์ (เช่นที่ antidiagonals ปรากฏในลำดับที่ถูกต้องหากเมทริกซ์แบน) จากนั้นเราแผนที่Listเหนือเซลล์ของเมทริกซ์พร้อมกับดัชนีซึ่งเปลี่ยนองค์ประกอบเมทริกซ์แต่ละแห่งiให้{i, {x, y}}อยู่ในตำแหน่งที่xและyเป็นพิกัดขององค์ประกอบในเมทริกซ์

Join@@...

ส่วนนี้แบนราบด้านนอกสุดเพื่อให้เรามีรายการองค์ประกอบเมทริกซ์แบบแบน (พร้อมพิกัด) ตามลำดับคอลัมน์ที่สำคัญ

GatherBy[..., Tr@*Last]

กลุ่มนี้องค์ประกอบเหล่านั้นด้วยผลรวมของพิกัดของพวกเขา โปรดทราบว่า antidiagonals เป็นเส้นค่าคงที่x+yดังนั้นนี่จึงเป็นการจัดกลุ่มตามที่เราต้องการ คำสั่งซื้อภายในแต่ละกลุ่มจะถูกเก็บรักษาไว้ ตอนนี้เราแค่ต้องกำจัดพิกัดอีกครั้ง สิ่งนี้ทำผ่านความลับที่ค่อนข้าง:

#&@@@#&/@...

ฟังก์ชันนี้แมปกับ#&@@@#&แต่ละกลุ่มซึ่งใช้ #&กับแต่ละองค์ประกอบในกลุ่มและ#เป็นเพียงอาร์กิวเมนต์แรกคือองค์ประกอบเมทริกซ์ดั้งเดิม


คำอธิบายเกี่ยวกับสาเหตุที่อ่านเป็น\[transpose]อะไร?
เสียชีวิต

1
@Falize มันเป็น Unicode codepoint ส่วนตัวที่ใช้งานได้และ glyph Mathematica เชื่อมโยงกับ codepoint นี้เป็น superscript T: reference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]เป็นเพียงการแปล ASCII ของอักขระ Unicode นั้น การคัดลอกอักขระ Unicode หรือการทับศัพท์ลงใน Mathematica จะใช้งานได้
Martin Ender

2

ระดับแปดเสียง 77 ไบต์

ด้วยaccumarrayฟังก์ชั่นการใช้งานที่ไม่เหมาะสม:

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

สิ่งนี้นิยามฟังก์ชันที่ไม่ระบุชื่อ หากต้องการใช้ให้กำหนดให้กับ varible หรือใช้ansหรือการใช้งาน

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

ในการแสดงผลลัพธ์คั่นด้วยช่องว่างและบรรทัดใหม่เท่านั้น: 83 ไบต์

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

นอกจากนี้คุณยังสามารถลองได้ที่นี่


2

JavaScript (Firefox), 86 75 ไบต์

a=>a.concat(a[0]).slice(1).map((_,i)=>[for(v of a)if(n=v[i--])n].reverse())

บันทึกแล้ว 11 ไบต์ขอบคุณ @Neil!

ทำงานได้ใน Firefox 30+ รับอาร์เรย์ของอาร์เรย์


อัลกอริทึมที่ดี แต่คุณสามารถใช้a.concat(a[0]).slice(1)เพื่อรับอาร์เรย์ของความยาวที่เหมาะสม นอกจากนี้[for(of)]ไม่ใช่ ES6; ปกติฉันเขียนมันเป็น (Firefox 30+) หรือบางอย่าง
Neil

@Neil ว้าวผมรู้สึกโง่บิตไม่ได้หาที่จะใช้และconcat sliceขอบคุณ!
user81655

2

อ็อกเทฟ63 63ไบต์

ลบออกหนึ่งไบต์ด้วย@DonMue ... @LuisMendo!

@(a)cellfun(@(x)x(x>0)',num2cell(spdiags(flipud(a)),1),'un',0)

ฉันไปตามเส้นทางที่น่าเบื่อแล้วก็ขับ antidiagonals

เรียกใช้ตัวอย่างในideone


ฉันคิดว่าคุณสามารถตัด'uni'ให้สั้นลง'un'
Luis Mendo

@ LuisMendo ทำไมใช่ฉันทำได้! ขอบคุณ! :)
บีกเกอร์


1

Python 128 ไบต์ (จำนวนมาก)

(lambda A: (lambda A,S:[[A[U][I-U] for U in range(min(S[1]-1,I),max(I-S[0]+1,0)-1,-1)] for I in range(S[1]+S[0]-1)])(A,A.shape))

ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนา & รหัสกอล์ฟ! โดยค่าเริ่มต้นการส่งต่อความท้าทายรหัสกอล์ฟจะต้องมีโปรแกรมหรือฟังก์ชั่นและการใช้หนึ่งในวิธีการที่ได้รับการอนุมัติสำหรับ I / O ไม่อนุญาตให้ใช้ข้อมูลโค้ดที่คาดว่าจะป้อนข้อมูลในตัวแปร hardcoded
เดนนิส

ดูเหมือนว่าคุณสามารถทำงานซ้ำโซลูชันแรกที่ใช้lambdaเป็นแลมบ์ดาที่คุณสามารถใช้เป็นการส่งของคุณ
Alex A.

ฉันจะแลมบ์ดา
Luis Masuelli

lambda A:[[A[U][I-U]for U in range(max(I-len(A)+1,0),min(len(A[0])-1,I)+1)]for I in range(len(A+A[0])-1)](เช่นเดียวกับการแก้ไขต้นฉบับของคุณ) จะสั้นลงเล็กน้อย นอกจากนี้คุณควรเปลี่ยนA[U][I-U]เพื่อA[I-U][U]ที่จะได้รับการปฐมนิเทศจากคำถาม
เดนนิส

ฉันจะตรวจสอบเมื่อกลับถึงบ้าน เหมาะสมแล้ว
Luis Masuelli

1

Pyth , 41 17 ไบต์

tm_<dx+dYk.T+LaYk

ลองออนไลน์!

แรงบันดาลใจจาก@ แก้ปัญหา Doorknob ที่จะเกิดปัญหาอื่น

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

tm_<dx+dYk.T+LaYk
            +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
                     '' '' '' '' 10 11 12
                     '' '' '' '' '' 13 14 15]
          .T        transpose, giving us
                    ['' '' '' '' ''
                     1  '' '' '' ''
                     2  4  '' '' ''
                     3  5  7  '' ''
                     6  8  10 ''
                     9  11 13
                     12 14
                     15]
 m_<dx+dYk          removes all empty strings in the
                    subarrays while reversing each one
t                   remove the first subarray

ความพยายามก่อนหน้า:

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK

ลองออนไลน์!

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

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK    input array stored as Q
JlQ                                          J = len(Q)
   KlhQ                                      K = len(Q[0])
       m                            Ut+JK    list for d from 0 to J+K-1:
        _m       }AAAAAAAAAABBBBBBBB             reversed list for k from A to B, where:
                  h.MZ,0-dtK                       A = max(0, d-(K-1))
                       0-dtK                               0  d-(K-1)
                            h.mb,tJd               B = min(J-1, d)
                                 tJd                       J-1  d
          @@Qk-dk                                    Q[k][d-k]

1

Groovy, 77 73 75

{i->o=[].withDefault{[]};a=0;i.each{b=0;it.each{o[a+b++].add(0,it)};a++};o}

ใช้อาร์เรย์ของอาร์เรย์เป็นอินพุตและส่งคืนอาร์เรย์ของอาร์เรย์

ลองมัน

แก้ไข: ฉันลืมที่จะส่งออก anwser หลังจากเพิ่มคะแนนไปถึง 75

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