15
\$\begingroup\$

The puzzle is as follows:

Create the traditional 'Guess my Number' game in as little keystrokes as possible. The player should input a guess between and including 1 and 100, and the computer should reply with either + (meaning the player needs to guess higher), - (meaning the player needs to guess lower) or = (meaning the player has guessed the number. The game continues until the player has guessed the number. The number that the computer generates MUST be a random number between and including 1 and 100.

Sample gameplay

50
+
75
-
60
-
55
+
57
=

Happy Golfing!

\$\endgroup\$
5
  • \$\begingroup\$ Whoever can post an answer fastest with the OSK in most OSes gets my vote. That's like, 3 keystrokes to open \$\endgroup\$
    – Bojangles
    Commented Apr 11, 2013 at 15:21
  • \$\begingroup\$ @Howard this one is basically a simplified version of the one you found. Not an exact duplicate, though \$\endgroup\$ Commented Apr 11, 2013 at 15:41
  • \$\begingroup\$ @JanDvorak, I feel its not a significant enough variant to warrant a different question. \$\endgroup\$
    – zzzzBov
    Commented Apr 11, 2013 at 20:30
  • \$\begingroup\$ @zzzzBov how does that work on a puzzle site, this is a slightly different question though I agree it's pretty close. However the other one has an accepted answer. what if people want to work this puzzle but not the other one? \$\endgroup\$
    – Ryan
    Commented Apr 11, 2013 at 22:31
  • \$\begingroup\$ @ryan, I don't know how it works on a site such as Code Golf. I fully understand the predicament of posing a challenge similar to an existing one, however in this case, I feel that this one is too similar to the existing one. It's an opinion, and in the end the votes are what will decide whether or not this gets closed or stays open. \$\endgroup\$
    – zzzzBov
    Commented Apr 11, 2013 at 22:34

24 Answers 24

10
\$\begingroup\$

Ruby: 63 58 52 49 characters

puts"=-+"[r=$_.to_i<=>n||=1+rand(100)];r==0&&exit

Sample run:

bash-4.2$ ruby -ne 'puts"=-+"[r=$_.to_i<=>n||=1+rand(100)];r==0&&exit'
50
-
25
+
37
+
43
-
40
+
42
=
\$\endgroup\$
5
  • 2
    \$\begingroup\$ A few small improvements: exit if r==0 -> r==0&&exit, and there is no whitespace needed in puts"=-+". \$\endgroup\$
    – primo
    Commented Apr 11, 2013 at 19:04
  • \$\begingroup\$ I remembered the && trick just this morning. Seems I'm getting slow. \$\endgroup\$
    – manatwork
    Commented Apr 12, 2013 at 7:21
  • \$\begingroup\$ Ups, sorry. I read the code wrong. \$\endgroup\$
    – Howard
    Commented Apr 12, 2013 at 10:50
  • \$\begingroup\$ Is 1+$$%100 random enough? \$\endgroup\$
    – Howard
    Commented Apr 12, 2013 at 10:59
  • \$\begingroup\$ +1 for 42 as a random number :) \$\endgroup\$
    – tomsmeding
    Commented Apr 14, 2013 at 17:31
9
\$\begingroup\$

Python 84 83 characters

import os
a,c=0,ord(os.urandom(1))%100+1
while c-a:a=input();print'=-+'[c!=a:][c>a]
\$\endgroup\$
2
  • \$\begingroup\$ I can not make it work with python 3. Here is my solution import os a,c=0,ord(os.urandom(1))%10+1 while c-a:a=int(input());print("not ok") print("ok") \$\endgroup\$
    – Chau Giang
    Commented Mar 26, 2021 at 11:40
  • \$\begingroup\$ Can you please try to run your code? \$\endgroup\$
    – Chau Giang
    Commented Mar 26, 2021 at 11:41
6
\$\begingroup\$

JavaScript, 52

for(u=r=1+new Date%100;u=r-prompt(u<0?'-':'+'););'='

Just paste it in the console.

