C'è un'eco nella mia matrice ... un'eco nella mia matrice ... la mia matrice


34

Aiuto! Mi sembra di avere un'eco fastidiosa in alcuni dei miei array e mi piacerebbe liberarmene. In questo caso, l'array originale si ripete da qualche parte nel mezzo causando l'aggiunta reciproca dei valori.

Ad esempio, l'array [ 422, 375, 527, 375, 859, 451, 754, 451 ]contiene un'eco di se stesso in questo modo:

[ 422, 375, 527, 375, 859, 451, 754, 451 ] <-- array with echo (input)

[ 422, 375, 105,   0, 754, 451           ] <-- original array (output)
[           422, 375, 105,   0, 754, 451 ] <-- echo of original array

Esempio 2:

[ 321, 526, 1072, 899, 6563, 798, 7038, 3302, 3032, 3478, 1806, 601 ] <-- input

[ 321, 526,  751, 373, 5812, 425, 1226, 2877, 1806,  601            ] <-- output
[            321, 526,  751, 373, 5812,  425, 1226, 2877, 1806, 601 ]

È anche possibile che non vi sia eco nell'array, nel qual caso restituire l'array originale:

Esempio 3:

[ 623, 533, 494, 382 ] <-- input
[ 623, 533, 494, 382 ] <-- output

Sfida:

Dato un array che può contenere un eco, rimuoverlo e restituire l'array senza un eco.

Ingresso:

  • Un array, un elenco, una stringa delimitata, schede perforate o l'equivalente adatto alla piattaforma, contenente tre o più numeri interi, nell'intervallo con almeno un elemento .0n<10000>0
  • L'eco non può iniziare dal primo o dopo l'ultimo elemento.
  • L'eco si verifica solo una volta o per niente all'interno dell'input.

Produzione:

  • Un array, un elenco, ecc. Di numeri interi , con l'eco rimossa.0n<10000
  • Se non c'è eco, restituisce l'array originale.

Regole e punteggio:

Casi test:

Con eco:

[ 422, 375, 527, 375, 859, 451, 754, 451 ]
[ 422, 375, 105, 0, 754, 451 ]

[ 321, 526, 1072, 899, 6563, 798, 7038, 3302, 3032, 3478, 1806, 601 ]
[ 321, 526, 751, 373, 5812, 425, 1226, 2877, 1806, 601 ]

[ 4330, 3748, 363, 135, 2758, 3299, 1674, 1336, 4834, 2486, 4087, 1099, 4098, 4942, 2159, 460, 4400, 4106, 1216, 3257, 1638, 2848, 3616, 3554, 1605, 490, 1308, 2773, 3322, 3284, 4037, 7109, 4171, 5349, 2675, 3056, 4702, 4229, 1726, 5423, 6039, 8076, 6047, 7088, 9437, 4894, 1946, 7501, 5331, 3625, 5810, 6289, 2858, 6610, 4063, 5565, 2200, 3493, 4573, 4906, 3585, 4147, 3748, 3488, 5625, 6173, 3842, 5671, 2555, 390, 589, 3553, 3989, 4948, 2990, 4495, 2735, 1486, 3101, 1225, 2409, 2553, 4651, 10, 2994, 509, 3960, 1710, 2185, 1800, 1584, 301, 110, 969, 3065, 639, 3633, 3544, 4268 ]
[ 4330, 3748, 363, 135, 2758, 3299, 1674, 1336, 4834, 2486, 4087, 1099, 4098, 4942, 2159, 460, 4400, 4106, 1216, 3257, 1638, 2848, 3616, 3554, 1605, 490, 1308, 2773, 3322, 3284, 4037, 2779, 423, 4986, 2540, 298, 1403, 2555, 390, 589, 3553, 3989, 4948, 2990, 4495, 2735, 1486, 3101, 1225, 2409, 2553, 4651, 10, 2994, 509, 3960, 1710, 2185, 1800, 1584, 301, 110, 969, 3065, 639, 3633, 3544, 4268 ]

