Seyrek bir matrisi sıkıştır


18

Sıkıştırılmış seyrek satırı (CSR, CRS veya Yale formatı) kullanarak seyrek bir matrisi sıkıştırın .

Bunların hepsi aynı sıkıştırma biçimidir (yeni Yale'yi yoksayın).

Giriş herhangi bir 2d veri yapısı olabilir (listelerin listesi, vb.): Ör.

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

Ve çıkış çıkışları ifade üç 1d veri yapıları (liste vs.) olmalıdır A, IAve JAörneğin,

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

İşlem wikipedia tarafından açıklanmaktadır:

  • A dizisi NNZ uzunluğundadır ve M'nin sıfırdan farklı tüm girişlerini soldan sağa yukarıdan aşağıya ("satır-ana") düzende tutar.

  • IA dizisi m + 1 uzunluğundadır. Bu özyinelemeli tanımla tanımlanır:

    • IA [0] = 0 IA [i] = IA [i - 1] + (orijinal matristeki (i - 1) satırındaki sıfır olmayan eleman sayısı)

    • Böylece, IA'nın ilk m elemanları, M'nin her satırındaki ilk sıfır olmayan elemanın A indeksini depolar ve son eleman IA [m], A olarak da düşünülebilen eleman sayısı olan NNZ'yi depolar. Matris M'nin sonunun hemen ötesinde bir hayalet sıranın ilk elemanının A indeksi. Orijinal matrisin i-sıra sırasının değerleri A [IA [i]] ile A [IA [i +) elemanlarından okunur. 1] - 1] (her iki uçta dahil), yani bir satırın başlangıcından sonrakinin başlangıcından hemen önceki son dizine. [5]

    • Üçüncü dizi, JA, A'nın her elemanının M cinsinden sütun indeksini içerir ve bu nedenle de NNZ uzunluğundadır.

Diliniz gerçek veri yapılarını desteklemiyorsa, giriş ve çıkış metin olabilir.

Test senaryoları

Giriş 1:

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

Çıkış 1:

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

Giriş 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]]

Çıkış 2:

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

Giriş 3:

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

Çıkış 3:

[ ]
[ 0 0 0 0 ]
[ ]

Giriş 4:

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

Çıkış 4:

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

Giriş 5:

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

Çıktı 5:

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

Girdilerin herhangi bir gerçek sayı içerebileceğini varsayın, matematiksel sembolleri veya üstel gösterimi dikkate almanıza gerek yoktur (örn. 5.000 asla 5e3 olarak girilmez). Sen işlemek gerek kalmayacak inf, -inf, NaNveya herhangi bir başka 'sözde numaralar'. Sen çıkış numarasının farklı bir temsilidir (5.000 edebilir olabilir bunu seçerseniz 5e3 olarak çıktı olun).

puanlama:

Bu bir , en az bayt kazanır.

Liderler

İşte hem düzenli bir skor tablosu hem de kazananları dile göre gözden geçirmek için bir Yığın Parçacığı.

Yanıtınızın göründüğünden emin olmak için lütfen aşağıdaki Markdown şablonunu kullanarak yanıtınızı bir başlıkla başlatın:

# Language Name, N bytes

Ngönderiminizin büyüklüğü nerede . Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

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

Başlığınıza birden fazla sayı eklemek istiyorsanız (örneğin, puanınız iki dosyanın toplamı olduğu veya yorumlayıcı bayrak cezalarını ayrı olarak listelemek istediğiniz için), gerçek puanın başlıktaki son sayı olduğundan emin olun :

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

Dil adını, daha sonra skor tablosu snippet'inde görünecek bir bağlantı da yapabilirsiniz:

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


Son sıra için 1 tabanlı indeks kullanılabilir mi?
Leo

@ JA için leo? Hayır.
Pureferret

1
IA[0] = 0Tamamen gereksiz değil mi? Sadece tanımlamak gerekir IA[i] = IA[i − 1]..., ancak i-1 < 00'ı kullanırsak, IA [0] her zaman 0'a eşittir, bu nedenle sıkıştırılabilir (evet, bunun algoritmanın bir eleştirisi olduğunu anlıyorum, bu zorluk değil).
Draco18s artık SE

Biz de bunun tersini yapacak mıyız?
Adám

1
Temiz! Daha önce her iki formata girmemiştim, ama başka birinin daha önce gördüğünü görmekten memnunum (bu eski algoritmalarda önemsiz optimizasyonları yapan kişi olmamalıyım).
Draco18s artık SE

Yanıtlar:


6

MATL , 19 bayt

!3#f!Dx0Gg!XsYshDq!

Giriş ;satır ayırıcı olarak kullanılır.

Çevrimiçi deneyin! Veya tüm test senaryolarını doğrulayın: 1 , 2 , 3 , 4 , 5 .

açıklama

!     % 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 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır:

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 karakter veya 36 33 bayt *

⎕IO←0Sıfır tabanlı indeksleme gerektirir . G / Ç listelerin listesidir.

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

Çevrimiçi deneyin!

{} Argümanın ile temsil edildiği anonim işlev

