Replacing parts of a matrix randomly

Hello I am trying to creat a programs that aska the user for an input from 1-15 and then randomly replaces that amount in a matrix. so for the matrix:
1 ABC DEF
2 ABC DEF
3 ABC DEF
4 ABC DEF
5 ABC DEF
6 ABC DEF
7 ABC DEF
it will randomly replace say input(5) letters to the letter x. the only problem i am having is that i don't want the first, second, and sixth columns to be selected.
clear;clc;
m=['1 ' 'ABC DEF'; '2 ' 'ABC DEF'; '3 ' 'ABC DEF'; '4 ' 'ABC DEF'; '5 ' 'ABC DEF'; '6 ' 'ABC DEF'; '7 ' 'ABC DEF';];
disp(m);
num= input('Enter an integer from 1 to 15: ');
f='y';
while (f=='y' || f=='Y')
if (num>=1 && num<=15 && rem(num,1)==0)
a=randperm(7,1);
b=randperm(9,1);
b~=1 && b~=2 && b~=6 && b~=0 && a~=0;
m(a,b)='x';
num=(num-1);
if (num==0);
break;
end
else disp(' ');
disp( 'The number you entered was not in the specified range. '); num=input('Please enter an integer between 1 and 15: ');
end
end
disp(m);
f=input('Enter y/Y to continue. All else terminates: ', 's');
This is the code i have come up with. All i need help with is to fix it to where it will not use those columns, to where it cannot duplicate the same result and replace the same letter twice, and for some reason i am having problems with the question at the end to continue or not. It seems to not work very well. I know this is a lot but if someone could help me iron this program out i would greatly appreciate it.
Mark Grano

 Accepted Answer

Image Analyst
Image Analyst on 28 Sep 2012
Edited: Image Analyst on 28 Sep 2012
Try this code:
m=['1 ' 'ABC DEF'; '2 ' 'ABC DEF'; '3 ' 'ABC DEF'; '4 ' 'ABC DEF'; '5 ' 'ABC DEF'; '6 ' 'ABC DEF'; '7 ' 'ABC DEF';]
while true
num= input('\nEnter an integer from 1 to 15: ');
if num <= 1 || num > 15
fprintf('%d is not between 1 and 15 inclusive.\n', num);
continue;
end
fprintf('You entered %d but I do not do anything with it.\n', num);
% Now get random row and column
randomRow = randi(7, 1);
randomColumn = randi(9, 1);
if randomColumn == 1 || randomColumn == 2 || randomColumn == 6
message = sprintf('Column %d was chosen at random but I am not allowed to change that\n', randomColumn);
uiwait(msgbox(message));
continue;
end
fprintf('Row %d, column %d changed to x:\n', randomRow, randomColumn);
m(randomRow, randomColumn) = 'x'
promptMessage = sprintf('Do you want to Continue or Cancel?');
titleBarCaption = 'Continue?';
button = questdlg(promptMessage, titleBarCaption, 'Continue', 'Cancel', 'Continue');
if strcmp(button, 'Cancel')
break;
end
end
I don't know why the asking for a number less than 15 was in there. I left it in but you can take it out. I just ask the user via questdlg() if they want to continue or quit.

1 Comment

Thank you for taking the time to help me. The reason why i included 1to 15 was because that determines how many letters to replace. If i enter in 5, then 5 letters should be replaced, not just one. Everything else has fixed the bugs i had. Thank you for your time once again.

Sign in to comment.

More Answers (1)

Matt Fig
Matt Fig on 28 Sep 2012
Edited: Matt Fig on 28 Sep 2012
Before your loop define:
X = [3 4 5 7 8 9];
Then when to pick your b, simply do this:
b = X(randi(6,1,1));
Thus no matter what randi returns, it will index into X to only get one of the allowed columns as defined in X.
.
.
.
I will also show how I would do what I think you are wanting to do:
function [] = replace_nums()
% Replace elements of an array randomly.
m=['1 ' 'ABC DEF'; '2 ' 'ABC DEF'; '3 ' 'ABC DEF';...
'4 ' 'ABC DEF'; '5 ' 'ABC DEF'; '6 ' 'ABC DEF';...
'7 ' 'ABC DEF';];
disp(m);
X = [3 4 5 7 8 9];
f = 'y';
while isequal('y',lower(f))
num = 0;
cnt = 1;
while num<1 || num>15
num = input('Enter an integer from 1 to 15: ');
cnt = cnt + 1;
if cnt>4,disp('Bored yet?'),return,end
end
% Loop could be replaced by:
% a = randi(7,1,num);
% b = X(randi(6,1,num));
% m(sub2ind([7,9],a,b)) = 'x';
for ii = 1:num
a = randi(7,1,1);
b = X(randi(6,1,1));
m(a,b) = 'x';
end
disp(m)
f = input('Enter y to continue. All else quits: ', 's');
end

12 Comments

Thank you for your help. im sorry if i was a tad confusing but when a column is selected, it cannot be the first, second, or sixth columns. only the letters are to be replaced. and if i enter in 5, only five letters should be replaced. Everything else is how i wanted it though. Any addtional help on this would be greatly appreciated.
No problem. I forgot you also said the first column. I fixed the above code to accommodate for this...
ok, great that works now. im sorry to keep adding to it but when i entered in 7, i only got six x's and when i entered in 9 i got twelve x's. any thoughts on that?
Matt Fig
Matt Fig on 28 Sep 2012
Edited: Matt Fig on 28 Sep 2012
Well it is entirely possible to draw the same row & column number during a run of the loop. So that would explain why you might get less than num replacements during any single run of the loop. When drawing randomly there is always a chance to get repeats, thus replacing an 'x' with another 'x'. This could be eliminated by more careful coding.
But I would say it is impossible that you got 12 when you asked for 9 because the FOR loop only goes to num! Unless MATLAB is completely broken, a FOR loop will not go past it's limit. I would venture a guess that you forgot that the array doesn't reset each time through... So you might have had 3 x's from the time before then got your 9 on top of it, making 12 x's.
ahh ok, i put clear;clc; at the top of the code and that fixed it for everytime. is there any way we can prevent duplicates?
maybe i didn't put the clear;clc; in the right place. where can i put it to where it resets every time you continue? sorry for all the questions. Just beginning matlab programming.
I used a function, so there is no need to put clear,clc in it because it has it's own workspace. Now, are you saying that each time you ask the user if he wants to continue you want to start with a fresh character array m?
yes that is what i would like. and if the user enters like 6.5, it needs to ask for a proper integer input. the only inputs allowed are 1 to 15 integers
O.k., as the very first line of the outer WHILE loop (before the line: num = 0;), put this:
mc = m;
Then everywhere inside the outer WHILE loop replace m with mc. That will give a fresh start every time.
As far as the integer checking, just add another check to the inner WHILE loop conditional:
|| floor(num)~=num
To ensure there are exactly num replacements each time, I would replace the FOR loop with a WHILE loop that increments a counter up to num and replaces mc(a,b) only if mc(a,b)~='x'.
Good luck!
Thank you for all your help! i just wanted to know if the way to prevent duplicates was addressed. i would like it to not duplicate any results and that is my only concern now. Thank you, i really appreciate your time
Yes, I addressed it in my last comment. "To ensure there are exactly num replacements each time..."
oh wow, my bad, completely missed that. Thank you for all your time once again, you really helped me out.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!