[ 24, 12, 52, 125, 154, 3, 567, 198, 49, 382, 53, 911, 166, 18, 635, 213, 113, 718, 56, 811, 67, 94, 80, 241, 343, 548, 68, 481, 96, 79, 12, 226, 255, 200, 13, 456, 41 ]
[ 24, 12, 52, 125, 154, 3, 567, 198, 25, 370, 1, 786, 12, 15, 68, 15, 88, 348, 55, 25, 55, 79, 12, 226, 255, 200, 13, 456, 41 ]

[ 1, 3, 2 ]
[ 1, 2 ]

[ 0, 1, 3, 2, 0 ]
[ 0, 1, 2, 0 ]

Senza eco:

[ 623, 533, 494, 382 ]
[ 623, 533, 494, 382 ]

[ 1141, 1198, 3106, 538, 3442, 4597, 4380, 3653, 1370, 3987, 1964, 4615, 1844, 5035, 2463, 6345, 4964, 4111, 5192, 8555, 5331, 3331, 4875, 6586, 5728, 4532, 5972, 2305, 3491, 6317, 2256, 2415, 5788, 4873, 6480, 2080, 5319, 4551, 6527, 5267, 4315, 2178, 2615, 5735, 5950, 6220, 7114, 6259, 5000, 4183, 6822, 6927, 7150, 8003, 5603, 3154, 8231, 5005, 5743, 6779, 4530, 4029, 5336, 6105, 4777, 6183, 6838, 5725, 6819, 8584, 3142, 3840, 3291, 4284, 2933, 4859, 2906, 5176, 2853, 2110, 2048, 4389, 4501, 2267, 2704, 431, 1495, 2712, 3008, 187, 3487, 630 ]
[ 1141, 1198, 3106, 538, 3442, 4597, 4380, 3653, 1370, 3987, 1964, 4615, 1844, 5035, 2463, 6345, 4964, 4111, 5192, 8555, 5331, 3331, 4875, 6586, 5728, 4532, 5972, 2305, 3491, 6317, 2256, 2415, 5788, 4873, 6480, 2080, 5319, 4551, 6527, 5267, 4315, 2178, 2615, 5735, 5950, 6220, 7114, 6259, 5000, 4183, 6822, 6927, 7150, 8003, 5603, 3154, 8231, 5005, 5743, 6779, 4530, 4029, 5336, 6105, 4777, 6183, 6838, 5725, 6819, 8584, 3142, 3840, 3291, 4284, 2933, 4859, 2906, 5176, 2853, 2110, 2048, 4389, 4501, 2267, 2704, 431, 1495, 2712, 3008, 187, 3487, 630 ]

[ 4791, 1647, 480, 3994, 1507, 99, 61, 3245, 2932, 8358, 6618, 1083, 5391, 3498, 4865, 1441, 3729, 5322, 5371, 6271, 2392, 1649, 5553, 9126, 3945, 2179, 3672, 2201, 4433, 5473, 4924, 6585, 6407, 3862, 6505, 1530, 5293, 4792, 6419, 6739, 3258, 3839, 3891, 7599, 2576, 5969, 5659, 6077, 5189, 1325, 4490, 5694, 6567, 6367, 5724, 5756, 6450, 5863, 4360, 2697, 3100, 3779, 4040, 4653, 1755, 3109, 2741, 3269 ]
[ 4791, 1647, 480, 3994, 1507, 99, 61, 3245, 2932, 8358, 6618, 1083, 5391, 3498, 4865, 1441, 3729, 5322, 5371, 6271, 2392, 1649, 5553, 9126, 3945, 2179, 3672, 2201, 4433, 5473, 4924, 6585, 6407, 3862, 6505, 1530, 5293, 4792, 6419, 6739, 3258, 3839, 3891, 7599, 2576, 5969, 5659, 6077, 5189, 1325, 4490, 5694, 6567, 6367, 5724, 5756, 6450, 5863, 4360, 2697, 3100, 3779, 4040, 4653, 1755, 3109, 2741, 3269 ]

