Cody
Follow


Help with Cody's 'Problem 672. Longest run of consecutive numbers', I wrote 'if a(i)==a(i+1)' and it says error

N/A on 10 Jan 2020
Latest activity Reply by Kurt on 30 Aug 2023

Hi, I'm trying to solve this problem but I'm getting an error so far.
Problem:
Given a vector a, find the number(s) that is/are repeated consecutively most often. For example, if you have
a = [1 2 2 2 1 3 2 1 4 5 1]
The answer would be 2, because it shows up three consecutive times
What I've written so far (not done):
a = [1 2 2 2 1 3 2 1 4 5 1];
[x,y] = size(a);
counter = zeros(1,10);
if x == 1
for i=1:1:y
if a(i) == a(i+1)
counter(a(i)) = counter(a(i))+1
end
end
else
for i=1:1:x
if a(i) == a(i+1)
counter(a(i)) = counter(a(i))+1
end
end
end
But it says "error" in the line of "if a(i) == a(i+1)". I noticed that it creates a variable called "i" which value is 11, but it should create a vector from 1 to 11. What's wrong here?
I know my solution might not be in the right direction or something, but please don't tell me anything!
Thanks in advance
Kurt
Kurt on 30 Aug 2023
I found I didn't need the "vertcat" function.
Here is my code inside the function with Comments to explain the logic behind the "diff" & "find" functions.
% Convert the Vector or Matrix into a single column Vector to simplify indexing and Consecutive Run Counting
b = a(:);
% Compare the values of the next adjacent element to the current element, the original vector length is reduced by 1; Zeros "flag" where the same Consecutive Number starting location is, the next nonzero value where it stops
c = diff(b);
% Surround the Difference Calculation Vector with nonzero elements. The original Vector length is now increased by 1
d = [1;c;1];
% Locate the Indices of the nonzero elements using the "find" function. The first & last indices are the ones that were added to "wrap" the vector in nonzero elements.
f = find(d);
% Count the occurance of each vector element in order of it's appearance. Values > 1 indicate a consecutive "run" but not neccessarily the most. Summing all these element values will give you the original Vector length.
g = diff(f);
% Determine the most frequent reoccurance(s), "mode" function isn't enough, there could be multiple numbers reoccuring for the same amount of times.
h = max(g);
% Retrieve the starting indices for where the most element values occur in the original vector
k = f(g==h);
% Return the Element Values that have the Longest Run of Consecutive Numbers which matches the input style
val = a(k);
Agam Sharma
Agam Sharma on 11 Jun 2022
count=zeros(1,length(a))
for i=2:length(a)
if(a(i)==a(i-1))
count(i)=count(i-1)+1
end
end
[m e]=max(count)
a(e)
Hikmat Binyaminov
Hikmat Binyaminov on 27 Feb 2021
function val=longrun(a)
sz = size(a);
n = zeros(sz);
k = 1;
n(k)=1;
for i=2:length(a)
if a(i)-a(i-1) == 0
n(k)=n(k)+1;
else
k = k+1;
n(k)=1;
end
end
n=n(n~=0);
I = find(n==max(n));
for j=1:length(I)
val(j) = a(sum(n(1:I(j))));
end
if sz(1)~=1;
val=val';
end
end
Ciro Bermudez
Ciro Bermudez on 8 Dec 2020
In my opinion It's a great problem, this is the solution I came up with
function val=longrun(a)
count = 1; max_count = 1; val = a(1); idx = 1;
for i = 2:length(a)
if a(i) == a(i-1)
count = count + 1;
else
count = 1;
end
if max_count == count
% if val(idx) ~= a(i)
idx = idx + 1;
val(idx) = a(i);
% end
end
if max_count < count
max_count = count;
val = a(i);
idx = 1;
end
end
if size(a,2) < size(a,1)
val = val.';
end
end
Something weird happens when you use the complete code, uncommenting the if statement, in my opinion gives a better solution, the down side is that it wouldn't pass Cody tests. Hopes it helps other people with ideas to solve this problem.
Peeyush Pankaj
Peeyush Pankaj on 28 Oct 2020
While diff() approach gives you good scores, here's logic based solution for the ones who want to understand how it should be done
function val=longrun(a)
N=max(size(a,1),size(a,2));
count=1; max_count=1; reset=0; j=1;
for i=2:N
if a(i) == a(i-1)
count=count+1;
% Enter this if loop for the first set of continuos numbers
if reset==0
max_count=count;
val(reset+1)=a(i);
% Elseif condition for next set of continuos numbers, but matching the max_count with previously detected
elseif reset>0 & count==max_count
j=j+1;
val(j)=a(i)
elseif count>max_count
max_count=count; j=1;
val(j)=a(i);
end
elseif count>1
count=1; reset=reset+1
else
count=1;
end
end
% If there's no duplicate values in a row
if reset==0 & max_count==1
val=a
% For outputing as column vector
elseif size(a,1)>size(a,2)
val=val'
end
end
aziz muhammed akkaya
aziz muhammed akkaya on 15 Mar 2021
Thank you for the code, it really helped me understand the logic. However, there is a subtle gap in the code. In the condition count>max_count if val is not emptied, it repeats the max number. For example in a case like this one a = [1 1 1 2 2 2 2 3 3 3], the answer will be [2 2]. So, in that condition val should be emptied somewhere before it is added the new value.
Again thank you for the code, it helped a lot.
David Hill
David Hill on 23 Mar 2020
function ans = longrun(a)
find(vertcat(1,diff(a(:)),1));
a(ans(diff(ans)==max(diff(ans))));
end
John D'Errico
John D'Errico on 22 Jun 2020
The ans solution is a common one used to improve Cody scores. It is also terribly poor coding style in my opinion, because it tends to create hard to read and debug code, for no good reason except to gain an improvement in Cody score. But sadly, Cody encourages it. Personally, I think the Cody scoring algorithm should deprecate that coding style.
Yeshwanth Sai Kothamasu
Yeshwanth Sai Kothamasu on 22 Jun 2020
Very impressive and good idea
Gautam Rawat
Gautam Rawat on 10 May 2020
As MATLAB Beginner I cant think like this. Excellent
Stephen23
Stephen23 on 29 Apr 2020
Relying on the implicit ans output is not recommended. It is much better to allocate explicitly to variables.
Mark Posen
Mark Posen on 29 Apr 2020
David, This is wonderfully elegant, and very impressive to a MATLAB beginner like me! I have learned a lot just understanding how/why it works!
David Hill
David Hill on 24 Mar 2020
The first line answer provides the index of the start and end of each run in the series.
find(vertcat(1,diff(a(:)),1));
Then,
diff(ans)==max(diff(ans));%provides a logical array indicating the start of the longest run
and,
ans(diff(ans)==max(diff(ans)));%provide the actual starting index within 'a' of the longest run
finally,
a(ans(diff(ans)==max(diff(ans))));%provides the value of 'a' at the start of the longest run
Anand H Lokapur
Anand H Lokapur on 23 Mar 2020
Could you please explain the last line of the code , and your thought process.
Thank you for the solution and would really appreciate the effort if you could help me (beginner) out.
Anand H Lokapur
Anand H Lokapur on 23 Mar 2020
could you please provide solution or the snippet of the main part, I have tried to figure this out but can't and now I really want to know how to .
N/A
N/A on 13 Jan 2020
Thank you so much, David! That function came really useful.
David Hill
David Hill on 11 Jan 2020
By cheating in my opinion. The real best solution is about 32. You should look at the function diff(). The use of diff() provides the best solution.
N/A
N/A on 11 Jan 2020
Thanks a lot, guys! John, I'm sorry about the other post. I thought I couldn't add more info and new questions on here.
Could you guys help me with this problem? Now that I've figured out the errors, it just doesn't behave as expected. I know there is stuff that I haven't addressed still (like the inclusion of 0s and negative numbers), but I don't know how to go on.
Here's my try:
[x,y] = size(a);
counter = zeros(1,10);
if x == 1
for i=1:1:y-1
if a(i) == a(i+1)
counter(a(i)) = counter(a(i))+1
end
end
else
for i=1:1:x-1
if a(i) == a(i+1)
counter(a(i)) = counter(a(i))+1
end
end
end
if counter ~= zeros(1,10) %if there is no repeated number anywhere, like in [1:5]
res = find(counter == max(counter))
else
res = []; %the output is empty
end
if x == 1
val = res;
elseif y == 1
val = res'; %if the input is a column, the output should also be a column
end
Also, I saw that the leading solution size is like 9. How is that even possible?
Aquatris
Aquatris on 10 Jan 2020
One thing is you are trying to access a(12) where a has only 11 variables. This can be solved by changing "for i = 1:1:y" to "for i = 1:1:(y-1)". Because you dont want to compare a(y) with a(y+1) since a(y+1) does not exist,
If you make that change, it seems like it works.
John D'Errico
John D'Errico on 10 Jan 2020
For a vector of length 10, what happens when i is 10? I.e., what will happen here:
if a(i) == a(i+1)
what would you expect matlab to do when it tries to access a(11)? Remember, it only has 10 elements.
N/A
N/A on 10 Jan 2020
Oh, I didn't know that, thank you! But still, why isn't it working?
Aquatris
Aquatris on 10 Jan 2020
What "for i = 1:1:11" does is not to assign the vector to i but individual elements in the vector to the i in each iteration. First iteration, i will be 1, second iteration i will be 2 and so on.