<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.3.1" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>
<channel>
	<title>Comments on: Puzzler: Cleverness needed</title>
	<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>
	<pubDate>Mon, 23 Nov 2009 00:30:16 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.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>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 'angle' 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'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)) &#38; 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 &#62;0 or &#60;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>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(:)' * 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>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&#62;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&#62;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>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's a tad wasteful, and it's not as fast.  But it'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>http://blogs.mathworks.com/videos/2008/09/25/puzzler-cleverness-needed/#comment-27</guid>
		<description>So I'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');

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>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 'function declarations' 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 "lookup vectors" 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-25</link>
		<dc:creator>dhull</dc:creator>
		<pubDate>Fri, 26 Sep 2008 17:04:51 +0000</pubDate>
		<guid>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 MALTAB 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 MALTAB 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: 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>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>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'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: 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>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>