\$\endgroup\$
9
  • \$\begingroup\$ Nice one! Even if skips some of the rules: uses 0..99 interval instead of 1..100 and not displays “=” on success. \$\endgroup\$
    – manatwork
    Commented Apr 11, 2013 at 17:39
  • \$\begingroup\$ @manatwork now I guess I can read the rules :) I edited for the 1..100. \$\endgroup\$ Commented Apr 11, 2013 at 17:41
  • \$\begingroup\$ @manatwork I edited for the = too. Much less elegant. I'll try later to make it shorter. \$\endgroup\$ Commented Apr 11, 2013 at 17:44
  • \$\begingroup\$ You can save 1 character by using a reference to prompt(): first p=prompt, then just p(). But something is wrong with the logic, as the “=” only appears if you guess the number on first try. \$\endgroup\$
    – manatwork
    Commented Apr 11, 2013 at 17:50
  • \$\begingroup\$ I must leave for a moment. But this version should work (less user friendly, though). \$\endgroup\$ Commented Apr 11, 2013 at 17:59
6
\$\begingroup\$

Perl 57 53 50 (thanks to @manatwork) Characters

$_=qw(= + -)[$^T%100+1<=>$_];print"$_
";exit if/=/

Note You need to invoke with -n option

Alternate version as suggested by @primo

Perl 40 Characters

$_=chr 44-($^T%100+1<=>$_||exit print'=')
\$\endgroup\$
11
  • 1
    \$\begingroup\$ qw(= - +) is shorter than ('=','-','+') \$\endgroup\$
    – manatwork
    Commented Apr 11, 2013 at 17:02
  • \$\begingroup\$ @manatwork: I am not a perl expert. Thank you for the advise :-) \$\endgroup\$
    – Abhijit
    Commented Apr 11, 2013 at 17:03
  • \$\begingroup\$ You not need while, if is enough. And please change the response logic. \$\endgroup\$
    – manatwork
    Commented Apr 11, 2013 at 17:05
  • \$\begingroup\$ @manatwork: I think you can use this answer to post a new one (you deserve it). Once you are done, I will delete it. As I said am not an expert of Perl :-) \$\endgroup\$
    – Abhijit
    Commented Apr 11, 2013 at 17:09
  • 2
    \$\begingroup\$ Bit of a re-work, but essentially the same for 41 (actually 40, because ^T can be replaced with character 20), requires -pl: $_=chr 44-($^T%100+1<=>$_||exit print'=') \$\endgroup\$
    – primo
    Commented Apr 11, 2013 at 18:25
5
\$\begingroup\$

APL (28)

{'='≠⎕←'+=-'[2+×⎕-⍵]:∇⍵}?100
\$\endgroup\$
1
  • 3
    \$\begingroup\$ I can't read this, but it looks cool. \$\endgroup\$
    – asteri
    Commented Apr 12, 2013 at 15:57
3
\$\begingroup\$

Haskell, 128

Won’t be winning any awards, but here it is.

main=fix.(.)(=<<(read<$>getLine)).f=<<(`mod`100).fst.next<$>newStdGen where p=putStrLn;f y r x|x<y=p"+">>r|x>y=p"-">>r|True=p"="

Ungolfed logic and imports:

import Control.Applicative
import Data.Function
import System.Random

main :: IO ()
main = do
  random <- newStdGen
  let number = fst (next random) `mod` 100
  fix $ \loop -> do
    guess <- read <$> getLine
    check number guess loop
  where
    check number guess loop
      | guess < number = do
        putStrLn "+"
        loop
      | guess > number = do
        putStrLn "-"
        loop
      | otherwise = putStrLn "="
\$\endgroup\$
3
\$\begingroup\$

C#: 147 136 Characters

It won't beat most other languages, but here's a C# solution for fun:

