Bulgarian Solitaire code doesn't iterate using if loop and for loop

1 view (last 30 days)
I need to create a game of Bulgarian Solitaire. It's not the most elegant, but the code I have so far works for one iteration. There's a flaw in that the code doesn't iterate properly (stops after the first time through the code). I'd appreciate your help in finding the error. Thanks!
% Bulgarian Solitaire
% Generate a random integer array whose elements total less than 46
array = randperm(45,1);
k = sum(array);
i = 2;
while k <= 45
array(i) = randperm(45,1);
k = sum(array);
i = i+1;
end
while k > 46
array(i) = 0;
k = sum(array);
i = i-1;
end
% Remove zeros from the initial array
value = find(array(:) == 0);
array(value) = [];
array = reshape(array, size(array,1), []);
% Sort array from smallest to largest
array = sort(array)
% Find the value of the largest element in the array
maxValue = max(array(:));
% Iterate the solitaire process
% If maxValue > 9, continue interation
count = 0;
if maxValue > 9
% Subtract one from each element of the array and increment counter
for i = 1:length(array)
array(i) = array(i) - 1;
count = count + 1;
i = i + 1;
end
% Increment array length by 1 and add the count value to the array
array(length(array) + 1) = count;
% Remove zeros from the array
value = find(array(:) == 0);
array(value) = [];
array = reshape(array, size(array,1), []);
% Find the value of the largest element in the array
maxValue = max(array(:));
% Sort array from smallest to largest
array = sort(array)
end
  2 Comments
Bill Symolon
Bill Symolon on 29 Jan 2017
The code needs to generate an array of numbers from 1, 2, ... n, where the elements of the array sum to the initial value of the "randomly" generated array.
For example, if the output of the first two while loops give:
if true
array =
3 33
end
the k = 36 and the output should be:
if true
array =
1 2 3 4 5 6 7 8
end
Hope this helps.

Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 29 Jan 2017
You mean like this:
array = [3 33]
theSum = sum(array)
linearArray = 1 : theSum
index = find(cumsum(linearArray) >= theSum)
% Take subarray
array = linearArray(1:index)
It produces:
array =
1 2 3 4 5 6 7 8
like you're asking for.

More Answers (1)

Image Analyst
Image Analyst on 29 Jan 2017
What do you mean by "elements total less than 46"? You mean that the sum of them is less than 46? That will never, ever, ever happen if your array is randperm(45). Not if you sum the whole array.
You can use cumsum(), instead of a for loop, to determine exactly when the sum goes over 46.
index = find(cumsum(array) >= 46);
% Take subarray
array = array(1:index-1);
You'd be better off using randi() and even then it will go over unless you put a very small upper limit on it.
I don't know what requirements you have, like a requirement on the max value of an element, or a requirement on the number of elements.

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!