Finish 2012-04-11 12:00:00 UTC

Interstate 9

by Nicholas Howe

Status: Passed
Results: 142698 (cyc: 7, node: 1251)
CPU Time: 92.722
Score: 14575.7
Submitted at: 2012-04-05 04:46:18 UTC
Scored at: 2012-04-05 04:48:58 UTC

Current Rank: 1069th (Highest: 1st )
Based on: Route 9S Bypass Repair (diff)
Basis for: Replicate 13 (diff)

Comments
Please login or create a profile.
Code
function [board,orientation] = interstate9(tiles,boardSize)

nt = size(tiles,1);
side = ceil(sqrt(nt));
if (side<min(boardSize))
    board = zeros(boardSize);
    [board(1:side,1:side),orientation] = internal(tiles,[side side]);
else
    [board,orientation] = internal(tiles,boardSize);
end;
end

function [board,orientation] = internal(tiles,boardSize)
% set up routes
nb = prod(boardSize);
nrow = boardSize(1);
ncol = boardSize(2);
route{1} = reshape(1:nb,nrow,ncol);  % down first
r = reshape(1:nb,ncol,nrow)';
[~,route{2}] = sort(r(:));  % across first
[~,route{3}] = sort(rand(1,nb));  % random
sp = spiralPath(nrow,ncol);
[~,route{4}] = sort(-sp(:));  % spiral in
[~,route{5}] = sort(sp(:));  % spiral out
dp = diagPath(nrow,ncol);
[~,route{6}] = sort(-dp(:));  % diagonal
dp2 = diagPath2(nrow,ncol);
[~,route{7}] = sort(-dp2(:));  % diagonal
sqp = squarePath(nrow,ncol);
[~,route{8}] = sort(sqp(:));  % square
sqp2 = squarePath2(nrow,ncol);
[~,route{9}] = sort(sqp2(:));  % square


nr = numel(route);
B = cell(1,nr);
O = cell(1,nr);
E = zeros(1,nr);
for i = 1:nr
    [B{i},O{i},E(i)] = routesolve(tiles,boardSize,route{i});
    if (E(i)==0)
        board = B{i};
        orientation = O{i};
        return;
    end;
end;
[~,i] = min(E);
board = B{i};
orientation = O{i};
end

function [board,orientation,err] = routesolve(tiles,boardSize,route)

nt = size(tiles,1);
board = zeros(boardSize);
nb = numel(board);
nrow = boardSize(1);
ncol = boardSize(2);
orientation = ones(nt,1);

unused = true(1,nt);
rt{4} = circshift(tiles,[0 1]);
rt{3} = circshift(tiles,[0 2]);
rt{2} = circshift(tiles,[0 3]);
rt{1} = tiles;
goalN = nan(boardSize);
goalN(1,:) = 0;
goalS = nan(boardSize);
goalS(end,:) = 0;
goalE = nan(boardSize);
goalE(:,end) = 0;
goalW = nan(boardSize);
goalW(:,1) = 0;
tsum = sum(tiles,2);
err = sum(tsum);

% greedily pick tiles
for ii = 1:min(nb,nt)
    i = route(ii);
    goal = [goalN(i),goalE(i),goalS(i),goalW(i)];
    for j = 1:4
        hd = bsxfun(@minus,rt{j}(unused,:),goal);
        hd(isnan(hd)) = 0;
        hs{j} = sum(abs(hd),2);
    end;
    hsm = cat(2,hs{:});
    hsm(hsm~=min(hsm(:))) = inf;
    hsm = bsxfun(@minus,hsm,tsum(unused));
    [~,pick] = min(hsm(:));
    [pick,ori] = ind2sub([nt-ii+1,4],pick);
    pick = find(unused,pick);
    pick = pick(end);
    board(i) = pick;
    orientation(pick) = ori;
    unused(pick) = false;
    
    % update goals
    if (i+nrow <= nb)
        goalW(i+nrow) = rt{ori}(pick,2);
    end;
    if (mod(i,nrow) ~= 0)
        goalN(i+1) = rt{ori}(pick,3);
    end;
    if (i-nrow >= 1)
        goalE(i-nrow) = rt{ori}(pick,4);
    end;
    if (mod(i-1,nrow) ~= 0)
        goalS(i-1) = rt{ori}(pick,1);
    end;
    
    % update err
    play = rt{ori}(pick,:);
    set = ~isnan(goal);
    err = err+sum(abs(play(set)-goal(set)))-sum(play(set))-sum(goal(set));
end;
end


function fitloc = spiralPath(nrow,ncol)
ntot = nrow*ncol;
xg = repmat(1:ncol,nrow,1);
yg = repmat((1:nrow)',1,ncol);
pos = reshape(1:ntot,nrow,ncol);
nextfit = 1;
steps = 0;
radius = ceil((nrow+ncol)/12);
tops = inf;
avail = true(nrow,ncol);
sqrad = max(abs(xg-ncol/2),abs(yg-nrow/2));
%th = mod(atan2(yg-nrow/2,xg-ncol/2)+pi/2-4*pi./(sqrad+2).^2,2*pi);
th = atan2(yg-nrow/2,xg-ncol/2);
%[~,fitloc] = sort(sqrad(:)+th(:)/8);
fitn = 0;
fitloc = zeros(nrow,ncol);
for i = reshape(unique(sqrad),1,[]);
    xmp = find(sqrad==i,1);
    ring1 = find((sqrad==i)&(th>th(xmp)));
    [~,r] = sort(th(ring1));
    fitloc(ring1(r)) = fitn+1:fitn+numel(ring1);
    fitn = fitn+numel(ring1);
    ring2 = find((sqrad==i)&(th<=th(xmp)));
    [~,r] = sort(th(ring2));
    fitloc(ring2(r)) = fitn+1:fitn+numel(ring2);
    fitn = fitn+numel(ring2);
end;
%[~,sp] = sort(fitloc(:));
end


function dp = diagPath(nrow,ncol)
ntot = nrow*ncol;
xg = repmat(1:ncol,nrow,1);
yg = repmat((1:nrow)',1,ncol);
dp = (xg+yg)+xg./ntot.^2;
end

function dp = diagPath2(nrow,ncol)
ntot = nrow*ncol;
xg = repmat(1:ncol,nrow,1);
yg = repmat((1:nrow)',1,ncol);
dp = (xg-yg)+xg./ntot.^2;
end

function sqp = squarePath(nrow,ncol)
ntot = nrow*ncol;
xg = repmat(1:ncol,nrow,1);
yg = repmat((1:nrow)',1,ncol);
sqp = max(xg,yg)+xg./ntot.^2+yg./ntot.^3;
end

function sqp = squarePath2(nrow,ncol)
ntot = nrow*ncol;
xg = repmat(1:ncol,nrow,1);
yg = repmat((1:nrow)',1,ncol);
sqp = max(ncol-xg+1,yg)+xg./ntot.^2+yg./ntot.^3;
end