Überprüfung der Wechselzeichenmatrix


16

Eine Wechselzeichenmatrix ist eine nBy- nMatrix bestehend aus den Zahlen -1, 0, 1, so dass:

  • Die Summe jeder Zeile und Spalte ist 1
  • Die Einträge ungleich Null in jeder Zeile und Spalte wechseln sich in Vorzeichen ab

Diese Matrizen verallgemeinern Permutationsmatrizen, und die Anzahl solcher Matrizen für eine gegebene Zeit nwar von Interesse. Sie treten natürlich während der Dodgson-Kondensationsmethode zur Berechnung von Matrixdeterminanten auf (benannt nach Charles Dodgson, besser bekannt als Lewis Carroll).

Hier einige Beispiele für 4 x 4 Wechselzeichenmatrizen:

 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

Und hier sind einige Beispiele für 4 mal 4 Matrizen, bei denen es sich nicht um Matrizen mit alternierenden Vorzeichen handelt:

 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)

Ihr Programm oder der Funktion wird eine gegeben ndurch nMatrix ( n >= 1Ausgang a -) von -1S, 0en und 1en truthy Wert , wenn die gegebenen Matrix ist ein alternierendes Zeichen matrix, andernfalls Ausgeben eines falsy Wert.

Dies ist , daher besteht das Ziel darin, die Anzahl der verwendeten Bytes zu minimieren.

Testfälle

Die folgenden Testfälle werden in einem Python-ähnlichen 2D-Listenformat angegeben.

Wahrheit:

[[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]]

Falsch:

[[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]]

Antworten:


3

Retina , 62 58 56 53 Bytes

Die Byteanzahl setzt die ISO 8859-1-Codierung voraus und \tsollte durch tatsächliche Tabulatoren ersetzt werden (0x09, die andernfalls von SE in Leerzeichen umgewandelt würden).

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

Das Eingabeformat ist eine Matrix, in der jede Spalte drei rechtsbündige Zeichen verwendet, z.

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

Die Ausgabe ist entweder 0(falsch) oder 1(wahr).

Testsuite. (Die ersten Zeilen transformieren das Eingabeformat und lassen Retina mehrere Testfälle gleichzeitig ausführen.)

Erläuterung

Zum Glück handelt es sich bei der Eingabe um eine quadratische Matrix: Das Transponieren von Quadraten ist in der Netzhaut praktisch möglich, während das Transponieren von Rechtecken ein schwerwiegender Schmerz ist.

$
\t$`¶

Wir beginnen, indem wir einen Tabulator anfügen, die gesamte Eingabe erneut (mit dem Präfix $`) und am Ende einen Zeilenvorschub (mit dem Alias ​​der Retina ). Wir verwenden einen Tabulator, um die beiden Kopien zu trennen, damit wir sie beim Transponieren voneinander unterscheiden können, und indem wir ein Leerzeichen verwenden, können wir später ein paar Bytes sparen.

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

Dies ist das schwierigste Bit: die erste Kopie der Matrix transponieren. Die Idee ist, Zellen in der ersten Kopie abzugleichen und sie dann (stabil) nach der horizontalen Position zu sortieren. Wir gleichen die Zellen mit ...(da sie immer drei Zeichen breit sind) ab und messen dann die horizontale Position (.+)innerhalb des Lookbehind. Um sicherzustellen, dass nur die erste Kopie transponiert wird, prüfen wir, ob der Anfang der Zeichenfolge erreicht werden kann, ohne an einem Tabulator vorbeizugehen.

Möglicherweise stellen Sie fest, dass dies auch einigen Drei-Byte-Zeichenfolgen (die nicht einmal an den Zellen ausgerichtet sind) in der ersten Zeile der zweiten Kopie entspricht, da .+diese die Registerkarte passieren können. Dies ist jedoch kein Problem, da die horizontale Position dieser Übereinstimmungen streng größer ist als diejenige in der ersten Kopie, sodass diese Übereinstimmungen an ihrer Position verbleiben.

Der Rest ist ziemlich einfach:

