Finish 2011-11-09 12:00:00 UTC

SOC first try _1_

by Alex P.

Status: Passed
Results: 78804145 (cyc: 14, node: 1037)
CPU Time: 4.874
Score: 788091.0
Submitted at: 2011-11-08 23:49:52 UTC
Scored at: 2011-11-08 23:50:09 UTC

Current Rank: 1401st (Highest: 1109th )
Basis for: SOC 3 (diff)

Comments
Please login or create a profile.
Code
function [moves, vine] = solver(board, limit)
% SOLVER moves insides vineS
% sucht anhängend an die Kette gleich die Züge ==> gehen mit in Bewertung
% ein
[rows,cols]=size(board);
dirs = [rows, 1, -rows, -1];
if rows==1 || cols==1; dirs = [1 -1]; end

%[~,ps] = sort(board(:),'descend');
ps = 1;
pm = 0;
[moves1, board, limit] = alex(board,limit);
%for st = 1:numel(ps)
[moves,v , b ] = findvine(board,ps,dirs,limit);
p = sum(b(v));
d = dirs(randperm(numel(dirs)));
[mov2,v2, b2] = findvine(board,ps,d, limit);
p2 = sum(b2(v));
if p2>p; v=v2;p=p2;b=b2;moves=mov2; end
if abs(p-p2)/(p+p2)>0.1
    d = dirs(randperm(numel(dirs)));
    [mov3,v3, b3] = findvine(board,ps,d, limit);
    p3 = sum(b3(v));
    if p3>p; v=v3;p=p3;b=b3;moves=mov3; end
end
if p>pm; vine = v; pm = p; end
%if sum(board)-p<20; break; end;
%end
first = find(vine==1);
if isempty(first)
    vine = 1;
else
    vine = vine(first:end);
end
end

function [moves,vine,modbrd] = findvine(brd,p,d, limit)
vine = p;
modbrd = brd;
p0 = p;
mb0=brd(p0);
[rows,cols]=size(brd);
pmax = rows*cols;
%dirs = [rows, 1, -rows, -1];
dirs = d;
brd(p)=-Inf;
mb=mb0;

%%
fini = false;
while ~fini
    pd = p+dirs;
    if rem(p-1,rows)==0;        pd(dirs==-1)=[];    end
    if rem(p-1,rows)+1==rows && rows>1;   pd(dirs==1)=[];     end
    pd(pd<1 | pd>pmax)=[];
    [m,id] = max(brd(pd));
    if m >= mb
        vine = [vine pd(id)];
        mb=m;
        brd(pd(id)) = -Inf;
        p = pd(id);
    else
        fini = true;
    end
end

%%
mb = mb0;
p = p0;
fini = false;
while ~fini
    pd = p+dirs;
    if rows>1 && cols>1
        if rem(p-1,rows)==0;        pd(dirs==-1)=[];    end
        if rem(p-1,rows)+1==rows;   pd(dirs==1)=[];     end
    end
    pd(pd<1 | pd>pmax)=[];
    [mb,id] = max(brd(pd) .* (brd(pd)<=mb) );
    if mb<0.1; break; end
    dirs = dirs([id:end 1:id-1]);
    %dirs = dirs(randperm(numel(dirs)));
    p = pd(id);
    vine = [pd(id) vine];
    brd(pd(id)) = -Inf;
end

%% check moves
moves = []; mv = 0;
dirs = [rows, 1, -rows, -1];
mb=modbrd(vine(end));
pmax = rows*cols;
for move=1:limit
    p = vine(end);
    movdirs = [2*dirs +rows-1 +rows+1 -rows+1 -rows-1];
    movdest = [dirs dirs];
    pd = p+movdirs;
    a = rem(pd-1,rows)==0 & rows>1;
    pd(a)=[]; movdest(a)=[]; %movdirs(a)=[];
    a = rem(pd-1,rows)+1==rows & rows>1;
    pd(a)=[]; movdest(a)=[]; %movdirs(a)=[];
    a = pd<1 | pd>pmax;
    pd(a)=[]; movdest(a)=[]; %movdirs(a)=[];
    [m,id] = max(brd(pd));
    if m >= mb
        p = p+movdest(id);
        moves = [moves; [pd(id) p]];
        modbrd(p)=modbrd(pd(id));
        modbrd(pd(id)) = 0;
        vine = [vine p];
        mb=m;
        brd(p) = -Inf;
        brd(pd(id))=0;
    else
        break;
        %fini = true;
    end
    
end

end

function [moves, cB, cL] = alex(board,limit)
moves=[];
if limit>0
    [nrow,ncol] = size(board);
    sz = [nrow,ncol];
    b1 = mean(board);
    [mc,idc] = max(b1);
    [mrow,mcol] = ind2sub(sz,idc);
    
    % Elemente um das Maximum sortieren
    [~,ide] = sort(board(mrow:end,mcol:end),'descend');
    ide = ide + (mrow-1) + (mcol-1)*nrow;
    % der Reihe nach zum Maximum bewegen
    cB = board;
    cL = limit;
    %    [mr,~] = ind2sub(sz, ide(1));  % Zeile des Maximums
    for k=2:numel(ide) %%%par
        if cL==0; break; end % limit erreicht
        p = ide(k);
        [pr,pc] = ind2sub(sz,p); % Zeile
        % überprüfe, ob nächster Wert in Richtung kleiner ist
        if pr==1 || pc==1
            continue;
        end
        if board(pr-1,pc)<board(pr,pc-1)
            d = 1;
        else
            d = nrow;
        end
        if cB(p-d) < cB(p)
            % bewegen
            moves = [moves; [p, p-d]];
            cL = cL-1;
            cB(p-d) = cB(p); cB(p)=0;
        end
    end
else
    cB = board; cL = limit;
end

end