-2

I am writing a program in Perl. A part of it requires sorting of numbers. But it's not a normal sorting. The values are something like this. 01,02,03,04,05,97,98,99. I want it to be sorted like this.

97
98
99
01
02
03
04
05

We are sorting data packets. If yesterday the last data pack was 96, today it will start from 97 and will go on till 99 then comes back to 01 02 ....and would stop at some number say 06.

ikegami
  • 367,544
  • 15
  • 269
  • 518
nithin
  • 73
  • 2
  • 7
  • How do you know that you start at 97? Are all the numbers sequential? – Sobrique Nov 09 '15 at 13:55
  • No it can start at any random no in between 1-99..the above one is just an example..the values will reach 99 and it start from 01 again and it will satrt at some random value. – nithin Nov 09 '15 at 14:01
  • @nithin Does it start from `1` or `01`? – TLP Nov 09 '15 at 14:05
  • It will start from 01 – nithin Nov 09 '15 at 14:09
  • 1
    that's how the requirement is.Actually we are sorting data packets here.If yesterday the last data pack was 88,today it will start from 89 and will go on till 99 then comes back to 01 02 ....and would stop at some number say 6. – nithin Nov 09 '15 at 14:26
  • Will you have cases where the break is ambiguous? For example: `01, 02, 50, 98, 99` (break could be before 50, or after). What is the smallest difference guaranteed to indicate a break? – TLP Nov 09 '15 at 14:50

2 Answers2

2

Say the last number from yesterday is 93 (case 1). You want

94: position 0
95: position 1
..
93: position 99

The modulus operation can be used to produce this mapping.

($_ - $last_from_yesterday - 1) % 100

Sorting becomes trivial:

sort { ($a - $last_from_yesterday - 1) % 100 <=> ($b - $last_from_yesterday - 1) % 100 }
ikegami
  • 367,544
  • 15
  • 269
  • 518
0

I'm guessing based in your data, that your numbers are sequential, but wrapping around 100. So you would find the 'start' by ordering everything, then looking for the gap. (This breaks if you have a complete cycle though!)

#!/usr/bin/env perl
use strict;
use warnings;

my @numbers = ( 1,2,3,4,5,97,98,99 ); 

#sort them
my @sorted = sort { $a <=> $b } @numbers;

#rotate the numbers until your 'gap' is off the end of the cycle. 

my $splice = 0; 
for ( my $index = 0; $index < $#numbers; $index++ ) {
    print 1+$sorted[$index]  % 100,",";
    print $sorted[$index+1] % 100,"\n";
    if ( ($sorted[$index] + 1 ) %100 < $sorted[$index+1] % 100 ) { 
        $splice = $index;
    }
}
print "Splicing on $splice\n";
@numbers = ( splice ( @sorted, $splice+1, @sorted - $splice ), splice ( @sorted, 0, $splice+1 ) );
print join ",", @numbers;

Edit: OK, new test cases. Might not work for those. Hopefully this illustrates an approach. But with gaps in your ordering (I have assumed no gaps) it's very hard to tell because you're basically looking for the biggest gap.

Sobrique
  • 52,974
  • 7
  • 60
  • 101
  • ya .I tested for this case:01,02,04,06,07,91,95,99 it gave me below answer Splicing on 6 99,1,2,4,6,7,91,95 – nithin Nov 09 '15 at 14:22
  • This works, but it doesn't work exhaustively - with numbers in sequence it's easy to detect a break. With numbers that _aren't_ it's quite hard to tell where the break should be. – Sobrique Nov 09 '15 at 14:23
  • @Sobrique You probably should not sort numbers in alphabetic order, even if it does happen to work with this data. – TLP Nov 09 '15 at 14:34
  • Good point. Amended. – Sobrique Nov 09 '15 at 14:36