Code covered by the BSD License  

Highlights from
MATLAB Contest - blackbox

from MATLAB Contest - blackbox by The MATLAB Contest Team
All the files needed to develop and score an entry for this MATLABĀ® Programming Contest.

charge+B; % set charge for absorptions
function varargout = beam(r,c,beamIntensity)

% Queries the black box or destroys a particle.
%
%  [ROWOUT, COLUMNOUT, SCORE] = BEAM(ROWIN,COLUMNIN) or
%  [ROWOUT, COLUMNOUT, SCORE] = BEAM(ROWIN,COLUMNIN,'low') shines a low
%  intensity light into the black box. If the beam is absorbed by any
%  particle ROWOUT and COLUMNOUT are both 0.
%
%  BEAM(ROWIN,COLUMNIN,'high') shines a high intensity light into the black
%  box, destroying any particle that tries to absorbe it.  
%

% Copyright 2006 The MathWorks, Inc.

persistent A turns charge newd ir ic n beamCtr dc saveinfo

if isempty(beamCtr)
    beamCtr = 0;
end

if nargin==1 % init puzzle and also used to get the number of function calls
    if isempty(r)
        A=[];
        [turns charge] = setCmds(A);
        if saveinfo
            varargout = {beamCtr,dc,0};
        else
            varargout = {beamCtr,0,0};
        end
        return
    else
        if any(r(:)<0)
            saveinfo = true;
            A = -r;
            dc = {};
        else
            saveinfo = false;
            A = r;
        end
        newd  = [0 0 0 0;    % end state     % 1 s, 2 e, 3 n, 4 w, 0 done
            1 2 3 4;    % go straight
            4 3 2 1;    % deflected
            2 1 4 3;    % deflected
            3 4 1 2];   % reflected
        ir = [1 0 -1 0];
        ic = [0 1 0 -1];
        n = length(A);
        [turns charge] = setCmds(A);
        varargout = {0,0,0};
        return
    end
end

if nargin==2
    beamIntensity = 'low';
end

if ~isscalar(r) || ~isscalar(c) || (~r==~c) || rem(r,1) || rem(c,1)
    error('rowIn or columnIn has invalid values.')
end

rrr = r;
ccc = c;

d = (c>0)+2*(r>0)+3*(c<0)+4*(r<0); %1 s, 2 e, 3 n, 4 w
r = abs(r);
c = abs(c);

if  r>n || c>n 
    error('abs(rowIn) or abs(columnIn) has a value larger than n.')
end

r = r+1 + ((n+1)*(d==3));
c = c+1 + ((n+1)*(d==4));
ch = charge(r,c);
rr = r;
cc = c;
if ~ch
    while d
        r = r + ir(d);
        c = c + ic(d);
        rr = [rr r];
        cc = [cc c];
        d = newd(turns(r,c),d);
        ch = ch + charge(r,c);
    end
end
d = (r==n+2)||(c==n+2);
r = rem(r-1,n+1);
c = rem(c-1,n+1);
des = [0;0];
switch beamIntensity
    case 'low'
        beamCtr = beamCtr+1;
        if r&&c
            ch = 0;
            varargout = {0,0,ch};    % beam is absorbed
        elseif d
            varargout = {-r,-c,ch}; % beam leaves at bottom or right
        else
            varargout = {r,c,ch};   % beam leaves at top or left
        end
    case 'high'
        ch = 0;
        if r&&c         % beam is absorbed and particle is destroyed
            beamCtr = beamCtr+A(r,c);   
            A(r,c) = 0;                  % destroy particle
            [turns charge] = setCmds(A); 
            des = [r;c];
        end
        varargout = {0,0,ch};
    otherwise
        error('beamIntensity can only be ''low'' or ''high''.')
end

if saveinfo
    if d
        dc = [dc;{rrr,ccc,rr,cc,ch,isequal(beamIntensity,'high'),des(1),des(2),-r,-c}];
    else
        dc = [dc;{rrr,ccc,rr,cc,ch,isequal(beamIntensity,'high'),des(1),des(2),r,c}];
    end
end

function [turns charge] = setCmds(A)
B = conv2(A,[0 0 0;0 1 0;0 0 0]);
C = conv2(A,[0 1 0;1 0 1;0 1 0])&~B;
turns = conv2(single(A>0),[1 0 2;0 0 0;2 0 1])+2;       % set turns
turns(~conv2(ones(size(A)),[0 0 0;0 1 0;0 0 0])|B) = 1; % set absorption and borders
turns(C) = 2;                                           % remove invalid turns
charge = conv2(A,ones(3)); % set charge for turns
charge(C|B) = 0;           % remove charge at invalid turns
charge = charge+B;         % set charge for absorptions

Contact us at files@mathworks.com