# Guess the number/With feedback (player)

**Guess the number/With feedback (player)**

You are encouraged to solve this task according to the task description, using any language you may know.

The task is to write a player for the game that follows the following rules:

- The scorer will choose a number between set limits. The computer player will print a guess of the target number. The computer asks for a score of whether its guess is higher than, lower than, or equal to the target. The computer guesses, and the scorer scores, in turn, until the computer correctly guesses the target number.

The computer should guess intelligently based on the accumulated scores given. One way is to use a Binary search based algorithm.

- Cf.

## [edit] Ada

with Ada.Text_IO;

procedure Guess_Number_Player is

procedure Guess_Number (Lower_Limit : Integer; Upper_Limit : Integer) is

type Feedback is (Lower, Higher, Correct);

package Feedback_IO is new Ada.Text_IO.Enumeration_IO (Feedback);

My_Guess : Integer := Lower_Limit + (Upper_Limit - Lower_Limit) / 2;

Your_Feedback : Feedback;

begin

Ada.Text_IO.Put_Line ("Think of a number!");

loop

Ada.Text_IO.Put_Line ("My guess: " & Integer'Image (My_Guess));

Ada.Text_IO.Put ("Your answer (lower, higher, correct): ");

Feedback_IO.Get (Your_Feedback);

exit when Your_Feedback = Correct;

if Your_Feedback = Lower then

My_Guess := Lower_Limit + (My_Guess - Lower_Limit) / 2;

else

My_Guess := My_Guess + (Upper_Limit - My_Guess) / 2;

end if;

end loop;

Ada.Text_IO.Put_Line ("I guessed well!");

end Guess_Number;

package Int_IO is new Ada.Text_IO.Integer_IO (Integer);

Lower_Limit : Integer;

Upper_Limit : Integer;

begin

loop

Ada.Text_IO.Put ("Lower Limit: ");

Int_IO.Get (Lower_Limit);

Ada.Text_IO.Put ("Upper Limit: ");

Int_IO.Get (Upper_Limit);

exit when Lower_Limit < Upper_Limit;

Ada.Text_IO.Put_Line ("Lower limit must be lower!");

end loop;

Guess_Number (Lower_Limit, Upper_Limit);

end Guess_Number_Player;

## [edit] AutoHotkey

Works with the AutoHotkey entry at: Guess the number/With feedback

MaxGuesses = 50

GetParams(LowerBound,UpperBound)

If Not GuessNum(LowerBound,UpperBound,MaxGuesses)

MsgBox, 16, Error, Could not guess number within %MaxGuesses% guesses.

GetParams(ByRef LowerBound,ByRef UpperBound)

{

WinWait, Number Guessing ahk_class #32770

Sleep, 100

WinGet, InputID, ID

ControlGetText, Temp1, Static1, ahk_id %InputID%

Temp2 := InStr(Temp1,A_Space,False,32)

LowerBound := SubStr(Temp1,31,Temp2 - 31)

UpperBound := SubStr(Temp1,Temp2 + 5,-1)

}

GuessNum(LowerBound,UpperBound,MaxGuesses)

{

Loop, %MaxGuesses%

{

Guess := LowerBound + ((UpperBound - LowerBound) // 2)

Temp1 := SendGuess(Guess)

ToolTip % Temp1

If Temp1 = Too Low

LowerBound = %Guess%

Else If Temp1 = Too High

UpperBound = %Guess%

Else

Return, 1

}

}

SendGuess(Guess)

{

WinGet, InputID, ID, Number Guessing ahk_class #32770

ControlSetText, Edit1, %Guess%, ahk_id %InputID%

ControlSend, Button1, {Enter}, ahk_id %InputID%

Loop

{

Sleep, 50

IfWinExist, Correct ahk_class #32770

Return

Else IfWinExist, Incorrect ahk_class #32770

Break

}

ControlGetText, Temp1, Static2

WinClose

WinWaitClose

IfInString, Temp1, low

Return, "Too Low"

Else

Return, "Too High"

}

## [edit] BBC BASIC

min% = 1

max% = 100

PRINT "Think of a number between "; min% " and " ;max%

PRINT "I will try to guess your number."

REPEAT

guess% = (min% + max%) DIV 2

PRINT "My guess is " ; guess%

INPUT "Is it higher than, lower than or equal to your number", answer$

CASE LEFT$(answer$,1) OF

WHEN "L","l": min% = guess% + 1

WHEN "H","h": max% = guess% - 1

WHEN "E","e": EXIT REPEAT

OTHERWISE: PRINT "Sorry, I didn't understand your answer."

ENDCASE

UNTIL FALSE

PRINT "Goodbye."

END

## [edit] C

#include <stdio.h>

int main(){

int bounds[ 2 ] = {1, 100};

char input[ 2 ] = " ";

/* second char is for the newline from hitting [return] */

int choice = (bounds[ 0 ] + bounds[ 1 ]) / 2;

/* using a binary search */

printf( "Choose a number between %d and %d.\n", bounds[ 0 ], bounds[ 1 ] );

do{

switch( input[ 0 ] ){

case 'H':

bounds[ 1 ] = choice;

break;

case 'L':

bounds[ 0 ] = choice;

break;

case 'Y':

printf( "\nAwwwright\n" );

return 0;

}

choice = (bounds[ 0 ] + bounds[ 1 ]) / 2;

printf( "Is the number %d? (Y/H/L) ", choice );

}while( scanf( "%1s", input ) == 1 );

return 0;

}

Demonstration (number is 57):

Choose a number between 1 and 100. Is the number 50? (Y/H/L) L Is the number 75? (Y/H/L) H Is the number 62? (Y/H/L) H Is the number 56? (Y/H/L) L Is the number 59? (Y/H/L) H Is the number 57? (Y/H/L) Y Awwwright

The following is a hacky solution using `bsearch()` and pointers to represent integers. Although the pointers do not point to valid things, `bsearch()` doesn't actually dereference the pointers or care what they point to; it just passes them to the comparator and searches the space of pointers. We can use that to search any space of integers.

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

enum {

LOWER = 0,

UPPER = 100,

KEY = LOWER-1 // some value that is not in the valid range

};

char dummy;

// A pointer to represent the integer 0, and the basis of our integer-as-pointer

// representation. We can't use the null pointer because bsearch() returns that

// for not found.

#define ZERO ((void *)&dummy)

int get_value(int x) {

if (x == KEY)

return 0;

printf("My guess is: %d. Is it too high, too low, or correct? (H/L/C) ", x);

char input[2] = " ";

scanf("%1s", input);

switch (tolower(input[0])) {

case 'l':

return -1;

case 'h':

return 1;

case 'c':

return 0;

}

fprintf(stderr, "Invalid input\n");

exit(1);

return 0;

}

int my_cmp(const void *x, const void *y) {

return get_value(x - ZERO) - get_value(y - ZERO);

}

int main() {

printf("Instructions:\n"

"Think of integer number from %d (inclusive) to %d (exclusive) and\n"

"I will guess it. After each guess, you respond with L, H, or C depending\n"

"on if my guess was too low, too high, or correct.\n",

LOWER, UPPER);

void *result = bsearch(ZERO + KEY, ZERO + LOWER, UPPER-LOWER, 1, my_cmp);

if (result == NULL)

fprintf(stderr, "That is impossible.\n");

else

printf("Your number is %d.\n", (int)(result - ZERO));

return 0;

}

## [edit] C++

A clever solution that takes advantage of C++'s built-in binary search function `lower_bound()`

. Instead of searching a slice of a container, we search a range of numbers by implementing a specially-designed custom iterator.

#include <iostream>

#include <algorithm>

#include <string>

#include <iterator>

struct GuessNumberIterator : std::iterator<std::random_access_iterator_tag, int> {

int i;

GuessNumberIterator() { }

GuessNumberIterator(int _i) : i(_i) { }

GuessNumberIterator& operator++() { ++i; return *this; }

GuessNumberIterator operator++(int) {

GuessNumberIterator tmp = *this; ++(*this); return tmp; }

bool operator==(const GuessNumberIterator& y) { return i == y.i; }

bool operator!=(const GuessNumberIterator& y) { return i != y.i; }

int operator*() {

std::cout << "Is your number less than or equal to " << i << "? ";

std::string s;

std::cin >> s;

return (s != "" && (s[0] == 'y' || s[0] == 'Y')) ? 0 : -1;

}

GuessNumberIterator& operator--() { --i; return *this; }

GuessNumberIterator operator--(int) {

GuessNumberIterator tmp = *this; --(*this); return tmp; }

GuessNumberIterator& operator+=(int n) { i += n; return *this; }

GuessNumberIterator& operator-=(int n) { i -= n; return *this; }

GuessNumberIterator operator+(int n) {

GuessNumberIterator tmp = *this; return tmp += n; }

GuessNumberIterator operator-(int n) {

GuessNumberIterator tmp = *this; return tmp -= n; }

int operator-(const GuessNumberIterator &y) { return i - y.i; }

int operator[](int n) { return *(*this + n); }

bool operator<(const GuessNumberIterator &y) { return i < y.i; }

bool operator>(const GuessNumberIterator &y) { return i > y.i; }

bool operator<=(const GuessNumberIterator &y) { return i <= y.i; }

bool operator>=(const GuessNumberIterator &y) { return i >= y.i; }

};

inline GuessNumberIterator operator+(int n, GuessNumberIterator &i) { return i + n; }

const int lower = 0;

const int upper = 100;

int main() {

std::cout << "Instructions:\n"

<< "Think of integer number from " << lower << " (inclusive) to "

<< upper << " (exclusive) and\n"

<< "I will guess it. After each guess, I will ask you if it is less than\n"

<< "or equal to some number, and you will respond with \"yes\" or \"no\".\n";

int answer = std::lower_bound(GuessNumberIterator(lower), GuessNumberIterator(upper), 0).i;

std::cout << "Your number is " << answer << ".\n";

return 0;

}

## [edit] C#

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading; //Remember to add this if you want the game to pause in RealisticGuess.Start()

namespace ConsoleApplication1

{

class RealisticGuess //Simulates a guessing game between two people. Guessing efficiency is not a goal.

{

private int max;

private int min;

private int guess;

public void Start()

{

Console.Clear();

string input;

try

{

Console.WriteLine("Please enter the lower boundary");

input = Console.ReadLine();

min = Convert.ToInt32(input);

Console.WriteLine("Please enter the upper boundary");

input = Console.ReadLine();

max = Convert.ToInt32(input);

}

catch (FormatException)

{

Console.WriteLine("The entry you have made is invalid. Please make sure your entry is an integer and try again.");

Console.ReadKey(true);

Start();

}

Console.WriteLine("Think of a number between {0} and {1}.", min, max);

Thread.Sleep(2500);

Console.WriteLine("Ready?");

Console.WriteLine("Press any key to begin.");

Console.ReadKey(true);

Guess(min, max);

}

public void Guess(int min, int max)

{

int counter = 1;

string userAnswer;

bool correct = false;

Random rand = new Random();

while (correct == false)

{

guess = rand.Next(min, max);

Console.Clear();

Console.WriteLine("{0}", guess);

Console.WriteLine("Is this number correct? {Y/N}");

userAnswer = Console.ReadLine();

if (userAnswer != "y" && userAnswer != "Y" && userAnswer != "n" && userAnswer != "N")

{

Console.WriteLine("Your entry is invalid. Please enter either 'Y' or 'N'");

Console.WriteLine("Is the number correct? {Y/N}");

userAnswer = Console.ReadLine();

}

if (userAnswer == "y" || userAnswer == "Y")

{

correct = true;

}

if (userAnswer == "n" || userAnswer == "N")

{

counter++;

if (max == min)

{

Console.WriteLine("Error: Range Intersect. Press enter to restart the game."); //This message should never pop up if the user enters good data.

Console.ReadKey(true); //It handles the game-breaking exception that occurs

Guess(1, 101); //when the max guess number is the same as the min number.

}

Console.WriteLine("Is the number you're thinking of lower or higher? {L/H}");

userAnswer = Console.ReadLine();

if (userAnswer != "l" && userAnswer != "L" && userAnswer != "h" && userAnswer != "H")

{

Console.WriteLine("Your entry is invalid. Please enter either 'L' or 'H'");

Console.WriteLine("Is the number you're thinking of lower or higher? {L/H}");

userAnswer = Console.ReadLine();

}

if (userAnswer == "l" || userAnswer == "L")

{

max = guess;

}

if (userAnswer == "h" || userAnswer == "H")

{

min = guess;

}

}

}

if (correct == true)

{

EndAndLoop(counter);

}

}

public void EndAndLoop(int iterations)

{

string userChoice;

bool loop = false;

Console.WriteLine("Game over. It took {0} guesses to find the number.", iterations);

while (loop == false)

{

Console.WriteLine("Would you like to play again? {Y/N}");

userChoice = Console.ReadLine();

if (userChoice != "Y" && userChoice != "y" && userChoice != "N" && userChoice != "n")

{

Console.WriteLine("Sorry, your input is invalid. Please answer 'Y' to play again, or 'N' to quit.");

}

if (userChoice == "Y" || userChoice == "y")

{

Start();

}

if (userChoice == "N" || userChoice == "n")

{

Environment.Exit(1);

}

}

}

}

class Program

{

static void Main(string[] args)

{

Console.Title = "Random Number";

RealisticGuess game = new RealisticGuess();

game.Start();

}

}

}

## [edit] Clojure

(require '[clojure.string :as str])

(defn guess-game [low high]

(printf "Think of a number between %s and %s.\n (use (h)igh (l)ow (c)orrect)\n" low high)

(loop [guess (/ (inc (- high low)) 2)

[step & more] (next (iterate #(/ % 2) guess))]

(printf "I guess %s\n=> " (Math/round (float guess)))

(flush)

(case (first (str/lower-case (read)))

\h (recur (- guess step) more)

\l (recur (+ guess step) more)

\c (println "Huzzah!")

(do (println "Invalid input.")

(recur guess step)))))

Output

user=> (guess-game 1 100) Think of a number between 1 and 100. (use (h)igh (l)ow (c)orrect) I guess 50 => l I guess 63 => h I guess 56 => l I guess 59 => l I guess 61 => c Huzzah!

## [edit] D

import std.stdio, std.string;

void main() {

immutable mnOrig = 1, mxOrig = 10;

int mn = mnOrig, mx = mxOrig;

writefln(

"Think of a number between %d and %d and wait for me to guess it.

On every guess of mine you should state whether the guess was

too high, too low, or equal to your number by typing h, l, or =",

mn, mx);

LOOP: for (int i = 1; ; i++) {

immutable guess = (mn + mx) / 2;

writef("Guess %2d is: %2d. The score for which is (h,l,=): ",

i, guess);

immutable string txt = readln().strip().toLower();

switch (txt) {

case "h":

mx = guess - 1;

break;

case "l":

mn = guess + 1;

break;

case "=":

writeln(" Yeehaw!!");

break LOOP;

default:

writefln(" I don't understand your input '%s'.",

txt);

continue LOOP;

}

if (mn > mx || mn < mnOrig || mx > mxOrig) {

writeln("Please check your scoring as" ~

" I cannot find the value");

break;

}

}

writeln("\nThanks for keeping score.");

}

- Output:

Think of a number between 1 and 10 and wait for me to guess it. On every guess of mine you should state whether the guess was too high, too low, or equal to your number by typing h, l, or = Guess 1 is: 5. The score for which is (h,l,=): l Guess 2 is: 8. The score for which is (h,l,=): h Guess 3 is: 6. The score for which is (h,l,=): l Guess 4 is: 7. The score for which is (h,l,=): = Yeehaw!! Thanks for keeping score.

## [edit] Erlang

% Implemented by Arjun Sunel

-module(guess_game).

-export([main/0]).

main() ->

L = 1 , % Lower Limit

U = 100, % Upper Limit

io:fwrite("Player 1 : Guess my number between ~p and ", [L]),

io:fwrite("and ~p until you get it right.\n", [U]),

N = random:uniform(100),

guess(L,U,N).

guess(L,U,N) ->

K = (L+U) div 2,

io:format("Player 2 : Number guessed : ~p~n",[K]),

if

K=:=N ->

io:format("Well guessed!! by Player 2\n");

true ->

if

K > N ->

io:format("Player 1 : Your guess is too high!\n"),

guess(L,K,N);

true ->

io:format("Player 1 : Your guess is too low!\n"),

guess(K,U,N)

end

end.

- Output:

Player 1 : Guess my number between 1 and and 100 until you get it right. Player 2 : Number guessed : 50 Player 1 : Your guess is too high! Player 2 : Number guessed : 25 Player 1 : Your guess is too high! Player 2 : Number guessed : 13 Player 1 : Your guess is too high! Player 2 : Number guessed : 7 Player 1 : Your guess is too low! Player 2 : Number guessed : 10 Well guessed!! by Player 2 ok

## [edit] Euphoria

include get.e

include wildcard.e

sequence Respons

integer min, max, Guess

min = 0

max = 100

printf(1,"Think of a number between %d and %d.\n",{min,max})

puts(1,"On every guess of mine you should state whether my guess was\n")

puts(1,"too high, too low, or equal to your number by typing 'h', 'l', or '='\n")

while 1 do

if max < min then

puts(1,"I think something is strange here...\n")

exit

end if

Guess = floor((max-min)/2+min)

printf(1,"My guess is %d, is this correct? ", Guess)

Respons = upper(prompt_string(""))

if Respons[1] = 'H' then

max = Guess-1

elsif Respons[1] = 'L' then

min = Guess+1

elsif Respons[1] = '=' then

puts(1,"I did it!\n")

exit

else

puts(1,"I do not understand that...\n")

end if

end while

## [edit] Fantom

class Main

{

public static Void main ()

{

Int lowerLimit := 1

Int higherLimit := 100

echo ("Think of a number between 1 and 100")

echo ("Press 'enter' when ready")

Env.cur.in.readLine

while (true)

{

if (higherLimit < lowerLimit)

{ // check that player is not cheating!

echo ("Something has gone wrong ... I give up")

break

}

myGuess := (higherLimit + lowerLimit) / 2

echo ("My guess is $myGuess")

echo ("Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal")

switch (Env.cur.in.readLine.trim.upper)

{

case "E":

echo ("I got it correct - thankyou!")

break // game over

case "H":

lowerLimit = myGuess + 1

case "L":

higherLimit = myGuess - 1

default:

echo ("Pardon? Let's try that again")

}

}

}

}

Example:

Think of a number between 1 and 100 Press 'enter' when ready My guess is 50 Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal a Pardon? Let's try that again My guess is 50 Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal l My guess is 25 Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal h My guess is 37 Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal h My guess is 43 Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal h My guess is 46 Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal h My guess is 48 Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal l My guess is 47 Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal e I got it correct - thankyou!

## [edit] Fortran

program Guess_a_number_Player

implicit none

integer, parameter :: limit = 100

integer :: guess, mx = limit, mn = 1

real :: rnum

character(1) :: score

write(*, "(a, i0, a)") "Think of a number between 1 and ", limit, &

" and I will try to guess it."

write(*, "(a)") "You score my guess by entering: h if my guess is higher than that number"

write(*, "(a)") " l if my guess is lower than that number"

write(*, "(a/)") " c if my guess is the same as that number"

call random_seed

call random_number(rnum)

guess = rnum * limit + 1

do

write(*, "(a, i0, a,)", advance='no') "My quess is: ", guess, " Score(h, l or c)?: "

read*, score

select case(score)

case("l", "L")

mn = guess

guess = (mx-guess+1) / 2 + mn

case("h", "H")

mx = guess

guess = mx - (guess-mn+1) / 2

case("c", "C")

write(*, "(a)") "I solved it!"

exit

case default

write(*, "(a)") "I did not understand that"

end select

end do

end program

Output

Think of a number between 1 and 100 and I will try to guess it. You score my guess by entering: h if my guess is higher than that number l if my guess is lower than that number c if my guess is the same as that number My guess is: 58 Score(h, l or c)?: h My guess is: 29 Score(h, l or c)?: l My guess is: 44 Score(h, l or c)?: l My guess is: 51 Score(h, l or c)?: l My guess is: 55 Score(h, l or c)?: l My guess is: 57 Score(h, l or c)?: c I solved it!

## [edit] Go

Go's binary search function (`sort.Search()`

) is general enough to be able to do this type of task, as mentioned in the documentation for the function itself.[1]

package main

import (

"fmt"

"sort"

)

func main() {

lower, upper := 0, 100

fmt.Printf(`Instructions:

Think of integer number from %d (inclusive) to %d (exclusive) and

I will guess it. After each guess, I will ask you if it is less than

or equal to some number, and you will respond with "yes" or "no".

`, lower, upper)

answer := sort.Search(upper-lower, func (i int) bool {

fmt.Printf("Is your number less than or equal to %d? ", lower+i)

s := ""

fmt.Scanf("%s", &s)

return s != "" && s[0] == 'y'

})

fmt.Printf("Your number is %d.\n", lower+answer)

}

Manual solution:

package main

import (

"bufio"

"fmt"

"os"

)

func main() {

lower, upper := 1, 100

fmt.Printf(`Instructions:

Think of integer number from %d (inclusive) to %d (inclusive) and I will guess it.

After each guess, you respond with l,h,or c depending on

if my guess was too low, too high, or correct.

Press enter when you are thinking of a number. `, lower, upper)

in := bufio.NewReader(os.Stdin)

in.ReadString('\n')

for {

guess := (upper+lower)/2

fmt.Printf("My guess: %d (l/h/c) ", guess)

s, err := in.ReadString('\n')

if err != nil {

fmt.Println("\nSo, bye.")

return

}

switch s {

case "l\n":

lower = guess + 1

case "h\n":

upper = guess - 1

case "c\n":

fmt.Println("I did it. :)")

return

default:

fmt.Println("Please respond by pressing l, h, or c")

}

}

}

## [edit] Icon and Unicon

procedure main ()

lower_limit := 1

higher_limit := 100

write ("Think of a number between 1 and 100")

write ("Press 'enter' when ready")

read ()

repeat {

if (higher_limit < lower_limit)

then { # check that player is not cheating!

write ("Something has gone wrong ... I give up")

exit ()

}

my_guess := (higher_limit + lower_limit) / 2

write ("My guess is ", my_guess)

write ("Enter 'H' if your number is higher, 'L' if lower, or 'E' if equal")

reply := map(trim(read ()))

case (reply) of {

"e" : {

write ("I got it correct - thankyou!")

exit () # game over

}

"h" : lower_limit := my_guess + 1

"l" : higher_limit := my_guess - 1

default : write ("Pardon? Let's try that again")

}

}

end

## [edit] J

require 'misc'

guess=:3 :0

'lo hi'=.y

while.lo < hi do.

smoutput 'guessing a number between ',(":lo),' and ',":hi

guess=.lo+?hi-lo

select.{.deb tolower prompt 'is it ',(":guess),'? '

case.'y'do. smoutput 'Win!' return.

case.'l'do. lo=.guess+1

case.'h'do. hi=.guess-1

case.'q'do. smoutput 'giving up' return.

case. do. smouput 'options: yes, low, high, quit'

end.

end.

)

Example session:

guess 1 100

guessing a number between 1 and 100

is it 86? hi

guessing a number between 1 and 85

is it 56? hi

guessing a number between 1 and 55

is it 24? lo

guessing a number between 25 and 55

is it 29? lo

guessing a number between 30 and 55

is it 43? lo

guessing a number between 44 and 55

is it 53? hi

guessing a number between 44 and 52

is it 51? hi

guessing a number between 44 and 50

is it 48? lo

guessing a number between 49 and 50

is it 49? lo

50

This could be made more efficient by replacing `guess=.lo+?hi-lo`

with `guess=.<.-:lo+hi`

. (The above example would have finished on the first guess, but the range 1..100 would never take more than 6 guesses -- the remaining answers would be determined after six guesses.)

## [edit] Java

A clever solution that uses the built-in binary search functions with a virtual list.

import java.util.AbstractList;

import java.util.Collections;

import java.util.Scanner;

public class GuessNumber {

public static final int LOWER = 0, UPPER = 100;

public static void main(String[] args) {

System.out.printf("Instructions:\n" +

"Think of integer number from %d (inclusive) to %d (exclusive) and\n" +

"I will guess it. After each guess, you respond with L, H, or C depending\n" +

"on if my guess was too low, too high, or correct.\n",

LOWER, UPPER);

int result = Collections.binarySearch(new AbstractList<Integer>() {

private final Scanner in = new Scanner(System.in);

public int size() { return UPPER - LOWER; }

public Integer get(int i) {

System.out.printf("My guess is: %d. Is it too high, too low, or correct? (H/L/C) ", LOWER+i);

String s = in.nextLine();

assert s.length() > 0;

switch (Character.toLowerCase(s.charAt(0))) {

case 'l':

return -1;

case 'h':

return 1;

case 'c':

return 0;

}

return -1;

}

}, 0);

if (result < 0)

System.out.println("That is impossible.");

else

System.out.printf("Your number is %d.\n", result);

}

}

## [edit] JavaScript

### [edit] Spidermonkey version

A boring solution that does nothing clever or inscrutable.

Well, it does use recursion for the guessing function, but that's OK because the depth is bounded by LOG_{2} of the range. That's not true if the user changes his number, but then he gets what he deserves.

#!/usr/bin/env js

var DONE = RIGHT = 0, HIGH = 1, LOW = -1;

function main() {

showInstructions();

while (guess(1, 100) !== DONE);

}

function guess(low, high) {

if (low > high) {

print("I can't guess it. Perhaps you changed your number.");

return DONE;

}

var g = Math.floor((low + high) / 2);

var result = getResult(g);

switch (result) {

case RIGHT:

return DONE;

case LOW:

return guess(g + 1, high);

case HIGH:

return guess(low, g - 1);

}

}

function getResult(g) {

while(true) {

putstr('Is it ' + g + '? ');

var ans = readline().toUpperCase().replace(/^\s+/, '') + ' ';

switch (ans[0]) {

case 'R':

print('I got it! Thanks for the game.');

return RIGHT;

case 'L':

return LOW;

case 'H':

return HIGH;

default:

print('Please tell me if I am "high", "low" or "right".');

}

}

}

function showInstructions() {

print('Think of a number between 1 and 100 and I will try to guess it.');

print('After I guess, type "low", "high" or "right", and then press enter.');

putstr("When you've thought of a number press enter.");

readline();

}

main();

An example session:

Think of a number between 1 and 100 and I will try to guess it. After I guess, type "low", "high" or "right", and then press enter. When you've thought of a number press enter. Is it 50? high Is it 25? high Is it 12? low Is it 18? high Is it 15? high Is it 13? right I got it! Thanks for the game.

Another example session:

Think of a number between 1 and 100 and I will try to guess it. After I guess, type "low", "high" or "right", and then press enter. When you've thought of a number press enter. Is it 50? n Please tell me if I am "high", "low" or "right". Is it 50? h Is it 25? h Is it 12? h Is it 6? h Is it 3? h Is it 1? h I can't guess it. Perhaps you changed your number.

## [edit] Lasso

#!/usr/bin/lasso9

local(

mini=0,

maxi=100,

status = false,

count = 0,

response,

guess

)

stdoutnl('Think of a number between ' + #mini + ' and ' + #maxi + '

Each time I guess indicate if I was to high (H), to low (L) or just right (R).')

while(not #status) => {

if(not(#mini <= #maxi)) => {

stdout('I think you are trying to cheat me. I will not play anymore.')

#status = true

else

#guess = ((#maxi - #mini) /2 ) + #mini

stdout('You are thinking on ' + #guess + ' ')

#response = null

// the following bits wait until the terminal gives you back a line of input

while(not #response or #response -> size == 0) => {

#response = file_stdin -> readSomeBytes(1024, 1000)

}

#response -> replace(bytes('\n'), bytes(''))

match(string(#response)) => {

case('L')

#mini = #guess + 1

#count++

case('H')

#maxi = #guess - 1

#count++

case('R')

stdout('Am I smart or smart! I guessed it in ' + #count ' tries!')

#status = true

case()

stdout('Are you having issues reading instructions? ')

}

}

}

Examples:

Think of a number between 0 and 100 Each time I guess indicate if I was to high (H), to low (L) or just right (R). You are thinking on 50 l You are thinking on 75 l You are thinking on 88 h You are thinking on 81 r Am I smart or smart! I guessed it in 4 tries!

Think of a number between 0 and 100 Each time I guess indicate if I was to high (H), to low (L) or just right (R). You are thinking on 50 k Are you having issues reading instructions? You are thinking on 50 tr Are you having issues reading instructions? You are thinking on 50 l You are thinking on 75 l You are thinking on 88 l You are thinking on 94 l You are thinking on 97 l You are thinking on 99 h You are thinking on 98 r Am I smart or smart! I guessed it in 6 tries!

You are thinking on 50 h You are thinking on 24 h You are thinking on 11 l You are thinking on 17 l You are thinking on 20 l You are thinking on 22 l You are thinking on 23 l I think you are trying to cheat me. I will not play anymore.

## [edit] Liberty BASIC

mini=0

maxi=100

print "Think of a number between ";mini;" and ";maxi

print "Each time I guess a number you must state whether my"

print "guess was too high, too low, or equal to your number."

while response$<>"="

if not(mini<=maxi) then

print "Error"

exit while

end if

guess=int((maxi-mini)/2)+mini

print "My guess is ";guess;". Type L for low, H for high, = for correct."

input response$

response$=upper$(response$)

select case response$

case "L"

mini=guess+1

case "H"

maxi=guess-1

case "="

print guess;" is correct."

exit while

case else

print "Your response was not helpful."

end select

wend

print "Thanks for playing."

## [edit] Lua

function wait(waittime)--wait function is used so that app will not quit immediately

local timer = os.time()

repeat until os.time() == timer + waittime

end

upperBound = 100

lowerBound = 0

print("Think of an integer between 1 to 100.")

print("I will try to guess it.")

while true do

upper1 = upperBound+1

upper2 = upperBound-1

if upperBound == lowerBound or upper1 == lowerBound or upper2 == lowerBound or lowerBound > upperBound then--make sure player is not cheating

io.write("You're cheating! I'm not playing anymore. Goodbye.")

wait(3)

break

else

Guess = math.floor((upperBound + lowerBound)/2)--guessing mechanism

print("My guess is: "..Guess..". Is it too high, too low, or correct? (h/l/c)")

input = io.read()

if input == "h" then --higher

upperBound = Guess

elseif input == "l" then --lower

lowerBound = Guess

elseif input == "c" then --correct

io.write("So I win? Thanks for playing with me.")

wait(3)

break

else

print("Invalid input. Please try again. ")

end

end

end

## [edit] MATLAB

function GuessNumberFeedbackPlayer

lowVal = input('Lower limit: ');

highVal = input('Upper limit: ');

fprintf('Think of your number. Press Enter when ready.\n')

pause

nGuesses = 1;

done = false;

while ~done

guess = floor(0.5*(lowVal+highVal));

score = input(sprintf( ...

'Is %d too high (H), too low (L), or equal (E)? ', guess), 's');

if any(strcmpi(score, {'h' 'hi' 'high' 'too high' '+'}))

highVal = guess-1;

nGuesses = nGuesses+1;

elseif any(strcmpi(score, {'l' 'lo' 'low' 'too low' '-'}))

lowVal = guess+1;

nGuesses = nGuesses+1;

elseif any(strcmpi(score, {'e' 'eq' 'equal' 'right' 'correct' '='}))

fprintf('Yay! I win in %d guesses.\n', nGuesses)

done = true;

else

fprintf('Unclear response. Try again.\n')

end

if highVal < lowVal

fprintf('Incorrect scoring. No further guesses.\n')

done = true;

end

end

end

- Output:

Lower limit: 0 Upper limit: 50 Think of your number. Press Enter when ready. Is 25 too high (H), too low (L), or equal (E)? L Is 38 too high (H), too low (L), or equal (E)? H Is 31 too high (H), too low (L), or equal (E)? H Is 28 too high (H), too low (L), or equal (E)? L Is 29 too high (H), too low (L), or equal (E)? E Yay! I win in 5 guesses.

Lower limit: 0 Upper limit: 10 Think of your number. Press Enter when ready. Is 5 too high (H), too low (L), or equal (E)? L Is 8 too high (H), too low (L), or equal (E)? hello Unclear response. Try again. Is 8 too high (H), too low (L), or equal (E)? H Is 6 too high (H), too low (L), or equal (E)? L Is 7 too high (H), too low (L), or equal (E)? H Incorrect scoring. No further guesses.

## [edit] Mathematica

guessnumber[min0_, max0_] :=

DynamicModule[{min = min0, max = max0, guess, correct = False},

guess[] := Round@Mean@{min, max};

Dynamic@If[correct, Row@{"Your number is ", guess[], "."},

Column@{Row@{"I guess ", guess[], "."},

Row@{Button["too high", max = guess[]],

Button["too low", min = guess[]],

Button["correct", correct = True]}}]];

guessnumber[1, 100]

## [edit] Modula-2

MODULE raden;Example:

IMPORT InOut;

VAR done, ok : BOOLEAN;

guess, upp, low : CARDINAL;

res : CHAR;

BEGIN

InOut.WriteString ("Choose a number between 0 and 1000.");

InOut.WriteLn;

InOut.WriteLn;

upp := 1000;

low := 0;

REPEAT

ok := FALSE;

guess := ( ( upp - low ) DIV 2 ) + low;

InOut.WriteString ("My guess is"); InOut.WriteCard (guess, 4); InOut.Write (11C);

InOut.WriteString ("How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : ");

InOut.WriteBf;

REPEAT

InOut.Read (res);

res := CAP (res)

UNTIL (res = 'Q') OR (res = 'L') OR (res = 'H');

CASE res OF

'L' : low := guess |

'H' : upp := guess

ELSE

ok := TRUE

END;

UNTIL ok;

InOut.WriteString ("So the number is"); InOut.WriteCard (guess, 4);

InOut.WriteLn;

InOut.WriteString ("Thanks for letting me play with you.");

InOut.WriteLn

END raden.

radenChoose a number between 0 and 1000.

My guess is 500 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : l My guess is 750 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : h My guess is 625 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : h My guess is 562 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : l My guess is 593 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : l My guess is 609 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : h My guess is 601 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : h My guess is 597 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : l My guess is 599 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : l My guess is 600 How did I score? 'L' = too low, 'H' = too high, 'Q' = OK : q So the number is 600

Thanks for letting me play with you.

## [edit] Nimrod

import rdstdin, strutils

let oRange = 1..10

var iRange = oRange

echo """Think of a number between $# and $# and wait for me to guess it.

On every guess of mine you should state whether the guess was

too high, too low, or equal to your number by typing h, l, or =""".format(iRange.a, iRange.b)

var i = 0

while true:

inc i

let guess = (iRange.a + iRange.b) div 2

let txt = readLineFromStdin("Guess $# is: $#. The score for which is (h,l,=): "

.format(i, guess))

case txt

of "h": iRange.b = guess - 1

of "l": iRange.a = guess + 1

of "=":

echo " Ye-Haw!!"

break

else: echo " I don't understand your input of '%s'?".format(txt)

if iRange.a > iRange.b or iRange.a < oRange.a or iRange.b > oRange.b:

echo "Please check your scoring as I cannot find the value"

break

echo "Thanks for keeping score."

Output:

Think of a number between 1 and 10 and wait for me to guess it. On every guess of mine you should state whether the guess was too high, too low, or equal to your number by typing h, l, or = Guess 1 is: 5. The score for which is (h,l,=): l Guess 2 is: 8. The score for which is (h,l,=): h Guess 3 is: 6. The score for which is (h,l,=): l Guess 4 is: 7. The score for which is (h,l,=): = Ye-Haw!! Thanks for keeping score.

## [edit] Objective-C

A clever solution that uses the built-in binary search functions with a virtual list.

#import <Foundation/Foundation.h>

@interface GuessNumberFakeArray : NSArray {

int lower, upper;

}

- (instancetype)initWithLower:(int)l andUpper:(int)u;

@end

@implementation GuessNumberFakeArray

- (instancetype)initWithLower:(int)l andUpper:(int)u {

if ((self = [super init])) {

lower = l;

upper = u;

}

return self;

}

- (NSUInteger)count { return upper-lower; }

- (id)objectAtIndex:(NSUInteger)i {

printf("My guess is: %d. Is it too high, too low, or correct? (H/L/C) ", lower + (int)i);

char input[2] = " ";

scanf("%1s", input);

switch (tolower(input[0])) {

case 'l':

return @-1;

case 'h':

return @1;

case 'c':

return @0;

}

return nil;

}

@end

#define LOWER 0

#define UPPER 100

int main(int argc, const char *argv[]) {

@autoreleasepool {

printf("Instructions:\n"

"Think of integer number from %d (inclusive) to %d (exclusive) and\n"

"I will guess it. After each guess, you respond with L, H, or C depending\n"

"on if my guess was too low, too high, or correct.\n",

LOWER, UPPER);

NSUInteger result = [[[GuessNumberFakeArray alloc] initWithLower:LOWER andUpper:UPPER]

indexOfObject:[NSNumber numberWithInt: 0]

inSortedRange:NSMakeRange(0, UPPER - LOWER)

options:0

usingComparator:^(id x, id y){ return [x compare: y]; }];

if (result == NSNotFound)

printf("That is impossible.\n");

else

printf("Your number is %d.", LOWER + (int)result);

}

return 0;

}

## [edit] PARI/GP

guessnumber2(b)={

my(c=0,d=b,a=0);

for(x=1,b,

for(y=1,b,

if(a<c||a==c||a==d||a>d,

a=random(b),

break()

)

);

print("I guess "a" am I h,l,or e ?");

g=input();

if(g==h,

d=a,

if(g==l,

c=a,

if(g==e,

break()

)

)

)

);

}

## [edit] Pascal

Program GuessIt(input, output);

var

done, ok: boolean;

guess, upp, low: integer;

res: char;

begin

writeln ('Choose a number between 0 and 1000.');

write ('Press Enter and I will start to guess the number.');

readln;

upp := 1000;

low := 0;

repeat

ok := false;

guess := ( ( upp - low ) div 2 ) + low;

write ('My guess is: ', guess:4);

write ('. How did i score? ''l'' = too low, ''h'' = too high, ''c'' = correct : ');

repeat

readln (res);

res := lowercase(res);

until (res = 'c') or (res = 'l') or (res = 'h');

case res of

'l': low := guess;

'h': upp := guess;

else

ok := true

end;

until ok;

writeln ('So the number is: ', guess:4);

writeln ('It was nice to play with you.');

end.

Output:

:> ./GuessTheNumberPlayerFeedback Choose a number between 0 and 1000. Press Enter and I will start to guess the number. My guess is: 500. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : h My guess is: 250. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : h My guess is: 125. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : l My guess is: 187. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : h My guess is: 156. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : h My guess is: 140. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : h My guess is: 132. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : l My guess is: 136. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : l My guess is: 138. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : h My guess is: 137. How did i score? 'l' = too low, 'h' = too high, 'c' = correct : c So the number is: 137 It was nice to play with you.

## [edit] Perl

#!/usr/bin/perl

my $min = 1;

my $max = 99;

my $guess = int(rand $max) + $min;

my $tries = 0;

print "=>> Think of a number between $min and $max and I'll guess it!\n

Press <ENTER> when are you ready... ";

<STDIN>;

{

do {

$tries++;

print "\n=>> My guess is: $guess Is your number higher, lower, or equal? (h/l/e)\n> ";

my $score = <STDIN>;

if ($max <= $min) {

print "\nI give up...\n" and last;

} elsif ($score =~ /^h/i) {

$min = $guess + 1;

} elsif ($score =~ /^l/i) {

$max = $guess;

} elsif ($score =~ /^e/i) {

print "\nI knew it! It took me only $tries tries.\n" and last;

} else {

print "error: invalid score\n";

}

$guess = int(($max + $min) / 2);

} while(1);

}

=>> Think of a number between 1 and 99 and I'll guess it! Press <ENTER> when are you ready... =>> My guess is: 88. Is your number higher, lower or equal? (h/l/e) > l =>> My guess is: 44. Is your number higher, lower or equal? (h/l/e) > l =>> My guess is: 22. Is your number higher, lower or equal? (h/l/e) > h =>> My guess is: 33. Is your number higher, lower or equal? (h/l/e) > l =>> My guess is: 28. Is your number higher, lower or equal? (h/l/e) > e I knew it! It took me only 5 tries.

## [edit] Perl 6

multi sub MAIN() { MAIN(0, 100) }

multi sub MAIN($min is copy where ($min >= 0), $max is copy where ($max > $min)) {

say "Think of a number between $min and $max and I'll guess it!";

while $min <= $max {

my $guess = (($max + $min)/2).floor;

given lc prompt "My guess is $guess. Is your number higher, lower or equal? " {

when /^e/ { say "I knew it!"; exit }

when /^h/ { $min = $guess + 1 }

when /^l/ { $max = $guess }

default { say "WHAT!?!?!" }

}

}

say "How can your number be both higher and lower than $max?!?!?";

}

You may execute this program with '`perl6 program`' or with '`perl6 program min max`'. Perl 6 creates a usage for us if we don't give the right parameters. It also parses the parameters for us and provides them via `$min` and `$max`. We use multi-subs to provide two MAIN subroutines so the user is able to choose between min and max parameters and no parameters at all, in which case min is set to 0 and max to 100.

## [edit] PicoLisp

(de guessTheNumber (Min Max)

(prinl "Think of a number between " Min " and " Max ".")

(prinl "On every guess of mine you should state whether my guess was")

(prinl "too high, too low, or equal to your number by typing 'h', 'l', Or '='")

(use Guess

(loop

(NIL (> Max Min)

(prinl "I think somthing is strange here...") )

(prin

"My guess is "

(setq Guess (+ Min (/ (- Max Min) 2)))

",is this correct? " )

(flush)

(NIL

(case (uppc (car (line)))

("H" (setq Max Guess))

("L" (setq Min Guess))

("=" (nil (prinl "I did it!")))

(T (prinl "I do not understand that...")) ) ) ) ) )

Output:

: (guessTheNumber 1 99) Think of a number between 1 and 99. On every guess of mine you should state whether my guess was too high, too low, or equal to your number by typing 'h', 'l', Or '=' My guess is 50,is this correct? h My guess is 25,is this correct? h My guess is 13,is this correct? l My guess is 19,is this correct? l My guess is 22,is this correct? = I did it!

## [edit] Prolog

min(1). max(10).

pick_number(Min, Max) :-

min(Min), max(Max),

format('Pick a number between ~d and ~d, and I will guess it...~nReady? (Enter anything when ready):', [Min, Max]),

read(_).

guess_number(Min, Max) :-

Guess is (Min + Max) // 2,

format('I guess ~d...~nAm I correct (c), too low (l), or too high (h)? ', [Guess]),

repeat,

read(Score),

( Score = l -> NewMin is Guess + 1, guess_number(NewMin, Max)

; Score = h -> NewMax is Guess - 1, guess_number(Min, NewMax)

; Score = c -> writeln('I am correct!')

; writeln('Invalid input'),

false

).

play :-

pick_number(Min, Max),

guess_number(Min, Max).

Example:

?- play.

Pick a number between 1 and 10, and I will guess it...

Ready? (Enter anything when ready):y.

I guess 5...

Am I correct (c), too low (l), or too high (h)? h.

I guess 2...

Am I correct (c), too low (l), or too high (h)? l.

I guess 3...

Am I correct (c), too low (l), or too high (h)? c.

I'm correct!

true

## [edit] PureBasic

min=0

max=100

If OpenConsole()

PrintN("Think of a number between "+Str(min)+" and "+Str(max)+".")

PrintN("On every guess of mine you should state whether my guess was")

PrintN("too high, too low, or equal to your number by typing 'h', 'l', Or '='")

Repeat

If max<=min

PrintN("I think somthing is strange here...")

Break

EndIf

Guess=(max-min)/2+min

Print("My guess is "+Str(Guess)+",is this correct? "): Respons.s=UCase(Input())

If Respons="H": max=Guess-1

ElseIf Respons="L": min=Guess+1

ElseIf Respons="="

PrintN("I did it!")

Break

Else

PrintN("I do not understand that...")

EndIf

ForEver

EndIf

## [edit] Python

inclusive_range = mn, mx = (1, 10)

print('''\

Think of a number between %i and %i and wait for me to guess it.

On every guess of mine you should state whether the guess was

too high, too low, or equal to your number by typing h, l, or =

''' % inclusive_range)

i = 0

while True:

i += 1

guess = (mn+mx)//2

txt = input("Guess %2i is: %2i. The score for which is (h,l,=): "

% (i, guess)).strip().lower()[0]

if txt not in 'hl=':

print(" I don't understand your input of '%s' ?" % txt)

continue

if txt == 'h':

mx = guess-1

if txt == 'l':

mn = guess+1

if txt == '=':

print(" Ye-Haw!!")

break

if (mn > mx) or (mn < inclusive_range[0]) or (mx > inclusive_range[1]):

print("Please check your scoring as I cannot find the value")

break

print("\nThanks for keeping score.")

**Sample Game-play**

Think of a number between 1 and 10 and wait for me to guess it. On every guess of mine you should state whether the guess was too high, too low, or equal to your number by typing h, l, or = Guess 1 is: 5. The score for which is (h,l,=): l Guess 2 is: 8. The score for which is (h,l,=): l Guess 3 is: 9. The score for which is (h,l,=): l Guess 4 is: 10. The score for which is (h,l,=): = Ye-Haw!! Thanks for keeping score.

### [edit] Obscure solution using bisect module

Hacky solution using a fake list class and the `bisect`

module from the standard library to do the binary search.

import bisect

try: input = raw_input

except: pass

class GuessNumberFakeList(object):

def __getitem__(self, i):

s = input("Is your number less than or equal to %d?" % i)

return 0 if s.lower().startswith('y') else -1

LOWER, UPPER = 0, 100

if __name__ == "__main__":

print("""Instructions:

Think of integer number from %d (inclusive) to %d (exclusive) and

I will guess it. After each guess, I will ask you if it is less than

or equal to some number, and you will respond with "yes" or "no".

""" % (LOWER, UPPER))

result = bisect.bisect_left(GuessNumberFakeList(), 0, LOWER, UPPER)

print("Your number is %d." % result)

- Sample output

Instructions: Think of integer number from 0 (inclusive) to 100 (exclusive) and I will guess it. After each guess, I will ask you if it is less than or equal to some number, and you will respond with "yes" or "no". Is your number less than or equal to 50?no Is your number less than or equal to 75?yes Is your number less than or equal to 63?no Is your number less than or equal to 69?no Is your number less than or equal to 72?yes Is your number less than or equal to 71?no Your number is 72.

## [edit] Racket

#lang racket

(define (guess low high)

(define (input-loop available)

(define input (car (string->list (symbol->string (read)))))

(if (member input available)

input

(begin

(printf "Invalid Input\n") (input-loop available))))

(define (guess-loop low high)

(define guess (floor (/ (+ low high) 2)))

(printf "My guess is ~a.\n" guess)

(define input (input-loop (list #\c #\l #\h)))

(case input

((#\c) (displayln "I knew it!\n"))

((#\l) (guess-loop low (sub1 guess)))

((#\h) (guess-loop (add1 guess) high))))

(printf "Think of a number between ~a and ~a.

Use (h)igh, (l)ow and (c)orrect to guide me.\n" low high)

(guess-loop low high))

Another way with loops and mutation

#lang racket

(define (guess minimum maximum)

(printf "Think of a number from ~a to ~a, use (h)igh, (l)ow and (c)orrect." minimum maximum)

(define input "")

(do ((guess (round (/ (+ maximum minimum) 2)) (round (/ (+ maximum minimum) 2))))

((string=? input "c"))

(printf "My guess is: ~a\n(h/l/=) > ")

(when (string=? input "h")

(begin (display "OK...")

(set! maximum (sub1 guess))))

(when (string=? input "l")

(begin (display "OK...")

(set! minimum (add1 guess)))))

(displayln "I was RIGHT!"))

## [edit] REXX

### [edit] with positive integers

This version only handles positive integers.

/*REXX pgm to play guess-the-number (with itself) with positive integers*/

parse arg low high .

if low=='' then low=1

if high=='' then high=1000

?=random(low,high)

say

try="Try to guess my integer (it's between" low 'and' high" inclusive)."

do j=1

say try; say

call guesser

select

when guess>? then info=right("It's too high.",40)

when guess<? then info=right("It's too low. ",40)

otherwise leave

end /*select*/

end /*j*/

say

say 'Congratulations! You guessed the secret number in' j "tries."

exit /*stick a fork in it, we're done.*/

/*──────────────────────────────────GUESSER subroutine──────────────────*/

guesser: oguess=guess

if pos('high',info)\==0 then high=guess

if pos('low' ,info)\==0 then low =guess

guess=low+(high-low)%2

if guess=oguess then guess=guess+1

say 'My guess is' guess

return

**output** shown is from playing several games:

Try to guess my number (it's between 1 and 1000 inclusive). My guess is 500 It's too low. My guess is 750 It's too low. My guess is 875 It's too high. My guess is 812 It's too low. My guess is 843 It's too high. My guess is 827 It's too high. My guess is 819 It's too low. My guess is 823 It's too low. My guess is 825 Congratulations! You guessed the secret number in 9 tries. _________________________________________________________________ Try to guess my number (it's between 1 and 1000 inclusive). My guess is 500 It's too high. My guess is 250 It's too high. My guess is 125 It's too high. My guess is 63 It's too high. My guess is 32 It's too low. My guess is 47 It's too low. My guess is 55 It's too low. My guess is 59 It's too high. My guess is 57 It's too low. My guess is 58 Congratulations! You guessed the secret number in 10 tries. _________________________________________________________________ Try to guess my number (it's between 1 and 1000 inclusive). My guess is 500 It's too high. My guess is 250 It's too low. My guess is 375 It's too high. My guess is 312 It's too low. My guess is 343 It's too low. My guess is 359 It's too high. My guess is 351 Congratulations! You guessed the secret number in 7 tries. _________________________________________________________________ Try to guess my number (it's between 1 and 1000 inclusive). My guess is 500 It's too low. My guess is 750 It's too high. My guess is 625 It's too low. My guess is 687 It's too high. My guess is 656 Congratulations! You guessed the secret number in 5 tries. _________________________________________________________________ Try to guess my number (it's between 1 and 1000 inclusive). My guess is 500 It's too high. My guess is 250 It's too high. My guess is 125 Congratulations! You guessed the secret number in 3 tries.

### [edit] with positive numbers

This version handles decimal fractions (method used only generates numbers with a one-digit decimal fraction, but this

REXX program will handle any length of decimal fractions than can be generated with the current **numeric digits**.

/*REXX pgm to play guess-the-number (with itself) with positive numbers.*/

parse arg low high .

if low=='' then low=1

if high=='' then high=1000

?=random(low*10,high*10)/10 /*make it tough, it may be a fraction.*/

say

try="Try to guess my number (it's between" low 'and' high" inclusive)."

do j=1; say try; say

call guesser

select

when guess>? then info=right("It's too high.",40)

when guess<? then info=right("It's too low. ",40)

otherwise leave

end /*select*/

end /*j*/

say

say 'Congratulations! You guessed the secret number in' j "tries."

exit /*stick a fork in it, we're done.*/

/*──────────────────────────────────GUESSER subroutine──────────────────*/

guesser: oguess=guess

if pos('high',info)\==0 then high=guess

if pos('low' ,info)\==0 then low =guess

guess=(low+(high-low)/2) / 1

if guess=oguess then guess=guess+1

say 'My guess is' guess

return

**output** will be about ten times longer (that is, has ten more times the guesses).

## [edit] Ruby

Computer plays versus itself

def play(low, high, turns=1)

num = (low + high) / 2

print "guessing #{num}\t"

case is_it?(num)

when 1

puts "too high"

play(low, num - 1, turns + 1)

when -1

puts "too low"

play(num + 1, high, turns + 1)

else

puts "found the number in #{turns} turns."

end

end

def is_it?(num)

num <=> $number

end

low, high = 1, 100

$number = rand(low .. high)

puts "guess a number between #{low} and #{high}"

play(low, high)

Example

guess a number between 1 and 100 guessing 50 too high guessing 25 too low guessing 37 too high guessing 31 too high guessing 28 too low guessing 29 too low guessing 30 found the number in 7 turns.

Since Ruby 2.0 it can be done actually using a binary search (output as above):

r = (1..100)

secret = rand(r)

turns = 0

puts "Guess a number between #{r.min} and #{r.max}"

r.bsearch do |guess| # bsearch works on ranges

print "Guessing #{guess} \t"

turns += 1

low_high = secret <=> guess # -1, 0, or 1

puts ["found the number in #{turns} turns", "too low", "too high"][low_high]

low_high

end

## [edit] Rust

use std::io::stdio::stdin;

static INITIAL_LOW: int = 1;

static INITIAL_HIGH: int = 100;

struct GameState {

low: int,

high: int,

current_guess: int,

number_of_guesses: int,

}

impl GameState {

fn new() -> GameState {

return GameState {

low: INITIAL_LOW,

high: INITIAL_HIGH,

current_guess: (INITIAL_LOW + INITIAL_HIGH) / 2,

number_of_guesses: 0

};

}

fn guess_higher (&self) -> GameState {

let new_low = self.current_guess;

let new_guess = (self.current_guess + self.high) / 2;

return GameState {

low: new_low,

high: self.high,

current_guess: new_guess,

number_of_guesses: self.number_of_guesses + 1

};

}

fn guess_lower(&self) -> GameState {

let new_high = self.current_guess;

let new_guess = (self.current_guess + self.low) / 2;

return GameState {

low: self.low,

high: new_high,

current_guess: new_guess,

number_of_guesses: self.number_of_guesses + 1

};

}

}

fn main() {

let mut current_state = GameState::new();

let mut stdin = stdin();

println!("Hello, please choose a number between {} and {} and remember it.", current_state.high, current_state.low);

println!("Got it? Good. Now I shall guess it using only the power of my mind.\n");

loop {

println!("My guess is {:d}. Is that too [h]igh, too [l]ow or is it [e]qual to it? ", current_state.current_guess);

println!("(please type h, l or e and then hit enter) (or type q to quit)");

let answer_str = match stdin.read_line().ok() {

Some(s) => s.trim().to_owned(),

None => ~""

};

match answer_str.as_slice() {

"e" | "E" => {

println!("Woot, I got it in only {} tries!", current_state.number_of_guesses + 1);

break;

}

"l" | "L" => current_state = current_state.guess_higher(),

"h" | "H" => current_state = current_state.guess_lower(),

"q" | "Q" => break,

_ => println!("sorry, I didn't quite get that")

}

if current_state.low == current_state.high {

println!("Your number must be {}. Or maybe you forgot it? It happens!", current_state.low);

break;

}

if current_state.low > current_state.high {

println!("Uh, I think something went wrong. Entirely my fault, I'm sure!");

break;

}

}

}

## [edit] Scheme

(define minimum 1)

(define maximum 100)

(display "Enter a number from ")(display minimum)

(display " to ")(display maximum)(display ": ")

(define number (read))

(define input "")

(do ((guess (round (/ (+ maximum minimum) 2)) (round (/ (+ maximum minimum) 2))))

((string= input "="))

(display "Is it ")(display guess)(display "?\n(h/l/=) > ")

(set! input (symbol->string (read)))

(if (string= input "h") (begin (display "OK...")

(set! maximum (- guess 1))))

(if (string= input "l") (begin (display "OK...")

(set! minimum (+ guess 1)))))

(display "I was RIGHT!\n")

## [edit] Seed7

The program reads the possible commands (l, h, c, q) as single keypresses from the KEYBOARD with getc. It is also possible to quit the program with q. The program recognices also a situation when there is only one possible number left and the command is not c.

$ include "seed7_05.s7i";

$ include "keybd.s7i";

const proc: main is func

local

var boolean: okay is FALSE;

var boolean: quit is FALSE;

var integer: low is 1;

var integer: high is 1000;

var integer: guess is 0;

var char: command is ' ';

begin

writeln("Choose a number between 1 and 1000.");

write("Press Enter and I will start to guess the number.");

readln;

repeat

guess := low + (high - low) div 2;

write("My guess is: " <& guess);

write(". How did I score (l=too low, h=too high, c=correct, q=quit)? ");

flush(OUT);

repeat

command := lower(getc(KEYBOARD));

until command in {'l', 'h', 'c', 'q'};

writeln(command);

case command of

when {'l'}: low := succ(guess);

when {'h'}: high := pred(guess);

when {'c'}: okay := TRUE;

when {'q'}: quit := TRUE;

end case;

until quit or okay or low > high;

if not quit then

writeln("So the number is: " <& guess);

if low > high then

writeln("Why did you cheat?");

end if;

end if;

writeln("It was nice to play with you.");

end func;

Example

Choose a number between 1 and 1000. Press Enter and I will start to guess the number. My guess is: 500. How did I score (l=too low, h=too high, c=correct, q=quit)? h My guess is: 250. How did I score (l=too low, h=too high, c=correct, q=quit)? l My guess is: 375. How did I score (l=too low, h=too high, c=correct, q=quit)? h My guess is: 312. How did I score (l=too low, h=too high, c=correct, q=quit)? l My guess is: 343. How did I score (l=too low, h=too high, c=correct, q=quit)? l My guess is: 359. How did I score (l=too low, h=too high, c=correct, q=quit)? l My guess is: 367. How did I score (l=too low, h=too high, c=correct, q=quit)? h My guess is: 363. How did I score (l=too low, h=too high, c=correct, q=quit)? l My guess is: 365. How did I score (l=too low, h=too high, c=correct, q=quit)? c So the number is: 365 It was nice to play with you.

## [edit] Smalltalk

Create a class like this:

Object subclass: #NumberGuesser

instanceVariableNames: ''

classVariableNames: ''

poolDictionaries: ''

category: 'Rosettacode'

Enter these methods into it:

playBetween: low and: high

Transcript clear.

number := (low to: high) atRandom.

self playBetween: low and: high atTurn: 1.

playBetween: low and: high atTurn: turn

| guess |

guess := (low + ((high - low) / 2)) asInteger.

self showGuessing: guess atTurn: turn.

true caseOf: {

[number > guess] ->

[self showNumberBeing: #low. self playBetween: guess and: high atTurn: turn+1 ].

[number < guess] ->

[self showNumberBeing: #high. self playBetween: low and: guess atTurn: turn+1 ].

[true] ->

[self showNumberFoundAtTurnNr: turn ] }.

showGuessing: guess atTurn: turn

Transcript show: ('{1}. guessing: {2}' format: {turn asString. guess asString}).

showNumberBeing: comparisonToken

Transcript show: ' ==> too ', (comparisonToken asString); cr.

showNumberFoundAtTurnNr: turn

Transcript show: (' ==> found the number in {1} turn(s).' format: {turn asString}); cr.

If you'd rather not use `caseOf:`

you can write `playBetween:and:atTurn:`

like this:

playBetween: low and: high atTurn: turn

| guess |

guess := (low + ((high - low) / 2)) asInteger.

self showGuessing: guess atTurn: turn.

(guess = number)

ifTrue: [self showNumberFoundAtTurnNr: turn ]

ifFalse: [

(number > guess)

ifTrue: [self showNumberBeing: #low. self playBetween: guess and: high atTurn: turn+1 ]

ifFalse: [self showNumberBeing: #high. self playBetween: low and: guess atTurn: turn+1]].

And evaluate this in a Workspace:

g := NumberGuesser new.

g playBetween: 1 and: 100.

Sample output:

1. guessing: 50 ==> too low 2. guessing: 75 ==> too low 3. guessing: 87 ==> too high 4. guessing: 81 ==> too low 5. guessing: 84 ==> too low 6. guessing: 85 ==> found the number in 6 turn(s).

## [edit] Standard ML

A clever solution that uses the built-in binary search functions with a virtual list.

structure GuessNumberHelper : MONO_ARRAY = struct

type elem = order

type array = int * int

fun length (lo, hi) = hi - lo

fun sub ((lo, hi), i) =

let

val n = lo + i

in

print ("My guess is: " ^ Int.toString (lo+i) ^ ". Is it too high, too low, or correct? (H/L/C) ");

let

val str = valOf (TextIO.inputLine TextIO.stdIn)

in

case Char.toLower (String.sub (str, 0)) of

#"l" => GREATER

| #"h" => LESS

| #"c" => EQUAL

end

end

(* dummy implementations for not-needed functions *)

type vector = unit

val maxLen = Array.maxLen

fun update _ = raise Domain

fun array _ = raise Domain

fun fromList _ = raise Domain

fun tabulate _ = raise Domain

fun vector _ = raise Domain

fun copy _ = raise Domain

fun copyVec _ = raise Domain

fun appi _ = raise Domain

fun app _ = raise Domain

fun modifyi _ = raise Domain

fun modify _ = raise Domain

fun foldli _ = raise Domain

fun foldl _ = raise Domain

fun foldri _ = raise Domain

fun foldr _ = raise Domain

fun findi _ = raise Domain

fun find _ = raise Domain

fun exists _ = raise Domain

fun all _ = raise Domain

fun collate _ = raise Domain

end

structure GuessNumberBSearch = BSearchFn (GuessNumberHelper)

val lower = 0

val upper = 100;

print ("Instructions:\n" ^

"Think of integer number from " ^ Int.toString lower ^

" (inclusive) to " ^ Int.toString upper ^ " (exclusive) and\n" ^

"I will guess it. After each guess, you respond with L, H, or C depending\n" ^

"on if my guess was too low, too high, or correct.\n");

case GuessNumberBSearch.bsearch (fn (_, x) => x) ((), (lower, upper)) of

NONE => print "That is impossible.\n"

| SOME (result, _) => print ("Your number is " ^ Int.toString result ^ ".\n")

## [edit] Tcl

set from 1

set to 10

fconfigure stdout -buffering none

while 1 {

set guess [expr {($from+$to) / 2}]

puts -nonewline "Guess: $guess\tWas it lower (<) equal (=) or higher (>)? "

switch -- [gets stdin] {

< { set from [expr {$guess + 1}] }

> { set to [expr {$guess - 1}] }

= {

puts "Found it: $guess"

break

}

default {

puts "What sort of a response was that?!"

}

}

if {$to < $from} {

puts "No answer possible?!"

break

}

}

Sample run:

Guess: 5 Was it lower (<) equal (=) or higher (>)? < Guess: 8 Was it lower (<) equal (=) or higher (>)? > Guess: 6 Was it lower (<) equal (=) or higher (>)? = Found it: 6

## [edit] VBA

Sub GuessNumberPlayer()

Dim iGuess As Integer, iLow As Integer, iHigh As Integer, iCount As Integer

Dim vSolved As Variant

On Error GoTo ErrHandler

MsgBox "Pick a number between 1 and 100. I will guess it!", vbInformation + vbOKOnly, "Rosetta Code | Guess the Number Player"

iCount = 0

iLow = 1

iHigh = 100

Do While Not vSolved = "Y"

iGuess = Application.WorksheetFunction.RandBetween(iLow, iHigh)

iCount = iCount + 1

CheckGuess:

vSolved = InputBox("My guess: " & iGuess & vbCr & vbCr & "Y = Yes, correct guess" & vbCr & _

"H = your number is higher" & vbCr & "L = your number is lower" & vbCr & "X = exit game", "Rosetta Code | Guess the Number Player | Guess " & iCount)

Select Case vSolved

Case "Y", "y": GoTo CorrectGuess

Case "X", "x": Exit Sub

Case "H", "h": iLow = iGuess + 1

Case "L", "l": iHigh = iGuess - 1

Case Else: GoTo CheckGuess

End Select

Loop

CorrectGuess:

MsgBox "I guessed number " & iGuess & " in just " & iCount & " attempts!", vbExclamation + vbOKOnly, "Rosetta Code | Guess the Number Player"

Exit Sub

ErrHandler:

MsgBox "Not possible. Were you cheating?!", vbCritical + vbOKOnly, "Rosetta Code | Guess the Number Player | ERROR!"

End Sub

## [edit] XPL0

include c:\cxpl\codes; \intrinsic 'code' declarations

int Hi, Lo, Guess;

[Text(0, "Think of a number between 1 and 100 then press a key.");

if ChIn(1) then [];

Lo:= 1; Hi:= 101;

loop [Guess:= (Lo+Hi)/2;

Text(0, "^M^JIs it "); IntOut(0, Guess);

Text(0, " (Y = yes, H = too high, L = too low)? ");

case ChIn(1) of

^L,^l: Lo:= Guess;

^H,^h: Hi:= Guess;

^Y,^y: quit

other ChOut(0, 7\bel\);

];

Text(0, "^M^JYippee!");

]

Example output:

Think of a number between 1 and 100 then press a key. Is it 51 (Y = yes, H = too high, L = too low)? H Is it 26 (Y = yes, H = too high, L = too low)? H Is it 13 (Y = yes, H = too high, L = too low)? L Is it 19 (Y = yes, H = too high, L = too low)? H Is it 16 (Y = yes, H = too high, L = too low)? L Is it 17 (Y = yes, H = too high, L = too low)? Y Yippee!

- Programming Tasks
- Games
- Ada
- AutoHotkey
- BBC BASIC
- C
- C++
- Clojure
- D
- Erlang
- Euphoria
- Fantom
- Fortran
- Go
- Icon
- Unicon
- J
- Java
- JavaScript
- Lasso
- Liberty BASIC
- Lua
- MATLAB
- Mathematica
- Modula-2
- Nimrod
- Objective-C
- PARI/GP
- Pascal
- Perl
- Perl 6
- PicoLisp
- Prolog
- PureBasic
- Python
- Racket
- REXX
- Ruby
- Rust
- Scheme
- Seed7
- Smalltalk
- Standard ML
- Tcl
- VBA
- XPL0
- GUISS/Omit
- Lilypond/Omit