valavanp has asked for the wisdom of the Perl Monks concerning the following question:
i have used the code given by corion for the problem which i faced. I have tested with some values and the results of them are:
Input Output Through Code Expected Output.
4ABC 8.432 11.93544
2A2B2C 8.644 23.87
3C 4.5 4.5
ABC 4.322 2.98386
Only 1 value is coming correct. Other values are showing some discrepancies. I am attaching the code below:
$a="ABC";
$b=length($a);
print "$b\n";
for($i=0;$i<$b;$i++){
$a=~s/(\d+)(.)/$2 x $1/ge;
}
print "$a\n";
my %value = (
A => 2.74,
B => 2.64,
C => 2.5,
);
my %factor = (
A => 50/100,
B => 55/100,
C => 60/100,
);
my @letters = split //, $a;
my $result = 0;
my $temp=0;
for my $letter (@letters) {
$result=$result + $value{ $letter }* $factor{ $letter };
#print "$result\n";
};
print $result;
Re: regex and string functions help needed.
by Corion (Patriarch) on Oct 25, 2006 at 12:13 UTC
|
That is because my code doesn't do what you want.
I stated the equation that my code calculates and you said that the calculation wasn't what you want. So it's not really a surprise that my code gives results that are different from what you want. Maybe you should restate what you want, and also what my code does, so somebody willing to hold your hand can then change my code for you to solve your homework.
| [reply] |
|
Corion, i used your code because i couldn't understand the replies given my holli and swamy_rio. I am able to understand your code better than mine and others. That's why i posted that. Since you advised me not to use if else constructs in my code, i didn't use that. The only solution i got is from your reply. So please forgive me if anything wrong done to you. Thanks.
| [reply] |
Re: regex and string functions help needed.
by davorg (Chancellor) on Oct 25, 2006 at 12:36 UTC
|
| [reply] |
Re: regex and string functions help needed.
by Samy_rio (Vicar) on Oct 25, 2006 at 13:15 UTC
|
The below code is developed based on your logic and I am getting the following output. But I am not getting your expected output. Check whether your expected output is correct.
use strict;
use warnings;
my %p = (A => 2.74, B => 2.64, C => 2.5);
my @range = (50,55,60,65,70,75,80,85,90);
while(my $str = <DATA>){
chomp($str);
print "\nInput : $str\n";
$str =~ s/(\d+)(\w)/($2 . '*') x $1/eg;
$str =~ s/(\w)(\w)/$1 . '*' . $2 . '*' /eg;
$str =~ s/(?!\*)$/*/;
$str =~ s/(.)\*(?!\1)/"$1\*\(".$range[ord($1) - 65]."\/100\)\*"/eg
+;
$str =~ s/\*+$//;
$str =~ s/$_/$p{$_}/g for (keys %p);
print "Expression: ".$str ."\n";
print "Output : ",eval$str ,"\n\n";
}
__DATA__
4ABC
2A2B2C
3C
ABC
Output is:
Input : 4ABC
Expression: 2.74*2.74*2.74*2.74*(50/100)*2.64*(55/100)*2.5*(60/100)
Output : 61.38045890064
Input : 2A2B2C
Expression: 2.74*2.74*(50/100)*2.64*2.64*(55/100)*2.5*2.5*(60/100)
Output : 53.96012424
Input : 3C
Expression: 2.5*2.5*2.5*(60/100)
Output : 9.375
Input : ABC
Expression: 2.74*(50/100)*2.64*(55/100)*2.5*(60/100)
Output : 2.98386
Regards, Velusamy R. eval"print uc\"\\c$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';
| [reply] [d/l] [select] |
|
| [reply] |
Re: regex and string functions help needed.
by holli (Abbot) on Oct 25, 2006 at 16:47 UTC
|
valanp,
first of all, you have changed the original content of your node without leaving notice. This will confuse future readers. Please don't do that.
As for your problem: next time please include complete sample data and input/expected output specs. In your OP there was only one special case.
Anyway, here is a subroutine for you that solves your problem:
use warnings;
use strict;
use Data::Dumper;
my %value = (
A => 2.74,
B => 2.64,
C => 2.5,
);
my %factor = (
A => 50/100,
B => 55/100,
C => 60/100,
);
sub calc
{
# fetch arguments
my $expression = shift;
my $values = shift;
my $factors = shift;
# build an array of normalized terms
# (normalize = replace non existant factors by 1)
# as in 4ABC => 4A 1B 1C
my @term;
while ( $expression =~ /([0-9]*)([A-Z])/g )
{
push @term, [$1?$1:1, $2];
}
# now iterate over that array and do the
# calculation
my $result = 1;
$result *= $_->[0] * $values->{$_->[1]} * $factors->{$_->[1]}
for @term;
return $result;
}
print calc ("4ABC", \%value, \%factor), "\n";
print calc ("2A2B2C", \%value, \%factor), "\n";
print calc ("3C", \%value, \%factor), "\n";
print calc ("ABC", \%value, \%factor), "\n";
| [reply] [d/l] |
Re: regex and string functions help needed.
by chargrill (Parson) on Oct 25, 2006 at 23:19 UTC
|
velanvp: I'm not sure the rest of your code does what you want, as your specifications are all over the place. However, near the end, you could try changing this:
my $result = 0;
my $temp=0;
for my $letter (@letters) {
$result=$result + $value{ $letter }* $factor{ $letter };
#print "$result\n";
};
Change $result to be initialized as 1, and change the assignment to $result inside your for loop to use the *= operator. And get rid of $temp - it doesn't look like you're using it. The result will look like this:
my $result = 1;
for my $letter (@letters) {
$result *= $value{ $letter } * $factor{ $letter };
};
If that doesn't work, or if you're still having trouble understanding what you're doing, see if you can understand the following any easier ( which has been Updated: replaced pop @divisors with shift @divisors, fixed output to match updated code. )
#!/usr/bin/perl
use strict;
use warnings;
sub calc {
my $string = shift;
my %p = (
A => 1.5,
B => 2.5,
C => 3.5,
);
# in another thread, he indicated this was the series he needed
my @divisors = ( 50/100, 55/100, 60/100, 65/100,
70/100, 75/100, 80/100, 85/100, 90/100 );
my $result = 1;
# in another thread, he said he needed to match A,B,C,D,E,F,G,H an
+d J
my @substrings = $string =~ /(\d{0,1}[A-HJ])/g;
for( @substrings ){
my $divisor = shift @divisors;
my( $exponent, $letter ) = /(\d){0,1}([A-HJ])/;
$exponent ||= 1;
$result *= $p{ $letter } ** $exponent * $divisor;
}
return $result;
}
for( qw( 2A 2B 2A2B2C 4ABC 4AC ABC BC ) ){
print "string: $_\n";
my $result = calc( $_ );
print "result: $result\n\n";
}
Output:
string: 2A
result: 1.125
string: 2B
result: 3.125
string: 2A2B2C
result: 28.423828125
string: 4ABC
result: 7.308984375
string: 4AC
result: 4.87265625
string: ABC
result: 2.165625
string: BC
result: 2.40625
Same idea as everyone else, and also seems to give you some of your desired output (at least for the values of A, B, and C that you posted earlier - I believe your expected output above is using your earlier values, not 2.74, 2.65, and 2.5 as above).
However, having said that - if this still doesn't satisfy your requirements, you really need to give us crystal clear requirements - because right now, we're working from a bare minimum. I'm sure you know what you mean, but we apparently do not. Start simple, like:
Divisors: 50/100, 55/100, 60/100
Values: A = 2, B = 3, C = 4.
String: 2A
Equation: ( A * A ) * ( 50 / 100 )
Output: 2
String: 3A
Equation: ( A * A * A ) * 50 / 100
Output: 4
String: 2A2B
Equation: ( ( A * A ) * ( 50 / 100 ) ) * ( ( B * B ) * ( 55 / 100 ) )
Output: 9.9
And then maybe introduce a few more advanced examples.
--chargrill
s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; =
qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
Re: regex and string functions help needed.
by doowah2004 (Monk) on Oct 25, 2006 at 13:58 UTC
|
valavanp,
I think this is what you wanted:
$a="ABC";
$b=length($a);
print "$b\n";
for($i=0;$i<$b;$i++){
$a=~s/(\d+)(.)/$2 x $1/ge;
}
print "$a\n";
my %value = (
A => 2.74,
B => 2.64,
C => 2.5,
);
my %factor = (
A => 50/100,
B => 55/100,
C => 60/100,
);
my @letters = split //, $a;
my $result = 1;
my $temp=0;
for my $letter (@letters) {
$result *= $value{ $letter };
#print "$result\n";
};
my %seen;
my @uniqed = grep !$seen{$_}++, @letters;
for my $letter (@uniqed) {
$result *= $factor{ $letter };
#print "$result\n";
};
print $result;
*UPDATE* I did not refresh my browser before I posted, it appears the two post before this get the same results... | [reply] [d/l] |
Re: regex and string functions help needed.
by monarch (Priest) on Oct 26, 2006 at 07:43 UTC
|
valavanp,
I think Corion has been very helpful to you.
Perhaps the most important lesson about being a programmer is that a computer is dumb. It needs YOU, yes YOU to understand exactly how to work out an answer. A computer can calculate quicker than you but it is not smarter than you.
It is clear that you did NOT understand your problem. If you did you'd have explained the solution clearly to others.
Are you at university solving a homework problem? Are you employed in a company and have been given a task to solve? Be brutally honest about your motivations here. I believe Corion and others deserve that at least. | [reply] |
|
|