Verifikasi tanda matriks bergantian

16

Sebuah matriks bolak tanda adalah ndengan nmatriks yang terdiri dari angka -1, 0, 1, sehingga:

  • Jumlah setiap baris dan kolom adalah 1
  • Entri bukan nol di setiap baris dan kolom bergantian masuk

Matriks-matriks ini menggeneralisasi matriks permutasi, dan jumlah matriks seperti itu untuk suatu waktu tertentu nmenarik. Mereka terjadi secara alami selama metode kondensasi Dodgson menghitung determinan matriks (dinamai Charles Dodgson, lebih dikenal sebagai Lewis Carroll).

Berikut adalah beberapa contoh dari 4 oleh 4 matriks tanda bergantian:

 0  1  0  0          1  0  0  0          0  0  1  0          0  0  1  0    
 0  0  1  0          0  0  1  0          0  1 -1  1          1  0 -1  1
 1  0  0  0          0  1 -1  1          1 -1  1  0          0  1  0  0
 0  0  0  1          0  0  1  0          0  1  0  0          0  0  1  0

Dan berikut adalah beberapa contoh dari 4 oleh 4 matriks yang tidak bergantian matriks tanda:

 0  1  0  0
 0  0  0  1
 1  0  0  0
 0  0  1 -1    (last row and last column don't add to 1)

 0  0  0  1
 1  0  0  0
-1  1  1  0
 1  0  0  0    (third row does not alternate correctly)

Program atau fungsi Anda akan diberikan noleh nmatriks ( n >= 1) dari -1s, 0s dan 1s - output nilai yang benar jika matriks yang diberikan adalah matriks tanda bolak-balik, jika tidak output nilai palsu.

Ini adalah , jadi tujuannya adalah untuk meminimalkan jumlah byte yang digunakan.

Uji kasus

Kasing uji berikut diberikan dalam format daftar 2D seperti Python.

Benar:

[[1]]
[[1,0],[0,1]]
[[0,1],[1,0]]
[[0,1,0],[0,0,1],[1,0,0]]
[[0,1,0],[1,-1,1],[0,1,0]]
[[0,1,0,0],[0,0,1,0],[1,0,0,0],[0,0,0,1]]
[[1,0,0,0],[0,0,1,0],[0,1,-1,1],[0,0,1,0]]
[[0,0,1,0],[0,1,-1,1],[1,-1,1,0],[0,1,0,0]]
[[0,0,1,0],[1,0,-1,1],[0,1,0,0],[0,0,1,0]]
[[0,0,1,0,0],[0,1,-1,1,0],[1,-1,1,0,0],[0,1,0,-1,1],[0,0,0,1,0]]
[[0,0,1,0,0,0,0,0],[1,0,-1,0,1,0,0,0],[0,0,0,1,-1,0,0,1],[0,0,1,-1,1,0,0,0],[0,0,0,0,0,0,1,0],[0,0,0,0,0,1,0,0],[0,1,-1,1,0,0,0,0],[0,0,1,0,0,0,0,0]]
[[0,0,0,0,1,0,0,0],[0,0,1,0,-1,1,0,0],[0,0,0,1,0,0,0,0],[1,0,0,-1,1,-1,1,0],[0,1,-1,1,-1,1,0,0],[0,0,0,0,1,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1]]

Falsy:

[[0]]
[[-1]]
[[1,0],[0,0]]
[[0,0],[0,1]]
[[-1,1],[1,0]]
[[0,1],[1,-1]]
[[0,0,0],[0,0,0],[0,0,0]]
[[0,1,0],[1,0,1],[0,1,0]]
[[-1,1,1],[1,-1,1],[1,1,-1]]
[[0,0,1],[1,0,0],[0,1,-1]]
[[0,1,0,0],[0,0,0,1],[1,0,0,0],[0,0,1,-1]]
[[0,0,1,0],[0,0,1,0],[1,0,-1,1],[0,1,0,0]]
[[0,0,0,1],[1,0,0,0],[-1,1,1,0],[1,0,0,0]]
[[1,0,1,0,-1],[0,1,0,0,0],[0,0,0,0,1],[0,0,0,1,0],[0,0,0,0,1]]
[[0,0,1,0,0],[0,1,-1,1,0],[1,-1,1,0,0],[0,1,1,-1,0],[0,0,-1,1,1]]
[[0,-1,0,1,1],[1,-1,1,-1,1],[0,1,1,0,-1],[1,1,-1,1,-1],[-1,1,0,0,1]]
[[0,0,1,0,0,0,0,0],[1,0,1,0,1,0,0,0],[0,0,0,1,-1,0,0,1],[0,0,1,-1,1,0,0,0],[0,0,0,0,0,0,1,0],[0,0,0,0,0,1,0,0],[0,1,-1,1,0,0,0,0],[0,0,1,0,0,0,0,0]]
Sp3000
sumber
1
Terkait
Peter Taylor

Jawaban:

3

Retina , 62 58 56 53 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1, dan \tharus diganti dengan tab aktual (0x09 yang akan diubah menjadi spasi oleh SE sebaliknya).

$
\t$`¶
O$#`...(?<=^[^\t]*(.+))
$.1
T` 0
^(1(-11)*\s)+$

Format input adalah matriks di mana setiap kolom menggunakan tiga karakter rata kanan, misalnya:

  0  0  1  0
  1  0 -1  1
  0  1  0  0
  0  0  1  0

Output bisa berupa 0(falsy) atau1 (benar).

Suite uji.(Beberapa baris pertama mengubah format input dan membiarkan Retina menjalankan beberapa test case sekaligus.)

Penjelasan

Untungnya, inputnya adalah matriks persegi: mentransposisi kotak hampir bisa dilakukan di Retina, sedangkan transposisi persegi panjang adalah rasa sakit besar.

$
\t$`¶

Kami mulai dengan menambahkan tab, seluruh input lagi (menggunakan awalan $`) dan kemudian linefeed di akhir (menggunakan Retina's alias ). Kami menggunakan tab untuk memisahkan dua salinan sehingga kami dapat membedakan di antara mereka ketika kami mentranspos salah satu dari mereka, dan dengan menggunakan karakter spasi putih kami dapat menyimpan beberapa byte nanti.

O$#`...(?<=^[^\t]*(.+))
$.1

Ini adalah bit yang paling sulit: transpos salinan pertama dari matriks. Idenya adalah untuk mencocokkan sel dalam salinan pertama dan kemudian menyortirnya (secara stabil) dengan posisi horizontal. Kami mencocokkan sel dengan ...(karena sel selalu tiga karakter) dan kemudian mengukur posisi horizontal dengan (.+)di dalam tampilan. Kemudian, untuk memastikan bahwa kami hanya memindahkan salinan pertama, kami memeriksa bahwa kami dapat mencapai awal string tanpa bergerak melewati tab.

Anda mungkin memperhatikan bahwa ini juga akan cocok dengan beberapa string tiga byte (yang bahkan tidak sejajar dengan sel) di baris pertama dari salinan kedua, karena .+ dapat melewati tab. Namun, ini bukan masalah karena posisi horizontal dari pertandingan ini benar-benar lebih besar daripada yang ada di dalam salinan pertama, sehingga pertandingan ini tetap di posisi mereka.

Sisanya cukup sederhana:

T` 0

Kami menghapus spasi dan nol dari input.

^(1(-11)*\s)+$

Dan akhirnya kami memeriksa bahwa seluruh input terdiri dari baris-baris yang diakhiri spasi-putih dari bentuk 1(-11)*, yaitu urutan bergantian dari 1dan -1yang dimulai dan diakhiri dengan 1(karena kalau tidak, jumlah itu tidak berarti 1).

Martin Ender
sumber
3

Jelly, 15 byte

;Zḟ€0;€-;@€-IFP

Cobalah online!

;Zḟ€0;€-;@€-IFP   Main monadic chain. Argument: z

;Z                Concatenate with its transpose.
  ḟ€0             Remove zeros from each sub-list. At this point,
                  one expects lists of the form [1, -1, 1, -1, ..., 1] for truthy,
                  and any other arrays containing purely 1 and -1 for falsey.
     ;€-          Append -1 to each sub-list.
        ;€@-      Prepend -1 to each sub-list.
            I     Compute the difference between each term. At this point,
                  for truthy, one expects arrays filled with 2, and arrays
                  containing 0 otherwise.
             FP   Product of every item. This checks if any item is equal to zero.
bocor Nun
sumber
3

Pyth, 16 byte

!sm-sM._+d_1U2+C

Cobalah online: Demonstrasi atau Test Suite

Penjelasan:

!sm-sM._+d_1U2+CQQ   two implicit Qs (=input matrix) at the end
              +CQQ   zip Q and connect it with Q (=list of columns and rows)
  m                  map each column/row d to:
        +d_1            append -1 to d
      ._                compute all prefixes of ^
    sM                  compute the sums of the prefixes
   -        U2          remove zeros and ones
                        a column/row is correct, if this gives an empty list 
 s                   connect up all resulting lists
!                    check, if this result is empty
Jakube
sumber
3

Jelly , 11 byte

;Zj-+\ṚQḄ=2

Mengembalikan 1 untuk matriks tanda bergantian, 0 sebaliknya. Cobalah online! atau verifikasi semua kasus uji .

Latar Belakang

Mengabaikan nol, setiap baris dan kolom harus terdiri dari pola (1, -1) * 1 , yaitu kejadian bergantian 1 dan -1 , dimulai dan diakhiri dengan 1 (jadi jumlahnya adalah 1 ).

Untuk memverifikasi hal ini, kami mengambil larik semua baris dan kolom, dan bergabung dengan mereka menggunakan -1 sebagai pemisah. Karena semua titik akhir adalah 1 's, array datar yang dihasilkan memenuhi pola (1, -1) * 1 jika dan hanya jika baris dan kolom lakukan.

Untuk pengujian yang sebenarnya, kami menghitung jumlah kumulatif array. Untuk matriks tanda bolak-balik, hasilnya adalah array 0 dan 1 yang berakhir dengan 1 .

Kami membalikkan jumlah kumulatif dan mendeduplikasinya, menjaga urutan kejadian awal dari semua elemen unik. Untuk input yang benar, hasilnya adalah daftar [1, 0] .

Untuk menghasilkan Boolean yang sesuai, kami mengonversi jumlah kumulatif yang digandakan dari biner ke integer dan menguji apakah hasilnya 2 .

Bagaimana itu bekerja

;Zj-+\ṚQḄ=2  Main link. Argument: M (matrix / 2D array)

 Z           Zip; transpose M's rows and columns.
;            Concatenate M and zipped M.
  j-         Join, separating by -1.
    +\       Take the cumulative sum of the result.
      Ṛ      Reverse the array of partial sums.
       Q     Unique; deduplicate the partial sums.
        Ḅ    Unbinary; convert from base 2 to integer.
         =2  Test for equality with 2.
Dennis
sumber
2

MATL, 18 16 15 13 byte

3 byte disimpan berkat @Luis

t!h"@s1=@Xzdv

Solusi ini menerima array 2D sebagai input dan akan menampilkan array yang benar atau salah . Penting untuk dicatat bahwa dalam MATL, array yang benar terdiri dari semua elemen non-nol sedangkan hasil falsey memiliki setidaknya satu elemen nol. Ini adalah demonstrasi lain dari array yang benar / palsu .

Cobalah secara Online

Versi modifikasi untuk menunjukkan semua kasus uji

Penjelasan

        % Implicitly grab input matrix
t!      % Duplicate and transpose input
h       % Horizontally concatenate input with transpose. This allows us to 
        % process only columns since now the columns *also* contain the rows.
"       % For each column (of our column/row combined matrix)
  @s1=  % Compute the sum and ensure it is equal to 1
  @Xz   % Get the non-zeros
  d     % Compute the element-to-element difference. The 1 and -1 alternate only if
        % all these differences are non-zero
  v     % Vertically concatenate everything on the stack
        % Implicit end of loop and implicitly display truthy/falsey value
Suever
sumber
2

Julia, 36 byte

!x=[x^0 x^0;-x -x'][:]|>cumsum⊆0:1

Cobalah online!

Dennis
sumber
1

JavaScript (ES6), 112 100 byte

a=>!/(^|,)(?!0*10*(-10*10*)*(,|$))/.test(a.map(b=>b.join``)+','+a.map((_,i)=>a.map(b=>b[i]).join``))

Ratakan larik dan transpos ke dalam string, lalu (abaikan 0s) memeriksa pola 1-11...1-11di setiap string.

Sunting: Disimpan 12 byte berkat @PeterTaylor.

Neil
sumber
1
Anda tidak perlu memeriksa polanya -11-1...-11-1karena karena entri berganti dan memiliki jumlah positif, pasti ada lebih 1dari satu -1, sehingga polanya harus 1-11...1-11.
Peter Taylor
@ PeterTaylor Ugh, itu kedua kalinya saya salah membaca pertanyaan. (Komentar yang berkaitan dengan pertama kali sejak itu telah dihapus.)
Neil
Header mengatakan 110 byte, tetapi hanya 100
Peter Taylor
1
@PeterTaylor Setidaknya "12 byte yang disimpan berkat @PeterTaylor" benar.
Neil
1

Python 2, 63 60 byte

s=0;x=input()
for r in x+zip(*x):
 for n in(-1,)+r:s+=[n][s]

Input adalah daftar tupel.

Ini diakhiri dengan kode keluar 0 untuk matriks tanda bergantian dan kode keluar 1 sebaliknya. Inilah yang benar dan salah dilakukan, dan - seperti yang ditunjukkan di bagian verifikasi - memang bisa digunakan sebagai kondisi di, misalnya, skrip Bash.

Verifikasi

test-cases.txt

[(1,)]
[(1, 0), (0, 1)]
[(0, 1), (1, 0)]
[(0, 1, 0), (0, 0, 1), (1, 0, 0)]
[(0, 1, 0), (1, -1, 1), (0, 1, 0)]
[(0, 1, 0, 0), (0, 0, 1, 0), (1, 0, 0, 0), (0, 0, 0, 1)]
[(1, 0, 0, 0), (0, 0, 1, 0), (0, 1, -1, 1), (0, 0, 1, 0)]
[(0, 0, 1, 0), (0, 1, -1, 1), (1, -1, 1, 0), (0, 1, 0, 0)]
[(0, 0, 1, 0), (1, 0, -1, 1), (0, 1, 0, 0), (0, 0, 1, 0)]
[(0, 0, 1, 0, 0), (0, 1, -1, 1, 0), (1, -1, 1, 0, 0), (0, 1, 0, -1, 1), (0, 0, 0, 1, 0)]
[(0, 0, 1, 0, 0, 0, 0, 0), (1, 0, -1, 0, 1, 0, 0, 0), (0, 0, 0, 1, -1, 0, 0, 1), (0, 0, 1, -1, 1, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 1, 0, 0), (0, 1, -1, 1, 0, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0)]
[(0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 1, 0, -1, 1, 0, 0), (0, 0, 0, 1, 0, 0, 0, 0), (1, 0, 0, -1, 1, -1, 1, 0), (0, 1, -1, 1, -1, 1, 0, 0), (0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 1)]
[(0,)]
[(-1,)]
[(1, 0), (0, 0)]
[(0, 0), (0, 1)]
[(-1, 1), (1, 0)]
[(0, 1), (1, -1)]
[(0, 0, 0), (0, 0, 0), (0, 0, 0)]
[(0, 1, 0), (1, 0, 1), (0, 1, 0)]
[(-1, 1, 1), (1, -1, 1), (1, 1, -1)]
[(0, 0, 1), (1, 0, 0), (0, 1, -1)]
[(0, 1, 0, 0), (0, 0, 0, 1), (1, 0, 0, 0), (0, 0, 1, -1)]
[(0, 0, 1, 0), (0, 0, 1, 0), (1, 0, -1, 1), (0, 1, 0, 0)]
[(0, 0, 0, 1), (1, 0, 0, 0), (-1, 1, 1, 0), (1, 0, 0, 0)]
[(1, 0, 1, 0, -1), (0, 1, 0, 0, 0), (0, 0, 0, 0, 1), (0, 0, 0, 1, 0), (0, 0, 0, 0, 1)]
[(0, 0, 1, 0, 0), (0, 1, -1, 1, 0), (1, -1, 1, 0, 0), (0, 1, 1, -1, 0), (0, 0, -1, 1, 1)]
[(0, -1, 0, 1, 1), (1, -1, 1, -1, 1), (0, 1, 1, 0, -1), (1, 1, -1, 1, -1), (-1, 1, 0, 0, 1)]
[(0, 0, 1, 0, 0, 0, 0, 0), (1, 0, 1, 0, 1, 0, 0, 0), (0, 0, 0, 1, -1, 0, 0, 1), (0, 0, 1, -1, 1, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 1, 0, 0), (0, 1, -1, 1, 0, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0)]

test-suite.sh

while read; do
        if python2 asmv.py <<< "$REPLY"; then
                echo "true"
        else
                echo "false"
        fi
done < test-cases.txt 2>&- | uniq -c

Keluaran

$ bash test-suite.sh
     12 true
     17 false

Bagaimana itu bekerja

Mengabaikan nol, setiap baris dan kolom harus terdiri dari pola (1, -1) * 1 , yaitu kejadian bergantian 1 dan -1 , dimulai dan diakhiri dengan 1 (jadi jumlahnya adalah 1 ).

Untuk memverifikasi hal ini, kami zip / mengubah matriks input M , menambahkan hasilnya M (sekarang terdiri dari daftar baris dan kolom), dan menambahkan -1 ke setiap baris / kolom.

Misalnya, jika M adalah salah satu dari matriks berikut (valid, tidak valid)

     0  1  0         0  0  0
     0  0  1         1  0  0
     1  0  0         0  1 -1

hasilnya

-1 | 0  1  0    -1 | 0  0  0
-1 | 0  0  1    -1 | 1  0  0
-1 | 1  0  0    -1 | 0  1 -1
------------    ------------
-1 | 0  0  1    -1 | 0  1  0
-1 | 1  0  0    -1 | 0  0  1
-1 | 0  1  0    -1 | 0  0 -1

Membaca matriks yang dihasilkan secara bijaksana harus menghasilkan urutan datar dengan pola (-1, 1) * . Untuk memverifikasi hal ini, kami mengambil jumlah kumulatif semua entri, dimulai dengan baris teratas.

Sebagai contoh matriks, ini menghasilkan

-1 -1  0  0 -1 -1 -1  0 -1  0  0  0 -1 -1 -1  0 -1  0  0  0 -1 -1  0  0
-1 -1 -1 -1 -2 -1 -1 -1 -2 -2 -1 -2 -3 -3 -2 -2 -3 -3 -3 -2 -3 -3 -3 -4

Untuk matriks tanda bergantian yang valid, output akan terdiri dari -1 dan 0 dan - karena setiap -1 membatalkan 1 sebelumnya dan sebaliknya - tidak ada nomor lain.

Pada pandangan pertama, ini mungkin tampak gagal memeriksa apakah kolom terakhir berakhir dengan 1 . Namun, untuk matriks n × n yang mengandung k nol, baris yang valid akan berisi n + k . Jika semua kolom kecuali yang terakhir juga valid, akan ada n + k - 1 di kolom, yang tidak mungkin.

Untuk menguji bahwa tidak ada angka lain, kami menyimpan jumlah parsial dalam variabel s dan memperbaruinya untuk setiap entri dengan matriks yang dihasilkan s+=[n][s].

Jika s = 0 atau s = -1 , ini setara dengan s+=n. Namun, untuk semua nilai lain dari s , itu menyebabkan IndexError , jadi Python segera berakhir dengan kode keluar 1 . Jika ini tidak terjadi pada titik mana pun, program selesai dengan bersih dengan kode keluar 0 .

Dennis
sumber
0

R, 54 byte

Fungsi anonim, menggunakan logika yang sama dengan jawaban Dennis Python 2, Jelly, dan Julia.

function(x)all(abs(cumsum(rbind(-1,cbind(t(x),x))))<2)
rturnbull
sumber