20
\$\begingroup\$

You have to make a game Too-low --- Too-high (TLTH) in shortest code (in bytes)

Game rules:

  1. Computer will choose a random number out of integer range (-32768..32767).
  2. Now you will think of a number and input it.
  3. The computer will tell if your number is lower (TOO LOW) or higher (TOO HIGH) than the chosen number.
  4. When you guess the number, the computer should display Congrats! You found the number!.

Code Rules:

  1. Do not use the characters T, O, L, W, H, I and G (neither lowercase nor uppercase) in string or character literals.
    For instance:

    tolower(T);  // Acceptable  
    cout<<"T";   // Unacceptable
    char ch='T'; // Unacceptable
    
  2. Remove 300 bytes if your code can display the game rules before starting the game.

  3. Remove 50 bytes if your code can count number of turns and display number of turns taken in the end of game like this:

    "Congrats! You found the number in n turns!"
    

    where n is number of turns taken, instead of

    "Congrats! You found the number!"  
    
  4. Remove 25 bytes from your score if your code can tell user that the number you input is out of integer range.
    For example:

    Enter the number: 40000  
    Sorry! This number is out of range
    Please Enter the number again:  
    
  5. Remove 25 bytes If your code takes the random number not from any built-in random function.

  6. Remove 10 bytes If your code display "congrats" in color (pick any color except default white).

Submission Rules:

  1. Add a heading with your language name and score with all bounty calculation and its explanation.

  2. Post your golfed and ungolfed code.

Winner

  1. The answer with least bytes wins.
  2. If there is a tie, the answer with the more votes wins.
  3. The winner will be chosen after 5 days.

EDIT:Please show your code's output.
EDIT-2: You can ignore Rule-1 for Rules-2,3 & 4 in Code Rules

Best Of Luck :]

\$\endgroup\$
29
  • 2
    \$\begingroup\$ is this a valid explanation of the game rules? WhileURong(USayNumbr;ISayBigrOrSmalr) \$\endgroup\$ Mar 4, 2014 at 5:18
  • 1
    \$\begingroup\$ Based on your description of the scoring, you have neither a code golf nor a popularity contest. It is a code challenge (with a popularity tiebreaker). Check out the tag wikis. I proposed an edit to tag the challenge appropriately. ps - Jinx! @mniip \$\endgroup\$ Mar 4, 2014 at 5:44
  • 1
    \$\begingroup\$ @JonathanVanMatre to me the wording sounds like code-golf, despite the tie-breaker. \$\endgroup\$
    – mniip
    Mar 4, 2014 at 5:46
  • 21
    \$\begingroup\$ Also, I don't particularly like the rule against assisting other players in improving their answer. In the immortal words of Andre the Giant in The Princess Bride, "That's not very sportsmanlike". \$\endgroup\$ Mar 4, 2014 at 5:47
  • 1
    \$\begingroup\$ This question is so . . . David H. Ahl \$\endgroup\$ Mar 4, 2014 at 18:00

15 Answers 15

20
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ That is a nice and clever answer! +1 from me \$\endgroup\$ Mar 4, 2014 at 16:14
  • \$\begingroup\$ Now that I see this I wonder if it could be beat with Ruby 1.8 if you take the penalty for def method_missing *args;args.join' ';end. \$\endgroup\$
    – Kaya
    Mar 4, 2014 at 17:01
  • \$\begingroup\$ I beat you with good old JavaScript! \$\endgroup\$
    – Toothbrush
    Mar 4, 2014 at 22:07
15
\$\begingroup\$

Python 2: -80 points (270-300-50)

print"WhileURong(USayNumbr;ISayBigrOrSmalr)"
import random
r=random.randint(-32768,32767)
g=i=1
while g:g=cmp(input(),r);print("C\x6fn\x67ra\x74s! Y\x6fu f\x6fund \x74\x68e number \x69n %d \x74urns!"%i,"\x54\x4f\x4f \x48\x49\x47\x48","\x54\x4f\x4f \x4c\x4f\x57")[g];i+=1

Score is 270 characters, minus 300 for showing the instructions, minus 50 for showing the number of guesses in the "congrats!" string, for a total of negative 80 points.

Ungolfed version of the loop, with unescaped strings:

while g:
    g=cmp(input(),r)
    print ("Congrats! You found the number in %d turns!"%i,
           "TOO HIGH",
           "TOO LOW")[g]
    i+=1

The built-in cmp function returns 0 if the values are equal, -1 if the first is smaller and 1 if the first is bigger. I use the value to index a tuple of strings, and then again as the exit condition of the loop. Indexing a sequence with a negative index (like -1) counts from the end of the sequence, rather than from the start.

I was sorely tempted to skip the imports and just use 4 as my random number, as per XKCD 221 (would that qualify for the -25 character bonus?).

