in reply to Re^2: alternatives to if and series of elsif
in thread alternatives to if and series of elsif
Your right, but I concluded (as I assume other responders did) that it was a bug in the original implementation. One that possibly doesn't show up because the situation doesn't arise in use.
My interpretation of the intent of the original algorithm, is that if a user has acquired a given number of points, and their quota has not yet been incremented to the appropriate level, then it is increased to that level.
My view was that the quota may represent something like "life force" or "energy" or "armour" in a game scenario, which gets increased in stages as the user accumulates points. This is an assumption, but one that seems to fit the facts as presented.
The thing I noticed with the original implementation is that if a user accumlated more points, but didn't accumulate any additional quota (through other mechanisms) between reassessments, then they are penalised (all the way back to the base level), until their points tally took them high enough to be awarded the next level of quota. At which point they regain both the penalised quota, plus the new increase. Vis:
#! perl -slw use strict; sub compare { my ($points, $quota) = @_; if ($points > 18000 && $quota < 24) { return 24; } elsif ($points > 16000 && $quota < 23) { return 23; } elsif ($points > 14000 && $quota < 22) { return 22; } elsif ($points > 12000 && $quota < 21) { return 21; } elsif ($points > 10000 && $quota < 20) { return 20; } elsif ($points > 8000 && $quota < 19) { return 19; } elsif ($points > 6000 && $quota < 18) { return 18; } elsif ($points > 4000 && $quota < 17) { #19 return 17; } elsif ($points > 2000 && $quota < 16) { #17 return 16; } return 15; } my $userQuota = 0; for my $userPoints ( map{ $_ * 1000 } 0 .. 19 ) { printf "Before: %5d : %5d", $userPoints, $userQuota; $userQuota = compare( $userPoints, $userQuota ); printf " After: %5d : %5d\n", $userPoints, $userQuota; } __END__ P:\test>471983 Before: 0 : 0 After: 0 : 15 Before: 1000 : 15 After: 1000 : 15 Before: 2000 : 15 After: 2000 : 15 Before: 3000 : 15 After: 3000 : 16 Before: 4000 : 16 After: 4000 : 15 Before: 5000 : 15 After: 5000 : 17 Before: 6000 : 17 After: 6000 : 15 Before: 7000 : 15 After: 7000 : 18 Before: 8000 : 18 After: 8000 : 15 Before: 9000 : 15 After: 9000 : 19 Before: 10000 : 19 After: 10000 : 15 Before: 11000 : 15 After: 11000 : 20 Before: 12000 : 20 After: 12000 : 15 Before: 13000 : 15 After: 13000 : 21 Before: 14000 : 21 After: 14000 : 15 Before: 15000 : 15 After: 15000 : 22 Before: 16000 : 22 After: 16000 : 15 Before: 17000 : 15 After: 17000 : 23 Before: 18000 : 23 After: 18000 : 15 Before: 19000 : 15 After: 19000 : 24
This doesn't fit with any pattern I could relate to, so I assumed it was a bug (that doesn't show up in use), with the original implementation.
However, you are correct that my implementations don't correctly comply with even my interpretation of the OPs requirements in as much as I have a fencepost error. The following two replacements correct that deficiency:
use constant STICK => pack 'C*', 15, map( ($_) x 2, 15 .. 23 ), (24) x + 100; sub stick{ my $q = ord substr STICK, 1+ $_[0] / 1000; return $q < $_[1] ? $_[1] : $q; } use constant STICK2 => [ 15, map( ($_) x 2, 15 .. 23 ), (24) x 100 ]; sub stick2{ my $q = STICK2->[ 1 + $_[0] / 1000 ]; return $q < $_[1] ? $_[1] : $q; }
I guess only kiat will be able to tell us if my assumption was a pragmatic one.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: alternatives to if and series of elsif
by gsiems (Deacon) on Jul 03, 2005 at 16:22 UTC | |
|
Re^4: alternatives to if and series of elsif
by kiat (Vicar) on Jul 03, 2005 at 11:19 UTC |