I'm not sure if the post was just showing off HOP::Parser or what but I hacked together the following code just based on intuition. hehe. Tried to figure out exactly how i processed the numbers and make the computer do that.
use strict;
use warnings;
use Data::Dumper;
use Test::More qw/no_plan/;
my $nums_to_value = {};
my $i = 0;
for (qw/zero one two three four five six seven eight nine ten
eleven twelve thirteen fourteen fifteen sixteen seventeen eigh
+tteen nineteen/) {
$nums_to_value->{$_} = $i++;
};
$i = 20;
for (qw/twenty thirty forty fifty sixty seventy eighty ninety/) {
$nums_to_value->{$_} = $i;
$i += 10;
}
my $mag = {
hundred => 100,
thousand => 1_000,
million => 1_000_000,
billion => 1_000_000_000,
};
#print Dumper($nums_to_value);
sub num {
my $word = shift;
if (index( $word, '-') > 0) {
my ($first,$second) = split /-/, $_;
return undef unless
exists $nums_to_value->{$first} and
exists $nums_to_value->{$second};
return $nums_to_value->{$first} +
$nums_to_value->{$second};
} else {
return undef unless exists $nums_to_value->{$word};
return $nums_to_value->{$word};
}
}
sub word_to_decimal {
my @words = @_;
my $out;
my $i = 0;
for (@words) {
my $temp = num($_);
$i += length($temp);
$out += $temp / 10**$i;
}
return $out;
}
sub word_to_num {
my $text = shift;
my @words = split / /, $text;
my @que;
my $scratch = 0;
my $mod = 1;
if ($words[0] eq 'negative') {
$mod = -1;
shift @words;
}
while (@words) {
$_ = shift @words;
my $temp = num($_);
if (defined $temp) {
$scratch += $temp;
} elsif($_ eq 'and') {
} elsif($_ eq 'point') {
push @que, word_to_decimal(@words);
@words = ();
} else {
my $magnitude = $mag->{$_};
my $sum = $scratch;
while (@que && ($sum + $que[-1]) < $magnitude) {
$sum += pop @que;
}
my $temp = ($sum || 1) * $magnitude;
push @que, $temp;
$scratch = 0;
}
}
push @que, $scratch;
my $out = sum(@que);
return $mod * $out;
}
sub sum {
my $temp = 0;
$temp += $_ for @_;
return $temp;
}
my $words = {
'three' => 3,
'forty' => 40,
'hundred' => 100,
'fourteen' => 14,
'thousand' => 1000,
'forty-two' => 42,
'ninety nine' => 99,
'hundred and two' => 102,
'hundred nineteen' => 119,
'hundred and twenty' => 120,
'hundred ninety-nine' => 199,
'two hundred and three' => 203,
'one thousand two hundred' => 1_200,
'one point one zero zero one' => 1.1001,
'negative hundred and three' => -103,
'twelve hundred and seventy three', => 1273,
'seven hundred thirty-three thousand' => 733_000,
'seven hundred thirty-three thousand five hundred',
733500,
'seven hundred thirty-three thousand five hundred and twenty-nine'
+,
733529,
'seventy three point two four five' => 73.245,
'three point seventeen' => 3.17,
'seven million' => 7000000,
'two hundred and ninety six million four hundred and twenty-two th
+ousand five hundred and seventy eight',
296_422_578,
'two hundred and ninety six million four hundred and twenty-two th
+ousand five hundred and seventy eight point three four seven',
296422578.347,
};
for my $word (sort {length $a <=> length $b} keys %$words) {
my $num = $words->{$word};
is word_to_num($word), $num, "... $word should be $num";
}
It passes all your tests, but i'm not sure that means it will pass everything. Anyway just felt like hacking it together. ;)
Update: Turns out there IS a module for this. Still fun anyway and we have three completly different methods. Lingua::EN::Words2Nums
___________
Eric Hodges
$_='y==QAe=e?y==QG@>@?iy==QVq?f?=a@iG?=QQ=Q?9';
s/(.)/ord($1)-50/eigs;tr/6123457/- \/|\\\_\n/;print;
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.