post
poster: jsaxton
description: Generates maps for contest
language: Perl
[download]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/perl
#Example Usage
#./createmap.pl -c "New York,Chicago,Denver,Los Angeles" -l 10 > file.txt

use Getopt::Std;
use POSIX qw(floor ceil);

# Let's first get our input parameters
%options=();
getopts("c:l:", \%options);

if(!defined($options{'c'}) || !defined($options{'l'})) {
    print "Syntax: ./createmap.pl -c num_cities -l num_lines\n";
    exit(1);
}

$cities = $options{'c'};
$lines = $options{'l'};

if($lines < 1) {
    print "Number of lines must be greater than zero.\n";
    exit(1);
}

my @cities_arr = split(",", $cities);

if(@cities_arr < 2) {
    print "You need to provide at least two cities\n";
    exit(1);
}

#let's create an array of hashes
@data_arr = ();
for($i=0;$i<$lines;$i++) {
    my %hash_element = ();

    #get source/dest
    $src_index = floor(rand(@cities_arr-1));
    $dest_index = get_dest_index($src_index);
    $hash_element{'source'} = $cities_arr[$src_index];
    $hash_element{'dest'} = $cities_arr[$dest_index];
    
    #get price
    $price = 30*abs($src_index - $dest_index);
    $hash_element{'price'} = $price + rand(15) - 7.5;
    
    #let's get a starting time
    $day = ceil(rand(5));
    $hour = floor(rand(24));
    $minute = floor(rand(60));
    $hash_element{'depart'} = sprintf "Day %d - %02d:%02d", $day, $hour, $minute;
    $hash_element{'arrive'} = get_finishing_time_str($day, $hour, $minute, $src_index - $dest_index);
    push(@data_arr, \%hash_element);
    #print $cities_arr[$src_index]." ".$cities_arr[$dest_index]." ".$i."\n";
}

foreach $ref (@data_arr) {
    %data = %$ref;
#    print $data{'depart'}.",".$data{'arrive'}.",".$data{'source'}.","$data{'dest'}.",".$data{'price'}."\n";
print $data{'depart'}.",";
print $data{'arrive'}.",";
print $data{'source'}.",";
print $data{'dest'}.",";
printf "%.2f\n", $data{'price'};
}

sub get_dest_index {
    $source_index = shift;
    if($source_index == 0) {
        #we go forward
        return get_fw_index();
    }
    else {
        #there's a 75% chance we go forward, a 25% chance we go backwards
        $rand_num = rand();
        #print $rand_num."\n";
        if($rand_num > .25) {
            return get_fw_index($source_index);
        }
        return get_bw_index($source_index);
    }
}

sub get_fw_index {
    my $source_index = shift;
    my $diff = @cities_arr - $source_index - 1;
    my $threshold = .5;
    my $rand_num = rand();
    my $i;
    for($i=1;$i<=$diff;$i++) {
        if($rand_num > $threshold) {
            return $source_index + $i;
        }
        $threshold = $threshold/2;
    }
    return @cities_arr - 1;
}

sub get_bw_index {
    $source_index = shift;
    $threshold = .5;
    local $rand_num = rand();
    while($source_index > 0) {
        $source_index--;
        if($rand_num > $threshold) {
            return $source_index
        }
        $threshold = $threshold/2;
    }
    return 0;
}

sub get_finishing_time_str {
    $start_day = shift;
    $start_hour = shift;
    $start_min = shift;
    $start_diff = shift;
    
    $trip_time = $start_diff*25 + $start_min;
    $finish_min = $trip_time % 60;
    $hours += ($trip_time - $finish_min)/60;
    $hours = $start_hour + $start_hour;
    $finish_hour = $hours % 24;
    $finish_day = ($hours - $finish_hour)/24 + $start_day;
    return sprintf "Day %d - %02d:%02d", $finish_day, $finish_hour, $finish_min;
}