Diffing "Compacter_speed" and "Compacter_speed2"

Title: Compacter_speed Compacter_speed2
Author: Heinrich Acker Heinrich Acker
Submitted: 2001-09-20 13:27:02 UTC 2001-09-20 13:47:54 UTC
Status: Passed Passed
Score: 1275.23 1784.44
Result:  62.94,  37.06 (80.19 taken)  28.50,  71.50 (93.49 taken)
CPU Time: 120.263 50.793
Code:
function finalAnswer = solver(numPegs,numColors,guessLimit,puzzleID)

[cs,numCallsMade,fr,finalAnswer,lsr]  =  findcols(numPegs,numColors,guessLimit,puzzleID);

if lsr>= numPegs | numCallsMade>= guessLimit | isempty(cs)
    return; 
end

[rows,cols] = size(cs); % to cancel consequentive calls to size().

% for i = 1:size(cs,1)
 for i = 1:rows
    [ind,numCallsMade]  =  ffc(finalAnswer,fr,cs(i,2),cs(i,1),lsr,guessLimit,puzzleID); 
    finalAnswer(fr(ind)) = cs(i,1); 
    fr(ind) = [];
    if numCallsMade >=  guessLimit, 
        for j = i+1:rows
            finalAnswer(fr(1:cs(j,2))) = cs(j,1); 
            fr = fr(cs(j,2)+1:end); 
        end; 
        return; 
    end;
    lsr = lsr + cs(i,2); 
    if lsr >= numPegs, 
        return; 
    end; 
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ind,numCallsMade] = ffc(gs,x,n,col,b0,gsLim,puzzleID)
if length(x) == n, 
    ind = 1:n; 
    numCallsMade = 0; 
    return; 
end;
if (length(x)<14) & (n~= 1)
    [ind,numCallsMade]  =  ffclp(gs,x,n,col,b0,gsLim,puzzleID);
    return;
end
i = floor(length(x)/2); 
g = gs; 
g(x(1:i)) = col; 
[black,white,numCallsMade]  =  scoreme(g,puzzleID);
nv = n-black+b0;
if black>b0, 
    if numCallsMade>= gsLim, 
        ind = [1:black-b0,(i+1:i+nv)]; 
        return; 
    end;
    [i1,numCallsMade] = ffc(gs,x(1:i),black-b0,col,b0,gsLim,puzzleID);
    if numCallsMade>= gsLim, 
        ind = [i1,(i+1:i+nv)]; 
        return; 
    end
elseif numCallsMade>= gsLim, 
    ind = i+1:i+nv; 
    return;
else
    i1 = [];
end
if nv, 
    [i2,numCallsMade] = ffc(gs,x(i+1:end),nv,col,b0,gsLim,puzzleID); 
    i2 = i2+i;
else
    i2 = []; 
end;

ind = [i1 i2];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [cs,numCallsMade,fr,a,lsr] = findcols(numPegs,numColors,guessLimit,puzzleID)
fr = 1:numPegs; 
cs = zeros(numColors,2); 
a = ones(1,numPegs); 
T = 0; 
j = 0; 
k = 1; 
lsr = 0; 
l = 1; 
mc = 0;
for i = 1:numColors-1
    a(fr) = i;
    if l<= j
        a(fr(k)) = cs(l,1);   
        [black,white,numCallsMade] = scoreme(a,puzzleID); 
        black = black + white - 1 - lsr;
        if white
            if white>1
                a(fr(k)) = i; 
                fr(k) = []; 
                lsr = lsr + 1; 
                black = black - 1; 
                T = T + 1;
            else
                k = k + 1;
            end
        else
            fr(k) = []; 
            cs(l,2) = cs(l,2)-1; 
            lsr = lsr+1;
            if cs(l,2)==0
                mc = cs(l,1); 
                l = l+1; 
                k = 1; 
            end; 
        end;
    else
        [black,white,numCallsMade] = scoreme(a,puzzleID); 
        black = black-lsr;
    end
    if black, 
        j = j+1; 
        cs(j,:) = [i,black]; 
        T = T+black;
    else
        mc = i;
    end
    if numCallsMade>= guessLimit | T>= numPegs, 
        break; 
    end;
end 
j = j+1; 
cs(j,:) = cat(2,numColors,numPegs-T); 
%cs(j,:) = [numColors,numPegs-T]; 


if numPegs == 1, 
    a = cs(1,1); 
    lsr = 1; 
    return; 
end;
cs = cs(l:j,:); 
if isempty(cs), 
    lsr = numPegs; 
    return;
elseif size(cs,1) == 1; 
    a(fr) = cs(1,1); 
    lsr = numPegs; 
    return;
end
if numCallsMade>= guessLimit, 
    j = 1;
    for i = 1:size(cs,1)
        a(fr(j:j+cs(i,2)-1)) = cs(i,1); 
        j = j+cs(i,2);
    end
    lsr = numPegs; 
    return;
end
if mc, 
    a(fr) = mc; 
    [i,j] = sort(-cs(:,2)); 
    cs = cs(j,:);
else
    cs = cs([2 1 3:end],:); 
    i = k; n1 = cs(1,2); 
    n2 = cs(2,2); 
    c1 = cs(1,1); 
    c2 = cs(2,1); 
    a(fr) = c1;
    while n2
        a(fr(i)) = c2; 
        [black,white,numCallsMade] = scoreme(a,puzzleID);
        if white==0 
            fr(i) = []; 
            n2 = n2-1; 
            lsr = lsr+1;
        else
            a(fr(i)) = c1; 
            i = i+1;
        end
        if numCallsMade>= guessLimit, 
            a(fr(1:n2)) = c2; 
            fr = fr(n2+1:end); 
            for i = 3:size(cs,1)
                a(fr(1:cs(i,2))) = cs(i,1); 
                fr = fr(cs(i,2)+1:end); 
            end;
            lsr = numPegs; 
            return; 
        end; 
    end; 
    a(fr) = c2; 
    cs(2,:) = []; 
    [i,j] = sort(-cs(:,2)); 
    cs = cs([j(end);j(1:end-1)],:);
    if size(cs,1) == 1, 
        a(fr) = cs(1,1); 
        lsr = numPegs; 
    end;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ind,numCallsMade] = ffclp(gs,index,n,cl,b0,guessLimit,puzzleID)
persistent guessesCache
numCallsMade = 0;
l = length(index);
if isempty(guessesCache) | length(guessesCache) < l | isempty(guessesCache{l})
   twoexp = 1;
   guesses = zeros(1, 0);
   for i = 1:l
      guesses = [guesses zeros(twoexp, 1);guesses ones(twoexp, 1)];
      twoexp = twoexp * 2;
   end;
   guessesCache{l} = guesses; 
else
   guesses = guessesCache{l};
end
answers = guesses(find(sum(guesses,2) == n),1:l)';
count = 0;
while (size(answers,2)~= 1) & (numCallsMade<guessLimit)
    count = count+1;
    if count == 1
    if count
        bestguess = (1:l)>l/2;
    elseif count == 2
        bestguess = ((1:l)<= round(l/4))+((1:l)>round(3*l/4));
    else
        [m,bestguessn] = min(sum(histc(guesses*answers,0:n,2).^2,2));
        bestguess = guesses(bestguessn,1:l);
    end
    g = gs; g(index(find(bestguess))) = cl;
    [black,white,numCallsMade] = scoreme(g,puzzleID);
    answers = answers(1:l,find(bestguess*answers == black-b0));
end
ind = find(answers(1:l,1+floor(rand(1)*size(answers,2))))';