ID:45666
Title:simplesearch2
Author:Will
Date:2008-04-30 15:46:24
Score:25397.3313
Result:253903.00 (cyc: 12, node: 609)
CPU Time:11.9026
Status:Passed
Comments:
Based on:none
Code:
function W = solver(B)
W = zeros(0,4);

%shift everything avoid boundry conditions
thisMat = zeros(size(B)+2);
thisMat(2:end-1,2:end-1)=B;

wiredMat = thisMat;


pegs = unique(nonzeros(thisMat));

IJpairs = arrayfun(@FindPossiblePairs,pegs,'uniformoutput',false);

IJmat = cell2mat(IJpairs);

[bestScores inds] = sort(abs(IJmat(:,1)-IJmat(:,3)) + abs(IJmat(:,2)-IJmat(:,4)) - 2*IJmat(:,5),'ascend');



for MainCounter = 1:length(bestScores)

    testedMove = FindShortestPath(IJmat(inds(MainCounter),:));
    
    if ~isempty(testedMove) && size(testedMove,1)<2*IJmat(inds(MainCounter),5)
        %thisVal=IJmat(inds(MainCounter),5);
        
        wiredMat(testedMove(:,1),testedMove(:,2))=1;
        W=[W;testedMove];
    end
end

%shift everything back
W=W-1;

    function Moves = FindShortestPath(Pos)
        allotedMoves=2*Pos(5);
        %since order is unimportant, always create paths with ascending
        %numbers for easy of programming
        if Pos(1) < Pos(3) || Pos(1) == Pos(3) && Pos(2) < Pos(4)
            startPos = Pos(1:2);
            endPos = Pos(3:4);
        else
            startPos = Pos(3:4);
            endPos = Pos(1:2);
        end
        
        Moves = zeros(allotedMoves,4);
        thiscounter = 0;
        currentPos = startPos;

        while (thiscounter<allotedMoves)
            thiscounter=thiscounter+1;
            Moves(thiscounter,1:2)=currentPos;
            currentDist=sum(abs(currentPos-endPos));
            thisMove = repmat(currentPos,[2,1])+eye(2);
            thisDist = sum(abs(thisMove - repmat(endPos,[2,1])),2);
            if any(thisDist==0)
                Moves(thiscounter,3:4)=thisMove(thisDist==0,:);
                break
            end

            if (~wiredMat(thisMove(1,1),thisMove(1,2)) && thisMat(thisMove(1,1),thisMove(1,2)) ~= Pos(5)) && thisDist(1)<currentDist
                Moves(thiscounter,3:4)=thisMove(1,:);
            elseif (~wiredMat(thisMove(2,1),thisMove(2,2)) && thisMat(thisMove(2,1),thisMove(2,2)) ~= Pos(5)) && thisDist(2)<currentDist
                Moves(thiscounter,3:4)=thisMove(2,:);
            else
                thiscounter=0;
                break
            end

            currentPos = Moves(thiscounter,3:4);
            
        end
        %if counter was reset to 0 then Moves will be empty
        Moves = Moves(1:thiscounter,:);
        return
        
        
    end

    function Pairs = FindPossiblePairs(Value)
        [thisI thisJ] = find(thisMat==Value);
        if length(thisI)==1
            Pairs=[];
            return
        end
        Pairs = zeros(ceil((length(thisI)+1)*(length(thisI)/2)),5);
        Pairs(:,5)=Value;
        counter=1;
        for k=1:length(thisI)
            mask = (1:length(thisI))>k;
            Pairs(counter:counter+nnz(mask)-1,1:2)=repmat([thisI(k) thisJ(k)],[nnz(mask) 1]);
            Pairs(counter:counter+nnz(mask)-1,3:4)=[thisI(mask) thisJ(mask)];
            counter=counter+nnz(mask)-1;
        end
        
        Pairs=Pairs(1:counter+1,:);
        
    end


end