Costruisci una matrice compagna


15

Hai un numero di polinomi che sono soli, quindi rendili alcuni compagni (che non minacciano di pugnalare)!

Per un polinomio di grado n, esiste una matrice cubon by n compagno per esso. È necessario creare una funzione che accetta un elenco di coefficienti per un polinomio in ordine crescente ( ) o decrescente ( ) (ma non entrambi) e generare la matrice associata. a + bx +cx^2 + …ax^n + bx^(n-1) + cx^(n-2)+…

per un polinomio c0 + c1x + c2x^2 + ... + cn-1x^(n-1) + x^n, la sua matrice compagna è

     (0, 0, 0, ..., -c0  ),
     (1, 0, 0, ..., -c1  ),
     (0, 1, 0, ..., -c2  ),
     (...................),
     (0, 0, ..., 1, -cn-1)

si noti che il coefficiente per x^nè 1. Per qualsiasi altro valore, dividere tutto il resto dei coefficienti per x^n's. Inoltre, gli 1 sono sfalsati rispetto alla diagonale.

Se la lingua che stai utilizzando contiene già una funzione o un modulo che lo fa, non puoi usarla - devi scrivere la tua.

Ad esempio, se avessi 4x^2 – 7x + 12, i coefficienti in ordine crescente sono (12, -7, 4)e in ordine decrescente (4, -7, 12). La funzione o il programma dovrebbero essere emessi [(0, -3.0), (1, 1.75)]per entrambi gli ordini. Specifica quale ordine accetta il tuo codice. Il polinomio minimo dovrebbe essere un quadratico. I coefficienti sono limitati ai numeri reali.

Di seguito sono riportati alcuni esempi: l'output non deve corrispondere alla formattazione graziosa, ma dovrebbe generare in ordine le righe (nella ()) della matrice.

Ordine ascendente:

input:
    [3., 7., -5., 4., 1.]
output:
    [(0, 0, 0, -3.),
     (1, 0, 0, -7.),
     (0, 1, 0,  5.),
     (0, 0, 1, -4.)]

input:
    [-4., -7., 13.]
output:
    [(0, 0.30769231),
     (1, 0.53846154)]

input:
    [23., 1., 92., 8., -45., 88., 88.]
output:
    [(0, 0, 0, 0, 0, -0.26136364),
     (1, 0, 0, 0, 0, -0.01136364),
     (0, 1, 0, 0, 0, -1.04545455),
     (0, 0, 1, 0, 0, -0.09090909),
     (0, 0, 0, 1, 0,  0.51136364),
     (0, 0, 0, 0, 1, -1.        )]

Ordine decrescente:

input:
    [1., 4., -5., 7., 3.]
output:
    [(0, 0, 0, -3.),
     (1, 0, 0, -7.),
     (0, 1, 0,  5.),
     (0, 0, 1, -4.)]

input:
    [13., -7., -4.]
output:
    [(0, 0.30769231),
     (1, 0.53846154)]

input:
    [88., 88., -45., 8., 92.,1., 23.]
output:
    [(0, 0, 0, 0, 0, -0.26136364),
     (1, 0, 0, 0, 0, -0.01136364),
     (0, 1, 0, 0, 0, -1.04545455),
     (0, 0, 1, 0, 0, -0.09090909),
     (0, 0, 0, 1, 0,  0.51136364),
     (0, 0, 0, 0, 1, -1.        )]

Dennis vince con 20 byte!


2
I coefficienti sono reali (non complessi), giusto?
Luis Mendo,

1
I programmi sono validi o funzionano solo? (Tieni presente che la limitazione del concorso alle funzioni non consente interessanti lingue senza funzioni.)
lirtosiast

1
Qual è il polinomio di grado minimo di cui dobbiamo tenere conto?
Alex A.

Risposte:


3

CJam, 23 20 byte

{)W*f/_,,_ff=1f>\.+}

Questa è una funzione che estrae l'input (ordine crescente) dallo stack e spinge l'output in cambio.

Provalo online nell'interprete CJam .

