บีบอัดเมทริกซ์เบาบาง


18

บีบอัดเมทริกซ์เบาบางใช้แถวเบาบางอัด (CSR จำหรือเยลรูปแบบ)

ทั้งหมดนี้เป็นรูปแบบการบีบอัดเดียวกัน (ไม่สนใจเยลใหม่)

อินพุตอาจเป็นโครงสร้างข้อมูล 2d ใด ๆ (รายการ, ฯลฯ ): เช่น

[[0 0 0 0],
 [5 8 0 0],
 [0 0 3 0],
 [0 6 0 0]]

และผลผลิตที่ควรจะเป็นสามโครงสร้างข้อมูล 1D (รายการ ฯลฯ ) ที่หมายถึงผลผลิตA, IAและJAยกตัวอย่างเช่น

[5, 8, 3, 6]
[0, 0, 2, 3, 4]
[0, 1, 2, 1,]

กระบวนการนี้อธิบายโดยวิกิพีเดีย:

  • อาร์เรย์ A มีความยาว NNZ และเก็บรายการที่ไม่ใช่ศูนย์ทั้งหมดของ M ในลำดับจากซ้ายไปขวาบนลงล่าง ("แถวหลัก")

  • IA ของอาร์เรย์มีความยาว m + 1 ซึ่งนิยามโดยนิยามแบบเรียกซ้ำ:

    • IA [0] = 0 IA [i] = IA [i - 1] + (จำนวนองค์ประกอบที่ไม่ใช่ศูนย์ในแถว (i - 1) -th ในเมทริกซ์ดั้งเดิม)

    • ดังนั้นองค์ประกอบ m แรกของ IA เก็บดัชนีลงใน A ขององค์ประกอบที่ไม่ใช่ศูนย์แรกในแต่ละแถวของ M และองค์ประกอบสุดท้าย IA [m] เก็บ NNZ จำนวนขององค์ประกอบใน A ซึ่งสามารถคิดได้ว่าเป็น ดัชนีใน A ขององค์ประกอบแรกของแถว phantom ที่อยู่นอกเหนือจากจุดสิ้นสุดของเมทริกซ์ M ค่าของแถว i-th ของเมทริกซ์ดั้งเดิมถูกอ่านจากองค์ประกอบ A [IA [i]] ถึง A [IA [i + 1] - 1] (รวมทั้งสองด้าน) ได้แก่ ตั้งแต่เริ่มต้นของแถวหนึ่งไปจนถึงดัชนีสุดท้ายก่อนเริ่มต้นถัดไป [5]

    • อาร์เรย์ที่สามคือ JA ประกอบด้วยดัชนีคอลัมน์ใน M ของแต่ละองค์ประกอบของ A และด้วยเหตุนี้จึงมีความยาว NNZ เช่นกัน

หากภาษาของคุณไม่รองรับโครงสร้างข้อมูลจริงอินพุตและเอาต์พุตอาจเป็นข้อความ

กรณีทดสอบ

อินพุต 1:

[[0 0 0 0],
 [5 8 0 0],
 [0 0 3 0],
 [0 6 0 0]]

เอาท์พุท 1:

[ 5, 8, 3, 6 ]
[ 0, 0, 2, 3, 4 ]
[ 0, 1, 2, 1, ]

อินพุต 2

[[10 20 0 0 0 0],
 [0 30 0 40 0 0],
 [0 0 50 60 70 0],
 [0 0 0 0 0 80]]

เอาท์พุท 2:

[ 10 20 30 40 50 60 70 80 ]
[  0  2  4  7  8 ]
[  0  1  1  3  2  3  4  5 ]

อินพุต 3:

[[0 0 0],
 [0 0 0],
 [0 0 0]]

เอาท์พุท 3:

[ ]
[ 0 0 0 0 ]
[ ]

อินพุต 4:

[[1 1 1],
 [1 1 1],
 [1 1 1]]

เอาท์พุท 4:

[ 1 1 1 1 1 1 1 1 1 ]
[ 0 3 6 9 ]
[ 0 1 2 0 1 2 0 1 2 ]

อินพุต 5:

[[0 0 0 0],
 [5 -9 0 0],
 [0 0 0.3 0],
 [0 -400 0 0]]

ผลลัพธ์ 5:

[ 5, -9, 0.3, -400 ]
[ 0, 0, 2, 3, 4 ]
[ 0, 1, 2, 1, ]

