Count sequence and number distance in an array

Asked

Viewed 764 times

2

I have an array and with it I need to count sequence and distance among 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 numerical sequences in $a:

  1. 1 - 2
  2. 8 - 9 - 10
  3. 15 - 16 - 17
  4. 20 - 21
  5. 23 - 24
  6. 26 - 27 - 28 - 29

And with the greater distance between the numbers of 7 tens (there are 7 numbers between 31 and 39):

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

How can I get these results?

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

  • O_O.. I don’t understand this logic :)

  • What don’t you understand? Rs, it’s well explained. I want to know how many sequences there are (in my example would be 6 sequences) and I need to know the LONGEST distance between the numbers within the array (in my example 7).

  • Sorry, but it seems those problems of the magazine Super Interesting. For me it was not clear at all. Sorry the irony but I didn’t understand anything. rs.. If any other friend understands you may help you.

  • I also understood paws.

2 answers

2


To find the shortest distance between each number you just need to compare the number on which you go with the front number, and if it is larger than the calculated distance so far, update it.

Sequences already involve more complexity, but you can discover them by seeing if the distance to the front element is 1 and if it is added this element to an array, which in turn is added to another global array of sequences. The end of the current sequence occurs when the distance ceases to be 1.

Example of implementation of 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++;
    }
}

Exit:

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 assumes 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 function abs, and so both contemplates positive and negative distances.
  • The distance between 39 and 31 really is 8, something the calculator can prove, but if you want to get the 7 because he wants to disregard his own 39 just need to subtract 1.
  • Perfect @Isac, exactly what I was looking for. Just an observation, I had to use array_values() in my array that came from an SQL query because it was returning values that were not compatible with reality. Thank you!

  • P.S.: After the use of array_values() the distance was ok, but the sequence messed everything up. For example, where the correct value would be 4, returned 8. Where it was 5, returned 7. Knows to inform the why?

  • @Hiago because the array_values ? Only the sequences matter and not their positions. To go through you must use a foreach and not a for that solves the problem. Example: foreach ($sequencias as $seq) {

0

Whereas the array is ordered, and you only need to know the number of sequences and the GREATEST distance between the numbers (got this).

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.