var r=new Random().Next(1,100);var g=0;while(g!=r){g=int.Parse(Console.ReadLine());Console.WriteLine(""+g+'\n'+(g<r?'+':g>r?'-':'='));}
\$\endgroup\$
6
  • \$\begingroup\$ Is that a complete C# program source ? \$\endgroup\$ Commented Apr 11, 2013 at 20:15
  • \$\begingroup\$ I remember seeing a post on meta about ignoring standard overhead/bloat from languages like C#/Java (can't find the link now). It will copy-paste into LINQPad. \$\endgroup\$
    – Anthony
    Commented Apr 12, 2013 at 10:23
  • \$\begingroup\$ If you remove overhead from other, they'll be shorter too. The Go one for example could be reduced to 105 chars. But it would be hard to define a unique line, so I don't think that really makes sense. \$\endgroup\$ Commented Apr 12, 2013 at 10:25
  • 1
    \$\begingroup\$ You can trim another 27 by changing your definition, loop handling, and unnecessary echo of the input. int r=new Random().Next(1,100),g=0;while(g!=r){g=int.Parse(Console.ReadLine());Console.WriteLine(g<r?'+':g>r?'-':'=');} \$\endgroup\$ Commented Apr 12, 2013 at 19:22
  • \$\begingroup\$ Your code will never choose the number "100", it should be Next(1,101) or Next(100)+1. :) \$\endgroup\$ Commented Aug 10, 2013 at 6:05
2
\$\begingroup\$

Clojure (117 characters)

java -jar clojure.jar  -e "(loop[n(int(*(rand 100)))]((get{-1#(prn '+)0#(do(prn '=)(System/exit 0))1#(prn '-)}(compare(eval(read))n)))(recur n))"
50
+
75
+
90
-
86
-
82
=

Clojure (74 characters)

Guessing a real number. Nobody will be patient enought to solve to "=", so nobody notice the missing exit.

java -jar clojure.jar  -e "(loop[n(rand)](prn (get{-1 '+ 0 '= 1 '-}(compare(eval(read))n)))(recur n))"
0.5
+
0.8
-
0.6
+
0.7
+
0.75
-
0.72
+
0.74
+
0.745
+
0.748
-
0.746
-
0.7455
-
...
\$\endgroup\$
2
\$\begingroup\$

R, 89 85 chars

s=sample(1:100,1);while(s!=(a=as.real(readline())))cat(ifelse(a>s,"-","+"));cat("=")
\$\endgroup\$
2
  • 1
    \$\begingroup\$ +1 putting the user guess in the while condition is indeed a good idea! However defining cat as a variable here actually cost you 2 characters: w=cat; (6) + 2 times w are 8 characters while 2 times cat is only 6 characters! :) I think you can also get rid of the curly braces since your while loop now contains only 1 line. \$\endgroup\$
    – plannapus
    Commented Apr 12, 2013 at 13:57
  • \$\begingroup\$ @plannapus Good points! The w= made a lot more sense when I was using write, but your way is better. \$\endgroup\$
    – eykanal
    Commented Apr 12, 2013 at 14:49
2
\$\begingroup\$

C89 92 90 89 (Thanks to @ugoren) 84 characters running on OS and linked with Linker supporting ASLR

main(c,g){g=g/8%100+1;while(scanf("%d",&c)&&printf("%c\n",g-c?"-+"[c<g]:'=')&&c-g);}
\$\endgroup\$
6
  • \$\begingroup\$ I don't think that will produce very random numbers in many OSes, unless address space randomization is turned on. \$\endgroup\$
    – fluffy
    Commented Apr 11, 2013 at 21:05
  • \$\begingroup\$ @fluffy: I already mentioned in my most. And IMHO, all modern OSes except RTOS supports ASLR \$\endgroup\$
    – Abhijit
    Commented Apr 12, 2013 at 2:46
  • \$\begingroup\$ main(c,g) would save int. Or maybe main(g,c), assuming the argument vector is randomized by ASLR. \$\endgroup\$
    – ugoren
    Commented Apr 12, 2013 at 10:14
  • \$\begingroup\$ However, ASLR will not randomize the low bits.The address of main will always be a multiple of 4 (at least). \$\endgroup\$
    – ugoren
    Commented Apr 12, 2013 at 10:15
  • \$\begingroup\$ @ugoren: Yes I agree and so changed my code accordingly. On another context I have not acceoted your edit, cause the particular bahaviour of missing type defaulting to int is not accepted in C99. \$\endgroup\$
    – Abhijit
    Commented Apr 12, 2013 at 10:55
1
\$\begingroup\$

K, 69