[ 235, 121, 52, 1249, 154, 26, 5672, 1975, 482, 3817, 532, 9104, 1661, 171, 6347, 2124, 1122, 7175, 558, 8101, 667, 934, 798, 2404, 3424, 5479, 672, 4808, 956, 789, 123, 2255, 2549, 200, 126, 4562, 41 ]
[ 235, 121, 52, 1249, 154, 26, 5672, 1975, 482, 3817, 532, 9104, 1661, 171, 6347, 2124, 1122, 7175, 558, 8101, 667, 934, 798, 2404, 3424, 5479, 672, 4808, 956, 789, 123, 2255, 2549, 200, 126, 4562, 41 ]

[ 1, 1, 1, 1, 1 ]
[ 1, 1, 1, 1, 1 ]

3
Cosa succede se ci sono più uscite possibili? Ingresso: [1, 2, 2, 2, 1]; Uscita: [1, 1, 1, 1]vs.[1, 2, 1]
tsh

3
Che cosa è l'uscita prevista per [1, 2, 3, 1, 2, 3], [1, 2, 3, 0, 1, 2, 3], [0, 1, 3, 2, 0]? Le risposte attuali non sono d'accordo su tutti questi input.
TSH

@tsh Ognuno di questi ( [1, 1, 1, 1]vs. [1, 2, 1]) sono accettabili. Inizialmente avevo una regola su cui scegliere, ma l'ho tolto nella sandbox perché sembrava applicarsi solo a un piccolo numero di casi limite.
640 KB

@tsh, [0, 1, 3, 2, 0]dovrebbe essere [0, 1, 2, 0]- ho aggiunto ai casi di test. Una risposta attesa sugli altri due potrebbe essere [1, 2, 3]anche se non prenderei in considerazione quei casi di test validi dal momento che secondo le regole the original array repeats itself somewhere in the middle.
640 KB

1
@nimi Buona. Direi che è ambiguo se [0,0,0](o qualsiasi 0array di tutte le dimensioni ) rappresenti un'eco di qualcosa o se [0,0,0](nessuna eco) sarebbe anche una risposta valida anche per questo caso speciale, poiché semplicemente non ci sono abbastanza informazioni per determinare quale è. Aggiornerò le regole per impedire che ciò costituisca un input valido, poiché ciò non invaliderà o altererà le risposte esistenti.
640 KB

Risposte:


8

MATL , 16 byte

t"GX@WQB&Y-~?w]x

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

Divisione polinomiale per la vittoria!

t      % Implicit input. Duplicate
"      % For each (do the following as many times as input length)
  G    %   Push input again. This will be the output if no solution exists
  X@   %   Push current iteration index, k
  WQB  %   2 raised to that, add 1, convert to binary. Gives [1 0 ... 0 1] (k-1 zeros)
  &Y-  %   Two-output polynomial division (deconvolution). Gives quotient and remainder
  ~    %   Logical negate: transforms zeros into 1, nonzeros into 0
  ?    %   If all values are nonzero (i.e. if remainder was all zeros): solution found
    w  %      Swap. This moves the copy of the input to top (to be deleted)
  ]    %   End
  x    %   Delete. This deletes the quotient if it was not a solution, or else deletes
       %   the copy of the input
       % End (implicit). Since it is guaranteed that at most one solution exists, at this
       % point the stack contains either the solution or the input
       % Implicit display

Nessun acquirente della generosità linguistica "eso" o "storica" ​​su questo ... quindi la generosità va alla popolarità!
640 KB

1
@ 640KB Non sapevo ci fosse una generosità in questa sfida! Grazie!
Luis Mendo,

7

Haskell , 167 byte

Innanzitutto è importante notare che se è presente un'eco, l'array di input è una convoluzione di un altro array con qualche array del modulo [1,1],[1,0,1],[1,0,0,1],....

Ciò significa che dobbiamo solo verificare questo per tutti questi array. Ma la convoluzione / deconvoluzione discreta è la stessa della moltiplicazione polinomiale / divisione lunga, quindi questa è solo un'implementazione che utilizza i polinomi, ogni volta che restituisce il quoziente, se possibile.

Un trucco che accorciava un po 'il tutto era in aggiunta agli array di cui sopra anche controllando [1]come caso base, perché se nessun altro array funziona, la deconvoluzione [1]funzionerà e restituirà il polinomio originale.

