Re: Guess That Number
by jdporter (Paladin) on Jul 09, 2009 at 14:24 UTC
|
my $low = 1; #Current low limit
my $high = 1000; #Current high limit
#This is the secret number...Add one because we
#don't need to wind up with a zero now do we?
my $goal = int(rand($high))+1;
That's only correct if $low = 1. The general correct algorithm would be:
my $goal = int(rand($high-$low+1))+$low;
Update: Since you seem to be having trouble proving to yourself that your algorithm is broken while mine is not, I offer here a test script and sample output.
my $low = 7;
my $high = 9;
sub original { int(rand($high))+1 }
sub fixed { int(rand($high-$low+1))+$low }
($,,$\)=(" ","\n");
print "Random numbers between $low and $high.";
print "original:", map original(), 1..20;
print " fixed:", map fixed(), 1..20;
Random numbers between 7 and 9.
original: 9 7 1 5 3 9 9 6 7 1 3 5 2 4 7 6 7 3 4 8
fixed: 9 7 9 7 7 8 7 9 7 7 8 8 9 7 8 8 7 9 8 9
Between the mind which plans and the hands which build, there must be a mediator... and this mediator must be the heart.
| [reply] [d/l] [select] |
|
|
The change you gave me jdporter worked fine...but now when I try to change the d to a D it keeps giving me Please enter a number only...
# jdporter's change...worked fine
my $goal = int(rand($high-$low+1))+$low;
while (1) {
print "Enter a number between $low and $high: ";
#The answer from the user
my $answer = <STDIN>;
chomp($answer);
# when I change the d to a D I get "Please enter a number only"
if ($answer !~ /\d+/) {
print "Please enter a number only\n";
next;
The early bird gets the worm but the second mouse gets the cheese.
pretendeavor
| [reply] [d/l] |
|
|
Please do not ignore BioLion's reply, below. He is correct, as is toolic. You are not looking closely enough. Could be Perl's fault for being so cryptic and terse, or it could be your fault for making assumptions about what the code is doing.
| [reply] |
Re: Guess That Number
by toolic (Bishop) on Jul 09, 2009 at 13:53 UTC
|
++ nice.
if ($answer !~ /\d+/) {
I think the following code better represents your intent:
if ($answer =~ /\D/) {
You only want someone to enter a positive integer. You don't want someone entering a number with letters or other characters in it, such as '123g'. This string slips through your regex test, then generates unnecessary warnings. | [reply] [d/l] |
|
|
toolic For a reason I haven't discovered yet, when I change it to D and remove the + sign it won't receive any number...can you get the same results?
The early bird gets the worm but the second mouse gets the cheese.
pretendeavor
| [reply] |
|
|
use strict;
use warnings;
my $low = 1; #Current low limit
my $high = 1000; #Current high limit
#This is the secret number...Add one because we
#don't need to wind up with a zero now do we?
my $goal = int(rand($high))+1;
while (1) {
print "Enter a number between $low and $high: ";
#The answer from the user
my $answer = <STDIN>;
chomp($answer);
if ($answer =~ /\D/) {
print "Please enter a number only\n";
next;
}
if ($answer == $goal) {
print "Holy cow! You guessed it!\n";
exit;
}
if (($answer < $low) || ($answer > $high)) {
print "Please stay between $low and $high.\n";
next;
}
if ($answer < $goal) {
$low = $answer;
} else {
$high = $answer;
}
}
| [reply] [d/l] |
Re: Guess That Number
by BioLion (Curate) on Jul 09, 2009 at 16:49 UTC
|
if ($answer !~ /\D+/) { ## if answer doesn't have any non-digits
print "Please enter a number only\n"; ## Really?
next;
}
when you want
if ($answer =~ /\D/) {
## if answer has any non-digits
print "Please enter a number only\n";
next;
}
the character escape \D includes '-' the minus sign hence the positive integer comment. With character classes, capitalisation usually means the opposite (i.e. \d = all digits, \D all non-digits. The '+' sign means 'one or more matches' not positive! See perlre. Other than that I like it! Got to get the kids started early!!
Just a something something...
| [reply] [d/l] [select] |
Re: Guess That Number
by JavaFan (Canon) on Jul 09, 2009 at 20:33 UTC
|
Instead of many ifs and explicite nexts, I'd use given/when:
use 5.010;
use strict;
use warnings;
my $low = 1;
my $high = 1000;
my $goal = $low + int rand $high - $low + 1;
sub prompt {print "Enter a number between $low and $high: "}
prompt;
while (my $guess = <>) { # Allows you terminate the program with ^D
$guess =~ s/^\s+//;
$guess =~ s/\s+$//;
given ($guess) {
when ("") {;}
when (/[^0-9]/) {say "Please enter digits only";}
when ($goal) {say "You won!"; exit;}
when ($_ < $low || $_ > $high) {say "Please stay within limits
+"}
when ($_ < $goal) {$low = $_ + 1}
when ($_ > $goal) {$high = $_ - 1}
}
}
continue {prompt}
__END__
| [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
|
|
No actually. /[^0-9]/ is correct, where /\D/ isn't. Your perl is from the previous century if /\D/ equals /[^0-9]/.
| [reply] [d/l] [select] |
|
|
|
|
|
Re: Guess That Number
by jdporter (Paladin) on Jul 10, 2009 at 03:48 UTC
|
You keep insisting that your $goal calculation function is perfect,
and you say that your testing demonstrates it to be so.
If you are being sincere about that, then your testing protocol is flawed.
It will appear to work correctly (that is, the program functions exactly as expected) as long as the randomly generated $goal is indeed >= $low.
And this will indeed be the case a large fraction of the time, depending on what you set $low and $high to.
But your $goal calculation function is not perfect, and will — some fraction of the time — set $goal to something less than $low,
in which case your program fails. Here's the output of a sample run, with $low set to 100, and printing out the value of $goal so we can see what we're up against:
(hint: goal=59)
Enter a number between 100 and 1000: 50
Please stay between 100 and 1000.
Enter a number between 100 and 1000: 59
Holy cow! You guessed it!
Use a correct $goal calculation function, such as the one I showed you, and you won't have this problem.
Between the mind which plans and the hands which build, there must be a mediator... and this mediator must be the heart.
| [reply] [d/l] [select] |
|
|
Give me some time...I see what you are saying. I just need to think it through how to make the goal perfect like you are saying...I will get it.
The early bird gets the worm but the second mouse gets the cheese.
pretendeavor
| [reply] |
|
|
Think I may have it now...let me know what you think,
The early bird gets the worm but the second mouse gets the cheese.
pretendeavor
| [reply] |
Re: Guess That Number
by Jorge_de_Burgos (Beadle) on Jul 11, 2009 at 13:32 UTC
|
| [reply] |