สมมติว่าอินพุตอาจมีจำนวนจริงใด ๆ คุณไม่จำเป็นต้องพิจารณาสัญลักษณ์ทางคณิตศาสตร์หรือการแทนเลขชี้กำลัง (เช่น 5,000 จะไม่ถูกป้อนเป็น 5e3) คุณจะไม่จำเป็นต้องจับinf, -inf, NaNหรืออื่น ๆ 'หลอกตัวเลข' คุณสามารถแสดงตัวเลขที่แตกต่างออกไปได้ (5,000 อาจเป็น 5e3 ถ้าคุณเลือก)

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

นี่คือซึ่งมีจำนวนไบต์น้อยที่สุดเป็นผู้ชนะ

ลีดเดอร์

นี่คือ Stack Snippet เพื่อสร้างทั้งกระดานผู้นำปกติและภาพรวมของผู้ชนะตามภาษา

เพื่อให้แน่ใจว่าคำตอบของคุณปรากฏขึ้นโปรดเริ่มคำตอบด้วยหัวข้อโดยใช้เทมเพลต Markdown ต่อไปนี้:

# Language Name, N bytes

ที่Nมีขนาดของส่งของคุณ หากคุณปรับปรุงคะแนนของคุณคุณสามารถเก็บคะแนนเก่าไว้ในพาดหัวโดยการตีพวกเขาผ่าน ตัวอย่างเช่น

# Ruby, <s>104</s> <s>101</s> 96 bytes

หากคุณต้องการรวมหลายตัวเลขไว้ในส่วนหัวของคุณ (เช่นเนื่องจากคะแนนของคุณคือผลรวมของสองไฟล์หรือคุณต้องการแสดงรายการการลงโทษการตั้งค่าสถานะของล่ามแยกต่างหาก) ตรวจสอบให้แน่ใจว่าคะแนนจริงเป็น ตัวเลขสุดท้ายในส่วนหัว:

# Perl, 43 + 2 (-p flag) = 45 bytes

นอกจากนี้คุณยังสามารถตั้งชื่อภาษาให้เป็นลิงค์ซึ่งจะปรากฏในตัวอย่างกระดานแต้มนำ:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


สามารถใช้ดัชนีที่อิงกับ 1 สำหรับแถวสุดท้ายได้หรือไม่
Leo

@Leo สำหรับ JA หรือไม่ ไม่
Pureferret

1
ไม่IA[0] = 0จำเป็นเลยเหรอ? จำเป็นต้องกำหนดIA[i] = IA[i − 1]...เท่านั้น แต่เราสามารถระบุได้ว่าหากi-1 < 0ใช้ 0 นั่นคือ IA [0] เท่ากับ 0 เสมอจึงสามารถบีบอัดได้ (ใช่ฉันรู้ว่านี่เป็นคำวิจารณ์ของอัลกอริทึม ไม่ใช่ความท้าทายนี้)
Draco18s

เราจะมีความท้าทายกลับกันหรือไม่?
อดัม

1
เรียบร้อย! ไม่เคยพบรูปแบบใดรูปแบบหนึ่งมาก่อน แต่ฉันดีใจที่เห็นคนอื่นเห็นแบบนั้นมาก่อน (ฉันไม่ควรเป็นคนที่เห็นการเพิ่มประสิทธิภาพเล็กน้อยในอัลกอริทึมแบบเก่านี้)
Draco18s

คำตอบ:


6

MATL , 19 ไบต์

!3#f!Dx0Gg!XsYshDq!

อินพุตใช้;เป็นตัวคั่นแถว

ลองออนไลน์! หรือตรวจสอบทุกกรณีทดสอบ: 1 , 2 , 3 , 4 , 5

คำอธิบาย

!     % Implicit input. Transpose
3#f   % 3-output version of find: it takes all nonzero values and pushes
      % their column indices, row indices, and values, as column vectors
!     % Transpose into a row vector
D     % Display (and pop) vector of values
x     % Delete vector of row values
0     % Push 0
G     % Push input
g     % Convert to logical: nonzeros become 1
!     % Transpose
Xs    % Sum of columns. Gives a row vector
Ys    % Cumulative sum
h     % Prepend the 0 that's below on the stack
D     % Display (and pop) that vector
q     % Subtract 1 from the vector of row indices
!     % Transpose into a row vector. Implicitly display


3

Haskell, 87 ไบต์

f s|a<-filter(/=0)<$>s=(id=<<a,scanl(+)0$length<$>a,s>>= \t->[i|(i,e)<-zip[0..]t,e/=0])