(... )(... )(...)  üç şeylerin bir listesini döndürür:

  ⍵≠0 Argümanın her bir alt liste için 0 0
  ⍸¨indeksinden farklı olduğu Boolean
  ϵ nlist (düzleştirmek) tek bir liste halinde birleştirmek

  ⍵~¨0 bağımsız değişken her bir alt listeden sıfır kaldırmak
  d← olarak mağazadan d
  ≢¨  çetelesini her
  +\ birikimli toplamı
  0, sıfır başa eklemek

  ∊dε nlist (düzleştirmek) d tek bir liste halinde birleştirmek

  


* Dyalog Classic'te çalıştırmak için ile değiştirin ⎕U2378.


Güzel, giriş formatını anlamıyorum ama? f 4 4⍴ve sonra değerler?
Pureferret

@Pureferret Kod işlevi tanımlar f. Girdi gerçekten aramaları REPL olduğu fsonucuna 4 4⍴…olan R 4 x 4 matris veri eshapes.
Adám

1
Rho için R eshapes . Anladım!
Pureferret

1
@Pureferret Çevrimiçi deneyin! Test durumlarını daha iyi göstermek için bağlantı.
Adám

2

PHP , 107 bayt

<?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);

Çevrimiçi deneyin!

PHP , 109 bayt

<?$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);

Çevrimiçi deneyin!


Bunun sayıların dize olması gerekir mi?
Pureferret

1
@Pureferret PHP'deki herhangi bir Girdi bir dize veya bir dize dizisidir. Eğer çıkış yerine int tamamen olduğuna isterseniz ben girişi dökme değil $x[]=$v ile$x[]=+$v
Jörg Hülsermann

2

JavaScript (ES6), 117 bayt

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]

Giriş 2B bir sayı dizisi ve çıkış bir dizi [A, IA, JA] .

Açıklaması

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

Testler


1

Python 2 , 115 bayt

lambda m:zip(*[[v,i]for k in m for i,v in enumerate(k)if v])+[reduce(lambda a,b:a+[len(b)-b.count(0)+a[-1]],m,[0])]

Çevrimiçi deneyin!

Çıktı [A, JA, IA]


1

Perl 6 , 84 bayt

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

Çevrimiçi deneyin!

Tek matris argümanı içeride $_.

  • .flatmap(*.grep(+*)) tüm matrisin sıfır olmayan elemanlarını seçer.
  • [\+] .map(+*.grep(+*))her satırdaki (bazı dillerin çağırdığı scan) öğelerin sayısında üçgen azalmadır . (0,|...)bu listeye sıfır ekler.
  • .flat.kvmatrisin tüm öğelerinin dizinlenmiş bir listesini üretir. .flatmap: { $^a % .[0] xx ?$^b }her bir dizinin modülü üzerinde, .[0]bir boolean olarak yorumlanan, öğenin kendisi tarafından çoğaltılan , dizideki sütun sayısı (, ilk satırdaki öğe sayısı) ile düz haritalar . Yani, sıfır olmayan elemanlar bir kez kopyalanır ve sıfır elemanlar sıfır kez kopyalanır (yani kaldırılır).

1

Python + SciPy, 79 bayt

sanırım yerleşikler yasak değildi

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

Biçimdeki girişi kabul eder [[0, 0, 0, 0],[5, 8, 0, 0],[0, 0, 3, 0],[0, 6, 0, 0]]


1

Japt , 31 27 bayt

Girdiyi bir dizi dizisi olarak alır ve bir dizi dizisi döndürür.

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

Test edin ( -Qyalnızca görselleştirme amacıyla işaretleyin)


açıklama

Örtülü dizi girişi U.
[[1,1,1],[1,1,1],[1,1,1]]

Uc f

İlk alt = -dizisi için, herhangi bir falsey öğesini (yani, 0s) kaldırarak düzleştiririz ( c) Uve sonra filtreleriz ( f)
[1,1,1,1,1,1,1,1,1]

U®         Ã

Harita üzerinde diğer 2 alt diziyi aynı anda inşa edeceğiz U.

£     Ã

Her öğeyi (alt dizi) U

Xgeçerli alt dizinin geçerli öğesidir ve ©mantıksal AND ( &&) şeklindedir, bu nedenle Xdoğru değilse (sıfır değil) sonraki bölüm yürütülmez.

NpY

Japt'te, Ntüm girdileri içeren bir dizidir, bu yüzden burada Xdoğruysa, geçerli öğenin pindex ( Y) ' ine ( ) iteriz N.
[[[1,1,1],[1,1,1],[1,1,1]],0,1,2,0,1,2,0,1,2]

Ana dizinin haritasına geri Zdönersek, her öğe ( ) için, o alt dizideki doğru (sıfır değil) öğelerin sayısını alırız.
[3,3,3]

å+

Toplayarak bu diziyi kümülatif olarak azaltın.
[3,6,9]

iT

iİkinci alt diziyi tamamlamak için 0 dizinine ( ) 0 ekleyin .
[0,3,6,9]

Son alt dizi için, sadece N1. öğeden dilimliyoruz.
[0,1,2,0,1,2,0,1,2]


Diğer örnekleri de çalıştırdım ve işe yarıyor
Pureferret
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.