Minimum maliyet bloğu köşegenleştirmesi


10

Ana diyagonal üzerinde 1'ler kare bloklara sahip olan ve her yerde 0 olan ikili blok çapraz matrisleri düşünün . Bu matrislere "geçerli" matrisler diyelim.

Örneğin, bazı geçerli 4x4 matrisleri şunlardır:

1 0 0 0     1 1 0 0     1 0 0 0     1 0 0 0     1 1 0 0    1 1 1 1
0 1 0 0     1 1 0 0     0 1 1 0     0 1 1 1     1 1 0 0    1 1 1 1
0 0 1 0     0 0 1 0     0 1 1 0     0 1 1 1     0 0 1 1    1 1 1 1
0 0 0 1     0 0 0 1     0 0 0 1     0 1 1 1     0 0 1 1    1 1 1 1

Bu matrisleri tarif etmenin alternatif bir yolunun, soldan sağa, sağdan sağa, köşeden köşeye değen 1 blokluk bir kare zincirinin ve diğer her yerde 0 olduğunu unutmayın.

Buna karşılık, bazı geçersiz 4x4 matrisleri şunlardır:

1 0 1 0     1 0 1 0     1 1 0 0     0 1 1 1     1 1 0 0    0 0 0 0
0 1 1 1     0 1 0 1     1 1 0 0     0 1 1 1     1 1 0 0    0 0 0 0
1 0 0 1     1 0 1 0     0 0 0 0     0 1 1 1     1 1 0 0    0 0 0 0
0 0 1 0     0 1 0 1     0 0 0 1     1 0 0 0     0 0 1 1    0 0 0 0

Bir verilecektir ntarafından ngirdi olarak ikili matrisin - minimum numarası nedir 0size sette gerekir bit 1geçerli bir matris elde etmek için?

Bir temsil uygun herhangi bir dize, liste veya matris biçiminde bir işlev veya program alma yazabilirsiniz ntarafından n(sürece preprocessed değil gibi) 0 ve 1 matrisi. Satırlar bir şekilde açıkça ayrılmalıdır, bu nedenle 1D bit dizisi gibi biçimlere izin verilmez.

Bu , bu nedenle amaç programınızdaki bayt sayısını en aza indirmektir.

Örnekler

Örneğin, giriş

0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 1

almak 0için beş bit ayarlayabilirsiniz, çünkü cevap 5'tir.1

1 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 1 0
0 0 0 0 1

ve bu gerekli olan minimum sayıdır. Ancak, giriş

0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

o zaman cevap 24'tür, çünkü sağ üstteki tek geçerli 5x5 matris 1tüm 1s matrisidir .

Test senaryoları

Testler burada bir 2 tam sayı dizisi olarak temsil edilir.

[[0]] -> 1
[[1]] -> 0
[[0,1],[0,0]] -> 3
[[1,0],[0,0]] -> 1
[[0,0,0],[0,1,0],[0,0,0]] -> 2
[[0,1,0],[0,0,0],[0,1,0]] -> 7
[[0,1,0],[1,0,0],[0,0,1]] -> 2
[[1,1,1],[1,1,1],[1,1,1]] -> 0
[[0,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,0]] -> 4
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]] -> 8
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,1,0]] -> 14
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,1,0,0]] -> 14
[[0,0,0,0,0],[0,0,0,0,0],[0,1,0,0,0],[0,0,0,0,1],[0,0,0,0,0]] -> 7
[[0,0,0,0,0],[0,0,0,0,0],[1,0,0,0,0],[0,0,0,0,1],[0,0,0,0,0]] -> 11
[[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,1]] -> 5
[[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] -> 24
[[0,0,0,1,0],[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] -> 23
[[0,1,0,0,0],[1,0,0,0,0],[0,0,1,0,0],[0,0,0,0,1],[0,0,0,1,0]] -> 4
[[0,1,1,1,0],[0,1,1,0,1],[0,1,1,1,0],[0,1,0,0,1],[0,0,0,0,0]] -> 14

notlar

Yanıtlar:


3

MATL , 46 43 bayt

nX^tQt:qZ^!tsb=Z)"@!"@1$l]@n$YdG-Q?6MG>zvX<

Giriş, satır ayırıcı olarak noktalı virgül içeren bir 2D dizidir. Örneğin, son test senaryosunun girdisi

[0,1,1,1,0;0,1,1,0,1;0,1,1,1,0;0,1,0,0,1;0,0,0,0,0]

Çevrimiçi deneyin! Veya tüm test senaryolarını doğrulayın (tüm girişleri almak için kod biraz değiştirildi; sonuçlar birkaç saniye sonra görünür)

açıklama

Girişin bir N × N matrisi olmasına izin verin . Kod önce uygun matris boyutunu üreten tüm ( N + 1) blok boyutlarını hesaplar . Örneğin, için N küpe olan 4 = 0 0 0 0 4, 0 0 0 1 3, ..., 4 0 0 0 0. Her bir demet için bu blok boyutlarıyla blok-diyagonal matrisi oluşturur. Daha sonra matrisin 1girişteki tüm girişleri kapsayıp kapsamadığını kontrol eder ve eğer varsa 1girişte bulunmayan giriş sayısını not eder. Nihai sonuç, elde edilen tüm sayıların minimumudur.

nX^      % Implicit input  an N×N matrix. Get N
t        % Duplicate N
Qt:q     % Vector [0 1 ... N]
Z^       % Cartesian power. Gives 2D array
!ts      % Transpose, duplicate, sum of each column
b=       % Logical vector that equals true if the sum is N
Z)       % Filter columns according to that. Only keep columns that sum to N. Each 
         % column is the size of one block