Come funziona

)   e# Pop the last element from the input array.
W*  e# Multiply it by -1.
f/  e# Divide the remaining array elements by this product.
_,  e# Push a copy of the array and compute its length (L).
,_  e# Push [0 ... L-1] twice.
ff= e# For each I in [0 ... L-1]:
    e#   For each J in [0 ... L-1]:
    e#     Push (I==J).
    e# This pushes the L x L identity matrix.
1f> e# Discard the first element of each row, i.e., the first column.
\   e# Swap the result with the modified input.
.+  e# Vectorized append; append the input as a new column.

3

CJam, 32 31 28 byte

0q~)f/f-_,(_,\0a*1+fm<~]W%z

Provalo online

Questo accetta l'input in ordine crescente, usando il formato elenco CJam. Input di esempio:

[-4.0 -7.0 13.0]

Spiegazione:

0     Push a 0 for later sign inversion.
q~    Get and interpret input.
)     Pop off last value.
f/    Divide all other values by it.
f-    Invert sign of values.
_,    Get count of values, which corresponds to n.
(     Decrement by 1.
_,    Create list of offsets [0 1 ... n-1] for later.
\     Swap n-1 back to top.
0a*   Create list of n-1 zeros.
1+    Append a 1. This is the second-but-last column [0 0 ... 0 1].
fm<   Apply rotation with all offsets [0 1 ... n-1] to column.
~     Unwrap the list of 0/1 columns.
]     Wrap all columns
W%    Invert their order from last-to-first to first-to last.
z     Transpose to get final matrix.
`     Convert to string for output.

3

APL, 40 30 byte

{(-n↑⍵÷⊃⊖⍵),⍨⍉1↓⍉∘.=⍨⍳n←1-⍨≢⍵}

Accetta input in ordine crescente.

Spiegazione:

{
                        n←1-⍨≢⍵    ⍝ Define n = length(input)-1
                   ∘.=⍨⍳           ⍝ Create an n×n identity matrix
               ⍉1↓⍉                ⍝ Drop the leftmost column
            ,⍨                     ⍝ Append on the right:
  (-n↑⍵                            ⍝ n negated coefficients,
       ÷⊃⊖⍵)                       ⍝ divided by the n+1st
}

Provalo online


3

Julia, 43 byte

c->rot180([-c[2:(n=end)]/c[] eye(n-1,n-2)])

Questo utilizza l'ordine decrescente per l'input. Costruisce la matrice ruotata di 180 gradi, al fine di consentire un uso più efficiente dell '"occhio", quindi ruota la matrice nell'orientamento corretto.


2

Julia, 64 44 byte

c->(k=c[n=end];[eye(n-=1)[:,2:n] -c[1:n]/k])

Accetta un vettore dei coefficienti in ordine crescente.

Ungolfed:

function f(c::Array)
    # Simultaneously define k = the last element of c and
    # n = the length of c
    k = c[n = end]

    # Decrement n, create an n×n identity matrix, and exclude the
    # first column. Horizontally append the negated coefficients.
    [eye(n-=1)[:,2:n] -c[1:n]/k]
end

Provalo online

Risparmiato 20 byte grazie a Glen O!


2

R, 71 59 byte

Accetta l'input in ordine crescente.

function(x)cbind(diag(n<-length(x)-1)[,2:n],-x[1:n]/x[n+1])

Ungolfed:

f <- function(x) {
    # Get the length of the input
    n <- length(x)-1

    # Create an identity matrix and exclude the first column
    i <- diag(n)[, 2:n]

    # Horizontally append the negated coefficients divided
    # by the last one
    cbind(i, -x[1:n]/x[n+1])
}

1

Matlab, 66 byte

function y=f(c)
n=numel(c);y=[[0*(3:n);eye(n-2)] -c(1:n-1)'/c(n)];

Utilizza l'ordine crescente per l'input, con formato [3., 7., -5., 4., 1.]o [3. 7. -5. 4. 1.].

Provalo online (in Octave).

Esempio (in Matlab):

>> f([23., 1., 92., 8., -45., 88., 88.])
ans =
                   0                   0                   0                   0                   0  -0.261363636363636
   1.000000000000000                   0                   0                   0                   0  -0.011363636363636
                   0   1.000000000000000                   0                   0                   0  -1.045454545454545
                   0                   0   1.000000000000000                   0                   0  -0.090909090909091
                   0                   0                   0   1.000000000000000                   0   0.511363636363636
                   0                   0                   0                   0   1.000000000000000  -1.000000000000000

Se un programma è valido (anziché una funzione), con stdin e stdout:

Matlab, 59 byte

c=input('');n=numel(c);[[0*(3:n);eye(n-2)] -c(1:n-1)'/c(n)]

Penso che tu possa faren=numel(c=input(''));
lirtosiast

@ThomasKwa Grazie! Tuttavia, questa non è una sintassi valida in Matlab. n=numel(input(''))sarebbe valido, ma devo criutilizzarlo più tardi
Luis Mendo il

Scusa; ha funzionato in Octave dove l'ho provato.
lirtosiast

1

Ottava, 45 44 byte

Supponendo che csia un vettore di colonna con il coefficiente della massima potenza di xalla fine.

@(c)[eye(n=rows(c)-1)(:,2:n),-c(1:n)/c(end)]

Vecchia versione:

@(c)[eye(n=numel(c)-1)(:,2:n),-c(1:n)/c(end)]

Il cinque, Julia!


1

Python 2, 141 byte

Il mio tentativo:

def C(p):
 c,r=p.pop(0),range;d=[-i/c for i in p];n=len(d);m=[[0]*n for i in r(n)]
 for i in r(n-1):m[i][i+1]=1
 m[-1]=d[::-1];return zip(*m)

Prende un elenco dei coefficienti in ordine decrescente e crea innanzitutto la trasposizione della matrice compagna, nota per pugnalare ed essere loquace. Il ritorno utilizza zip per produrre la trasposizione di questa trasposizione per ottenere la matrice effettiva.

>>> C([1., 4., -5., 7., 3.])
[(0, 0, 0, -3.0), (1, 0, 0, -7.0), (0, 1, 0, 5.0), (0, 0, 1, -4.0)]

1

JavaScript (ES6) 85

Ordine ascendente.

Prova a eseguire lo snippet di seguito in qualsiasi browser compatibile con EcmaScript 6.

f=c=>alert(c.map((v,i)=>c.map((x,j)=>++j-i?j-c.length?0:-v/m:1),m=c.pop()).join(`
`))

// test
// redefine alert to write into the snippet body
alert=x=>O.innerHTML+=x+'\n'

function test() {
  v=I.value.match(/\d+/g)
  I.value=v+''
  alert(v)
  f(v)
}  

test()
<input value='23.,1.,92.,8.,-45.,88.,88.' id=I><button onclick="test()">-></button>
<pre id=O></pre>


0

TI-BASIC, 50 byte

Ans→X
List▶matr(ΔList(Ans-cumSum(Ans)),[A]
dim(Ans
augment(augment(0randM(Ans-2,1),identity(Ans-2))ᵀ,[A]∟X(Ans)⁻¹

Accetta l'input in ordine crescente. Si noti che ciò non funzionerà per i polinomi di grado <2, poiché TI-BASIC non supporta matrici o elenchi vuoti. In attesa di una sentenza da OP, posso risolvere questo problema al costo di pochi byte.

Innanzitutto, memorizziamo l'elenco ∟Xper utilizzare l'ultimo elemento in un secondo momento; quindi, calcoliamo ΔList(Ans-cumSum(Ans)), che è solo l'elenco negato con l'ultimo elemento tagliato e convertito in un vettore di colonna. Dato che List▶matr(non si modifica Ans, possiamo usare la riga successiva per prendere la dimensione della lista, che usiamo tre volte. TI-BASIC non ha concatenazione verticale, quindi dobbiamo prendere trasposizioni e concatenare orizzontalmente. Nell'ultima riga,[A]/∟X(Ans non funzionerebbe perché le matrici possono essere moltiplicate per scalari ma non divise.

A parte: per generare il vettore di riga degli zeri, sfruttiamo il randM(comando raramente utile . randM(crea una matrice casuale, ma le sue voci sono sempre numeri interi casuali tra -9 e 9 (!), quindi è davvero utile solo creare matrici zero.


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.