b:1b;g:1+*1?100;while[b;-1(*$[g<f:"I"$m:0:0;"-";g>f;"+";("=";b:0b)])]

Could definitely be golfed more

k)b:1b;g:1+*1?100;while[b;-1(*$[g<f:"I"$m:0:0;"-";g>f;"+";("=";b:0b)])]
50
+
75
-
60
+
65
-
63
+
64
=
\$\endgroup\$
1
\$\begingroup\$

Go, 152

Golfed :

package main
import(f"fmt";"os")
func main(){
c:=1+os.Getpid()%100
u:=0
for u!=c{
f.Scanf("%d",&u)
s:="="
if u<c{s="+"}else if u>c{s="-"}
f.Println(s)}}

Ungolfed :

package main

import (
    f "fmt"
    "os"
)

func main() {
    c := 1 + os.Getpid()%100
    u := 0
    for u != c {
        f.Scanf("%d", &u)
        s := "="
        if u < c {
            s = "+"
        } else if u > c {
            s = "-"
        }
        f.Println(s)
    }
}

Session :

guess

4

+

88

-

66

+

77

-

71

+

73

+

75

=

Hard to golf when you start any program with package main and a list of imports...

\$\endgroup\$
1
  • 2
    \$\begingroup\$ But real golf has big bags full of heavy clubs. There are even wheels on the bags. What's more they are "imported" for you by your caddy. And you drive around a big, reserved field in electric carts. Let's not even speak about the annual fee. \$\endgroup\$
    – Kaz
    Commented Apr 12, 2013 at 3:13
1
\$\begingroup\$

R: 88 characters

r=sample(1:100,1);i=scan(n=1);while(i!=r){cat(ifelse(i<r,"+","-"));i=scan(n=1)};cat("=")

Ex:

> r=sample(1:100,1);i=scan(n=1);while(i!=r){cat(ifelse(i<r,"+","-"));i=scan(n=1)};cat("=")
1: 23
Read 1 item
+
1: 46
Read 1 item
-
1: 35
Read 1 item
-
1: 31
Read 1 item
-
1: 28
Read 1 item
+
1: 30
Read 1 item
-
1: 29
Read 1 item
=
>
\$\endgroup\$
1
  • \$\begingroup\$ Look at my answer; this can be shortened by (1) defining a cat variable and (2) defining i in the while loop. You can also use the quiet option to remove the "Read 1 item" notice, but I don't think you can turn off scan's "1:" prompt. \$\endgroup\$
    – eykanal
    Commented Apr 12, 2013 at 12:40
1
\$\begingroup\$

PHP: 95 91 87 73 71 65 chars

