ID:45665
Title:seems ok
Author:JamesT
Date:2008-04-30 15:31:01
Score:27974.3363
Result:279708.00 (cyc: 6, node: 616)
CPU Time:5.6781
Status:Passed
Comments:
Based on:none
Code:
function W = solver(B)
W = [];
% lets find the biggest group
usedNodes = ones(size(B)+[2 2]);
usedNodes(2:end-1, 2:end-1) = B>0;


avail = unique(B(:));

scores = zeros(size(avail));
for i = 1:length(avail)
    scores(i) = sum(sum(B(B==avail(i))));
end

[C,I] = sort(scores);

for j = (length(scores)-1):(-1):2
[row, col] = find(B==avail(I(j)));
currentUsed = ones(size(usedNodes));
currentUsed(2:end-1, 2:end-1) = (B==avail(I(j)));

for i = 1:(sum(sum(B==avail(I(j))))-1);
    % find the nearest, make a path to it, remove previous
    [dummy nearest] = min((row(2:end) - row(1)).^2 + (col(2:end) - col(1)).^2);
    from = [row(1) col(1)];
    to = [row(1+nearest) col(1+nearest)];

    temp = usedNodes;
    temp(2:end-1,2:end-1) = temp(2:end-1,2:end-1) - currentUsed(2:end-1,2:end-1);
    [newW currentUsed] = makePath(from, to, temp, currentUsed);
    if isempty(newW)
        break;
    end
    
    row = row(2:end);
    col = col(2:end);
    
    W = [W ; newW];
    usedNodes = usedNodes|currentUsed;
end
end

if isempty(W)
    W  = zeros(0,4);
end


function [W currentUsed] = makePath(from, to, usedNodes, currentUsed)
newW = takeStep(from, to, usedNodes);
W = newW;
while ~isempty(newW) && ~all(newW(3:4)==to) % still a move but have not hit destination
    newW = takeStep(newW(3:4), to, usedNodes);
    W = [W ; newW];
    if size(W,1)>50   
        W = [];
        return;
    end
end
if isempty(newW)
    W = [];
else
    currentUsed(sub2ind(size(currentUsed),W(:,3)+1,W(:,4)+1)) = true;
end

function newW = takeStep(from, to, usedNodes)
% only 4 possible steps
moves = [];
if ~usedNodes(from(1), from(2)+1) 
    moves = [moves ; from(1)-1, from(2)];
end
if ~usedNodes(from(1)+1, from(2)) 
    moves = [moves ; from(1), from(2)-1];
end
if ~usedNodes(from(1)+2, from(2)+1) 
    moves = [moves ; from(1)+1, from(2)];
end
if ~usedNodes(from(1)+1, from(2)+2) 
    moves = [moves ; from(1), from(2)+1];
end
if isempty(moves)
    newW = [];
else
    dist = (moves(:,1)-to(1)).^2 + (moves(:,2)-to(2)).^2;
    [dummy, I] = min(dist);
    newW = [from moves(I,:)];
end