Verifica della matrice di segni alternati


16

Una matrice di segni alternati è una matrice nper nmatrice costituita dai numeri -1, 0, 1, in modo tale che:

  • La somma di ogni riga e colonna è 1
  • Le voci diverse da zero in ogni riga e colonna si alternano nel segno

Queste matrici generalizzano le matrici di permutazione e il numero di tali matrici per un dato nera di interesse per qualche tempo. Si verificano naturalmente durante il metodo di condensazione di Dodgson per il calcolo dei determinanti della matrice (dal nome di Charles Dodgson, meglio noto come Lewis Carroll).

Ecco alcuni esempi di matrici di segni alternati 4 per 4:

 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

Ed ecco alcuni esempi di matrici 4 per 4 che non alternano matrici di segni:

 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)

Il programma o funzione sarà data una nda nmatrice ( n >= 1) di -1S, 0 e 1 - uscita un valore truthy se la matrice è una matrice proposta alternato segno, altrimenti uscita un valore falsy.

Questo è , quindi l'obiettivo è ridurre al minimo il numero di byte utilizzati.

Casi test

I seguenti casi di test sono riportati in un formato elenco 2D simile a Python.

Truthy:

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

Risposte:


3

Retina , 62 58 56 53 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1 e \tdovrebbe essere sostituito con schede effettive (0x09 che altrimenti verrebbero trasformate in spazi da SE).

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

Il formato di input è una matrice in cui ogni colonna utilizza tre caratteri allineati a destra, ad esempio:

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

L'output è 0(falso) o 1(verità).

Suite di test. (Le prime righe trasformano il formato di input e consentono a Retina di eseguire contemporaneamente diversi casi di test.)

Spiegazione

Per fortuna, l'input è una matrice quadrata: trasporre quadrati è quasi fattibile in Retina, mentre trasporre rettangoli è un dolore enorme.