Example run (complete with an error, where I can't do negative math):

WhileURong(USayNumbr;ISayBigrOrSmalr)
0
TOO HIGH
-16000
TOO LOW
-8000
TOO HIGH
-12000
TOO HIGH
-14000
TOO LOW
-13000
TOO HIGH
-13500
TOO HIGH
-13750
TOO LOW
-13625
TOO HIGH
-13712
TOO LOW
-13660
TOO HIGH
-13640
TOO HIGH
-13685
TOO HIGH
-13700
TOO LOW
-13695
TOO LOW
-13690
TOO LOW
-13687
Congrats! You found the number in 17 turns!
\$\endgroup\$
6
  • \$\begingroup\$ Please show your code's sample output. \$\endgroup\$ Mar 4, 2014 at 11:22
  • 2
    \$\begingroup\$ Isn't this breaking code rule 1? WhileURong(USayNumbr;ISayBigrOrSmalr) contains one or more Os, Ls, Ws, Hs, Is and Gs. \$\endgroup\$
    – Fors
    Mar 4, 2014 at 17:04
  • \$\begingroup\$ @Cruncher: I'm not sure what you mean, as the program does terminate. After you get the value right g is zero and the while loop ends. \$\endgroup\$
    – Blckknght
    Mar 4, 2014 at 19:30
  • \$\begingroup\$ @Blckknght oops, quick read \$\endgroup\$
    – Cruncher
    Mar 4, 2014 at 19:32
  • \$\begingroup\$ @Fors You can ignore Rule-1 for Rules-2,3 & 4 in Code Rules \$\endgroup\$
    – Cruncher
    Mar 4, 2014 at 19:33
13
\$\begingroup\$

JavaScript 293, -300 (rules) - 50 (turns display) - 25 (range warning) - 25 (no random function) = -107 (new score)

r=new Date%65536+~(z=32767);n=x="";for((A=alert)("\107uess my number, \111 \147\151ve feedback");(x=prompt())!=r;A(0>(x-~z^x-z)?"\164\157\157 "+(x>r?"\150\151\147\150":"\154\157\167"):"Ran\147e: "+~z+" - "+z))n++;A("C\157n\147ra\164s! Y\157u f\157und \164\150e number \151n "+ ++n+"\164urns!")

I'd claim that by RGB conventions that black is a color, but that would be kinda cheating...

Oh, and might I add, no breaking rule #1, either!

Output in a series of alerts and prompts

ALERT: Guess my number, I give feedback
PROMPT: 0
ALERT: too low
PROMPT: 16000
ALERT: too low
PROMPT: 24000
ALERT: too low
PROMPT: 28000
ALERT: too high
PROMPT: 26000
ALERT: too high
PROMPT: 25000
ALERT: too low
PROMPT: 25500
ALERT: too high
PROMPT: 25250
ALERT: too low
PROMPT: 25375
ALERT: too high
PROMPT: 25310
ALERT: too low
PROMPT: 25342
ALERT: too low
PROMPT: 25358
ALERT: too low
PROMPT: 25366
ALERT: too high
PROMPT: 25362
ALERT: too high
PROMPT: 25360
ALERT: too high
PROMPT: 25359
ALERT: Congrats! You found the number in 16 turns!

Ungolfed code:

r = (new Date)%65536+~(z=32767); //Generates random number in range based off date's milliseconds... I'd use epoch, but I need to conserve
n=x=""; // Sets count and input to blank, these change as time goes on
// The line below sets up a call for `alert`, provides the initial rules, and subsequent loops compares the prompt with the number, as well as sets up "too", "high",  "low" and "out of range" message strings, and provides the feedback
for((A=alert)("\107uess my number, \111 \147\151ve feedback");(x=prompt())!=r;A(0>(x-~z^x-z)?"\164\157\157 "+(x>r?"\150\151\147\150":"\154\157\167"):"Ran\147e: "+~z+" - "+z))
{
    n++; // adds one to count providing the number isn't guessed yet
}
alert("C\157n\147ra\164s! Y\157u f\157und \164\150e number \151n "+ ++n+" \164urns!") // Congratulates the player, and displays the correct number of turns taken
\$\endgroup\$
5
  • \$\begingroup\$ you read the rules carefully ? well you have to post ungolfed code with one output \$\endgroup\$ Mar 4, 2014 at 12:14
  • \$\begingroup\$ @MukulKumar sorted... \$\endgroup\$ Mar 4, 2014 at 12:33
  • \$\begingroup\$ You can save 4 by prefixing your answer with A=alert; and replacing all of the alert with A. And one more if you move the alert A(0>(x... after the semicolon in prompt())!=r;)n++1. \$\endgroup\$
    – DocMax
    Mar 4, 2014 at 21:28
  • \$\begingroup\$ you can change feedback if too high/low which uses 84 characters currently to i give feedback (which would only require \151 \147\151ve feedback or 24 characters to save 60 characters. \$\endgroup\$
    – corsiKa
    Mar 4, 2014 at 22:15
  • 1
    \$\begingroup\$ I may be wrong, but I think you can you move the n++ from the for loop into the x=prompt(n++) to save having to do + ++n+ in the final alert. It would save 3. \$\endgroup\$
    – DocMax
    Mar 6, 2014 at 19:36
7
\$\begingroup\$

Javascript, 324 bytes, score -76

[Updated due to rule changes]

  • 324 bytes
  • -300 for showing the rules
  • -50 for showing the turns when the user wins
  • -25 for telling the user when he inputs a number outside the range
  • -25 for not using built-in random (updated)

Total score: -76

Golfed:

function q(y){return y.replace(/./g,function(x){h=x.charCodeAt(0);return String.fromCharCode(h>32&h<58?h+32:h)})}d=o=32768;alert("WhileURong(USayNumbr;ISayBigrOrSmalr)");for(a=1,n=new Date%(2*o)-o;d-n;a++)d=+prompt(a),alert(d>=o|d<-o?"BAD":d<n?q("4// ,/7"):d>n?q("4// ()'("):"Congrats! You found the number in "+a+" turns!")

Lets ungolf this mess.

First, properly idented (but this is still not very good with obfuscated code):

function q(y) {
  return y.replace(/./g, function(x) {
    h = x.charCodeAt(0);
    return String.fromCharCode(h > 32 & h < 58 ? h + 32 : h)
  })
}

d = o = 32768;
alert("WhileURong(USayNumbr;ISayBigrOrSmalr)");

for (a = 1, n = new Date % (2 * o) - o; d - n; a++)
  d = +prompt(), alert(d >= o | d < -o ? "BAD" : d < n ? q("4// ,/7") : d > n ? q("4// ()'(") : "Congrats! You found the number in " + a + " turns!")

Second, renaming identifiers:

function unencrypt(encrypted) {
  return encrypted.replace(/./g, function(character) {
    charCode = character.charCodeAt(0);
    return String.fromCharCode(charCode > 32 & charCode < 58 ? charCode + 32 : charCode)
  })
}

guess = limit = 32768;
alert("WhileURong(USayNumbr;ISayBigrOrSmalr)");

for (tries = 1, randomNumber = new Date % (2 * o) - o; guess - randomNumber; tries++)
  guess = +prompt(),
  alert(guess >= limit | guess < -limit ? "BAD" : guess < randomNumber ? unencrypt("4// ,/7") : guess > randomNumber ? q("4// ()'(") : "Congrats! You found the number in " + tries + " turns!")

So the unencrypt function gets all characters between ASCII 33 (!) and ASCII 58 (:) and adds 32, converting them in characters in the range A-Z.

Lets ungolf the code more by unecrypting all the strings:

guess = limit = 32768;
alert("WhileURong(USayNumbr;ISayBigrOrSmalr)");

for (tries = 1, randomNumber = new Date % (2 * o) - o; guess - randomNumber; tries++)
  guess = +prompt(),
  alert(guess >= limit | guess < -limit ? "BAD" : guess < randomNumber ? "TOO LOW" : guess > randomNumber ? "TOO HIGH" : "Congrats! You found the number in " + tries + " turns!")

And finally lets move some instructions to other places, replace the long ternary chain with ifs and elses, join concatenating strings, and simplify the math, to increase the readability:

guess = 32768;
alert("WhileURong(USayNumbr;ISayBigrOrSmalr)");

randomNumber = new Date % 65536 - 32768;

for (tries = 1; guess - randomNumber; tries++) {
  guess = +prompt(); // The preceding + is a golfing trick to convert string to number.
  if (guess > 32767 | guess < -32768) {
    alert("BAD");
  } else if (guess < randomNumber) {
    alert("TOO LOW");
  } else if (guess > randomNumber) {
    alert("TOO HIGH");
  } else {
    alert("Congrats! You found the number in " + tries + " turns!");
  }
}

Sample:

ALERT:  WhileURong(USayNumbr;ISayBigrOrSmalr)
PROMPT: 5
ALERT:  TOO LOW
PROMPT: 20000
ALERT:  TOO LOW
PROMPT: 30000
ALERT:  TOO HIGH
PROMPT: 25000
ALERT:  TOO HIGH
PROMPT: 22500
ALERT:  TOO HIGH
PROMPT: 21000
ALERT:  TOO HIGH
PROMPT: 20500
ALERT:  TOO HIGH
PROMPT: 20200
ALERT:  TOO LOW
PROMPT: 20400
ALERT:  TOO LOW
PROMPT: 20450
ALERT:  TOO LOW
PROMPT: 20475
ALERT:  TOO HIGH
PROMPT: 20460
ALERT:  TOO LOW
PROMPT: 20468
ALERT:  TOO HIGH
PROMPT: 20464
ALERT:  TOO LOW
PROMPT: 20466
ALERT:  TOO LOW
PROMPT: 20467
ALERT:  Congrats! You found the number in 16 turns!"
\$\endgroup\$
3
  • 1
    \$\begingroup\$ I really like it :) \$\endgroup\$
    – ˈvɔlə
    Mar 4, 2014 at 10:19
  • \$\begingroup\$ Please show your code's sample output. \$\endgroup\$ Mar 4, 2014 at 11:20
  • \$\begingroup\$ @MukulKumar. Done, output added \$\endgroup\$ Mar 4, 2014 at 15:56
7
\$\begingroup\$

C - 272 characters - 300 - 50 - 25 = -103

  • -300 for displaying the rules;
  • -50 for telling the player the number of turns;
  • -25 for not using a standard RNG library.

Golfed code:

main(i){short a,c=i=0,b=time(0);for(a=b;b--;a=(a*233)+4594);b=a;puts("WhileURong(USayNumbr;ISayBigrOrSmalr)");while(1){i++;scanf("%hi",&a);if(a==b){printf("Congrats! You found the number in %i turns!",i);break;}for(c=0;c^9;c++)putchar(c[a<b?"kff7cfn7!":"kff7_`^_!"]-23);}}

Ungolfed:

int main(int i) {
    short a,
          b = time(0),
          c = i = 0;

    for( a = b ; b-- ; a = (a * 233) + 4594);
    b = a;

    puts("WhileURong(USayNumbr;ISayBigrOrSmalr)");

    while(1) {
        i++;
        scanf("%hi", &a);
        if(a == b) {
            printf("Congrats! You found the number in %i turns!", i);
            break;
        }
        for( c = 0 ; c ^ 9 ; c++ )
            putchar(c[ a < b ? "kff7cfn7!" : "kff7_`^_!" ] - 23);
    }
}

Output:

Output

\$\endgroup\$
4
  • \$\begingroup\$ Where is output ? \$\endgroup\$ Mar 4, 2014 at 17:10
  • \$\begingroup\$ @IlmariKaronen, EDIT2. Also, I don't just take the epoch. \$\endgroup\$
    – Oberon
    Mar 4, 2014 at 17:15
  • \$\begingroup\$ @Oberon please post the output also \$\endgroup\$ Mar 4, 2014 at 17:16
  • \$\begingroup\$ @MukulKumar, posted. \$\endgroup\$
    – Oberon
    Mar 4, 2014 at 17:22
5
\$\begingroup\$

C: 237 - 300 - 50 - 25 - 25 - 10: -173 points

-300 for the rules, -50 for showing the number of guesses, -25 for not using any built-in random number generator, -25 for the out of range message and -10 for colouring the congrats message.

int s[3]={542068564},g,n;main(r){for(r=(short)&r,puts("WhileURong(USayNumbr;ISayBigrOrSmalr)");n++,scanf("%d",&g),s[1]=g<r?5721932:1212631368,g^r;puts(g^(short)g?"OOR":s));printf("\033[31mCongrats! You found the number in %d turns!",n);}

Ungolfed:

int s[3]={542068564},g,n;

main(r){
        for(
                r=(short)&r,
                puts("WhileURong(USayNumbr;ISayBigrOrSmalr)");

                n++,
                scanf("%d",&g),
                s[1]=g<r?5721932:1212631368,
                g^r;

                puts(g^(short)g?"OOR":s)
        );

        printf("\033[31mCongrats! You found the number in %d turns!",n);
}

Example run:

WhileURong(USayNumbr;ISayBigrOrSmalr)
-32769
OOR
32768
OOR
0
TOO HIGH
-16384
TOO HIGH
-24576
TOO HIGH
-28672
TOO LOW
-26624
TOO LOW
-25600
TOO HIGH
-26112
TOO LOW
-25856
TOO LOW
-25728
TOO LOW
-25664
TOO HIGH
-25696
TOO HIGH
-25712
TOO LOW
-25704
Congrats! You found the number in 15 turns!

The last line shows up as red.

\$\endgroup\$
1
  • \$\begingroup\$ Bravo! You Hit all of the bounties !!! \$\endgroup\$ Mar 5, 2014 at 18:19
4
\$\begingroup\$

C#: -30 points

  • 345 bytes
  • -300 for showing the rules
  • -50 for showing the turns when the user wins
  • -25 for telling the user when he inputs a number outside the range

Golfed:

int l=-32768,h=32767,n=new Random().Next(l,h),t=0,g=h+1;Console.Write("WhileURong(USayNumbr;ISayBigrOrSmalr)\n");while(n!=g){g=Convert.ToInt32(Console.ReadLine());Console.WriteLine(g==n?"C\x6fn\x67ra\x74s! Y\x6fu f\x6fund \x74\x68\x65 number in {0} \x74urns!":g<l||g>h?"BAD":g<n?"\x54\x4f\x4f \x4c\x4f\x57":"\x54\x4f\x4f \x48\x49\x47\x48",++t);}

To run it, put it in a file (code.cs) and run with scriptcs on the command line: scriptcs code.cs.

Ungolfed: Expanded variable names into something easier to understand, and changed hex letters into real letters.

int low = -32768, 
    high = 32767, 
    number = new Random().Next(low, high), 
    turns = 0, 
    guess = h+1;
Console.Write("WhileURong(USayNumbr;ISayBigrOrSmalr)\n");  // instructions
while (number != guess)
{
    guess = Convert.ToInt32(Console.ReadLine());
    Console.WriteLine(
      guess == number                                     // if you got it right 
        ? "Congrats! You found the number in {0} turns!"  // give the victory speech
        : guess < low || guess > high                     // if out of range
          ? "BAD"                                         // let them know
          : guess < number                                // if guess is low
            ? "TOO LOW"                                   // tell them low
            : "TOO HIGH"                                  // otherwise tell them high
      , ++turns                                           // preincrement turns, add to output
    );
}

Sample output available here.

\$\endgroup\$
5
  • 3
    \$\begingroup\$ Sorry for telling this, but the rule states that "Do not use the characters T, O, L, W, H, I and G (neither lowercase nor uppercase) in string or character literals." \$\endgroup\$ Mar 4, 2014 at 10:01
  • \$\begingroup\$ So just replace T, O, L... with \x54, \x4F, \x4C... and you're fine. \$\endgroup\$
    – sloth
    Mar 4, 2014 at 10:39
  • \$\begingroup\$ Thanks. I just put in hex encodings for the applicable chars in string literals in the golfed version, and modified the scoring accordingly. \$\endgroup\$ Mar 4, 2014 at 10:53
  • \$\begingroup\$ Please show your code's sample output. \$\endgroup\$ Mar 4, 2014 at 11:22
  • \$\begingroup\$ @MukulKumar see here for output. I also just made a few small changes to the logic, fixed an issue. \$\endgroup\$ Mar 4, 2014 at 11:41
4
\$\begingroup\$

bash, -137

Score

273 (bytes) - 300 (rules) - 50 (count tries) - 25 (OOF warning) - 25 (custom PRNG) - 10 (color)

Golfed version

IFS=# a=(`<$0`)
c=65536
y=$[10#`date +%N`%c]
e(){ echo -e ${a[$1]/z/$z};}
e 7
while read x
do((z++,x+=c/2,i=3+(x>y),x==y))&&break
((x<0||x>c-1))&&i=6
e $i
done
e 5
#TOO LOW#TOO HIGH#\e[32mCongrats! You found the number in z turns!#OOR#Guess my number. I'll say HIGH or LOW.

Note that the last line is a comment, so it contains no string or character literals.

Ungolfed version

MYNUMBER=$[10#$(date +%N) % 65536 - 32768]
echo "Guess my number. I'll say HIGH or LOW."

while true; do
    read YOURGUESS
    GUESSES=$((GUESSES + 1))

    if ((YOURGUESS == MYNUMBER)); then
        break
    elif ((YOURGUESS < -32768 || YOURGUESS > 32767)); then
        echo OOR
    elif ((YOURGUESS < MYNUMBER)); then
        echo "TOO LOW"
    else
        echo "TOO HIGH"
    fi
done

echo -e "\e[32mYou found the number in $GUESSES turns!"

Sample output

$ ./tlth
Guess my number. I'll say HIGH or LOW.
-32769
OOR
32768
OOR
0
TOO LOW
16384
TOO HIGH
8192
TOO HIGH
4096
TOO HIGH
2048
TOO HIGH
1024
TOO HIGH
512
TOO HIGH
256
TOO HIGH
128
TOO HIGH
64
TOO HIGH
32
TOO LOW
48
TOO HIGH
40
TOO LOW
44
TOO HIGH
42
Congrats! You found the number in 17 turns!

The last line is printed in green.

\$\endgroup\$
2
\$\begingroup\$

JavaScript (-210 points (190 bytes - 300 (for the rules) - 50 (for the number of guesses) - 25 (for not using any built-in random number source) - 25 (for telling you if the input is out of the range of a signed 16-bit integer)):

Golfed:

alert('Guess number',n=(m=2<<15)/2-new Date%m);for(z=0;a=+prompt(++z);)alert(a>m|a<1-m?m+'-'+-~-m:a==n?'Great! You found the number in '+z+' turns':atob('VE9P\x47E'+(a>n?'hJR0g=':'xPVw==')))

Full code (nicely formatted):

var max = 2 << 15;
var random = max/2 - new Date%max;
var counter = 0;

while (1) {
    var guess = +prompt();

    ++counter;

    if (guess > max | guess < -~-max) {
        alert(-~-max + '-' + max); // Shows that the range is between -32767 and 32768
    } else if (guess > random) {
        alert('TOO HIGH');
    } else if (guess < random) {
        alert('TOO LOW');
    } else if (guess == random) {
        alert('Congrats! You found the number in ' + counter + ' turns');
        break;
    }
}

Output:

ALERT:  Guess number
PROMPT: 5
ALERT:  TOO LOW
PROMPT: 20000
ALERT:  TOO LOW
PROMPT: 30000
ALERT:  TOO HIGH
PROMPT: 25000
ALERT:  TOO HIGH
PROMPT: 22500
ALERT:  TOO HIGH
PROMPT: 21000
ALERT:  TOO HIGH
PROMPT: 20500
ALERT:  TOO HIGH
PROMPT: 20200
ALERT:  TOO LOW
PROMPT: 20400
ALERT:  TOO LOW
PROMPT: 20450
ALERT:  TOO LOW
PROMPT: 20475
ALERT:  TOO HIGH
PROMPT: 20460
ALERT:  TOO LOW
PROMPT: 20468
ALERT:  TOO HIGH
PROMPT: 20464
ALERT:  TOO LOW
PROMPT: 20466
ALERT:  TOO LOW
PROMPT: 34000
ALERT:  -32767-32768
PROMPT: 20467
ALERT:  Great! You found the number in 17 turns!
PROMPT: (nothing)
\$\endgroup\$
2
  • \$\begingroup\$ @IlmariKaronen Sorry, I made a mistake. I've updated my answer. \$\endgroup\$
    – Toothbrush
    Mar 5, 2014 at 11:18
  • \$\begingroup\$ Thanks, now it runs... but it seems to break if I guess 0. :-( Also, shouldn't there be a space in TOO LOW / TOO HIGH? \$\endgroup\$ Mar 5, 2014 at 14:00
2
\$\begingroup\$

C++ 505 + (-300-50-25-25) = 105

-300 : Instructions
-50 : Showing number of turns
-25 : Not using random function
-25 : warning user about input out of range

GOLFED

#include<iostream>
#include<stdlib.h>
using namespace std;int main(){short int a,i=0,*r=new short int;int b=0;a=*r;char t[]={84,79,79,' ','\0'},l[]={76,79,87,'\n','\0'},h[]={72,73,71,72,'\n','\0'};cout<<"WhileURong(USayNumbr;ISayBigrOrSmalr)\n";while(a!=b){cin>>b;if(b<-32768||b>32767){cout<<"Sorry! the number is out of range please enter the number again\n";continue;}i++;if(b<a){cout<<'\n'<<t<<l;}if(b>a){cout<<'\n'<<t<<h;}if(a==b){cout<<"Congrats!You found the number in "<<i<<" turns!";}}return 0;}  

UNGOLFED

#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
    short int a,i=0,*r=new short int;
    int b=0;
    a=*r;
    char t[]={84,79,79,' ','\0'},l[]={76,79,87,'\n','\0'},h[]={72,73,71,72,'\n','\0'};
    cout<<"WhileURong(USayNumbr;ISayBigrOrSmalr)\n";
    while(a!=b)
    {
        cin>>b;
        if(b<-32768||b>32767)
        {
            cout<<"Sorry! the number is out of range please enter the number again\n";
            continue;
        }
        i++;
        if(b<a)
        {
            cout<<'\n'<<t<<l;
        }
        if(b>a)
        {
        cout<<'\n'<<t<<h;
        }
    if( a==b)
    {   

            cout<<"Congrats!You found the number in "<<i<<" turns!";
        }
    }
    return 0;
}  

OUTPUT

\$\endgroup\$
1
  • \$\begingroup\$ Personally, I could not stop myself.. :) \$\endgroup\$ Mar 4, 2014 at 16:57
2
\$\begingroup\$

C, 183-300-25=-142

183 bytes -300 for the rules -25 for not using a random library

main(){short g,n=time(0)*(time(0)&1?1:-1);puts("WhileURong(USayNumbr;ISayBigrOrSmalr)");while(g^n)scanf("%d",&g),puts(g>n?"TOO HIGH":g<n?"TOO LOW":"Congrats! You found the number!");}

ungolfed version:

main(){
    short g,n=time(0)*(time(0)&1?:-1);
    puts("WhileURong(USayNumbr;ISayBigrOrSmalr)");
    while(g^n)
        scanf("%d",&g),
        puts(g>n?"TOO HIGH":g<n?"TOO LOW":"Congrats! You found the number!");
}

sample run:

WhileURong(USayNumbr;ISayBigrOrSmalr)
40
TOO HIGH
20
TOO HIGH
1
TOO HIGH
0
TOO HIGH
-20
TOO HIGH
-200
TOO HIGH
-2000
TOO HIGH
-20000
TOO LOW
-10000
TOO LOW
-5000
TOO LOW
-3000
TOO HIGH
-4000
TOO LOW
-3500
TOO HIGH
-3700
TOO HIGH
-3900
TOO HIGH
-3950
TOO HIGH
-3970
TOO LOW
-3960
Congrats! You found the number!
\$\endgroup\$
6
  • \$\begingroup\$ "TOO HIGH" and "TOO LOW" both contain illegal characters TOLWHIGtolwhig. \$\endgroup\$
    – Oberon
    Mar 4, 2014 at 17:58
  • \$\begingroup\$ As does "Congrats! You found the number!" and "WhileURong(USayNumbr;ISayBigrOrSmalr)". \$\endgroup\$
    – Fors
    Mar 4, 2014 at 18:13
  • \$\begingroup\$ @Fors but those are allowed (see EDIT2). \$\endgroup\$
    – Oberon
    Mar 4, 2014 at 18:21
  • \$\begingroup\$ Indeed they are! By some reason I missed that edit. \$\endgroup\$
    – Fors
    Mar 4, 2014 at 18:23
  • \$\begingroup\$ @Oberon So is TOO LOW allowed by EDIT 2, too? \$\endgroup\$
    – Toothbrush
    Mar 5, 2014 at 11:53
2
\$\begingroup\$

J - 190 char -300 -50 = -160 pts

'Congrats, you found the number in ',' turns!',~":1>:@]^:(]`(1[2:1!:2~a.{~71+13 8 8 _39,(5 8 16;1 2 0 1){::~0&>)@.*@-[:".1!:1@1:)^:_~32767-?2^16['WhileURong(USayNumbr;ISayBigrOrSmalr)'1!:2]2

Explanation (recall that J is read from right to left):

  • 'WhileURong(USayNumbr;ISayBigrOrSmalr)'1!:2]2 - Print the rules.
  • 32767-?2^16[ - Toss the return value, and then generate a random number between 0 and 2^16-1 inclusive. Then, adjust it to the range -32768..32767 by subtracting it from 32767.
  • 1>:@]^:(...)^:_~ - The x u^:v^:_ y pattern is kinda like a while loop. x stays constant, and y gets mutated with every execution of u. This continues until either x v y returns 0 or x u y results in no change to y. The ~ swaps the two arguments, so that x will be the random number and y will begin at 1. Our u is >:@], which increments this 1 and returns it, so it acts as a counter and the x u y termination condition can never occur.
  • [:".1!:1@1: - Take the counter, and ignore its value, using the number 1 instead (1:). Read in a line of input (1!:1) from the keyboard (file handle 1) and execute it (".). This allows J, whose negative sign is normally _, to take numbers in the form -n (evaluates as negation applied to the number n).
  • ]`(...)@.*@- - Take the difference of the random number from before and the guess (-). Now, we select the next action depending on whether this difference is zero (@.*). If it is, return (]`) that 0 as the result for x v y, so that execution terminates, and the whole while loop returns the counter. Else...
  • 71+13 8 8 _39,(5 8 16;1 2 0 1){::~0&> - Return the array 5 8 16 if the number is negative, and 1 2 0 1 if it is positive. Then prepend 13 8 8 _39 and add 71 to everything, so we have either 84 79 79 32 76 79 87 or 84 79 79 32 72 73 71 72.
  • 1[2:1!:2~a.{~ - Turn these numbers to ASCII characters by indexing the alphabet a. with them. Then print them out with 1!:2 (using file handle 2) and return 1 as the result of x v y.
  • 'Congrats, you found the number in ',' turns!',~": - When the loop finishes, it returns the counter. Convert it to a string with ": and put it in between the strings 'Congrats, you found the number in ' and ' turns!'.

Sample output:

   'Congrats, you found the number in ',' turns!',~":1>:@]^:(]`(1[2:1!:2~a.{~71+13 8 8 _39,(5 8 16;1 2 0 1){::~0&>)@.*@-[:".1!:1@1:)^:_~32767-?2^16['WhileURong(USayNumbr;ISayBigrOrSmalr)'1!:2]2
WhileURong(USayNumbr;ISayBigrOrSmalr)
0
TOO HIGH
-20000
TOO LOW
-10000
TOO LOW
-5000
TOO HIGH
-7500
TOO HIGH
-8750
TOO HIGH
-9000
TOO HIGH
-9500
TOO LOW
-9250
TOO HIGH
-9375
TOO HIGH
-9450
TOO LOW
-9400
TOO HIGH
-9425
TOO HIGH
-9437
TOO LOW
-9431
TOO LOW
-9428
TOO HIGH
-9430
TOO LOW
-9429
Congrats, you found the number in 18 turns!
\$\endgroup\$
2
\$\begingroup\$

JavaScript -40

335 - 300 (rules) - 50 (count turns) - 25 (out of range)

Not gonna win but a fun way to get the letters I think.

Golfed

!function T(O,L,W,H,I,G){a=T.toString();c=L.floor(65536*L.random())+H;O(W+G+" between "+H+" & "+I);k=(f=a[9]+(d=a[11])+d+" ")+(e=a[17])+a[19]+a[21]+e;l=f+a[13]+d+a[15];for(m=1;(n=prompt(W+G))!=c;m++)n<H||n>I?O("Out of range"):n>c?O(l):O(k);O("Congrats! You found the"+G+" in "+m+" turns!")}(alert,Math,"Guess a",-32768,32767," number")

Ungolfed

!function T(O,L,W,H,I,G){
    fn = T.toString();
    random = L.floor(L.random() * 65536) + H;

    O(W + G + " between " + H + " & " + I);

    tooLow = (too = fn[9] + (o = fn[11]) + o + " ") + (h = fn[17]) + fn[19] + fn[21] + h;
    tooHigh = too + fn[13] + o + fn[15];

    for (n=1; (guess = prompt(W + G)) != random; n++) {
        if (guess < H || guess > I) {
            O("Out of range");  
        } else if (guess > random) {
            O(tooHigh);
        } else {
            O(tooLow);  
        }
    }

    O("Congrats! You found the" + G + " in " + n + " turns!");
}(alert, Math, "Guess a", -32768, 32767, " number")

Sample output

(ALERT) Guess a number between -32768 & 32767
(PROMPT) Guess a number
9999999
(ALERT) Out of range
(PROMPT) Guess a number
0
(ALERT) TOO LOW
(PROMPT) Guess a number
8008
(ALERT) Congrats! You found the number in 3 turns!
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog) (157 - 300 - 50 = -193)

(Yes, these count as bytes, the APL charset fits in a byte.)

I've claimed "display the game rules" and "count the number of turns".

G
n←32768-?65536
t←0
⎕←'Guess 16-bit signed number'
t+←1
→8/⍨n=g←⎕
⎕←⎕AV[(⌽⎕AV)⍳'×↑↑ ','○↑-' '∇⌊∘∇'⊃⍨1+n<g]
→4
⎕←'Congrats! You found the number in't'tries!'

Example run:

      G
Guess 16-bit signed number
⎕:
      0
TOO HIGH
⎕:
      -10000
TOO LOW
⎕:
      -5000
TOO LOW
⎕:
      -2500
TOO LOW
⎕:
      -1250
TOO HIGH
⎕:
      -1750
TOO LOW
⎕:
      -1500
TOO LOW
⎕:
      -1375
TOO LOW
⎕:
      -1300
TOO LOW
⎕:
      -1275
TOO LOW
⎕:
      -1265
TOO HIGH
⎕:
      -1270
TOO HIGH
⎕:
      -1273
 Congrats! You found the number in  13  tries!

Ungolfed:

GuessNumber;num;tries;guess;decode;too;low;high
decode←{⎕AV[(⌽⎕AV)⍳⍵]} ⍝ invert the character code, char 1 becomes char 255 etc.
num←32768-?65536 ⍝ select a random number
tries←0

⍝ strings for low/high
too←decode '×↑↑ '
low←decode '○↑-'
high←decode '∇⌊∘∇'

⎕←'Guess 16-bit signed number'

try:
  tries +← 1
  guess ← ⎕
  →(guess=num)/found
  ⍝ still here: number was wrong
  ⎕←too, (1+num<guess)⊃low high  ⍝ output appropriate word
  →try ⍝ try again
found:
  ⎕←'Congrats! You found the number in' tries 'tries!'
\$\endgroup\$
1
\$\begingroup\$

Pogo: -95 (255 - 300 - 50)

method main:void
    print("Guess the number. You will be told if you are high or low.")
    declare(integer,n,0)
    declare(integer,i,0)
    declare(integer,j,0)
    random() i
    while j != i
        set(n+1) n
        print("Number?")
        getinput() j
        if j > i
            print("High")
        end
        else
            print("Low")
        end
    end
    print("Yay" n "turns")
end main

If the number is 10:

Number?

5

Low

8

Low

12

High

10

Yay 4 turns


The character count is based on the code with all whitespace removed.

Note that Pogo is not a fake language. I created it and wrote a compiler and IDE for it here: https://github.com/nrubin29/Pogo

\$\endgroup\$
2
  • \$\begingroup\$ Read my EDIT and EDIT - 2 \$\endgroup\$ Mar 6, 2014 at 2:25
  • \$\begingroup\$ Updated as per the edits. \$\endgroup\$
    – nrubin29
    Mar 6, 2014 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.