#!/usr/bin/env perl use 5.012; use warnings; use List::Util qw(min max); # Build cost table my %costs; while (my $_ = ) { # Remove newlines, stop at empty line. chomp; last unless $_; # Split input into fields # NOTE: use proper CSV parser in production code my ($prefix, $name, $cost) = split /\s*;\s*/; # Fix broken decimal point notation and convert into cost per second $cost =~ y/,/./; # Create table entry $costs{$prefix} = { name => $name, cost => $cost }; } # Determine minimum and maximum prefix length my ($min_prefix, $max_prefix) = do { my @lengths = map length, keys %costs; min(@lengths), max(@lengths); }; # Lookup prefix in cost table sub cost_ref { my ($number) = @_; for my $_ (reverse $min_prefix .. $max_prefix) { if (my $entry = $costs{substr $number, 0, $_}) { return $entry; } } return undef; } # Examine data while (my $_ = ) { # Remove newlines chomp; # Split input into fields # NOTE: use proper CSV parser in production code my ($f0, $f1, $f2, $hms, $f3, $f4, $number) = split /\s*;\s*/; # Convert H:M:S into minutes my ($h, $m, $s) = split /:/, $hms, 3; $m += $h*60 + $s/60; # Find cost information and report results if (my $entry = cost_ref($number)) { my ($name, $cost) = map $entry->{$_}, qw(name cost); $cost *= $m; say "Call to $number for $m m using $name with cost $cost"; } else { say "Call to $number for $ m with unknown cost"; } } __DATA__ 0041; schweiz festnetz; 3,1 004176; schweiz mobil; 30 004178; schweiz mobil; 30 004179; schweiz mobil; 30 004186076; schweiz mobil; 30 004186078; schweiz mobil; 30 004186079; schweiz mobil; 30 a; b; c; 0:02:34; d; e; 0041442011234 a; b; c; 0:01:42; d; e; 0041795091234 a; b; c; 0:42:23; d; e; 0041860765091234