"        % For each column
  @      %   Push that column
  "      %   For each entry of that column
    @    %     Push that entry
    1$l  %     Square matrix with that size, filled with 1
  ]      %   End
  @n     %   Column size. This is the number of blocks in the block-diagonal matrix
  $Yd    %   Build block-diagonal matrix from those blocks
  G-Q    %   Subtract input matrix element-wise, and add 1
  ?      %   If all entries are nonzero (this means each that entry that is 1 in the
         %   block-diagonal matrix is also 1 in the input matrix)
    6M   %   Push block-diagonal matrix again
    G>   %   For each entry, gives 1 if it exceeds the corresponding entry of the
         %   input, that is, if the block-diagonal matrix is 1 and the input is 0
    z    %   Number of 1 entries
    v    %   Concatenate vertically with previous values
    X<   %   Take minimum so far
         %   Implicit end
         % Implicit end
         % Implicit display

3

Numpy ile Python, 102

from numpy import*
lambda M:sum(diff([k for k in range(len(M)+1)if(M|M.T)[:k,k:].any()-1])**2)-M.sum()

Etkili bir algoritma. Diyagonal üzerinde blokları ayırabilen "boyun noktalarını" bulur. Bunlar yukarıda ve sağda, ayrıca aşağıda ve solda 0'ların hepsine sahiptir. Minimal bloklar boyun noktaları arasındaki bloklardır.

??000
??000
00???
00???
00???

Bir bloğun uzunluğu, ardışık boyun noktaları arasındaki farktır, bu nedenle bunların toplam karelerinin toplam alanı. Orijinal matrisin toplamının çıkarılması, 0'dan 1'e kadar gerekli olan döndürme sayısını verir.


2

Pyth, 45 bayt

-hSlMf@I.DRlQx1sQTms.b^+LsYN2d+0._ds.pM./lQss

Zor bir görev, bu yüzden oldukça uzun.

Çevrimiçi deneyin: Gösteri veya Test Paketi

Açıklama:

s.pM./lQtüm tamsayı bölümlerini hesaplar len(matrix). ms.b^+LsYN2d+0._donları koordinat çiftlerine dönüştürür. Örneğin bölme [1, 2, 2]arasında 5dönüştürülen biniyor [[0,0], [1,1], [1,2], [2,1], [2,2], [3,3], [3,4], [4,3], [4,4].

f@I.DRlQx1sQTdaha sonra matrisi tamamen üst üste .DRlQx1sQbindiren bölümler için filtreler (matristeki aktif hücrelerin tüm koordinat çiftlerini hesaplar).

-hSlM...ss kalan her bölümün hücrelerini sayar, en az hücreye sahip olanı seçer ve zaten aktif hücreleri çıkarır.


0

Matricks , 180 bayt ( rakipsiz )

Matricks, son zamanlarda matris problemleriyle (bunun gibi), sadece 2 veri türüne sahip olmak için oluşturduğum yeni bir esolang. Henüz tam özellikli değil ve hala çok sayıda eksik işlem var (bu zorluk için bazı işlevler eklemek zorunda kaldım). Her neyse, işte kod:

il=1:j3;:bdx;;;s1::L;j1;;
b{q:1;mgr:c;|gc:r;|(r=c)|(gr-1:c;|gr:c+1;)&(rec)|(gr+1:c;|gr:c-1;)&(cer):l:L;};z:(l-1)/2;B1;s1::g1:;-1;ig1:;=0:j2;:j1;;
s1::d{q:1;};;kg1:;-g:;;
kg:;*-1+1;

açıklama

İlk bölüm, il=1:j3;:...;dizinin 1 boyutunda olup olmadığını kontrol eder. Eğer öyleyse, son satıra atlar kg:;*-1+1;, bu basit bir 0 <-> 1işlevdir.

Aksi takdirde, kodun geri kalanıyla devam eder. bdx;;;hücreyi 0,0geçerli toplama ayarlar ve s1::L;j1;aşağıdaki satırdaki hücrede bir sayaç oluşturur.

Bir sonraki satır biraz daha karmaşık. Bu, matrisin boyutu olan nzamanları çalıştıran bir döngüdür n. Örnek olarak 3. test senaryosunu kullanacağım. İkinci satıra ilk geldiğimizde, matris şöyle görünür:

1 0 1
2 0 0

İlk olarak, matris kavrayışına giriyoruz {q:1;m...;}. Bu, diyagonal yapar ve doldurulması gereken 0'ı temizlemek için elinden geleni yapar. Tüm bunlar basit boole operatörleri kullanılarak gerçekleştirilir. Sonra, bunu şu matrise başlatarak şunu veriyoruz:

    V--data we want to keep
1 1 1 0 1 <-|
1 1 2 0 0 <-- old matrix

Ardından, eski matrisi kullanarak kesiyoruz ve kullanarak z:(l-1)/2;tüm matrisi sola döndürüyoruz B1;. Bu bize bir sonraki yinelemeye hazır bir matris verir, şöyle görünür:

1 1 1
2 1 1

Son olarak, sayacı azaltır, kontrol eder ve devam ederiz. ig1:;=0:j2;:j1;;

Döngü koptuktan sonra, yeni toplamı buluruz ve sayacın eski yerini ile belirleriz s1::d{q:1;};;. Sonunda, farkı alıp geri dönüyoruz kg1:;-g:;;. kgeçerli diziyi bir değere ayarlar ve yazdırma örtüktür.

...

Gördüğünüz gibi, Matricks oldukça ayrıntılı ve çok iyi bir golf dili değil. Ama kahretsin, göstermek istedim.

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.