Perl 5.10+: 159 144 bytes − 350 = −206 points
say"Guess 16 bit signed number";$==32767-rand 65536;say(TOO.$",$_<0?LOW:HIGH)while++$i,$_=<>-$=;say"Congrats! You found the number in $i turns!"
Edit 2: With the recent rules change that allows me to use any string literal for the "congrats" message, I can save 15 bytes from my original 159-byte solution. There's nothing particularly novel or interesting about the new code above as compared to the old code (I just got rid of the p
function, and call say
directly instead), so the remainder of this post will describe the original code, shown below:
sub p{say join$",@_}p Guess,16,bit,signed,number;$==32767-rand 65536;p(TOO,$_<0?LOW:HIGH)while++$i,$_=<>-$=;p Congrats."!",You,found,the,number,in,$i,turns."!"
Yeah, I'm abusing the hell out of rule 1. Who needs strings, when you can have barewords? ;-)
Run with perl -M5.010
to enable the Perl 5.10+ say
feature (or replace the body of the p
function with print join$",@_,$/
for an extra cost of 5 bytes).
Bonus scores:
- −300 points: "display the game rules before starting the game"
- −50 points: "display number of turns taken in the end of game"
The code contains no string literals in a strict sense, so I'd say that rule 1 is, technically, not violated. The trick is that, in Perl, without use strict
, any identifier that doesn't correspond to a known language keyword or subroutine will simple evaluate to its own name. The function p
then simply takes a list of words and prints them out, separated by spaces.
Example play-through:
Guess 16 bit signed number
0
TOO HIGH
-10000
TOO LOW
-5000
TOO HIGH
-7500
TOO LOW
-6250
TOO HIGH
-6875
TOO LOW
-6553
TOO HIGH
-6700
TOO HIGH
-6790
TOO LOW
-6745
TOO HIGH
-6767
TOO LOW
-6756
TOO HIGH
-6761
Congrats! You found the number in 13 turns!
Edit: Oh, right, the rules say I need to post an un-golfed version of the code too, so here it goes. Technically, it's "de-golfed", since I usually compose my code golf programs in more or less fully golfed form from the beginning, and it can sometimes be tricky to remove all the "golfy" optimizations without fundamentally changing how some parts of the program work. Still, I've at least tried to add whitespace, comments and more meaningful function / variable names:
sub output {
# print all arguments separated by spaces, plus a newline:
# (in the golfed code, I use the special variable $" instead of " " for a space)
say join " ", @_;
}
# print the rules:
output Guess, 16, bit, signed, number;
# choose a random number between -32768 and 32767 inclusive:
# (in the golfed version, using the special variable $= allows
# the int() to be left out, since $= can only take integer values)
$number = int( 32767 - rand 65536 );
# loop until the input equals the chosen number, printing "TOO LOW / HIGH":
# (the loop ends when $diff == 0, since 0 is false in Perl)
output (TOO, $diff < 0 ? LOW : HIGH) while ++$count, $diff = (<> - $number);
# print congratulations, including the loop count:
output Congrats."!", You, found, the, number, in, $count, turns."!";
Ps. As an alternative, if just using barewords instead of strings feels too cheaty for you, here's a 182-byte solution that doesn't use the letters TOLWHIG
even in barewords (but does use them in a transliteration operator). It still gets the same bonuses, for a total score of 182 − 350 = −168 points:
sub t{pop=~y/kpqvxyz/tolwhig/r}say"Guess 16 bit signed number";$==32767-rand 65536;say uc t"kpp ".($_<0?qpv:xyzx)while++$n,$_=<>-$=;say t"Cpnzraks! Ypu fpund kxe number yn $n kurns!"
The output looks exactly the same as above. Per the (original) rules, I do use the letters t
and i
in printing the rules, since it's allowed; eliminating even those uses would only cost two extra bytes, though. Conversely, making all the output uppercase (which, based on comments above, seems to be allowed) would let me save three bytes.
WhileURong(USayNumbr;ISayBigrOrSmalr)
\$\endgroup\$