MATLAB Answers

0

[Solved] question

Asked by Ryan Shishegar on 8 Nov 2019 at 19:42
Latest activity Commented on by Stephen Cobeldick on 5 Dec 2019 at 8:08
This question was flagged by Walter Roberson
a

  1 Comment

Stephen Cobeldick on 5 Dec 2019 at 8:08
Original question (from Google Cache):
"How can I make my output into a 2D char array instead of separate answers?"
Hi, sorry if this is trivial, but I am writing a function that gives directions on how to solve the Tower of Hanoi given d discs, and I can't quite seem to figure out how to produce a single 2D char array that contains all the instructions for solving the game on separate lines. The output I am looking for looks like this:
instruction =
'Move one disk from peg 1 to peg 2'
'Move one disk from peg 1 to peg 3'
'Move one disk from peg 2 to peg 3'
My code looks like this and produces the instructions on separate output statements only if I omit a semicolon at the end of the sprintf line:
function instruction = hanoi(d, origin, inter, target)
if d == 1
instruction = sprintf('Move one disk from peg %s to peg %s', origin, target)
else
hanoi(d-1, origin, target, inter);
hanoi(1, origin, inter, target);
hanoi(d-1, inter, origin, target);
end
end
My idea was to concatenate each line, but it doesn't seem possible without resetting what's contained in the variable instruction.
Thank you in advance.

Sign in to comment.

2 Answers

Guillaume
Answer by Guillaume
on 8 Nov 2019 at 19:55

My idea was to concatenate each line, but it doesn't seem possible without resetting
Well, you're doing assignment which indeed overwrites the data. There's no attempt at concatenating anything.
If you want to grow instruction through the recurence, you'll have to pass it to each recursion. An easy way
%in the function that starts the recursion:
instruction = hanoi(somed, o, i, t, []); %start with empty instruction.
%your recurring function, now has 5 input arguments
function instruction = hanoi(d, origin, inter, target, instruction)
if d == 1
instruction = [instruction; sprintf('Move one disk from peg %s to peg %s', origin, target)]; %append a new row to instruction
else
...
end
end
Note that 2D char arrays require each row to be the same length, so you have to be careful that your sprintf always produces a vector the same size, regardless of the value of origin and target otherwise you'll get the error: "Dimensions of arrays being concatenated are not consistent."
Also, I presume that origin and target are supposed to be numeric, in which case %s is not the correct format specifier. See the sprintf documentation, it's %d or %u or %i for integers.

  3 Comments

Ryan Shishegar on 8 Nov 2019 at 20:09
I understand and successfully implemented concatenation using the aforementioned method; however, the function is for an assignment and is supposed to only take three input arguments. I thought to assign instruction to an empty array at the beginning of the code but that obviously resets it on every recurence. I also tried using:
if exist('instruction','var') == 0
instruction = [];
end
yet that did not seem to work either.
Also, all of the inputs except for the number of disks d are of type char so %s works in this case.
Guillaume
on 8 Nov 2019 at 20:22
Of course, exist didn't work, it's not going to be looking at the workspace of other functions, only the local workspace.
If hanoi is supposed to have only 3 input arguments, then I would suspect you're supposed to implement the recursion in a subfunction:
function instruction = hanoi(d, origin, inter, target)
instruction = hanoi_recurse(d, origin, inter, target, []);
end
function instruction = hanoi_recurse(d, origin, inter, target, instruction)
if d == 1
instruction = [instruction; sprintf('Move one disk from peg %s to peg %s', origin, target)]; %append a new row to instruction
else
...
end
end
Otherwise, the only other way is to make instruction non-local to the function or make it persistent, neither of which I will explain as they are absolutely not appropriate for this and would be teaching you extremely bad coding style.
Ryan Shishegar on 8 Nov 2019 at 20:29
I see. I ended up figuring out how to produce the output I wanted by assigning instruction initially and then appending it as the function recursed.
function instruction = hanoi(d, origin, inter, target)
if d == 1
instruction = sprintf('Move one disk from peg %s to peg %s', origin, target);
else
instruction = hanoi(d-1, origin, target, inter);
instruction = [instruction; hanoi(1, origin, inter, target)];
instruction = [instruction; hanoi(d-1, inter, origin, target)];
end
end

Sign in to comment.


Fangjun Jiang
Answer by Fangjun Jiang
on 8 Nov 2019 at 20:23

You have a recursive function which makes it a little complicated. But this modification seems to work.
%%
out=hanoi(3, 1, 2, 3)
function out=hanoi(d, origin, inter, target)
persistent instruction;
if d == 1
instruction = [instruction, sprintf('Move one disk from peg %d to peg %d\n', origin, target)];
else
hanoi(d-1, origin, target, inter);
hanoi(1, origin, inter, target);
hanoi(d-1, inter, origin, target);
end
out=instruction;
end
out =
'Move one disk from peg 1 to peg 3
Move one disk from peg 1 to peg 2
Move one disk from peg 3 to peg 2
Move one disk from peg 1 to peg 3
Move one disk from peg 2 to peg 1
Move one disk from peg 2 to peg 3
Move one disk from peg 1 to peg 3
'

  0 Comments

Sign in to comment.