in reply to Re^9: Why does my get_max_index function return zero? (High Water Mark Algorithm)
in thread Why does my get_max_index function return zero? (High Water Mark Algorithm)
So, there seems to be multiple problems with holli's code
The only way that the flip-flop will work as the counter is if the FF is run every time, but imax only increased sometimes... and then the ff shows off-by-one, because it starts at 1, so you have to correct for that. And my solution involved a separate variable to hold the ff state, which means it would have been better to just use a counter-variable to begin with. And my variant still doesn't solve the problem of multiple calls not resetting the ff state.
here's some example code which shows some of those above:
use strict; use warnings; use Test::More; $| = 1; sub holli { my $imax = 0; foreach (@_) { $imax = ($0 .. !$0) if $_ > $_[$imax]; } return $imax; } is( holli(1,2,13,4,5), 2, "holli(1,2,13,4,5): seems to work"); is( holli(1,2,13,4,5), 2, "holli(1,2,13,4,5): except that if you run i +t a second time, it will fail, because ff holds its state from last i +nstance"); is( do{local @_ = (1,2,13,4,5); my $imax=0; foreach(@_){$imax = ($0..! +$0) if $_>$_[$imax]}; $imax }, 2, "do(1,2,13,4,5): same data set, but + use a local do{} instead of the function to avoid the again bug"); is( do{local @_ = (1,2,13,4,5,99); my $imax=0; foreach(@_){$imax = ($0 +..!$0) if $_>$_[$imax]}; $imax }, 5, "AnomalousMonk(1,2,13,4,5,99): t +his data set fails, I think because"); is( do{local @_ = (3,2,1,3,2,1,3,2,1,15); my $imax=0; foreach(@_){$ima +x = ($0..!$0) if $_>$_[$imax]}; $imax }, 9, '(3,2,15): should be 9, b +ut is 1, because ff-if-cond only triggers once'); is( do{local @_ = (1,0,13); my $imax=0; foreach(@_){$imax = ($0..!$0) +if $_>$_[$imax]}; $imax }, 2, "do(1,0,13): second element is lower ra +ther than higher than first, so third is the first time that if-then- +ff triggers"); is( do{local @_ = (1,0,13,4); my $imax=0; foreach(@_){$imax = ($0..!$0 +) if $_>$_[$imax]}; $imax }, 2, "do(1,0,13,4): you would think this w +ould fail, too... but because \$_=4 happens to be greater than \$_[\$ +imax]=\$_[1]=0, it fakes it into passing, because of where values end +ed up."); ### here's my updated algorithm, to fix the couting errors and off-by- +one, but it does not fix the hold-state-between-runs ### ### also, note, I couldn't come up with a way to run the flipflop ever +y time, but assign to imax only on conditional, without storing the f +f result in a separate counter... in which case, the counter-based lo +ops make more sense than a flipflop anyway. is( do{ local @_ = (1,2,13,4,5); my $imax=0; foreach(@_){my$ff = $0 .. + !$0; $imax = $ff-1 if $_ > $_[$imax]}; $imax;}, 2, "pryrt: do(1,2,13 +,4,5)" ); is( do{ local @_ = (1,2,13,4,5,99); my $imax=0; foreach(@_){my$ff = $0 + .. !$0; $imax = $ff-1 if $_ > $_[$imax]}; $imax;}, 5, "pryrt: do(1,2 +,13,4,5,99)" ); is( do{ local @_ = (3,2,1,3,2,1,3,2,1,15); my $imax=0; foreach(@_){my$ +ff = $0 .. !$0; $imax = $ff-1 if $_ > $_[$imax]}; $imax;}, 9, "pryrt: + do(3,2,1,3,2,1,3,2,1,15)" ); is( do{ local @_ = (1,0,13); my $imax=0; foreach(@_){my$ff = $0 .. !$0 +; $imax = $ff-1 if $_ > $_[$imax]}; $imax;}, 2, "pryrt: do(1,0,13)" ) +; is( do{ local @_ = (1,0,13,4); my $imax=0; foreach(@_){my$ff = $0 .. ! +$0; $imax = $ff-1 if $_ > $_[$imax]}; $imax;}, 2, "pryrt: do(1,0,13,4 +)" ); done_testing();
|
|---|