<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Puzzler: Cleverness needed</title>
	<atom:link href="http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/</link>
	<description>Doug Hull is a proud MathWorker who is on a mission to help you with MATLAB.</description>
	<lastBuildDate>Fri, 10 Feb 2012 20:31:50 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: Bradley</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-1358</link>
		<dc:creator>Bradley</dc:creator>
		<pubDate>Wed, 11 Mar 2009 12:56:03 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-1358</guid>
		<description>This solution uses a method different to those above, and so may be of interest. It uses &#039;angle&#039; to determine which square is the correct target, without needing to construct any spiral matrices.
It should work for any size input matrix (although I&#039;ve only tested 5x5, and even-edged matrices will assume a starting point for the spiral at one of the cells near the centre).

The code assumes that inMatrix is of type logical.

&lt;pre&gt; &lt;code&gt;
[deltaX, deltaY] = puzzler(inMatrix)

halfsize = floor(length(inMatrix)/2);  %a vector of possible distances from the centre
[X,Y] = meshgrid(-halfsize:halfsize,-(-halfsize:halfsize));
therange = max( abs(X), abs(Y) );  %the distance of each point from the centre
orientation = Angle(-Y + i*X); %Is a maximum vertically and decreases clockwise.
closest = find( therange == min(therange(inMatrix)) &amp; inMatrix ); %removes all non-closest elements of inMatrix
[direction,index] = max(orientation(closest)); %finds the element we want to move towards
%Find whether the X,Y coordinates of our target are &gt;0 or &lt;0.
deltaX = sign(X(closest(index)));
deltaY = sign(Y(closest(index)));
&lt;/code&gt; &lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>This solution uses a method different to those above, and so may be of interest. It uses &#8216;angle&#8217; to determine which square is the correct target, without needing to construct any spiral matrices.<br />
It should work for any size input matrix (although I&#8217;ve only tested 5&#215;5, and even-edged matrices will assume a starting point for the spiral at one of the cells near the centre).</p>
<p>The code assumes that inMatrix is of type logical.</p>
<pre> <code>
[deltaX, deltaY] = puzzler(inMatrix)

halfsize = floor(length(inMatrix)/2);  %a vector of possible distances from the centre
[X,Y] = meshgrid(-halfsize:halfsize,-(-halfsize:halfsize));
therange = max( abs(X), abs(Y) );  %the distance of each point from the centre
orientation = Angle(-Y + i*X); %Is a maximum vertically and decreases clockwise.
closest = find( therange == min(therange(inMatrix)) &amp; inMatrix ); %removes all non-closest elements of inMatrix
[direction,index] = max(orientation(closest)); %finds the element we want to move towards
%Find whether the X,Y coordinates of our target are &gt;0 or &lt;0.
deltaX = sign(X(closest(index)));
deltaY = sign(Y(closest(index)));
</code> </pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Oliver Woodford</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-1335</link>
		<dc:creator>Oliver Woodford</dc:creator>
		<pubDate>Mon, 16 Feb 2009 15:53:23 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-1335</guid>
		<description>If you happen to want to do this for every pixel in a binary image then you can do something different to the methods suggested above, which I think will work out being faster, because it involves a multiplication which could be done over an image using conv2:&lt;pre&gt;&lt;code&gt;function [deltaX, deltaY] = puzzler(inMatrix)
% Our arbitrary order - could be anything
order = [24 25 10 11 12;
         23  9  2  3 13;
         22  8  1  4 14;
         21  7  6  5 15;
         20 19 18 17 16];
% Compute multiplication matrix - powers of two means highest bit indicates
% highest in the order
M = 2 .^ (numel(order) - order);
% Multiply with the input - for an image this can be achieved with a
% convolution
M = M(:)&#039; * inMatrix(:);
% Special case
if M == 0
    deltaX = -3;
    deltaY = -3;
    return;
end
% Compute highest set bit
[M M] = log2(M);
% Compute offsets in X and Y
deltaX = [-1 -2 -2 -2 -2 -2 -1 0 1 2 2 2 2 2 1 0 -1 -1 -1 0 1 1 1 0 0];
deltaY = [-2 -2 -1 0 1 2 2 2 2 2 1 0 -1 -2 -2 -2 -1 0 1 1 1 0 -1 -1 0];
deltaY = deltaY(M);
deltaX = deltaX(M);&lt;/code&gt;&lt;/pre&gt;
In fact, I use exactly this trick in my print2im function on the FEX.</description>
		<content:encoded><![CDATA[<p>If you happen to want to do this for every pixel in a binary image then you can do something different to the methods suggested above, which I think will work out being faster, because it involves a multiplication which could be done over an image using conv2:
<pre><code>function [deltaX, deltaY] = puzzler(inMatrix)
% Our arbitrary order - could be anything
order = [24 25 10 11 12;
         23  9  2  3 13;
         22  8  1  4 14;
         21  7  6  5 15;
         20 19 18 17 16];
% Compute multiplication matrix - powers of two means highest bit indicates
% highest in the order
M = 2 .^ (numel(order) - order);
% Multiply with the input - for an image this can be achieved with a
% convolution
M = M(:)' * inMatrix(:);
% Special case
if M == 0
    deltaX = -3;
    deltaY = -3;
    return;
end
% Compute highest set bit
[M M] = log2(M);
% Compute offsets in X and Y
deltaX = [-1 -2 -2 -2 -2 -2 -1 0 1 2 2 2 2 2 1 0 -1 -1 -1 0 1 1 1 0 0];
deltaY = [-2 -2 -1 0 1 2 2 2 2 2 1 0 -1 -2 -2 -2 -1 0 1 1 1 0 -1 -1 0];
deltaY = deltaY(M);
deltaX = deltaX(M);</code></pre>
</p><p>In fact, I use exactly this trick in my print2im function on the FEX.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Yi Cao</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-29</link>
		<dc:creator>Yi Cao</dc:creator>
		<pubDate>Sat, 27 Sep 2008 15:03:37 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-29</guid>
		<description>Doug,

Thanks for pointing out errors in my original code. I should test it before posting. Anyway, here is the version with corrections. It has been tested, hence should be correct.
 
&lt;pre&gt; &lt;code&gt;
function [deltaX, deltaY] = puzzler(inMatrix)
% Using lookup tables to solve the probelm
if isempty(inMatrix(inMatrix&gt;0))
    deltaX=ceil(3*rand)-2;
    deltaY=ceil(3*rand)-2;
    return
end
%spiral positions
spiralMatrix = [
	24 25 10 11 12;
	23  9  2  3 13;
	22  8  1  4 14;
	21  7  6  5 15;
	20 19 18 17 16];
dX=repmat([-1 -1 0 1 1],5,1);
dY=rot90(dX);
idx=spiralMatrix==min(spiralMatrix(inMatrix&gt;0));
deltaX=dX(idx);
deltaY=dY(idx);
&lt;/code&gt; &lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Doug,</p>
<p>Thanks for pointing out errors in my original code. I should test it before posting. Anyway, here is the version with corrections. It has been tested, hence should be correct.</p>
<pre> <code>
function [deltaX, deltaY] = puzzler(inMatrix)
% Using lookup tables to solve the probelm
if isempty(inMatrix(inMatrix&gt;0))
    deltaX=ceil(3*rand)-2;
    deltaY=ceil(3*rand)-2;
    return
end
%spiral positions
spiralMatrix = [
	24 25 10 11 12;
	23  9  2  3 13;
	22  8  1  4 14;
	21  7  6  5 15;
	20 19 18 17 16];
dX=repmat([-1 -1 0 1 1],5,1);
dY=rot90(dX);
idx=spiralMatrix==min(spiralMatrix(inMatrix&gt;0));
deltaX=dX(idx);
deltaY=dY(idx);
</code> </pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Marc</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-28</link>
		<dc:creator>Marc</dc:creator>
		<pubDate>Fri, 26 Sep 2008 22:44:27 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-28</guid>
		<description>for those who really want to tackle the problem of creating spiral matrices...

compare a recursive approach like this, to the classic for-loop approach in spiral.m.  I think a recursive approach like this is far and away easier to understand for a problem like this.  Memorywise, it&#039;s a tad wasteful, and it&#039;s not as fast.  But it&#039;s readable.  

&lt;pre&gt;&lt;code&gt;

function s = myspiral(n)
% returns spiral matrix (recursive method)
% MYSPIRAL(n) is an n-by-n matrix with elements ranging
%   from 1 to n^2 in a rectangular spiral pattern.
% see also spiral.m

if n == 1
    s = 1;
    return
end

if n == 2
    s = [4 1; 3 2];
    return
end

% now, do outer loop, and recursively solve inner parts

mymax = n^2;
mymin = ((n-2)^2)+1;
mynum = mymax:-1:mymin;

s = zeros(n,n);

%left
s(:,1) = mynum(1:n);
mynum(1:n) = []; %chop away used numbers as we go
%bottom
s(end, 2:end) = mynum(1:(n-1));
mynum(1:(n-1)) = [];
%top
s(1,2:(n-1)) = fliplr(mynum(round(length(mynum)/2)+1:end));
mynum(round(length(mynum)/2)+1:end) = [];
%right
s(1:n-1, n) = flipud(mynum(:));

% recurse to middle

s(2:n-1, 2:n-1) = myspiral(n-2);


&lt;/code&gt;&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>for those who really want to tackle the problem of creating spiral matrices&#8230;</p>
<p>compare a recursive approach like this, to the classic for-loop approach in spiral.m.  I think a recursive approach like this is far and away easier to understand for a problem like this.  Memorywise, it&#8217;s a tad wasteful, and it&#8217;s not as fast.  But it&#8217;s readable.  </p>
<pre><code>

function s = myspiral(n)
% returns spiral matrix (recursive method)
% MYSPIRAL(n) is an n-by-n matrix with elements ranging
%   from 1 to n^2 in a rectangular spiral pattern.
% see also spiral.m

if n == 1
    s = 1;
    return
end

if n == 2
    s = [4 1; 3 2];
    return
end

% now, do outer loop, and recursively solve inner parts

mymax = n^2;
mymin = ((n-2)^2)+1;
mynum = mymax:-1:mymin;

s = zeros(n,n);

%left
s(:,1) = mynum(1:n);
mynum(1:n) = []; %chop away used numbers as we go
%bottom
s(end, 2:end) = mynum(1:(n-1));
mynum(1:(n-1)) = [];
%top
s(1,2:(n-1)) = fliplr(mynum(round(length(mynum)/2)+1:end));
mynum(round(length(mynum)/2)+1:end) = [];
%right
s(1:n-1, n) = flipud(mynum(:));

% recurse to middle

s(2:n-1, 2:n-1) = myspiral(n-2);

</code></pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Marc</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-27</link>
		<dc:creator>Marc</dc:creator>
		<pubDate>Fri, 26 Sep 2008 21:45:57 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-27</guid>
		<description>So I&#039;m a little late to the party.  What I came up with was pretty much what everyone else came up with.

&lt;pre&gt; &lt;code&gt;
%% All the code so someone can just copy and paste it from 
%% the comments.

function [deltax, deltay] = puzzler(matrixin)

% puzzler 9/26/08

values25 = [ 24 25 10 11 12;
            23 9 2 3 13;
            22 8 1 4 14;
            21 7 6 5 15;
            20 19 18 17 16;];
        
bigdeltax = [-1*ones(5,2) zeros(5,1) ones(5,2)];
bigdeltay = flipud(bigdeltax&#039;);

hits = values25(matrixin==1);
idx = find(values25==min(hits));

deltax = bigdeltax(idx);
deltay = bigdeltay(idx);

if sum(matrixin) == 0
    deltax = floor(2.9*rand(1))-1;;
    deltay = floor(2.9*rand(1))-1;    
end

&lt;/code&gt; &lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>So I&#8217;m a little late to the party.  What I came up with was pretty much what everyone else came up with.</p>
<pre> <code>
%% All the code so someone can just copy and paste it from
%% the comments.

function [deltax, deltay] = puzzler(matrixin)

% puzzler 9/26/08

values25 = [ 24 25 10 11 12;
            23 9 2 3 13;
            22 8 1 4 14;
            21 7 6 5 15;
            20 19 18 17 16;];

bigdeltax = [-1*ones(5,2) zeros(5,1) ones(5,2)];
bigdeltay = flipud(bigdeltax');

hits = values25(matrixin==1);
idx = find(values25==min(hits));

deltax = bigdeltax(idx);
deltay = bigdeltay(idx);

if sum(matrixin) == 0
    deltax = floor(2.9*rand(1))-1;;
    deltay = floor(2.9*rand(1))-1;
end

</code> </pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Fig</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-26</link>
		<dc:creator>Matt Fig</dc:creator>
		<pubDate>Fri, 26 Sep 2008 18:02:06 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-26</guid>
		<description>Doug,

You caught me!  I must have copied your formatting example from above, then pasted my function in the middle.  I think I remember seeing two &#039;function declarations&#039; and deleting one.  I must have erased mine instead of yours!  Oh, well, you get that the function declaration should look like:

function [dx,dy] = puzzler(a)  

I would be interested to see if one could come up with a fast way to get idxa for any size input, and if that is faster than some of the other scalable submissions.  The other two &quot;lookup vectors&quot; should be easy enough to generate.  Interesting...</description>
		<content:encoded><![CDATA[<p>Doug,</p>
<p>You caught me!  I must have copied your formatting example from above, then pasted my function in the middle.  I think I remember seeing two &#8216;function declarations&#8217; and deleting one.  I must have erased mine instead of yours!  Oh, well, you get that the function declaration should look like:</p>
<p>function [dx,dy] = puzzler(a)  </p>
<p>I would be interested to see if one could come up with a fast way to get idxa for any size input, and if that is faster than some of the other scalable submissions.  The other two &#8220;lookup vectors&#8221; should be easy enough to generate.  Interesting&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: dhull</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-24</link>
		<dc:creator>dhull</dc:creator>
		<pubDate>Fri, 26 Sep 2008 17:03:34 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-24</guid>
		<description>Matt,

It is always interesting to see how people solve the problem.  Yours is a little different from the rest.  It took me a while to understand what IDXA was.  Then I figured out it was the absolute indices of the matrix in preferred order.  The rest follows from that.  This makes the problem a short look-up table type of problem

While it makes the code a little harder to visualize, it does make for very clean code.  There are always trade-offs.

Doug

PS.  You never actually define your outputs in the function, not do you have the function keyword, but the ideas are there.</description>
		<content:encoded><![CDATA[<p>Matt,</p>
<p>It is always interesting to see how people solve the problem.  Yours is a little different from the rest.  It took me a while to understand what IDXA was.  Then I figured out it was the absolute indices of the matrix in preferred order.  The rest follows from that.  This makes the problem a short look-up table type of problem</p>
<p>While it makes the code a little harder to visualize, it does make for very clean code.  There are always trade-offs.</p>
<p>Doug</p>
<p>PS.  You never actually define your outputs in the function, not do you have the function keyword, but the ideas are there.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Adam</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-23</link>
		<dc:creator>Adam</dc:creator>
		<pubDate>Fri, 26 Sep 2008 13:31:32 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-23</guid>
		<description>&lt;pre&gt; &lt;code&gt;
function [dX dY] = puzzler(inMatrix)

    mSp = [
    	24 25 10 11 12;
    	23  9  2  3 13;
    	22  8  1  4 14;
    	21  7  6  5 15;
    	20 19 18 17 16];

    % find smallest point
    ind = find(inMatrix .* mSp);
    pts = mSp(ind);
    
    % if empty make random point
    if isempty(pts) 
        dX = floor(3*rand)-1;
        dY = floor(3*rand)-1;
        
    % not empty so find deltas
    else                
        [r c] = find(spiralMatrix == min(pts));

        dX = sign(c-3);
        dY = sign(3-r);
    end
end

&lt;/code&gt; &lt;/pre&gt;

Pros:
Scalable
Doesn&#039;t generate big matrix

Cons:
Uses find twice, possibly slow

~Adam</description>
		<content:encoded><![CDATA[<pre> <code>
function [dX dY] = puzzler(inMatrix)

    mSp = [
    	24 25 10 11 12;
    	23  9  2  3 13;
    	22  8  1  4 14;
    	21  7  6  5 15;
    	20 19 18 17 16];

    % find smallest point
    ind = find(inMatrix .* mSp);
    pts = mSp(ind);

    % if empty make random point
    if isempty(pts)
        dX = floor(3*rand)-1;
        dY = floor(3*rand)-1;

    % not empty so find deltas
    else
        [r c] = find(spiralMatrix == min(pts));

        dX = sign(c-3);
        dY = sign(3-r);
    end
end

</code> </pre>
<p>Pros:<br />
Scalable<br />
Doesn&#8217;t generate big matrix</p>
<p>Cons:<br />
Uses find twice, possibly slow</p>
<p>~Adam</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: dhull</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-25</link>
		<dc:creator>dhull</dc:creator>
		<pubDate>Fri, 26 Sep 2008 13:04:51 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-25</guid>
		<description>Daniel,

Spiral is not documented as such, because it is not a MATLAB function, it is a MATLAB demo:

&gt;&gt; which spiral
C:\Program Files\MATLAB\R2008a\toolbox\matlab\demos\spiral.m

These are treated differently, even thought this demo happens to be useful as a stand alone function also.

Doug</description>
		<content:encoded><![CDATA[<p>Daniel,</p>
<p>Spiral is not documented as such, because it is not a MATLAB function, it is a MATLAB demo:</p>
<p>>> which spiral<br />
C:\Program Files\MATLAB\R2008a\toolbox\matlab\demos\spiral.m</p>
<p>These are treated differently, even thought this demo happens to be useful as a stand alone function also.</p>
<p>Doug</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Armyr</title>
		<link>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-22</link>
		<dc:creator>Daniel Armyr</dc:creator>
		<pubDate>Fri, 26 Sep 2008 06:52:02 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-22</guid>
		<description>Speaking of which, the spiral function seems to exist and have embedded help coments, but it does not seem to exist in the doc. Sneaky there.....</description>
		<content:encoded><![CDATA[<p>Speaking of which, the spiral function seems to exist and have embedded help coments, but it does not seem to exist in the doc. Sneaky there&#8230;..</p>
]]></content:encoded>
	</item>
</channel>
</rss>

