function z=guessgame(isleq,n,k)
% z=guessgame(isleq,n,k)
%
% Integer guessing 'game' for a function isleq that returns true for all
% values less than or equal to a mystery number
%
% in tertiary function notation:
%
% guess(n,k) =
% | k==0 :: isleq(n) ? n : n+1;
% | k>0 :: isleq(n+(2^k)-1) ? guess(n,k-1) : guess(n+2^k,k-1);
% | k<0 :: isleq(n+(2^(-k))-1) ? guess(n,(-k)-1) : guess(n+(2^(-k)),k-1);
%
% guess(n,-k) for -k negative refers to an unbounded search [n,inf] with
% current search depth up to (n+2^(-k)-1)
% e.g. guess(15,-4) denotes [15,30]
%
% guess(n,k) for k positive refers to a search over the interval [n,(n+(2^(k+1))-1)]
% e.g. guess(63,5) denotes [63,126]
%
% Author: Adam W. Gripton (a.gripton -AT- hw.ac.uk) 2012/03/21
%
if isnumeric(isleq)
isleq=@(p) p>=isleq;
end
if nargin<=2 || isempty(k)
k=-1;
end
k=fix(k(1));
if nargin<=1 || isempty(n)
n=1;
end
%n=max(1,floor(abs(n(1))));
n=fix(n);
%disp([n,k])
fprintf('(n,k) = (%d,%d) : ',n,k);
if k==0
fprintf('searching over [%d,%d]\n',n,n+1);
if isleq(n)
fprintf('found at [%d]\n',n);
z=n;
else
fprintf('found at [%d]\n',n+1);
z=n+1;
end
elseif k>0
fprintf('searching over [%d,%d]\n',n,(n+(2^(k+1))-1));
if isleq(n+(2^k)-1)
z=guessgame(isleq,n,k-1);
else
z=guessgame(isleq,n+(2^k),k-1);
end
elseif k<0
fprintf('searching over [%d,Inf] with depth up to %d\n',n,(n+2^(-k)-1));
if isleq(n+(2^(-k))-1)
z=guessgame(isleq,n,(-k)-1);
else
z=guessgame(isleq,n+(2^(-k)),k-1);
end
end