too long have programs been made that make user guess some number. it's time to switch the roles up - now the user will think of an integer between 1 and 100 (inclusive), and your program will guess the number!
while any language is allowed, a number of standard interfaces are proposed. in functional languages, such as C and Python, one could define a procedure that accepts a closure as an argument, which the procedure calls with an integer to submit its guesses, and the closure returns, as an integer, the result: -1 if the guess is too low, 1 if the guess is too high, or 0 if the guess is spot on. closure can be called multiple times, until a guess is found. the sigmature would look like this in C:
void entry(int (*submit)(int, void*), void *data) {
int result = submit(42, data);
// ...
}
or in Python:
def entry(submit):
result = submit(42)
// ...
similar pattern should be adaptable to other languages. if not, there is an alternate interface. instead, you can communicate with the user via the standard IO streams. simply print the guess on its own line using ASCII digits to stdout, then read a line from stdin: it will spell "LOW" (no quotes) if your guess is too low, "HIGH" if your guess is too high, "WIN" if your guess is spot on. rinse and repeat until WIN.
if neither standard interface works for your language or you just don't like to implement it, you are free to invent your own interface.
your challenge, given a procedure, write a program that guesses a number between 1 and 100. any language is allowed, there is an API.
# the actual value the program is looking for (we pretend that the guess function is unaware of this variable)TRUE_VALUE=$(($(ddif=/dev/urandomcount=12>/dev/null|cksum|cut-d' '-f1)%100))# $1 should be the guess# using echo as return is for little skibidi toilets, hence im using error codes# (this function is implemented for testing purposes)
submit(){echo"guess: $1"# Too bigif(($1<TRUE_VALUE));thenreturn-1# overflows to 255elif(($1>TRUE_VALUE));thenreturn1elif[[$1-eq$TRUE_VALUE]];thenreturn0elsewhiletrue;doprintf"crazy? i was crazy once. they put me in a room. a rubber room. a rubber room with rats. the rats made me ..."donefi}
guess(){# I was initially planning to do a perfectly suboptimal search (binary search, but guessing all values in the wrong direction before proceeding), but then it occurred to me... i couldn't be botheredforiin{0..100};dosubmit$iif[[$?-eq"0"]];thenecho"welp that was fun, im off"return0fidone}
guess
// guesser#include<limits.h>#include<stddef.h>#include<stdlib.h>#include<fcntl.h>#include<unistd.h>#include"code.h"staticunsignedcharrandbyte();staticvoidmemrand(void*buf,size_tsize);staticintlimrand(intmin,intmax);structguesser_data{intmin;intmax;struct{guess_submit_closurefn;void*data;}submit;void(*print)(constchar*);};staticvoiddefault_print(constchar*msg){}staticvoidinit_guesser_data(structguesser_data*data,guess_submit_closuresubmit,void*submit_data){data->min=INT_MIN;data->max=INT_MAX;data->submit.fn=submit;data->submit.data=submit_data;data->print=default_print;}staticvoidguesser_basic(structguesser_data*data);staticvoidguesser_extended(structguesser_data*data);staticvoidwhoppenheimer(structguesser_data*data);voidentry(guess_submit_closuresubmit,void*data){structguesser_dataguesser_data;init_guesser_data(&guesser_data,submit,data);guesser_basic(&guesser_data);}voidguesser_basic(structguesser_data*data){while(1){intmin=data->min<1?1:data->min;intmax=data->max>100?100:data->max;intnum=limrand(min,max);intresult=data->submit.fn(num,data->submit.data);if(result==0){return;}if(((num==data->min)&&result>0)||(num==data->max&&result<0)){returnwhoppenheimer(data);}if(result<0){data->min=num+1;}elseif(result>0){data->max=num-1;}if((num==1&&result>0)||(num==100&&result<0)){data->print("Hmm, that's not right. Are you sure the number is between 1 and 100?");returnguesser_extended(data);}}}voidguesser_extended(structguesser_data*data){while(1){intmin=data->min;intmax=data->max;intnum=limrand(min,max);intresult=data->submit.fn(num,data->submit.data);if(result==0){return;}if(((num==data->min)&&result>0)||(num==data->max&&result<0)){returnwhoppenheimer(data);}if(result<0){data->min=num+1;}elseif(result>0){data->max=num-1;}}}#if (__GNUC__ > 4)typedefunsigned__int128whoppentype;#elsetypedefstruct{longlonga,b;}whoppentype;#endifvoidwhoppenheimer(structguesser_data*data){whoppentypeguess;memrand(&guess,sizeof(guess));data->print("There is no number that satisfies all this, you must be messing with me. Goodbye.");// lets see how you like THAT, huh((int(*)(whoppentype,void*))data->submit.fn)(guess,data->submit.data);abort();}unsignedcharrandbyte(){staticunsignedcharbytes[256];staticintpos=sizeof(bytes);staticintrandfd=-1;if(randfd==-1){randfd=open("/dev/urandom",O_RDONLY);}if(randfd==-1){abort();}if(pos>=sizeof(bytes)){if(read(randfd,bytes,sizeof(bytes))!=sizeof(bytes)){abort();}pos=0;}returnbytes[pos++];}voidmemrand(void*buf,size_tsize){unsignedchar*p=buf;unsignedchar*pend=buf+size;for(;p<pend;++p){*p=randbyte();}}intlimrand(intmin,intmax){unsignedintlimit=(unsignedint)max-(unsignedint)min;unsignedintlimit2;unsignedintnum=0;if(limit==UINT_MAX){memrand(&num,sizeof(num));returnmin+num;}if(limit==0){returnmin;}limit2=limit;limit2|=limit2>>1;limit2|=limit2>>2;limit2|=limit2>>4;limit2|=limit2>>8;#if (UINT_WIDTH > 16)limit2|=limit2>>16;#endif#if (UINT_WIDTH > 32)#error int type is too big#endiflimit2++;do{num=0;unsignedintlimit3=limit2-1;while(limit3){limit3>>=8;num<<=8;num^=randbyte();}num&=limit2-1;}while(num>limit);returnmin+num;}
#include<stdio.h>#include<string.h>#include"code.c"voidreal_print(constchar*msg){fprintf(stderr,"%s\n",msg);}intsubmit_io_guess(intnum,void*data){if(*((int*)data)!=42){abort();}fprintf(stderr,"\nMy guess is: ");fflush(stderr);fprintf(stdout,"%d\n",num);fflush(stdout);while(1){charbuf[64];fprintf(stderr,"? ");fflush(stderr);if(!fgets(buf,sizeof(buf),stdin)){exit(1);}if(buf[strlen(buf)-1]=='\n'){buf[strlen(buf)-1]='\0';}if(strcmp(buf,"HIGH")==0){return1;}elseif(strcmp(buf,"LOW")==0){return-1;}elseif(strcmp(buf,"WIN")==0){return0;}fprintf(stderr,"My guess is %d. Type \"LOW\" if too LOW, \"HIGH\" if too high, \"WIN\" if correct. No quotes or spaces.\n",num);}}intmain(){if(!isatty(STDOUT_FILENO)){if(!freopen("/dev/null","w",stderr)){return1;}}fprintf(stderr,"Think of a number between 1 and 100.\n");fprintf(stderr,"I will guess the number.\n");fprintf(stderr,"If my guess is too low, type \"LOW\".\n");fprintf(stderr,"If my guess is too high, type \"HIGH\".\n");fprintf(stderr,"If my guess is correct, type \"WIN\", and the game will end.\n");structguesser_dataguesser_data;intcookie=42;init_guesser_data(&guesser_data,submit_io_guess,(void*)&cookie);guesser_data.print=real_print;guesser_basic(&guesser_data);}
# hello worlddefentry(submit):yinmn=1guess=0trout=0whilesubmit(guess)-1:guess+=yinmnyinmn+=yinmn# print(guess)whiletrout:=submit(guess):yinmn/=2guess-=yinmn*trout# print(guess)returnguess# challenge = lambda N: lambda n: -1 if n < N else 1 if n > N else 0
HAI 1.2
I HAS A MAX ITZ 101
I HAS A MIN ITZ 0
I HAS A USERIN
I HAS A GUESS
IM IN YR GAMELOOP
GUESS R QUOSHUNT OF SUM OF MAX AN MIN AN 2
VISIBLE GUESS
GIMMEH USERIN
BOTH SAEM USERIN AN "WIN"
O RLY?
YA RLY
GTFO
MEBBE BOTH SAEM USERIN AN "LOW"
MIN R GUESS
MEBBE BOTH SAEM USERIN AN "HIGH"
MAX R GUESS
OIC
IM OUTTA YR GAMELOOP
KTHXBYE
post a comment