La matrice è al primo posto?


21

Data una matrice di numeri interi, verifica se è di rango uno, il che significa che ogni riga è un multiplo dello stesso vettore. Ad esempio, in

 2   0  -20  10  
-3   0   30 -15
 0   0   0   0

ogni riga è un multiplo di 1 0 -10 5.

La stessa definizione funziona anche con le colonne al posto delle righe. In alternativa, una matrice è di livello 1 se è come una tabella di moltiplicazione:

 *    1   0  -10  5
    ----------------
 2 |  2   0  -20  10  
-3 | -3   0   30 -15
 0 |  0   0   0   0

Abbiamo assegnato etichette di riga r[i]ed etichette di colonna in c[j]modo che ogni voce della matrice M[i][j]sia il prodotto delle etichette corrispondenti come M[i][j] = r[i] * c[j].

Ingresso:

Una matrice intera come contenitore 2D a tua scelta. Ad esempio, un elenco di elenchi, un array 2D o simile. Non si dovrebbe prendere la larghezza o l'altezza come input aggiuntivi a meno che il formato dell'array non lo richieda.

La matrice può essere non quadrata. Avrà almeno una voce diversa da zero: non devi avere a che fare con matrici vuote o zero.

Puoi presumere che i numeri interi non causino problemi di overflow.

Produzione:

Un valore coerente per le matrici di rango uno e un valore coerente diverso per le altre matrici.

Built-in:

Non è possibile utilizzare alcun built-in per calcolare il rango o controllare direttamente il rango uno. Puoi usare altri built-in come autovalori, decomposizioni, ecc., Ma incoraggio a migliorare le risposte che non hanno built-in per la maggior parte del lavoro.

Casi test:

Classifica-one:

[[2, 0, -20, 10], [-3, 0, 30, -15], [0, 0, 0, 0]]
[[0, 0, 0], [0, 3, 0], [0, 0, 0]]
[[-10]]
[[0, 0, 0], [0, 4, 11], [0, -4, -11]]

Non al primo posto:

[[-2, 1], [2, 4]]
[[0, 0, 3], [-22, 0, 0]]
[[1, 2, 3], [2, 4, 6], [3, 6, 10]]
[[0, -2, 0, 0], [0, 0, 0, 1], [0, 0, -2, 0]]

Classifica:


2
Per i curiosi, una risposta di Mathematica che usa i builtin sarebbe simile a questa (16 byte):MatrixRank@#==1&
JungHwan Min


2
Un bel teorema è che il rango di colonna è uguale al rango di riga per le matrici di dimensioni finite.
Leaky Nun,

3
Dobbiamo preoccuparci dei problemi di precisione del galleggiante? Ad esempio, possono far sembrare una matrice di rango 1 rango 2
Luis Mendo,

@LuisMendo Devi gestire problemi di precisione come autovalori di 1.0000000001, ma puoi presumere che la matrice non sia grande e non sia stata specificatamente scelta per essere classificata erroneamente.
xnor,

Risposte:


13

Gelatina , 6 byte

ẸÐfÆrE

Provalo online!

Come funziona

ẸÐfÆrE  Main link. Argument: M (2D array)

ẸÐf     Filter by any, removing rows of zeroes.
   Ær   Interpret each row as coefficients of a polynomial and solve it over the
        complex numbers.
     E  Test if all results are equal.

Precisione

Ærusa metodi numerici, quindi i suoi risultati sono generalmente inesatti. Ad esempio, l'ingresso [6, -5, 1] , che rappresenta il polinomio 6 - 5x + x² , risulta nelle radici 3.0000000000000004 e 1.999999999999999998 . Tuttavia, moltiplicando tutti i coefficienti di un polinomio per la stessa costante diversa da zero si ottengono radici ugualmente inesatte. Ad esempio, Ærottiene le stesse radici per [6, -5, 1] e [6 × 10 100 , -5 × 10 100 , 10 100 ] .

Va notato che la precisione limitata del galleggiante e dei tipi complessi può causare errori. Ad esempio, Ærotterrebbe le stesse radici per [1, 1] e [10 100 , 10 100 + 1] . Dal momento che possiamo supporre che la matrice non sia grande e non sia stata specificatamente scelta per essere classificata erroneamente , ciò dovrebbe andare bene.