import Math.Polynomial
import Data.Ratio
p=poly LE
c z=last[polyCoeffs LE q|k<-zipWith const[p(take k(1:repeat 0)++[1])|k<-[0..]]z,(q,r)<-[quotRemPoly(p z)k],r==zero] 

Provalo online!


Buon trucco con il case base! Ho cercato di incorporarlo nella mia risposta, ma ho potuto abbreviare il codice
Luis Mendo l'

4

JavaScript , 211 171 145 byte

s=>{for(n=x=0,y=s.length;++x<y/2&!n;)for(n=s.slice(i=0,x);i+x<y-x&&n;)n=(n[i+x]=s[i+x]-n[i++])<0?0:n;return n&&n.slice(1-x)+''==s.slice(1-x)?n:s}

Provalo online

40 byte da Kevin Cruijssen

Altri 26 byte da Arnauld

La mia prima risposta di golf del codice, invalida i potenziali offset e restituisce l'array originale o nuovo in base a ciò che trova. Se qualcuno sa come renderlo più breve, fammi sapere, sembra un gioco divertente.


1
Non sono troppo esperto con JavaScript, ma con alcuni campi da golf di base (ad esempio la rimozione di parentesi non necessarie, la modifica dei posizionamenti di ++, il passaggio &&a &nel primo controllo, la modifica di entrambi .toString()in +'', ecc.) Ho ridotto il codice a 181 byte . Se non li hai ancora visti, i suggerimenti per giocare a golf in JavaScript e i suggerimenti per giocare a golf in tutte le lingue potrebbero essere interessanti da leggere. :)
Kevin Cruijssen il

1
Oh, dimenticato uno ( function q(s)può essere s=>): 171 byte . Goditi la permanenza! :)
Kevin Cruijssen il

Grazie per quello, avrò una lettura. Non sono molto utile con JavaScript ma ho dovuto fare un po 'di recente e ho pensato che questo potrebbe essere un buon modo per ripulire un po' i miei tempi di inattività
Levi Faid,

1
Golfato ancora un po ' (senza tutti i test in modo che si adatti come URL diretto in questo commento)
Arnauld

1
Benvenuti in Code Golf SE! Speriamo che tu ti diverta a giocare a golf qui!
Giuseppe

3

Haskell, 112 111 110 byte

l=length
(!)=splitAt
f a=last$a:[x|i<-[1..l a],let (h,t)=i!a;o=h++zipWith(-)t o;(x,y)=l t!o,all(>=0)o,sum y<1]

Provalo online!

f a=                
      i<-[1..l a]                -- for all indices 'i' of the input array 'a'
      (h,t)=i!a                  -- split 'a' at 'i' into 'h' and 't'
                                 -- e.g. a: [1,2,3,4], i: 1 -> h: [1], t:[2,3,4] 
      o=                         -- calculate the original array by
        h++                      --   prepended 'h' to
        zipWith(-)t o            --   the (element-wise) difference of
                                 --   't' and itself
      (x,y)=l t!o                -- split 'o' at position <length of t>
                                 --
                                 -- example:
                                 --      a: [0,1,3,2,0]
                                 --      h: [0]
                                 --      t: [1,3,2,0]
                                 --   now
                                 --      o: [0,1,2,0,0]
                                 --      x: [0,1,2,0]
                                 --      y: [0]
                                 --
    ,                            -- 'o' is valid, if
     all(>=0)o                   --   all elements of 'o' are not negative
    ,sum y<1                     --   and 'y' is all zeros
  [x|         ]                  -- keep 'x' (a valid echo array) if 'o' is valid

 last $ a :[  ]                  -- if there's no echo, the list of 'x's is empty
                                 -- and 'a' is picked, else the last of the 'x's 

3

Wolfram Language (Mathematica) , 131 129 120 119 102 98 97 96 95 byte

