# 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.

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.

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;

## ALGOL 68

Works with: ALGOL 68G version Any - tested with release 2.8.3.win32
BEGIN    INT    lower    :=    1;    INT    upper    :=  100;    print( ( "Think of a number between ", whole( lower, 0 ), " and ", whole( upper, 0 ), newline ) );    print( ( "Please enter Y if I guess correctly, L is it is lower, G if it is greater or Q if you've had enough", newline ) );    WHILE        INT mid = lower + ( ( upper - lower ) OVER 2 );        CHAR reply;        WHILE            print( ( "Is it ", whole( mid, 0 ), "?    Y/L/G/Q: " ) );            read( ( reply, newline ) );            NOT char in string( reply, NIL, "YLGQylgq" )        DO SKIP OD;        IF   reply = "Q" OR reply = "q" OR reply = "Y" OR reply = "y"        THEN FALSE        ELIF lower >= upper THEN            print( ( "Based on your answers so far, it must be ", whole( lower, 0 ), newline ) );            FALSE        ELSE            IF   reply = "L" OR reply = "l" THEN upper := mid - 1            ELIF reply = "G" OR reply = "g" THEN lower := mid + 1            FI;            TRUE        FI    DO SKIP ODEND

## AppleScript

-- defining the range of the number to be guessedproperty minLimit : 1property maxLimit : 100 on run	-- ask the user to think of  a number in the given range	display dialog "Please think of a number between " & minLimit & " and " & maxLimit 	-- prepare a variable for the lowest guessed value		set lowGuess to minLimit	-- prepare a variable for the highest guessed value		set highGuess to maxLimit 	repeat		-- guess a number inside the logical range		set computersGuess to (random number from lowGuess to highGuess)		-- ask the user to check my guess		set guessResult to button returned of (display dialog "I guess " & computersGuess & "!" & return & "What do you think?" buttons {"Lower", "Correct", "Higher"})		if guessResult = "Lower" then			-- the number is less than the guess, switch the upper limit to the guess			set highGuess to computersGuess		else if guessResult = "Higher" then			-- the number is greater than the guess, switch the lower limit to the guess			set lowGuess to computersGuess		else if guessResult = "Correct" then			-- the computer guessed the number, beep and exit			beep			exit repeat		end if	end repeatend run

## 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"}

      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 ## Batch File  @echo off:: Player is prompted to give a number between %min% and %max%. If the input is out of those limits they are prompted to choose again:chooseset min=0set max=100 set /p "number=Choose a number [%min%-%max%]: "if %number% gtr %max% goto chooseif %number% lss %min% goto chooseset attempts=0:: Loops the guessing process until completed:compset /a attempts+=1set /a guess=(%max%-%min%)/2+%min%choice /c "HLE" /n /m "Guess: %guess% - [H]igher, [L]ower or [E]qual"if errorlevel 3 goto endif errorlevel 2 ( set max=%guess% goto comp)if errorlevel 1 ( set min=%guess% goto comp) :endecho Guesses: %attempts%pause>nul  Output: Choose a number [0-100]: 42 Guess: 50 - [H]igher, [L]ower or [E]qual L Guess: 25 - [H]igher, [L]ower or [E]qual H Guess: 37 - [H]igher, [L]ower or [E]qual H Guess: 43 - [H]igher, [L]ower or [E]qual L Guess: 40 - [H]igher, [L]ower or [E]qual H Guess: 41 - [H]igher, [L]ower or [E]qual H Guess: 42 - [H]igher, [L]ower or [E]qual E Guesses: 7  ## 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. Translation of: Java #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 = " "; scanf("%1s", input); switch (tolower(input)) { 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;} ## 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. Translation of: Go #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 == 'y' || s == '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;} ## 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(); } }}  ## Ceylon shared void run() { while(true) { variable value low = 1; variable value high = 10; variable value attempts = 1; print("Please choose a number between low and high. Press enter when ready."); process.readLine(); while(true) { if(low > high) { print("Something is wrong. I give up."); break; } variable value guess = (low + high) / 2; print("Is guess (e)qual, (h)igher or (l)ower to your number? (enter q to quit)"); value answer = process.readLine()?.trimmed?.lowercased; switch(answer) case("e") { print("I got it in only attempts attempts == 1 then "try" else "tries"!"); break; } case("h") { high = guess - 1; attempts++; } case("l") { low = guess + 1; attempts++; } case("q") { return; } else { print("Please enter an e, h, l or q"); } } }} ## 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!  ## Common Lisp An imperative solution using LOOP:  (defun guess-the-number (&optional (max 1000) (min 0)) (flet ((get-feedback (guess) (loop initially (format t "I choose ~a.~%" guess) for answer = (read) if (member answer '(greater lower correct)) return answer else do (write-line "Answer greater, lower, or correct.")))) (loop initially (format t "Think of a number between ~a and ~a.~%" min max) for guess = (floor (+ min max) 2) for answer = (get-feedback guess) until (eq answer 'correct) if (eq answer 'greater) do (setf min guess) else do (setf max guess) finally (write-line "I got it!"))))  A recursive solution (we use LABELS instead of FLET for the local function definitions in this version so that GUESS-LOOP will be able to call itself recursively):  (defun guess-the-number (&optional (max 1000) (min 0)) (labels ((guess-loop (min max) (let ((guess (floor (+ min max) 2))) (format t "I choose ~a.~%" guess) (case (read) (greater (guess-loop guess max)) (lower (guess-loop min guess)) (correct (write-line "I got it!")) (otherwise (write-line "Please answer greater, lower, or correct.") (guess-loop min max)))))) (format t "Think of a number between ~a and ~a.~%" min max) (guess-loop min max)))  ## D Translation of: Python 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. ## Elixir Works with: Elixir version 1.2 defmodule Game do def guess(a..b) do x = Enum.random(a..b) guess(x, a..b, div(a+b, 2)) end defp guess(x, a.._b, guess) when x < guess do IO.puts "Is it #{guess}? Too High." guess(x, a..guess-1, div(a+guess, 2)) end defp guess(x, _a..b, guess) when x > guess do IO.puts "Is it #{guess}? Too Low." guess(x, guess+1..b, div(guess+b+1, 2)) end defp guess(x, _, _) do IO.puts "Is it #{x}?" IO.puts " So the number is: #{x}" endendGame.guess(1..100) sample: Is it 50? Too High. Is it 25? Too High. Is it 13? Too High. Is it 7? Too Low. Is it 10? So the number is: 10  ## 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 ## Euphoria Translation of: PureBasic include get.einclude wildcard.e sequence Responsinteger min, max, Guessmin = 0max = 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 = 'H' then max = Guess-1 elsif Respons = 'L' then min = Guess+1 elsif Respons = '=' then puts(1,"I did it!\n") exit else puts(1,"I do not understand that...\n") end ifend while ## 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

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!