5
moltiplicando tutti i coefficienti di un polinomio per la stessa costante diversa da zero si ottengono radici ugualmente inesatte Questo è un approccio geniale
Luis Mendo,

8

Haskell , 50 byte

rprende un elenco di liste di se Integerrestituisce Falsese la matrice ha una posizione in classifica, Truealtrimenti.

r l=or[map(x*)b<map(y*)a|a<-l,b<-l,(x,y)<-zip a b]

Provalo online!

Come funziona

  • Genera tutte le coppie di righe ae b(comprese le pari righe), e per ciascuna coppia, immobili xe ycorsa attraverso elementi corrispondenti.
  • Moltiplica la riga bper xe la riga aper y. La matrice avrà un rango uno se e solo se i risultati sono sempre uguali.
  • Poiché le coppie vengono generate in entrambi gli ordini, è <possibile utilizzare per verificare se c'è mai una disuguaglianza. L'elenco dei risultati del test è combinato con or, fornendo Truese ci sono righe non proporzionali.

7

Mathematica, 51 33 byte

RowReduce@#~Count~Except@{0..}<2&

Ingresso

[{{2,0, -20,10}, {- 3,0,30, -15}, {0,0,0,0}}]

-14 byte dall'utente202729
Altri 3 byte salvati da junghwanmin


Suggerisco che, invece di costruire una tabella con lunghezza uguale a quella di First@#, è possibile calcolare 0First@#poiché 0 si moltiplica per tutto ciò che è 0 e la moltiplicazione è elencabile. Inoltre puoi prendere in considerazione l'utilizzo Tr[1^<list>]per calcolare la lunghezza di un elenco.
user202729

molto bello, lo modificherò!
J42161217

Invece 0#&@@#, {0..}avrebbe funzionato anche. E poi Infixfunziona, quindi potrebbe essere il codice finale RowReduce@#~Count~{0..}==Tr[1^#]-1&, risparmiando 2 byte.
JungHwan Min

In realtà, Exceptpuò essere usato per sbarazzarsi di Trcose. -3 byte:RowReduce@#~Count~Except@{0..}==1&
JungHwan Min

Penso che la matrice con riga ridotta sia garantita per essere diversa da zero (perché la matrice originale è diversa da zero), quindi il risultato del conteggio sarà un numero intero positivo, quindi <2può essere utilizzato al posto di ==1.
user202729

4

JavaScript (ES6), 68 67 65 byte

Questo è basato su risposta 05AB1E di Neil ed è significativamente più efficiente del mio approccio originale.

Restituisce falseper il primo posto e truenon solo.

f=(a,R,V,X)=>a.some(r=>r.some((v,x)=>R?v*V-r[X]*R[x]:f(a,r,v,x)))

Casi test


Risposta originale, 84 byte

Restituisce falseper il primo posto e truenon solo.

a=>a.some(r=>r.some((x,i)=>(isNaN(x/=a.find(r=>r.some(x=>x))[i])?r:1/r[0]?r=x:x)-r))

Casi test

Come?

a => a.some(r =>          // given a matrix a, for each row r of a:
  r.some((x, i) =>        //   for each value x of r at position i:
    (                     //
      isNaN(x /=          //     divide x by a[ref][i]
        a.find(r =>       //       where ref is the index of the first row that
          r.some(x => x)  //       contains at least one non-zero value
        )[i]              //       (guaranteed to exist by challenge rules)
      ) ?                 //     we get NaN for 0/0, in which case:
        r                 //       use r, so that this column is ignored
      :                   //     else:
        1 / r[0] ?        //       if r is still holding the current row:
          r = x           //         set it to x (either a float, +Inf or -Inf)
        :                 //       else:
          x               //         use x
    ) - r                 //     subtract r from the value set above (see table)
  )                       //   end of some()
)                         // end of every()

La sottrazione che viene eseguita alla fine del codice può portare a molte situazioni diverse, che sono riassunte di seguito:

A                   | B              | A - B       | False / True
--------------------+----------------+-------------+-------------
array of 1 number   | same array     | 0           | False
array of 2+ numbers | same array     | NaN         | False
a number            | same number    | 0           | False
+Infinity           | +Infinity      | NaN         | False
-Infinity           | -Infinity      | NaN         | False
a number            | another number | <> 0        | True
+Infinity           | -Infinity      | +Infinity   | True
-Infinity           | +Infinity      | -Infinity   | True
a number            | +/-Infinity    | +/-Infinity | True
+/-Infinity         | a number       | +/-Infinity | True

Il test fallisce non appena si ottiene un valore truthy: ciò avviene quando si incontrano due rapporti distinti (diversi da 0/0 ) tra un (i, y) e un (i, r) in qualsiasi riga y della matrice, dove r è l'indice di una riga diversa da zero.


Eh, mi stavo solo chiedendo che io stesso ...
Neil,

@Neil Desideri pubblicarlo come nuova risposta? Fammi sapere.
Arnauld,


3

Gelatina , 12 byte

ẸÐfµ÷"ЀZE€Ẹ

Provalo online!

Spiegazione

ẸÐfµ÷"ЀZE€Ẹ  Main link
 Ðf           Filter; keep all elements where
Ẹ             At least one element is truthy (remove zero-rows)
      Ѐ      For each row on the right side
    ÷"        Divide it by each row in the original
        Z     Zip the array
          €   For each submatrix
         E    Are all rows equal?
           Ẹ  Is at least one of the elements from above truthy?

La spiegazione potrebbe essere leggermente errata in quanto questa è la mia interpretazione del golf di miglia del mio algoritmo originale

-5 byte grazie alle miglia


... Il tuo codice è dipendente dal denaro. (Ricevo il deja vu ...)
totalmente umano il

@icrieverytim Ehi, almeno il numero di simboli del dollaro questa volta è inferiore alla metà della lunghezza del codice! : P
HyperNeutrino,

1
@icrieverytim ha corretto un bug e ora anche meno segni del dollaro: P
HyperNeutrino,

Credo che questo dovrebbe funzionare anche per 12 byte ẸÐfµ÷"ЀZE€Ẹ TIO
miglia

@miles Oh bello! L'approccio per il tuo è un po 'diverso (penso?), Quindi puoi
postarlo

3

05AB1E , 16 byte

2ãεø2ãε`R*`Q}W}W

Provalo online! Utilizza la proprietà della tabella di moltiplicazione secondo cui gli angoli opposti di qualsiasi rettangolo hanno lo stesso prodotto. Spiegazione:

2ãε           }     Loop over each pair of rows
   ø                Transpose the pair into a row of pairs
    2ãε     }       Loop over each pair of columns
       `R*`Q        Cross-multiply and check for equality
             W W    All results must be true

3

TI-Basic (serie TI-83), 28 27 28 byte (62 caratteri)