T` 0

Wir entfernen Leerzeichen und Nullen aus der Eingabe.

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

Und schließlich prüfen wir, ob die gesamte Eingabe aus Zeilen besteht, die mit Leerzeichen abgeschlossen sind 1(-11)*, dh eine abwechselnde Folge von 1und -1die beginnt und endet mit 1(weil sie sonst nicht summiert 1).


3

Gelee, 15 Bytes

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

Probieren Sie es 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.

3

Pyth, 16 Bytes

!sm-sM._+d_1U2+C

Probieren Sie es online aus: Demo oder Test Suite

Erläuterung:

!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

3

Jelly , 11 Bytes

;Zj-+\ṚQḄ=2

Gibt 1 für Matrizen mit alternierendem Vorzeichen zurück, andernfalls 0 .Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Hintergrund

Ohne Berücksichtigung von Nullen muss jede Zeile und Spalte aus dem Muster (1, -1) * 1 bestehen , dh abwechselnd 1 und -1 , beginnend und endend mit einer 1 (die Summe ist also 1 ).

Um dies zu überprüfen, nehmen wir das Array aller Zeilen und Spalten und verbinden sie mit -1 als Trennzeichen. Da alle Endpunkte 1 sind , erfüllt das resultierende flache Array das Muster (1, -1) * 1 genau dann, wenn die Zeilen und Spalten dies tun.

Für den eigentlichen Test berechnen wir die kumulative Summe des Arrays. Für eine Wechselzeichenmatrix ist das Ergebnis ein Array von 0 und 1 , das mit einer 1 endet .

Wir kehren die kumulative Summe um und deduplizieren sie, wobei wir die Reihenfolge der anfänglichen Vorkommen aller eindeutigen Elemente beibehalten. Für eine wahrheitsgemäße Eingabe ist das Ergebnis die Liste [1, 0] .

Um den entsprechenden Booleschen Wert auszugeben, konvertieren wir die duplizierten kumulativen Summen von binär in ganzzahlig und prüfen, ob das Ergebnis ist 2 ist .

Wie es funktioniert

;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.

2

MATL, 18, 16, 15 13 Bytes

3 Bytes gespart dank @Luis

t!h"@s1=@Xzdv

Diese Lösung akzeptiert ein 2D-Array als Eingabe und gibt ein wahres oder falsches Array aus. Es ist wichtig zu beachten, dass in MATL ein wahres Array aus allen Nicht-Null-Elementen besteht, während ein falsches Ergebnis mindestens ein Null-Element enthält. Hier ist eine weitere Demonstration von Truthy / Falsey-Arrays .

Probieren Sie es online

Geänderte Version, um alle Testfälle anzuzeigen

Erläuterung

        % 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


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``))

Verflacht das Array und seine Transponierung in Strings und 0prüft dann (ohne Berücksichtigung von s), ob 1-11...1-11in jedem String ein Muster vorhanden ist .

Bearbeiten: 12 Bytes dank @PeterTaylor gespeichert.


1
Sie müssen nicht nach dem Muster -11-1...-11-1suchen, da sich die Einträge abwechseln und eine positive Summe haben, muss es mehr 1als eins geben -1, also muss das Muster sein 1-11...1-11.
Peter Taylor

@PeterTaylor Ugh, das ist das zweite Mal, dass ich die Frage falsch verstanden habe. (Die Kommentare zum ersten Mal wurden seitdem gelöscht.)
Neil

Der Header sagt 110 Bytes, aber es ist nur 100
Peter Taylor

1
@PeterTaylor Mindestens die "Gespeicherten 12 Bytes dank @PeterTaylor" waren korrekt.
Neil

1

Python 2, 63 60 Bytes

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

Input ist eine Liste von Tupeln.

Dies endet mit dem Exit-Code 0 für Matrizen mit wechselndem Vorzeichen und dem Exit-Code 1 ansonsten. Dies ist das, was true und false tun, und - wie im Abschnitt zur Überprüfung gezeigt - kann es tatsächlich als Bedingung in z. B. einem Bash-Skript verwendet werden.

Nachprüfung

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

Ausgabe

$ bash test-suite.sh
     12 true
     17 false

Wie es funktioniert

Ohne Berücksichtigung von Nullen muss jede Zeile und Spalte aus dem Muster (1, -1) * 1 bestehen , dh abwechselnd 1 und -1 , beginnend und endend mit einer 1 (die Summe ist also 1) ).

Um dies zu überprüfen, müssen wir die Eingabematrix M zippen / transponieren , das Ergebnis an M anhängen (jetzt bestehend aus einer Liste von Zeilen und Spalten) und jeder Zeile / Spalte ein -1 voranstellen .

Zum Beispiel, wenn M eine der folgenden Matrizen ist (gültig, ungültig)

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

Die Ergebnisse sind

-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

Das zeilenweise Lesen der generierten Matrix muss zu einer flachen Sequenz mit dem Muster (-1, 1) führen * . Um dies zu überprüfen, nehmen wir die kumulative Summe aller Einträge, beginnend mit der obersten Zeile.

Für die Beispielmatrizen ergibt sich

-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

Für eine gültige Wechselzeichenmatrix besteht die Ausgabe aus -1 und 0 und - da bei jedem -1 die vorherige 1 gelöscht wird und umgekehrt - aus keinen anderen Zahlen.

Auf den ersten Blick scheint dies zu scheitern, wenn geprüft wird, ob die letzte Spalte mit einer 1 endet . Für eine n × n- Matrix mit k Nullen enthalten gültige Zeilen jedoch n + k Einsen. Wenn alle Spalten außer der letzten ebenfalls gültig wären, gäbe es n + k - 1 in den Spalten, was unmöglich ist.

Um zu testen, dass es keine anderen Zahlen gibt, speichern wir die Teilsummen in einer Variablen s und aktualisieren sie für jeden Eintrag mit der generierten Matrix mit s+=[n][s].

Wenn s = 0 oder s = -1 ist , ist dies äquivalent zu s+=n. Bei allen anderen Werten von s wird jedoch ein IndexError ausgelöst , sodass Python sofort mit Exit-Code 1 beendet wird . Geschieht dies zu keinem Zeitpunkt, wird das Programm sauber mit dem Exit-Code beendet 0 beendet .


0

R, 54 Bytes

Bei der anonymen Funktion wird dieselbe Logik wie bei Dennis 'Antworten zu Python 2, Jelly und Julia verwendet.

function(x)all(abs(cumsum(rbind(-1,cbind(t(x),x))))<2)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.