(w=#;Do[(w=v/.#)&/@Thread[#==PadLeft[v=Array[x,L-d],L]+v~PadRight~L]~Solve~v,{d,L=Tr[1^#]}];w)&

Provalo online!

-1 byte grazie ad attinat : possiamo scrivere L=Tr[1^#]invece che L=Length@#quando l'argomento è un elenco di numeri.

Spiegazione del codice: scorrere tra il restringimento d(differenza tra le lunghezze di input e output). Per ogni lunghezza dell'elenco di output, costruisci un elenco di incognite v={x[1],x[2],...,x[L-d]}e aggiungilo a se stesso con riempimento a sinistra e con riempimento a destra in lunghezza L( PadLeft[v,L]+PadRight[v,L]), quindi imposta questa somma uguale all'elenco di input e risolvi gli incogniti x[1]...x[L-d]. Scegli la soluzione più breve, che è l'ultima generata: continua a sovrascrivere la variabile wogni volta che viene trovata una soluzione.

Versione senza golf:

F = Function[A,                                  (* A is the input list *)
  Module[{L = Length[A],                         (* length of A *)
          v,                                     (* list of unknowns *)
          x,                                     (* unknowns in v *)
          w = A},                                (* variable for solution, defaults to A *)
    Do[                                          (* loop over shrinkage: d = Length[A]-Length[output] *)
      v = Array[x, L - d];                       (* list of unknowns to be determined *)
      (w = v /. #) & /@                          (* overwrite w with every... *) 
        Solve[                                   (* ...solution of... *)
          Thread[PadLeft[v,L]+PadRight[v,L]==A], (* ...v added to itself, left-padded and right-padded, equals A *)
          v],                                    (* solve for elements of v *)
    {d, L}];                                     (* loop for shrinkage from 1 to L (the last case d=L is trivial) *)
    w]];                                         (* return the last solution found *)

-1 con Tr[1^#]invece diLength@#
attinat

2

Gelatina , 25 24 byte

ðsạ\FḣL_¥,+¥Ż⁹¡$µⱮLṪ⁼¥Ƈȯ

Provalo online!

Un collegamento monadico che accetta e restituisce un elenco di numeri interi. Tecnicamente, i risultati positivi sono nidificati in due ulteriori elenchi, ma quando eseguito come programma completo l'output implicito di stdout ignora gli elenchi ridondanti.


2

Python 2 , 113 123 128 127 123 122 byte

def f(a,i=1):
 e=a[:i]
 for v in a[i:-i]:e+=v-e[-i],
 return i<=len(a)/2and(min(e)>=0<e[-i:]==a[-i:]and e or f(a,i+1))or a

Provalo online!

1 byte grazie a TFeld ; e 1 byte grazie a Sebastian Kreft .

Ad ogni chiamata a f, costruiamo un potenziale eco di lunghezza len(a)-i. La prima parte è solo i primi ibyte di a; il resto viene calcolato in modo che la "somma eco" sia corretta per la sezione "sovrapposta" della somma eco (ovvero, la somma eco sia corretta fino a a[:-i]).

Quindi il confronto molto corto, non golfato, dà:

if i>=len(a)/2+1:
    return a # because it can't be that short, so there is no echo
else:
    if min(e)>=0                       # all elements are non-negative
                 and e[-i:]==a[-i:]:   # and the tails are the same
        return e                       # it's a match!
    else:
        return f(a,i+1)                # recurse

e+=[v-e[-i]]può esseree+=v-e[-i],
TFeld l'

puoi radere un altro personaggio facendoi<=len(a)/2
Sebastian Kreft il

2

Wolfram Language (Mathematica) , 93 byte

(b=#;Do[a=#;Do[a[[i+j]]-=a[[j]],{j,2k}];a/.{__?(#>=0&),0}:>(b=a~Drop~-i),{i,k=Tr[1^#]/2}];b)&

Provalo online!

Restituisce l'eco più breve presente nell'elenco.


Sembra che questo fallisca ancora {1,1,1}e ancora {1,0,1}.
Roman

@Roman non c'è eco per nessuno di questi casi?
attinat

Perché {1,1,1}non c'è eco, quindi è necessario restituire l'array originale. Perché {1,0,1}direi che l'eco è {1}ma ammetto che non è chiaro quali siano le regole.
Roman

Ah giusto. Grazie per la cattura!
attinat

2

PHP , 124 byte

function($a){while(!$z&&++$y<$c=count($b=$a))for($x=0;$x<$c&$z=0<=$b[$x+$y]-=$b[$x++];);return array_slice($b,0,$c-$y)?:$a;}

Provalo online!

Spiegazione:

>0

function( $a ) {
  // iterate through all possible offsets of echo
  while( ! $b && ++$y < $c = count( $b = $a ) ) {
    // create a copy of input array, iterate through all elements
    for( $x = 0; $b && $x < $c; ) {
      // if difference between the elements in the offset copy of 
      // the array is positive, subtract the value in the input array
      // from the offset array in the same column
      if ( ( $b[ $x+$y ] -= $b[ $x++ ] ) < 0 ) {
        // result is not valid, erase array and break out of loop
        $b = 0;
      }
    }
  }
  // truncate output array to correct size. if still contains values, 
  // it is a valid result. otherwise return the original array
  return array_slice( $b, 0, $c-$y ) ?: $a;
}

2

Python 3 , 111 byte

def f(r,l=1):o=r[:l];o+=(v-o[-l]for v in r[l:]);return l<len(r)and(min(o)<any(o[-l:])and f(r,l+1)or o[:-l])or r

Provalo online!

La soluzione prende alcune idee dalla soluzione di @Chas Brown come la struttura ricorsiva e la costruzione dell'array di output. Nel frattempo, apporta anche alcune modifiche ai criteri di valutazione e inserisce il ciclo for in un'espressione di generatore per consentire una soluzione a riga singola. La versione non golfata è mostrata di seguito. Qui, l'array outviene calcolato fino alla fine dell'array di input e quindi controlliamo se gli ultimi lelementi di esso sono tutti zero. In tal caso, i primi len(arr)-lelementi vengono restituiti come risposta se tutti sono non negativi.

Versione non rigata, non ricorsiva

def remove_echo(arr):
    l = 1
    while l < len(arr):
        out = arr[:l]
        out += (v - out[-l] for v in arr[l:])
        if min(out) >= 0 and out[-l:] == [0] * l:
            return out[:-l]
        l += 1
    return arr

Provalo online!


1
@ 640 KB Ho verificato se la risposta restituita corrisponde al risultato previsto nel mio codice e stampa il messaggio solo in caso di mancata corrispondenza. Quindi nessun output significa che tutto è corretto. Ammetto che questo può essere fonte di confusione a prima vista e lo aggiornerò in seguito per stampare "Corretto" su una partita.
Gioele il

1
@ 640 KB Aggiornato.
Gioele il

1

Carbone , 62 byte

≔⁰ζF⊘Lθ«≔E⊕ι⁰ηFLθ§≔ηκ⁻§θκ§ηκ¿⬤η¬κ≔⊕ιζ»F⁻Lθζ⊞υ⁻§θι∧ζ∧¬‹ιζ§υ±ζIυ

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

≔⁰ζ

Supponiamo che non ci sia eco.

F⊘Lθ«

Prova tutti i possibili punti di inizio dell'eco. Nota: potrei aver letto male la domanda e potrei non provare abbastanza dimensioni di eco, nel qual caso non sarebbe necessario.

≔E⊕ι⁰η

Inizia con una matrice di zeri delle stesse dimensioni del punto iniziale dell'eco.

FLθ§≔ηκ⁻§θκ§ηκ

Per ogni elemento dell'array originale, sottrarre ciclicamente l'elemento nell'array echo. Ogni elemento nell'array echo crea così la somma alternata degli elementi che si allontanano.

¿⬤η¬κ≔⊕ιζ»

Se tutte le somme alternate sono pari a zero, salvarlo come possibile punto di partenza. (Quindi se esiste più di una possibilità, viene utilizzato il punto di partenza più grande possibile.)

F⁻Lθζ⊞υ⁻§θι∧ζ∧¬‹ιζ§υ±ζ

Costruisci la matrice di eco sottraendo gli elementi dopo il punto iniziale dall'elemento appropriato precedentemente calcolato.

Iυ

Cast su stringa per output implicito su righe separate.

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.