Sottosequenza aritmetica più lunga


11

Data una sequenza finita non intera di numeri interi, restituisce una sottosequenza aritmetica di lunghezza massima.

Se sono presenti multipli della stessa lunghezza massima, è possibile restituire uno di essi.

definizioni:

Una sequenza aritmetica è una sequenza a(1),a(2),a(3),a(4),...tale che esiste una costante ctale che a(m+1)-a(m) = cper tutti m. In altre parole: la differenza tra due termini successivi è costante.

Data una sequenza, b(1),b(2),b(3),b(4),...una sottosequenza è una sequenza b(s(1)),b(s(2)),b(s(3)),b(s(4)),...dove 1 <= s(1)e s(m) < s(m+1)per tutti m. In altre parole: prendi la sequenza originale e rimuovi tutte le voci che desideri.

Esempi

Input                     Output
[4,1,2,3,6,5]             [1,3,5] or [1,2,3]
[5,4,2,-1,-2,-4,-4]       [5,2,-1,-4]
[1,2,1,3,1,4,1,5,1]       [1,1,1,1,1] or [1,2,3,4,5]
[1]                       [1]

Alcuni casi di test più lunghi:

Length: 25
Input: [-9,0,5,15,-1,4,17,-3,20,13,15,9,0,-6,11,17,17,9,26,11,5,11,3,16,25]
Output: [15,13,11,9] or [17,13,9,5]

Length: 50
Input: [35,7,37,6,6,33,17,33,38,30,38,12,37,49,44,5,19,19,35,30,40,19,11,5,39,11,20,28,12,33,25,8,40,6,15,12,27,5,21,6,6,40,15,31,49,22,35,38,22,33]
Output: [6,6,6,6,6] or [39,33,27,21,15]

Length: 100
Input: [6,69,5,8,53,10,82,82,73,15,66,52,98,65,81,46,44,83,9,14,18,40,84,81,7,40,53,42,66,63,30,44,2,99,17,11,38,20,49,34,96,93,6,74,27,43,55,95,42,99,31,71,67,54,70,67,18,13,100,18,4,57,89,67,20,37,47,99,16,86,65,38,20,43,49,13,59,23,39,59,26,30,62,27,83,99,74,35,59,11,91,88,82,27,60,3,43,32,17,18]
Output: [6,18,30,42,54] or [8,14,20,26,32] or [46,42,38,34,30] or [83,63,43,23,3] or [14,17,20,23,26] or [7,17,27,37,47] or [71,54,37,20,3]

sfondo

Ho avuto questa idea quando ho ricordato il Teorema del Tao verde del 2004, in cui si afferma che la sequenza di numeri primi contiene sequenze aritmetiche finite di lunghezza arbitraria.

Risposte:


5

Gelatina , 8 byte

ŒPIE$ÐfṪ

Provalo online! o verifica tutti i casi di test .

Come funziona

ŒPIE$ÐfṪ  Main link. Argument: A (list of integers)

ŒP        Powerset; generate all sublists of A, sorted by length.
     Ðf   Filter the powerset by the link to the left:
    $       Combine the two atoms to the left into a monadic link.
  I           Compute all increments.
   E          Test whether they're all equal.
          This returns all arithmetic subsequences, sorted by length.
       Ṫ  Tail; extract the last sequence.

2

Pyth, 12 11 byte

ef!P{-VTtTy

Suite di test.

          y  powerset of implicit input, generate all subsequences
ef       T   find the last subsequence (sorted increasing in length) where...
       Tt      bifurcate over tail, giving [1,2,3,4,5] [2,3,4,5]
     -V        vectorize over -, giving differences of each consecutive pair
    {          dedup (remove duplicate elements)
   P           pop, resulting in [] if all differences were equal
  !            boolean not, resulting in True if all differences were equal

Grazie a @LeakyNun per un byte!


2

MATL, 19 18 17 16 18 byte

1 byte salvato (e 2 byte aggiunti indietro) grazie a Luis!

"GX@XN!"@dun2<?vx@

Un approccio abbastanza ingenuo che la forza bruta controlla tutte le permutazioni ordinate dell'input. Ovviamente questo può richiedere del tempo per sequenze più lunghe. Per salvare un byte, ho iniziato con le sub-sequenze più piccole (lunghezza = 1) e ho lavorato fino alle sequenze più grandi (lunghezza = N).

Provalo online!

Spiegazione

                % Impilicitly grab input array (N)
"               % For each value in this array
    G           % Explicitly grab the input
    X@          % Loop index, will be [1, 2, ... length(N)] as we iterate
    XN          % Determine all permutations of k elements (nchoosek). The output is 
                % each k-length permutation of the input as a different row. Order doesn't 
                % matter so the result is always ordered the same as the input
    !           % Take the transpose so each k-length permutation is a column
    "           % For each column
        d       % Compute the difference between successive elements
        un      % Determine the number of unique differences
        2<?     % If there are fewer than 2 unique values
            vx  % Vertically concatenate everything on the stack so far and delete it
            @   % Push the current permuatation to the stack
                % Implicit end of if statement
                % Implicit end of for loop
                % Implicit end of for loop
                % Implicitly display the stack

@LuisMendo Grazie! Mi sono sempre chiesto come ottenere l'iterazione del ciclo #.
Suever,

@LuisMendo Oh buona cattura, hai ragione. Quel doppio diffdà un array vuoto che non può essere negato.
Suever,

1

Python 2, 124 115 98 97 byte

p=[[]]
for n in input():p+=[x+[n][:2>len(x)or n-x[-1]==x[1]-x[0]]for x in p]
print max(p,key=len)

Molto lento e ad alta memoria. Provalo su Ideone .

Versione alternativa, 98 byte

p={()}
for n in input():p|={x+(n,)[:2>len(x)or n-x[-1]==x[1]-x[0]]for x in p}
print max(p,key=len)

Questo completa istantaneamente tutti i casi di test. Provalo su Ideone .


1
byte o velocità, questa è la domanda
downrep_nation

0

Pyth checkout 8593c76, 24 marzo , 10 byte

efq-VTtT)y

Questo è esattamente lo stesso della risposta di Doorknob, tranne che a marzo, c'era una funzione a 2 byte ( q ... )) che controllava se tutti gli elementi di un elenco erano uguali, che è lo stesso !P{, che è il meglio che puoi fare attualmente.


0

JavaScript (ES6), 157 byte

a=>{for(m=i=0,l=a.length;i<l;i++)for(j=i;++j<l;)for(t=n=a[k=i],c=0;k<l;k++)a[k]==t&&(t+=a[j]-n,++c>m)?q=a[m=c,p=n,j]-n:q;return a.slice(-m).map(_=>(p+=q)-q)}

Quasi 20 volte più a lungo della risposta Jelly ... Ungolfed:

function subsequence(a) {
    var max = 0;
    for (var i = 0; i < a.length; i++) {
        for (var j = i + 1; j < a.length; j++) {
            var target = a[i];
            var count = 0;
            for (var k = i; k < a.length; k++) {
                if (a[k] == target) {
                    count++;
                    target += a[j] - a[i];
                    if (count > max) {
                        max = count;
                        start = a[i];
                        step = a[j] - a[i];
                    }
                }
            }
        }
    }
    var result = new Array(max);
    for (var i = 0; i < max; i++) {
        result[i] = start + step * i;
    }
    return result;
}
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.