ลองออนไลน์!

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

a<-filter(/=0)<$>s           -- let a be the list of lists with all 0 removed]
                             -- e.g. [[1,0,0],[0,3,4]] -> [[1],[3,4]]

                             -- return a triple of

id=<<a                       -- a concatenated into a single list -> A 

scanl(+)0$length<$>a         -- partial sums of the length of the sublists of a
                             -- strating with an additional 0 -> IA

s>>=                         -- map the lambda over the sublists of s and concatenate
                             -- into a single list
   \t->[i|(i,e)<-zip[0..]t,e/=0]  -- the indices of the non-zero elements -> JA


2

APL (Dyalog) , 31 28 ตัวอักษรหรือ36 33 ไบต์ *

ต้องใช้⎕IO←0การจัดทำดัชนีตามศูนย์ I / O เป็นรายการของรายการ

{(∊d)(0,+\≢¨d←⍵~¨0)(∊⍸¨⍵≠0)}

ลองออนไลน์!

{} ฟังก์ชั่นไม่ระบุชื่อโดยมีการโต้แย้งโดย

(... )(... )(...)  กลับรายการของสามสิ่ง:

  ⍵≠0 บูลีนที่แตกต่างโต้แย้งจาก 0
  ⍸¨ɩ ndices ของคนเหล่านั้นสำหรับแต่ละรายการย่อย
  ε nlist (เรียบ) จะรวมเข้าไปในรายการเดียว

  ⍵~¨0 ลบศูนย์จากแต่ละรายการย่อยของอาร์กิวเมนต์
  d← ร้านค้าที่เป็นd
  ≢¨  นับแต่ละ
  +\ ผลรวมสะสม
  0, ย่อหน้าศูนย์

  ∊dε nlist (เรียบ) dจะรวมเข้าไปในรายการเดียว

  


* ในการทำงานใน Dyalog คลาสสิกเพียงแทนที่ด้วย⎕U2378


ดีฉันไม่เข้าใจรูปแบบการป้อนข้อมูลใช่ไหม f 4 4⍴แล้วค่า
Pureferret

@Pureferret fรหัสกำหนดฟังก์ชั่น การป้อนข้อมูลเป็นจริง REPL ซึ่งเรียกfผลของการ4 4⍴…ที่อา eshapes ข้อมูลลงใน 4 × 4 เมทริกซ์
Adám

1
Rho สำหรับeshapes r ฉันเข้าใจแล้ว!
Pureferret

1
@Pureferret ฉันได้อัปเดตลองออนไลน์แล้ว! ลิงก์ไปยังดีกว่าแสดงกรณีทดสอบ
Adám

2

PHP , 107 ไบต์

<?for($y=[$c=0];$r=$_GET[+$l++];)foreach($r as$k=>$v)!$v?:[$x[]=$v,$z[]=$k,$y[$l]=++$c];var_dump($x,$y,$z);

ลองออนไลน์!

PHP , 109 ไบต์

<?$y=[$c=0];foreach($_GET as$r){foreach($r as$k=>$v)if($v){$x[]=$v;$z[]=$k;$c++;}$y[]=$c;}var_dump($x,$y,$z);

ลองออนไลน์!


จำเป็นต้องใช้ตัวเลขเป็นสตริงหรือไม่?
Pureferret

1
@Pureferret การป้อนข้อมูลใด ๆ ใน PHP เป็นสตริงหรืออาร์เรย์ของสตริง ฉันยังไม่ได้ป้อนอินพุตดังนั้นหากคุณต้องการให้ผลลัพธ์นั้นเป็น int หมดจดแทนที่$x[]=$v ด้วย$x[]=+$v
JörgHülsermann

2

JavaScript (ES6), 117 ไบต์

a=>[a.map((b,i)=>(b=b.filter((x,c)=>x&&o.push(c)),m[i+1]=m[i]+b.length,b),m=[0],o=[]).reduce((x,y)=>x.concat(y)),m,o]

อินพุตเป็นอาร์เรย์ตัวเลขสองมิติและเอาต์พุตเป็นอาร์เรย์ของ [A, IA, JA]มิติของตัวเลขและการส่งออกเป็นอาร์เรย์ของ

อธิบาย

a=>[
    a.map((b,i) => (                                // map each matrix row
            b = b.filter((x,c) => x                 // filter to only non-zero elements
                && o.push(c)                        // and add this index to JA
            )
            m[i+1] = m[i] + b.length,               // set next value of IA
            b                                       // and return filtered row
        ),
        m=[0],o=[]                          // initialize IA (m) and JA (o)
    ).reduce((x,y) => x.concat(y)),                 // flatten the non-zero matrix
m,o]                                                // append IA and JA