## Fortran

Works with: Fortran version 95 and later
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 doend 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!

## FreeBASIC

' FB 1.05.0 Win64 Dim hle As StringDim lowest As Integer = 1Dim highest As Integer = 20Dim guess As Integer = 10Print "Please choose a number between 1 and 20 but don't tell me what it is yet"PrintDo  Print "My guess is"; guess  Do    Input "Is this higher/lower or equal to your chosen number h/l/e : "; hle    hle = LCase(hle)    If hle = "l" AndAlso guess = highest Then      Print "It can't be more than"; highest; ", try again"      hle = "i" '' invalid    ElseIf hle = "h" AndAlso guess = lowest Then      Print "It can't be less than"; lowest; ", try again"      hle = "i"    End If      Loop Until hle = "h" OrElse hle = "l" OrElse hle = "e"  If hle = "e" Then    Print "Good, thanks for playing the gaame with me!"    Exit Do  ElseIf hle = "h" Then    If highest > guess - 1 Then highest = guess - 1     Else    If lowest < guess + 1  Then lowest = guess + 1  End If    guess = (lowest + highest)\2  LoopEnd

Sample input/output

Output:
Please choose a number between 1 and 20 but don't tell me what it is yet

My guess is 10
Is this higher/lower or equal to your chosen number h/l/e : ? l
My guess is 15
Is this higher/lower or equal to your chosen number h/l/e : ? h
My guess is 12
Is this higher/lower or equal to your chosen number h/l/e : ? h
My guess is 11
Is this higher/lower or equal to your chosen number h/l/e : ? e
Good, thanks for playing the gaame with me!


## 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.

package main import (    "fmt"    "sort") func main() {    lower, upper := 0, 100    fmt.Printf(Instructions:Think of integer number from %d (inclusive) to %d (exclusive) andI will guess it. After each guess, I will ask you if it is less thanor 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 == '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 onif 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")        }    }}

Explicit version with arbitrary range:

## 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 100guessing a number between 1 and 100is it 86? higuessing a number between 1 and 85is it 56? higuessing a number between 1 and 55is it 24? loguessing a number between 25 and 55is it 29? loguessing a number between 30 and 55is it 43? loguessing a number between 44 and 55is it 53? higuessing a number between 44 and 52is it 51? higuessing a number between 44 and 50is it 48? loguessing a number between 49 and 50is it 49? lo50

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.)

## Java

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

Translation of: Go
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);    }}

## JavaScript

### 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 LOG2 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) {            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.


## Julia

This version uses the expression $\left\lceil -\log \left({\frac {1}{\mathrm {upper} -\mathrm {lower} }}\right)/\log(2)\right\rceil$ to calculate the maximum number of guesses it will need.

print("Enter an upper bound: ")lower = 0input = readline()upper = parse(Int, input) if upper < 1    throw(DomainError)end attempts = 1print("Think of a number, ", lower, "--", upper, ", then press ENTER.")readline()const maxattempts = round(Int, ceil(-log(1 / (upper - lower)) / log(2)))println("I will need at most ", maxattempts, " attempts ",    "(⌈-log(1 / (", upper, " - ", lower, ")) / log(2)⌉ = ",    maxattempts, ").\n")previous = -1guess = -1 while true    previous = guess    guess = lower + round(Int, (upper - lower) / 2, RoundNearestTiesUp)     if guess == previous || attempts > maxattempts        println("\nThis is impossible; did you forget your number?")        exit()    end     print("I guess ", guess, ".\n[l]ower, [h]igher, or [c]orrect? ")    input = chomp(readline())     while input ∉ ["c", "l", "h"]        print("Please enter one of \"c\", \"l\", or \"h\". ")        input = chomp(readline())    end     if input == "l"        upper = guess    elseif input == "h"        lower = guess    else        break    end     attempts += 1end println("\nI win after ", attempts, attempts == 1 ? " attempt." : " attempts.")

## Kotlin

Translation of: FreeBASIC