# [✓] Count the zeros between the ones in a list?

Posted 4 months ago
548 Views
|
15 Replies
|
1 Total Likes
|
 I have a list with zero’s separated by ones and I want to count the zero’s between the ones. I tried pure functions but in the wrong way. Can anybody give me a solution? (Needless to say that I am not very experience in Mathematica.) In[23]:= Test = {1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0}; In[24]:= Test = Flatten[Position[Test, 1]] Out[24]= {1, 6, 9} {* The output should be {4, 2} I tried Map[#2 - #1 - 1 &, Test] but it dosn' t.
15 Replies
Sort By:
Posted 4 months ago
 You may try SequenceSplit: l = {1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0}; SequenceSplit[l, {1 ..}] Map[Length, %] This counts also the trailing three zeros. You can correct that problem if you really need it.
Posted 4 months ago
 Thank you very much. In the meantime I have found a simple , not very sophisticated, workaround solution but it works. I will try your suggestion and try to understand it.Best regards, Chiel Geeraert
Posted 4 months ago
 t=FromDigits[Test]//IntegerString; StringCases[t,x:("1"~~"0"..~~"1"):>StringLength[x]-2,Overlaps->True] Maybe faster for large list?
Posted 4 months ago
 Can be done even shorter: SequenceCases[{1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0}, x : {0 ..} :> Length[x]] 
Posted 4 months ago
 Thank you very much. In the meantime I have found a simple , not very sophisticated, workaround solution but it works. I will try your suggestion and try to understand it.Met vriendelijke groet, Chiel Geeraert
Posted 4 months ago
 SequenceCases[{1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0}, x : {1,0 ..,1} :> Length[x]-2,Overlaps->True] 
Posted 4 months ago
 Thank you very much. In the meantime I have found a simple , not very sophisticated, workaround solution but it works. I will try your suggestion and try to understand it.Best regards, Chiel Geeraert
Posted 4 months ago
 We would like to see your workaround solution.
Posted 4 months ago
 Here is my workaround : In[20]:= Test = {1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}; (* The desired output is the number of zero's between the ones so {4,2,5,7} *) In[15]:= Test = Flatten[Position[Test, 1]] Out[15]= {1, 6, 9, 15, 23} In[17]:= Result = Table[Test[[k + 1]] - Test[[k]] - 1, {k, 1, Length[Test] - 1}] Out[17]= {4, 2, 5, 7} 
Posted 4 months ago
 A slight variation: Differences@Flatten@Position[Test, 1] - 1 
Posted 4 months ago
 Really a nice solution. I learned quite a few things from all reactions.Best regards, Chiel Geeraert (Netherlands)
Posted 4 months ago
 Mr. Rascal,Your idea of converting the list to a string is a very nice solution . (SequenceCases doesn't work with my version of Mathematica). I understand how it works and I keep in my trickbox.Best Regards , Chiel Geeraert
Posted 4 months ago
 Chiel, your code is good. But it returns too many unneeded values, try for example with this list: Test = {0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0}; SequenceCases[ ] was introduced in 2015 (10.1) and is like Cases[ ] terribly inefficient. If your list has over 3 000 elements, then you can forget about the solution with SequenceCases[ ]. The solution with StringCases[ ] will work superfast even with lists with over 1 000 000 elements. I've tested it with test lists: SeedRandom[0]; Test = RandomChoice[{0.3, 0.7} -> {1, 0}, 1000000]; The trick to convert a regular list into a string is not a trick but a common thing to do when dealing with huge lists plus a pattern matcher.
 To the collection of possible approaches here comes one more: data = {0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0}; ComponentMeasurements[Image[1 - {data}], "Count"]