การทดสอบ



1

Perl 6 , 84 ไบต์

{.flatmap(*.grep(+*)),(0,|[\+] .map(+*.grep(+*))),.flat.kv.flatmap:{$^a%.[0]xx?$^b}}

ลองออนไลน์!

$_อาร์กิวเมนต์เมทริกซ์เดียวใน

  • .flatmap(*.grep(+*)) เลือกองค์ประกอบที่ไม่ใช่ศูนย์ของเมทริกซ์ทั้งหมด
  • [\+] .map(+*.grep(+*))คือการลดรูปสามเหลี่ยมของจำนวนองค์ประกอบในแต่ละแถว (ซึ่งบางภาษาเรียกscan) (0,|...)เติมศูนย์ให้กับรายการนั้น
  • .flat.kvสร้างรายการดัชนีขององค์ประกอบทั้งหมดของเมทริกซ์ .flatmap: { $^a % .[0] xx ?$^b }แผนที่แบนเหนือโมดูลัสของแต่ละดัชนีโดยจำนวนคอลัมน์ในอาเรย์ ( .[0]จำนวนองค์ประกอบในแถวแรก), ทำซ้ำโดยองค์ประกอบของตัวเองตีความว่าเป็นบูลีน นั่นคือองค์ประกอบที่ไม่ใช่ศูนย์จะถูกจำลองหนึ่งครั้งและองค์ประกอบศูนย์จะถูกจำลองแบบศูนย์ครั้ง (เช่นลบออก)

1

Python + SciPy, 79 ไบต์

ฉันคิดว่าบิวด์อินไม่ได้รับอนุญาต

from scipy.sparse import*
A=csr_matrix(input())
print A.data,A.indptr,A.indices

ยอมรับอินพุตในรูปแบบ [[0, 0, 0, 0],[5, 8, 0, 0],[0, 0, 3, 0],[0, 6, 0, 0]]


1

Japt , 31 27 ไบต์

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

[Uc f U®£X©NpYÃZèÃå+ iT NÅ]

ทดสอบ ( -Qตั้งค่าสถานะเพื่อการสร้างภาพข้อมูลเท่านั้น)


คำอธิบาย

Uการป้อนข้อมูลโดยปริยายของอาร์เรย์
[[1,1,1],[1,1,1],[1,1,1]]

Uc f

สำหรับ sub--array แรกเราจะแผ่ ( c) Uและกรอง ( f) มันโดยกำจัดองค์ประกอบที่เป็นเท็จ (เช่น 0s)
[1,1,1,1,1,1,1,1,1]

U®         Ã

เรากำลังจะสร้างอีก 2 Uย่อยอาร์เรย์ในเวลาเดียวกันโดยการทำแผนที่มากกว่า

£     Ã

เราแม็พกับแต่ละองค์ประกอบ (sub-array) ใน U

Xเป็นองค์ประกอบปัจจุบันของอาร์เรย์ย่อยปัจจุบันและ©เป็นตรรกะ AND ( &&) ดังนั้นหากXไม่ใช่ความจริง (ไม่เป็นศูนย์) ส่วนถัดไปจะไม่ถูกดำเนินการ

NpY

ใน Japt, Nเป็นอาร์เรย์ที่มีปัจจัยการผลิตทั้งหมดเพื่อให้ที่นี่ถ้าXเป็น truthy เราผลักดัน ( p) ดัชนี ( Y) Nขององค์ประกอบปัจจุบัน
[[[1,1,1],[1,1,1],[1,1,1]],0,1,2,0,1,2,0,1,2]

กลับไปที่แผนที่ของอาเรย์หลักและสำหรับแต่ละองค์ประกอบ ( Z) เราจะได้รับจำนวนองค์ประกอบในอาเรย์ย่อยนั้นที่เป็นจริง (ไม่เป็นศูนย์)
[3,3,3]

å+

ลดอาร์เรย์นี้ด้วยการรวม
[3,6,9]

iT

แทรก ( i) 0 ที่ดัชนี 0 เพื่อทำอาร์เรย์ย่อยที่สองให้สมบูรณ์
[0,3,6,9]

สำหรับชุดย่อยสุดท้ายเราแบ่งNจากองค์ประกอบที่ 1
[0,1,2,0,1,2,0,1,2]


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