Count sequence and distance of numbers in an array

1

I have an array and I need to count the sequence and distance between the numbers.

$a = array(1, 2, 4, 6, 8, 9, 10, 15, 16, 17, 20, 21, 23, 24, 26, 27, 28, 29, 31, 39);

Note that there are 6 blocks of numeric sequences in $a :

  • 1 - 2
  • 8 - 9 - 10
  • 15-16-17
  • 20 - 21
  • 23-24
  • 26 - 27 - 28 - 29
  • And with the largest distance between 7-dozen numbers (there are 7 numbers between 31 and 39):

    31 32 - 33 - 34 - 35 - 36 37 - 38 - 39

    How can I get these results?

    I've tried some codes, but I think my logic is incorrect.

        
    asked by anonymous 29.10.2017 / 05:00

    2 answers

    1

    To find the shortest distance between each number you just need to compare the number that goes with the front, and if it is greater than the distance calculated so far, update it.

    The sequences already involve more complexity, but you can find them by seeing if the distance to the front element is 1 and if it adds that element to an array, which in turn is added to another global array of sequences. The term of the current sequence is given when the distance ceases to be 1 .

    Example of implementing this logic:

    $a = array(1, 2, 4, 6, 8, 9, 10, 15, 16, 17, 20, 21, 23, 24, 26, 27, 28, 29, 31, 39);
    
    $maiorDistancia = 0;
    $sequencias = [];
    $ultimaSeq = 0;
    
    for ($i = 0; $i < count($a)-1; ++$i){
        $dist = abs($a[$i]-$a[$i+1]); //distancia entre este e o proximo
    
        if ($dist > $maiorDistancia) $maiorDistancia = $dist; //se maior atualiza
    
        if (($a[$i+1]-$a[$i]) == 1){ //teste para sequencia
            if (isset($sequencias[$ultimaSeq])){
                $sequencias[$ultimaSeq][] = $a[$i+1]; //se ja existe uma sequencia acrescente
            }
            else { //se é uma nova insere os 2 primeiros elementos
                $sequencias[$ultimaSeq][0] = $a[$i];
                $sequencias[$ultimaSeq][1] = $a[$i+1];
            }
        }
        else {
            $ultimaSeq++;
        }
    }
    

    Output:

    Maior distancia: 8 
     Sequencias: Array
    (
        [0] => Array
            (
                [0] => 1
                [1] => 2
            )
    
        [3] => Array
            (
                [0] => 8
                [1] => 9
                [2] => 10
            )
    
        [4] => Array
            (
                [0] => 15
                [1] => 16
                [2] => 17
            )
    
        [5] => Array
            (
                [0] => 20
                [1] => 21
            )
    
        [6] => Array
            (
                [0] => 23
                [1] => 24
            )
    
        [7] => Array
            (
                [0] => 26
                [1] => 27
                [2] => 28
                [3] => 29
            )
    
    )
    

    Ideone with this solution

    Notes:

    • The solution only takes increasing sequences, so if it is possible to have decreasing sequences it becomes necessary to make some adjustments to the code.
    • The distance used was calculated based on the abs function, which is why both distance positive and negative.
    • The distance between 39 and 31 is even 8 , something the calculator can check, but if you want to get the 7 because you want to ignore the 39 itself you only need to subtract 1 .
    29.10.2017 / 14:12
    -1

    Considering that the array is ordered, and that you only need to know the number of sequences and the GREATER distance between the numbers (I understand this).

    Just scroll through the array, looking at two consecutive numbers and storing the values. You can do this (I did it in a more python style, not php handle, but the question is quite independent of language):

    i=0
    MAIOR_DIST = 0
    IN_SEQUENCIA = false
    SEQUENCIAS = 0
    last = null
    for elemento in array:
        if last==null:
            last = elemento
            continue
        if elemento - last > 1: //nao e sequencia
            if IN_SEQUENCIA:
                SEQUENCIAS += 1 //significa que terminou uma sequencia
            IN_SEQUENCIA=false
            if elemento - last > MAIOR_DIST://se for maior que a ultima maior distancia, atualiza
                MAIOR_DIST=elemento-last
        else:
            IN_SEQUENCIA=1
    
     print SEQUENCIAS, MAIOR_DIST
    
        
    29.10.2017 / 12:07