Längste arithmetische Teilfolge

11

Geben Sie bei einer nicht leeren endlichen Folge von ganzen Zahlen eine arithmetische Teilfolge maximaler Länge zurück.

Wenn es mehrere gleiche maximale Länge gibt, kann jeder von ihnen zurückgegeben werden.

Definitionen:

Eine arithmetische Folge ist eine Folge a(1),a(2),a(3),a(4),..., bei der es eine Konstante gibt c, die a(m+1)-a(m) = cfür alle gilt m. Mit anderen Worten: Der Unterschied zwischen zwei nachfolgenden Begriffen ist konstant.

Bei einer Sequenz b(1),b(2),b(3),b(4),...einer Teilsequenz ist eine Sequenz , b(s(1)),b(s(2)),b(s(3)),b(s(4)),...wo 1 <= s(1)und s(m) < s(m+1)für alle m. Mit anderen Worten: Nehmen Sie die ursprüngliche Sequenz und entfernen Sie so viele Einträge, wie Sie möchten.

Beispiele

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]

Einige längere Testfälle:

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]

Hintergrund

Ich kam auf diese Idee, als ich mich an das Green-Tao-Theorem von 2004 erinnerte, das besagt, dass die Folge von Primzahlen endliche arithmetische Folgen beliebiger Länge enthält.

fehlerhaft
quelle

Antworten:

5

Gelee , 8 Bytes

ŒPIE$ÐfṪ

Probieren Sie es online aus! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

Œ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.
Dennis
quelle
2

Pyth, 12 11 Bytes

ef!P{-VTtTy

Testsuite.

          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

Danke an @LeakyNun für ein Byte!

Türknauf
quelle
2

MATL, 19 18 17 16 18 Bytes

1 Byte gespeichert (und 2 Bytes wieder hinzugefügt) dank Luis!

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

Ein ziemlich naiver Ansatz, bei dem Brute Force alle geordneten Permutationen der Eingabe überprüft. Offensichtlich kann dies für längere Sequenzen eine Weile dauern. Um ein Byte zu speichern, habe ich mit den kleinsten Teilsequenzen (Länge = 1) begonnen und bis zu den größeren Sequenzen (Länge = N) gearbeitet.

Probieren Sie es online aus!

Erläuterung

                % 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
Suever
quelle
@ LuisMendo Danke! Ich habe mich immer gefragt, wie ich die Schleifeniteration # bekomme.
Suever
@ LuisMendo Oh guter Fang, du hast recht. Dieses Double differgibt ein leeres Array, das nicht negiert werden kann.
Suever
1

Python 2, 124 115 98 97 Bytes

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)

Sehr langsam und speicherintensiv. Testen Sie es auf Ideone .

Alternative Version, 98 Bytes

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)

Damit sind alle Testfälle sofort abgeschlossen. Testen Sie es auf Ideone .

Dennis
quelle
1
Byte oder Geschwindigkeit, das ist die Frage
downrep_nation
0

Pyth Checkout 8593c76, 24. März , 10 Bytes

efq-VTtT)y

Dies ist genau das Gleiche wie die Antwort von Doorknob, außer dass es im März eine 2-Byte-Funktion ( q ... )) gab, die prüfte, ob alle Elemente einer Liste gleich waren, was das gleiche ist wie !P{das Beste, was Sie tun können zur Zeit.

isaacg
quelle
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)}

Fast 20 mal länger als die Antwort von 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;
}
Neil
quelle