ID:45815
Title:OnlyLines.
Author:Carlos Prieto
Date:2008-05-01 11:44:00
Score:27921.3468
Result:279145.00 (cyc: 11, node: 863)
CPU Time:13.6956
Status:Passed
Comments:No time for more in darkness.
Based on:none
Code:
function W = solver(B)
W = zeros(0,4);
[r,c]=size(B); % Size of the board
numbers=unique(B); % Numbers in the board
for i=length(numbers):-1:2 % Every number
    [r1,c1]=find(B==numbers(i)); % Positions of current number
    if size(r1,1)==1
        numbers(end)=[];
        continue;
    end
    [rbad,cbad]=find(xor(B>0,B==numbers(i))); % Banned positions;
    rbad=[rbad;W(:,1)]; % First approach. Lines banned
    cbad=[cbad;W(:,2)]; % First approach. Lines banned
    cpos=[r1(1),c1(1)]; % Current position
    W1=line(r,c,r1(2),c1(2),rbad,cbad,cpos);
    W=[W;W1];
end
if isempty(W)
    W = zeros(0,4);
end

function W=line(r,c,r1,c1,rbad,cbad,cpos)
W = zeros(0,4);
nonmoved=[];
while sum(cpos==[r1,c1])<2
    moves=findmoves(r,c,cpos(1),cpos(2),rbad,cbad,r1,c1);
    if isempty(moves) % no possible movements from current position
        if isempty(nonmoved),
            if ~isempty(W)
                W=[];
            end
            break;
        end
        while size(W,1)~=nonmoved(end,3)
            cpos=W(end,1:2);
            W(end,:)=[];
        end
        rbad(end+1)=cpos(1);
        cbad(end+1)=cpos(2);
        W(end+1,:)=[cpos nonmoved(end,1:2)];
        cpos=nonmoved(end,1:2);
        nonmoved(end,:)=[];
    elseif size(moves,1)==1, % Mandatory movement
        rbad(end+1)=cpos(1);
        cbad(end+1)=cpos(2);
        W(end+1,:)=[cpos moves(1,:)];
        cpos=moves(1,:);
    else % Several posibilities
        nonmoved(end+[1:(size(moves,1)-1)],:)=[moves(2:end,:) ...
            ones((size(moves,1)-1),1)*size(W,1)];
        rbad(end+1)=cpos(1);
        cbad(end+1)=cpos(2);
        W(end+1,:)=[cpos moves(1,:)];
        cpos=moves(1,:);

    end
    aa=find(sum(abs([cpos(1)-W(:,1) cpos(2)-W(:,2)]),2)==1);
    if length(aa)>1,
        arround=aa;
        W((arround(1)+1):end,:)=[];
        W(end,3:4)=cpos;
        if ~isempty(nonmoved)
            nonmoved(nonmoved(:,3)>=size(W,1),:)=[];
            if ~isempty(nonmoved)&nonmoved(end,1:2)==cpos
                nonmoved(end,:)=[];
            end
        end
    end
end


% Find possible movements from current position;
function moves=findmoves(r,c,r1,c1,rbad,cbad,r2,c2)

rr=r2-r1;
cc=c2-c1;
% Preferred direction of the movements.
if rr>0
    if cc>0
        if abs(rr)>abs(cc)
            inc=[1 0;0 1;0 -1;-1 0];
        else
            inc=[0 1;1 0;-1 0;0 -1];
        end
    else
        if abs(rr)>abs(cc)
            inc=[1 0;0 -1;0 1;-1 0];
        else
            inc=[0 -1;1 0;-1 0;0 1];
        end
    end
else
    if cc>0
        if abs(rr)>abs(cc)
            inc=[-1 0;0 1;0 -1;1 0];
        else
            inc=[0 1;-1 0;1 0;0 -1];
        end
    else
        if abs(rr)>abs(cc)
            inc=[-1 0;0 -1;0 1;1 0];
        else
            inc=[0 -1;-1 0;1 0;0 1];
        end
    end
end
moves=ones(4,1)*[r1 c1]+inc;
moves=moves(~sum([moves<ones(4,2)|moves>ones(4,1)*[r c]]'),:);
for i=size(moves,1):-1:1,
    if sum(moves(i,1)==rbad & moves(i,2)==cbad)
        moves(i,:)=[];
    end
end