Finish 2010-11-17 12:00:00 UTC

CaptainNeedsSleep

by Leendert Combee

Status: Passed
Results: 18187 (cyc: 7, node: 870)
CPU Time: 20.534
Score: 3638.33
Submitted at: 2010-11-12 02:36:10 UTC
Scored at: 2010-11-12 02:37:23 UTC

Current Rank: 2129th (Highest: 20th )

Comments
Please login or create a profile.
Code
function [thrustRow, thrustCol] = solver(chart, aIndex, bIndex, maxThrottle)

[nr,nc,dummy] = size(chart);
rw = reshape(chart(:,:,1),nr,nc);                % row winds 
cw = reshape(chart(:,:,2),nr,nc);                % colum winds
sp = aIndex;  [spr,spc]=ind2sub([nr nc],sp);     % start 
ep = bIndex;  [epr,epc]=ind2sub([nr nc],ep);     % end

%-- make a throttle matrix
mxt = maxThrottle;
thr = [-mxt:mxt]'*ones(1,2*mxt+1);
thc = ones(2*mxt+1,1)*[-mxt:mxt];
th  = [thr(:)';thc(:)'];
id  = find(sum(abs(th))<=mxt); th=th(:,id);       % possible throttles at any
X1  = [0.4 0.6 0.7]'*ones(1,3);
X2  = ones(3,1)*[0.4 0.6 0.7];
X   = [X1(:)';X2(:)'];
W   = ones(1,9);

score0=1e30; done=0; isc=1; nsc=0;                % loop over a number of possibilities
while ~done,                                      % and we pick the best until no more
   ni  = 1; tR=[]; tC=[];                         % improvement
   zz  = []; for kk=1:9, zz=[zz kk*ones(1,W(kk))]; end;
   ix  = zz(ceil(rand*length(zz)));
   x1  = X(1,ix); x2 = X(2,ix);
  
   [tR,tC,ri,ci,vRi,vCi,ni,dA] = trackpath(epr,epc,spr,spc,0,0,rw,cw,th,ni,tR,tC,x1,x2);
   [tR,tC,ri,ci,vRi,vCi,ni,dB] = trackpath(spr,spc,ri,ci,vRi,vCi,rw,cw,th,ni,tR,tC,x1,x2);
   score = dA + dB + sum(abs(tR)) + sum(abs(tC));
   if score<score0,
     score0 = score; dA0 = dA; dB0 = dB; VV=sum(abs(tR)) + sum(abs(tC));
     thrustRow = tR;
     thrustCol = tC;
     nsc=0; W(ix)=W(ix)+1; 
    else 
     nsc=nsc+1;
    end;
    isc = isc+1; 
    done=(isc>44 | nsc>18); 
 end;  
% [dA0 dB0 VV]
 return;


function [tR,tC,ri,ci,vRi,vCi,ni,dT] = trackpath(tr,tc,ri,ci,vRi,vCi,rw,cw,th,ni,tR,tC,x1,x2)

 done=(ni>999);                                  % check if already done
 [nr,nc] = size(rw);                             % get dimensions
 ts = sum(abs(th));                              % throttle used for each possible move
 di = (ri-tr)^2 + (ci-tc)^2;                     % initial distance to target
 
 while ~done,                                    % start tracking loop

   dRw = rw(ri,ci); vR=vRi+dRw;                  % movement without throttle
   dCw = cw(ri,ci); vC=vCi+dCw;                  % movement without throttle
   vRp = vR + th(1,:);                           % add possible throttles
   vCp = vC + th(2,:);                           % add possible throttles
   
   rn  = ri + vRp;                               % possible next positions                           
   cn  = ci + vCp;                                
   
   %-- eliminate those that go out of board
   
   id = find(rn>0 & rn<=nr & cn>0 & cn<=nc);     % possible moves
   len = length(id);                             % 
   if len==0,                                    % cannot move, stop here
      done = 1;
   else                                          % can still move
     dn  = (rn(id)-tr).^2 + (cn(id)-tc).^2;      % distances
     ts0 = find(ts(id)==0);                      % a move without using throttle
     if isempty(ts0)                             % not possible
       ts0 = len+1; dn(ts0)=1e30;
     end;
   
     %-- if zero throttle brings us closer, use
     
     choice = pickstep(di,dn,ts(id),ts0,x1,x2);     
     di = dn(choice);
     choice = id(choice);
   
   %-- move to new square, update variables
     rin = rn(choice);
     cin = cn(choice);
     pi = sub2ind([nr nc],rin,cin);
     vRi = vRp(choice);
     vCi = vCp(choice);
     tR=[tR; th(1,choice)];
     tC=[tC; th(2,choice)];
   
     if rin==ri & cin==ci, done=1; else ri=rin; ci=cin; end;  
     ni   = ni+1;
end;
done = done | (ni>999) | (di<=15);  %
end;
dT = di;
return;




function choice = pickstep(di,dn,ts,ts0,x1,x2)
   
if dn(ts0)<di & rand>x1,
   choice=ts0;    
else
   if dn(ts0)<di, dn(ts0)=1e30;  end;         % make sure this one doesn't get picked!
   jd=find(dn<di);                            % which ones get closer
              
   if ~isempty(jd) & rand>x2,                 % find the one with least thrust
       
 [mnv,loc] = min(ts(jd));      choice = jd(loc);
   elseif rand>0.1                            
      [mnv,choice] = min(dn);                 % the one gets closest      
   else
      choice = ceil(rand*length(ts));
   end;  
end;
return;