:Prompt [A]
:{0→X
:Matr►list(ref([A])ᵀ,L₁,X
:not(max(abs(ᶫX

Calcola la forma del tratteggio della matrice [A] , memorizza la sua prima riga (da scartare) L₁e la seconda riga in ᶫX. Quindi max(abs(ᶫXsarà zero se è ᶫXcostituito solo da zero e un valore positivo altrimenti, qualenot( cambia in 1 se la matrice è al primo posto, 0 in caso contrario.

Per una matrice a 1 riga, ᶫXè impostato su {0}e quindi non viene modificato quando proviamo a guardare la seconda riga inesistente della matrice.


-1 byte grazie a Scott Milner

+1 byte per correggere l'errore di dimensione per le matrici a 1 riga. Viene fuori il Matr►list( comando si lamenta se si tenta di estrarre la seconda riga da una matrice con una sola riga; tuttavia, se si tenta di estrarre la prima e la seconda riga dalla matrice, non funzionerà in modo silenzioso.


1
È possibile salvare un byte con Prompt [A]invece di Ans→[A].
Scott Milner,

@ScottMilner Grazie! Probabilmente c'è un modo per evitarlo se usiamo qualcosa di simile ClrListper inizializzare ᶫX, ma non riesco a farlo funzionare in meno spazio.
Misha Lavrov,

Elimina la seconda riga, poiché Matr►list(sovrascriverà l'elenco, anche se non esiste, e risparmierai 5 byte.
kamoroso94,

1
@ kamoroso94 Il punto della seconda riga non è quello di creare un elenco quando non esiste: il punto della seconda riga è quello di creare un valore predefinito per la seconda riga quando la matrice ha solo una riga. Se si elimina la seconda riga, il codice si arresta in modo anomalo per le matrici 1xN.
Misha Lavrov,

2
@ kamoroso94 Dovremmo sostituire L1 con ᶫY, non Y; in caso contrario, la calcolatrice penserà "estrai la riga Y-esima della matrice in ᶫX", non "estrai la prima riga in ,Y e la seconda riga in ᶫX".
Misha Lavrov,

3

Brachylog , 27 byte

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ

Provalo online!

Usa l'approccio di Neil ai "prodotti degli angoli opposti di ogni rettangolo dovrebbero essere uguali". Il prodotto incrociato è costoso e richiede 10 byte interi, ma questo è ancora più breve di qualsiasi approccio basato sulla divisione che ho provato, principalmente a causa della stipulazione di due output coerenti per verità e falsità nella domanda: rendere falsa essere solo un false., e talvolta non un errore di divisione per zero, utilizza troppi byte.

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ
{⊇Ċ}ᶠ                        Get each pair of rows from the matrix
                             eg.: [ [[a, b, c], [k, l, m]], ... ]
     zᵐ                      Zip each pair's elements
                                  [ [[a, k], [b, l], [c, m]], ... ]
       {                 }ᵐ  Map this over each pair of rows:
                                  [[a, k], [b, l], [c, m]]
        ↰₁ᶠ                  Get each pair of paired elements from the rows
                                  [[[a, k], [b, l]], [[b, l], [c, m]], [[a, k], [c, m]]]
           {           }ᵐ    Map this over each pair of pairs
                                  [[a, k], [b, l]]
            ⟨hz{t↔}⟩         Zip the first pair with the reverse of the second
                                  [[a, l], [k, b]]
                    ×ᵐ       Multiply within each sublist
                                  [al, kb]
                      =      The results should be equal
                             (If the results are unequal for any pair, the whole predicate fails,
                              and outputs false.)

Approccio alternativo basato sulla divisione per elemento ( 30 byte ):

{≡ᵉ¬0&}ˢ\↰₁ˢ{c׬0&⟨hz∋⟩ᶠ/ᵐ²=ᵐ}

Provalo online!


2

Gelatina , 9 byte

ẸÐf÷g/$€E

Provalo online!

ẸÐf         Discard zero rows
   ÷  $€    Divide each row by
    g/        its greatest common divisor
        E   Does this list have only one unique element?

1

SageMath, 40 byte

lambda M:any(M.rref()[1:])*(M.nrows()>1)

Provalo online

Questa funzione anonima ritorna Falsese la matrice è al primo posto eTrue contrario.

La funzione accetta una matrice Mcome input, la converte in forma di riga-scaglione ridotta ( M.rref()) e verifica che anyle righe oltre la prima siano diverse da zero. Quindi, quel valore viene moltiplicato per M.nrows()>1(la matrice ha più di una riga?).


1

Python 3 , 93 91 byte

lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))

Provalo online!

Come funziona

Verifica se qualche 2 minore ha un determinante diverso da zero. In tal caso, il rango deve essere almeno 2: "Un p-minor non-evanescente (sottomodella p × p con determinante diverso da zero) mostra che le righe e le colonne di quella sottostruttura sono linearmente indipendenti, e quindi quelle righe e le colonne della matrice completa sono linearmente indipendenti (nella matrice completa), quindi il rango di riga e colonna è almeno pari al rango determinante "(da Wikipedia )

Nota: rasato due byte grazie al commento di user71546.


1
91 - più breve se si inserisce l'enumerazione negli argomenti della funzione e quindi si elimina la necessità di f=:lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))
Shieru Asakoto,

@ user71546 Grazie! Fatto!
Luca Citi,

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.