All entries

Chronology

19 Nov 2013
Эта же задача по-русски: здесь.

Once upon a time… In autumn 2001, Leon maintained a web service, which provided a feed of tweets. Wait, there was no Twitter in 2001! Well, the web service had a newsfeed or something like that. Important is that the records had been sorted chronologically.

Everything was OK until once Leon saw the following (notice the weird successor of ‘10:43’):

Sunday, 05:56
Sunday, 05:56
Sunday, 05:58
Sunday, 05:58
Sunday, 06:05
Sunday, 06:23
Sunday, 06:24
Sunday, 06:26
Sunday, 06:26
Sunday, 06:27
Sunday, 06:27
Sunday, 06:27
Sunday, 06:33
Sunday, 06:33
Sunday, 06:34
Sunday, 06:36
Sunday, 06:38
Sunday, 07:18
Sunday, 07:32
Sunday, 07:36
Sunday, 07:47
Sunday, 07:51
Sunday, 08:04
Sunday, 08:11
Sunday, 08:13
Sunday, 08:49
Sunday, 08:56
Sunday, 09:24
Sunday, 09:27
Sunday, 09:30
Sunday, 09:32
Sunday, 09:45
Sunday, 09:50
Sunday, 10:07
Sunday, 10:08
Sunday, 10:09
Sunday, 10:13
Sunday, 10:14
Sunday, 10:16
Sunday, 10:22
Sunday, 10:31
Sunday, 10:36
Sunday, 10:43
Sunday, 00:03
Sunday, 00:05
Sunday, 00:31
Sunday, 00:33
Sunday, 00:49
Sunday, 01:08
Sunday, 01:19
Sunday, 01:31
Sunday, 01:32
Sunday, 01:33
Sunday, 01:38
Sunday, 02:04
Sunday, 02:18
Sunday, 02:18
Sunday, 02:59
Sunday, 03:22
Sunday, 03:24
Sunday, 03:27
Sunday, 03:43
Sunday, 04:20
Sunday, 04:42
Sunday, 05:03
Sunday, 05:13
Sunday, 05:30
Sunday, 05:32
Sunday, 05:37
Sunday, 05:38
Sunday, 05:39

What the hell is going on? Certainly there is a sort call in code that compares timestamps!

Hint

Show

perl -le '$x = 9; $y = 10; print $x gt $y ? "$x is greater than $y" : "$y is greater than $x"' 

Hint-2

Show

perl -le '$x = 9; $y = 10; print $x > $y ? "$x is greater than $y" : "$y is greater than $x"'

Hint-3

Show

perl -le 'print scalar localtime(1_000_000_000)'

Solution

Show

For Moscow:

> perl -le 'print scalar localtime(1_000_000_000)'
Sun Sep  9 05:46:40 2001

September 9, 2001 the 1000000000th second of Unix epoch occured, so timestamps became 10-digit decimal numbers instead of 9-digit decimals.

There is a funny thing about comparing numbers: you may compare them lexicographically, and as long as they have the same amount of digits, the result is correct.

But if you compare two numbers of different length as strings, the result differs from numerical comparison. The weird order of records in our story was produced by lexicographic sorting by timestamps.

A small demonstration of the effect:

> perl -le 'print join ", ", sort {$a cmp $b} qw/1 2 9 10 11 12 19 20 29 30 31 99/;'
1, 10, 11, 12, 19, 2, 20, 29, 30, 31, 9, 99

There was something like this:

@items = sort {$a->{date} cmp $b->{date}} @items;

, whereas it should be:

@items = sort {$a->{date} <=> $b->{date}} @items;