$
\t$`¶

Iniziamo aggiungendo nuovamente una scheda, l'intero input (usando il prefisso $`) e quindi un avanzamento di riga alla fine (usando l'alias di Retina ). Stiamo usando una scheda per separare le due copie in modo da poterle distinguere quando ne stiamo trasponendo una e usando un carattere di spazio bianco possiamo salvare un paio di byte in seguito.

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

Questo è il bit più complicato: trasporre la prima copia della matrice. L'idea è di abbinare le celle nella prima copia e quindi ordinarle (stabilmente) per posizione orizzontale. Abbiniamo le celle con ...(dal momento che sono sempre tre caratteri di larghezza) e quindi misuriamo la posizione orizzontale con (.+)dentro il lookbehind. Quindi, per assicurarci di trasporre solo la prima copia, controlliamo di poter raggiungere l'inizio della stringa senza passare oltre una scheda.

Potresti notare che questo corrisponderà anche ad alcune stringhe di tre byte (che non si allineano nemmeno con le celle) nella prima riga della seconda copia, perché il .+ possono passare attraverso la scheda. Tuttavia, questo non è un problema perché la posizione orizzontale di queste partite è strettamente maggiore di qualsiasi altra all'interno della prima copia, quindi queste partite rimangono nella loro posizione.

Il resto è abbastanza semplice:

T` 0

Rimuoviamo spazi e zeri dall'input.

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

E infine controlliamo che l'intero input sia costituito da righe del modulo con spazi vuoti 1(-11)*, ovvero una sequenza alternata di 1e -1che inizia e finisce con 1(perché altrimenti non si somma a 1).


3

Gelatina, 15 byte

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

Provalo 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 byte

!sm-sM._+d_1U2+C

Provalo online: Dimostrazione o Test Suite

Spiegazione:

!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

Gelatina , 11 byte

;Zj-+\ṚQḄ=2

Restituisce 1 per le matrici di segni alternati, 0 altrimenti. Provalo online! o verifica tutti i casi di test .

sfondo

Ignorando gli zeri, ogni riga e colonna deve essere costituita dal modello (1, -1) * 1 , ovvero alternando occorrenze di 1 e -1 , iniziando e terminando con un 1 (quindi la somma è 1 ).

Per verificare questo è il caso, prendiamo l'array di tutte le righe e colonne e li uniamo usando -1 come separatore. Poiché tutti gli endpoint sono 1 , la matrice piatta risultante soddisfa il modello (1, -1) * 1 se e solo se le righe e le colonne lo fanno.

Per il test effettivo, calcoliamo la somma cumulativa dell'array. Per una matrice di segni alternati, il risultato sarà una matrice di 0 e 1 che termina con 1 .

Invertire la somma cumulativa e deduplicarla, mantenendo l'ordine delle occorrenze iniziali di tutti gli elementi univoci. Per un input veritiero, il risultato sarà la lista [1, 0] .

Per generare il corrispondente valore booleano, convertiamo le somme cumulative duplicate da binarie a numeri interi e testiamo se il risultato è 2 .

Come funziona

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

3 byte salvati grazie a @Luis

t!h"@s1=@Xzdv

Questa soluzione accetta un array 2D come input e genererà un array truey o falsey . È importante notare che in MATL, un array truey è composto da tutti gli elementi diversi da zero mentre un risultato falsey ha almeno un elemento zero. Ecco un'altra dimostrazione di array di verità / falsità .

Provalo online

Versione modificata per mostrare tutti i casi di test

Spiegazione

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

Appiattisce l'array e la sua trasposizione in stringhe, quindi (ignorando 0s) verifica lo schema 1-11...1-11in ciascuna stringa.

Modifica: salvato 12 byte grazie a @PeterTaylor.


1
Non è necessario per verificare il modello -11-1...-11-1, perché dal momento che le voci si alternano e si hanno a somma positiva, ci deve essere un altro 1che -1, in modo che il modello deve essere 1-11...1-11.
Peter Taylor,

@PeterTaylor Ugh, è la seconda volta che leggo male la domanda. (Da allora i commenti relativi alla prima volta sono stati cancellati.)
Neil,

L'intestazione dice 110 byte, ma sono solo 100
Peter Taylor,

1
@PeterTaylor Almeno i "12 byte salvati grazie a @PeterTaylor" erano corretti.
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]

L'input è un elenco di tuple.

Questo termina con il codice di uscita 0 per le matrici di segni alternati e il codice di uscita 1 in caso contrario. Questo è ciò che fanno il vero e il falso e, come mostrato nella sezione di verifica, può effettivamente essere usato come condizione in, ad esempio, uno script Bash.

Verifica

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

Produzione

$ bash test-suite.sh
     12 true
     17 false

Come funziona

Ignorando gli zeri, ogni riga e colonna deve essere costituita dal modello (1, -1) * 1 , ovvero alternando occorrenze di 1 e -1 , iniziando e terminando con un 1 (quindi la somma è 1 ).

Per verificare ciò, comprimiamo / trasponiamo la matrice di input M , aggiungiamo il risultato a M (ora costituito da un elenco di righe e colonne) e anteponiamo un -1 a ogni riga / colonna.

Ad esempio, se M è una delle seguenti matrici (valida, non valida)

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

i risultati sono

-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

La lettura della matrice generata in ordine di riga deve comportare una sequenza piatta con motivo (-1, 1) * . Per verificare ciò, prendiamo la somma cumulativa di tutte le voci, a partire dalla riga superiore.

Per le matrici di esempio, questo risulta in

-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

Per una matrice di segni alternati valida, l'output sarà composto da -1 'e 0 ' e - poiché ogni -1 annulla il precedente 1 e viceversa - nessun altro numero.

A prima vista, questo potrebbe non riuscire a verificare se l'ultima colonna termina con un 1 . Tuttavia, per una matrice n × n contenente k zero, le righe valide conterranno n + k . Se anche tutte le colonne tranne l'ultima fossero valide, ci sarebbero n + k - 1 nelle colonne, il che è impossibile.

Per verificare che non vi siano altri numeri, memorizziamo le somme parziali in una variabile s e le aggiorniamo per ogni voce di con matrice generata con s+=[n][s].

Se s = 0 o s = -1 , questo equivale a s+=n. Tuttavia, per tutti gli altri valori di s , provoca un IndexError , quindi Python termina immediatamente con il codice di uscita 1 . Se ciò non accade in nessun momento, il programma termina in modo pulito con il codice di uscita 0 .


0

R, 54 byte

La funzione anonima utilizza la stessa logica delle risposte Python 2, Jelly e Julia di Dennis.

function(x)all(abs(cumsum(rbind(-1,cbind(t(x),x))))<2)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.