<?php $n=rand(1,100);while(@$g!=$n){$g=trim(fgets(STDIN));echo$g==$n?'=':($g>$n?'-':'+')."\n";}
<? for($n=rand(1,100);@$g!=$n?$g=trim(fgets(STDIN)):0;)echo$g==$n?'=':($g>$n?'-':'+')."\n";
<? for($n=rand(1,100);$n!=$g=trim(fgets(STDIN));print(($g>$n?'-':'+')."\n"));echo"=\n";
<? for($n=rand(1,100);$n!=$g=fgets(STDIN);print(($g>$n?'-':'+')."\n"))?>=
<? for($n=rand(1,100);$n!=$g=fgets(STDIN);print($g>$n?'-':'+')."\n")?>=
<?for($n=rand(1,100);$n!=$g=fgets(STDIN);print$g>$n?"-
":"+
")?>=
\$\endgroup\$
3
  • 1
    \$\begingroup\$ 89: <? for($n=rand(1,100);($g=trim(fgets(STDIN)))!=$n;print$g==$n?'=':($g>$n?'-':'+')."\n"); \$\endgroup\$ Commented Apr 12, 2013 at 20:17
  • \$\begingroup\$ You don't need to call trim, since 8 == "8\n". That brings it down to 81 characters: <? for($n=rand(1,100);$n!=$g=fgets(STDIN);print(($g>$n?'-':'+')."\n"));echo"=\n"; \$\endgroup\$ Commented Apr 12, 2013 at 20:57
  • \$\begingroup\$ You can get it down to 73 characters by exiting PHP mode at the end instead of calling echo: <? for($n=rand(1,100);$n!=$g=fgets(STDIN);print(($g>$n?'-':'+')."\n"))?>= \$\endgroup\$ Commented Apr 12, 2013 at 21:51
1
\$\begingroup\$

C: 86 characters

i;main(r){r+=(7*time(0)+3)%100;while(scanf("%d",&i)&&puts(i<r?"+":i>r?"-":"=")&&i-r);}

It is well-behaved, implements a simple LCG and compiles under both Clang (Clang is much more picky than GCC) and GCC.

\$\endgroup\$
1
\$\begingroup\$

R 70

n=sample(1e2)[1];while(n-(g=scan(n=1)))cat(if(n>g)"+"else"-");cat("=")
\$\endgroup\$
1
\$\begingroup\$

VB.net 146

Dim r,g As Integer:Dim s As String:r=New Random().Next(1,100):Do Until g=r:g=InputBox(s):If g<r Then s="+" Else If r=g Then s="-" Else s="=" Loop

\$\endgroup\$
1
  • \$\begingroup\$ Your code will never choose the number "100", it should be Next(1,101) \$\endgroup\$ Commented Aug 10, 2013 at 6:18
1
\$\begingroup\$

Tcl, 96 chars

set n [expr int(rand()*100)+1];while {[gets stdin g]&&$g!=$n} {puts [expr $g<$n?"+":"-"]};puts =

Ok, and now guessing a real number (91 chars):

set n [expr rand()*100+1];while {[gets stdin g]&&$g!=$n} {puts [expr $g<$n?"+":"-"]};puts =

And here a small script to test this: (Solver)

set fd [open "| /usr/local/bin/tclsh hilo.tcl" RDWR]
fconfigure $fd -buffering none
lassign 0\ 100 + -
while 1 {
    puts "-> [set new [expr {(${-} - ${+}) / 2. + ${+}}]]"
    puts $fd $new
    gets $fd in
    puts "<- $in"
    if {$in in {+ -}} {set $in $new} break
}

Change the 2. to 2 for integers.

\$\endgroup\$
0
\$\begingroup\$

Javascript (75 74 chars):

for(n=1+Math.random(a=alert)*100>>0;(g=+prompt())-n;)a('+-'[+(g>n)]);a('=') 
for(n=1+Math.random(a=alert)*100>>0;(g=+prompt())-n;)a(n>g?'+':'-');a('=')

Numbers are actually random

\$\endgroup\$
0
\$\begingroup\$

J: 64 characters

r=.>:?100
while.(t=.{&'<=>'>:*-&r".(1!:1)1)~:'='do.t(1!:2)2 end.t

Doing I/O in J is sort of bulky compared to the rest of the language.

\$\endgroup\$
0
\$\begingroup\$

vbScript 115 110

Randomize:dim n,r,s:r=(Int)((100*Rnd+1)*2):do until(r=n*2):n=inputbox(s):If(n*2>r)Then:s="-":else:s="+":end if:loop

Randomize:dim n,r,s:r=Int(100*Rnd+1)*2:do until r=n*2:n=inputbox(s):If(n*2>r)Then:s="-":else:s="+":end if:loop
\$\endgroup\$
0
\$\begingroup\$

Mathematica 66

n=RandomInteger@100;For[,(i=Input[])!=n,Print@If[n>i,"+","-"]];"="
\$\endgroup\$
0
\$\begingroup\$

GWBASIC, 104

1 RANDOMIZE TIMER:Z=INT(RND*100)+1:WHILE Q<>Z:INPUT Q:IF Q<Z THEN ?"+" ELSE IF Q>Z THEN ?"-"
2 WEND:?"="

(just because I can)

\$\endgroup\$
0
\$\begingroup\$

vba, 95

(immediate window)

randomize:z=int(rnd()*100)+1:while q<>z:q=cint(inputbox(q)):?iif(q<z,"+",iif(q>z,"-","=")):wend
\$\endgroup\$
1
  • \$\begingroup\$ You can use Int instead of CInt. ;-) \$\endgroup\$
    – Gaffi
    Commented Apr 15, 2013 at 21:45

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