Counting frequency of runs of consecutive 1s in an array - scilab

I have defined an array of arr=[0 0 1 1 1 0 0 0 0 1 1 0 1 1 1].
I would like to count the continuous repetition and store in another array.
For example above, the first repetition is 3 of 1s. So I assume the length of this continuous repetition is 3.
Therefore, the the array should be like arr[length]=1 . The 1 stands for it has been encountered once. The final output should be
arr[3]=2 //it means length of repetition with 3 of 1s has been encountered twice
arr[2]=1 //length of repetition with 2 has been encountered once.
Below is my code progress so far.
err=0;
no_err=0;
flag=0;
arr=[0 0 1 1 1 0 0 0 0 1 1 0 1 1 1] //assume 15
for x=1:15;
val=arr(x);//access array values
if(val==0)//if no error
flag=0; //indicates no error
elseif(val==1) //if there is an error
flag=1; //indicates error
end
if(flag==0)
no_err=no_err+1;//counter of no error
err=0; //reset error to zero
elseif(flag==1)//
err=err+1;//
tmperr=err;//will keep updating with latest err count length
end
end

Some of the logic is reasonable, but this part is strange:
if(flag==0)
....
elseif(flag==1)
This could be simply else. More importantly, the state of flag could have been changed by the earlier part of the loop, which will render the logic of the second if statement invalid.
I suggest considering four scenarios, focusing on counting only repetitions of 1s:
flag is 0 and value is 0: do nothing (no need to have a clause for this)
flag is 1 and value is 1: increment the count of consecutive 1s
flag is 0 and value is 1: set the flag to 1, set the count of consecutive 1s to 1.
flag is 1 and value is 0: set the flag to 0, record the count of 1s in the output array.
Since the second bullet item does not change the state of flag, it can be dealt with first; the two others are considered within if/elseif construction.
Also, the end of array should be ending the current run of 1s. Instead of writing a separate clause for this, it's easier to pad the given array with 0.
err=0
flag=0
arr=[0 0 1 1 1 0 0 0 0 1 1 0 1 1 1]
output = zeros(arr)
paddedarr = [arr 0]
for x=1:length(paddedarr)
val=paddedarr(x)
if (val==1 & flag==1)
err=err+1
end
if (val==1 & flag==0)
flag = 1
err = 1
elseif (val==0 & flag==1)
output(err) = output(err)+1
flag = 0
err = 0
end
end
Output:
0. 1. 2. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
Note that I used length command instead of assuming the length of array.

Related

Build xy+xz+yz using NAND port

for an homework I have to write xy+xz+yz using only NANDS port.
I will use the notation NAND(x,y) - or other types of bracket to make things clearer -, below my attempt and then an explanation for every step. I'd like to know if i'm doing this right and if there are better ways to do it.
My Solution
NAND[NAND(NAND(NAND(x,y),NAND(x,z)),NAND(NAND(x,y),NAND(x,z))),NAND(NAND(NAND(y,z),NAND(y,z)),NAND(NAND(y,z),NAND(y,z))))]`
I know this looks really impossible to read and keep track of. I'm sorry, didn't know how to make this more beautiful. Hope my explanation will clarify things.
I divided xy+xz+yz in two groups: xy+xz and yz
First Group:
xy+xz = NAND(NAND(x,y),NAND(xz)) = NOT[NOT(xy)*NOT(xz)] = xy+xz
Second Group:
yz = NAND(NAND(y,z),NAND(y,z)) = NOT(NOT(yz)*NOT(yz)) = yz (since yz+yz = yz)
Now I have to combine the first group with the second, for readibility I'll call the first group (in NAND as g1) and the second g2;
g1+g2= NAND[NAND(g1,g1),NAND(g2,g2)] = NOT[NOT(g1)*NOT(g2)] = g1+g2
So at the end:
xy+xz+yz= NAND[NAND(NAND(NAND(x,y),NAND(x,z)),NAND(NAND(x,y),NAND(x,z))),NAND(NAND(NAND(y,z),NAND(y,z)),NAND(NAND(y,z),NAND(y,z))))]
Is my reasoning right? There's a more easy way?
Thanks a lot guys
Your answer is correct (although you have some missing punctuation -- a couple commas and a parenthesis). You can confirm by generating a truth table of all possible outputs as so. I wrote a few lines of C code to confirm. As for your second question to whether there is an easier way, I don't know. Maybe someone else can help out.
x y z xy+xz+yz nands
------------------------------
0 0 0 0 0
0 0 1 0 0
0 1 0 0 0
0 1 1 1 1
1 0 0 0 0
1 0 1 1 1
1 1 0 1 1
1 1 1 1 1

How to quickly tell if an "unknown" number is divisible by 3?

I'm trying to tackle down a problem where the time limit is very low (1 second) and the number of cases is supposedly high.
You need to tell if a number is divisible by 3, but the problem is that you don't get the direct number, you get a number k, and then need to check if the concatenation of numbers from 1 to k (123...k) is divisible by 3.
Example input:
4 // The number of cases
2
6
15
130000000
Output:
YES // Because 12 is divisible by 3
YES // Because 123456 is divisible by 3
YES // Because 123456789101112131415 is divisible by 3
NO
I've found some topics about quickly checking the divisibility, but what most time takes I think is to build the number. There are cases where the initial number is as high as 130000000 (so the final is 1234...130000000) which I thinks overflows any numeric data type.
So, what am I missing here? Is there any way to know if something is divisible by 3 without concatenating the number? Any ideas?
PD: Someone also posted the triangular numbers formula which also is a correct solution and then deleted the answer, it was:
if ((1 + num) * num / 2) % 3 == 0 ? "YES" : "NO"
Every third number is divisible by three.
Every number divisible by three has a digit sum divisible by 3.
Every third number has a digit sum divisible by 3.
In between these, every third number has a digit sum congruent to 1 and then 2 mod 3.
Take a look:
n digit sum mod 3
0 0
1 1
2 2
3 0
4 1
5 2
6 0
...
10 1
11 2
12 0
...
19 1
20 2
21 0
...
Say we have a string of digits constructed as you describe, and the number we just added was divisible mod 3. When we append the next number's digits, we are appending digits whose sum is congruent to 1 mod 3, and when added to those in our number, we will get a combined digit sum congruent to 1 mod 3, so our answer for the next one will be "no". The next one will add a number with digit sum congruent to 2 mod 3, and this causes the total to become congruent to 0 again, so the answer here is "yes". Finally, adding the next number which must be divisible by 3 keeps the digit sum congruent to 0.
The takeaway?
if n is congruent to 0 modulo 3, then the answer is "yes"
if n is congruent to 1 modulo 3, then the answer is "no"
if n is congruent to 2 modulo 3, then the answer is "yes"
In particular, your example for n=15 is wrong; the digit string obtained represents a number that should be divisible by 3, and indeed it is (try it on a big enough calculator to verify).
All that is left is to find an implementation that is fast enough and handles all the required cases. If n is guaranteed to be under ~2 billion, then you are probably safe with something like
return (n % 3) != 1;
If n can be an arbitrarily large number, never fear; you can check whether the digit sum is congruent to 0 modulo 3 by adding up the digits in linear time. If not, you can add 1 from the number by coding addition like you do it by hand on paper and then check the result of that for divisibility by 3, again in linear time. So something like:
if (digit_sum_mod_3(n) == 0) return true;
else if (digit_sum_mod_3(add_one(n)) == 0) return false;
else return true;
Then you would have something like
digit_sum_mod_3(n[1...m])
sum = 0
for k = 1 to m do
sum = sum + n[k]
// keep sum from getting too big
if sum >= 18 then
sum = sum - 18
return sum % 3
add_one(n[1...m])
// work from right to left, assume big-endian
for k = m to 1 do
if n[k] < 9 then // don't need to carry
n[k] = n[k] + 1
break
else then // need to carry
n[k] = 0
if n[1] = 0 then // carried all the way to the front
n[1] = 1
n[m+1] = 0
return n
Any three consecutive numbers sum up to 0 == a + a + 1 + a + 2 mod 3.
The answer reduces to k%3 == 0, or 2k-1 % 3 == 0. The latter is equivalent to k%3 == 2, which leaves out k%3==1 which then simplifies further to k%3 != 1.
It is a known trick in mathematics that a number is divisible by three if the sum of its individual decimal digits is divisible by three.
Example:
2271
2+2+7+1 = 12
12 is divisible by 3, therefore so is 2271
Additionally, the sum of any three consecutive integers must be divisible by three. This is because:
((n)+(n+1)+(n+2))/3 = (3n+3)/3 = n+1 = integer
Therefore:
If k mod 3 == 0, then concatenation of 1 to k is divisible by three.
If k mod 3 == 1, then concatenation of 1 to k is not divisible by three.
If k mod 3 == 2, then it is a bit trickier. In this case, concatenation of 1 to k is divisible by three if the sum of k and the number before k (which evaluates to (k)+(k-1), which is 2k-1) is divisible by three.
Therefore, the final condition is:
(k mod 3 == 0) || ((k mod 3 == 2) && (2k-1 mod 3 == 0))
However, this can be even further simplified.
It turns out that k mod 3 can only equal 2 whenever 2k-1 mod 3 equals 0 and vice versa.
See simple graph below that shows cyclic pattern of this behavior.
Therefore, the formula can be further simplified just to:
(k mod 3 == 0) || (k mod 3 == 2)
Or, even more simply:
(k mod 3 != 1)
I realize answerer already provided this answer so I don't expect this to be the accepted answer, just giving a more thorough mathematical explanation.
A number is divisible by three if the sum of its digits is divisible by three (see here). Therefore, there is no need to "construct" your number, you need simply add the digits of the individual numbers. Thus for your 15 case, you do not need to "construct" 123456789101112131415, you just need to sum all of the digits in [1, 2, 3, 4, ... 14, 15].
This is simpler than it sounds because the problem only needs to check numbers of a very specific format: 12345789101112131415…k. You can use Gauss's method to quickly get the sum of the numbers 1 to k and then check if that sum is divisible by three using the usual methods. The code for that is:
'NO' if (k*(k+1)/2)%3 else 'YES'
If you look at the pattern that occurs as k increases (NO, YES, YES, NO, YES, YES, ...), you don't even need the multiplication or division. In short, all you need is:
'YES' if (k-1)%3 else 'NO'
Here is Python code which reads integers from a file and, if it wouldn't take too long also checks the answer the hard way so you can see that it is right. (Python numbers can be infinitely long, so you don't need to worry about overflow):
#!/usr/bin/python3
# Read integers from stdin, convert each int to a triangular number
# and output YES (or NO) if it is divisible by 3.
def sumgauss(x):
'''Return the sum from 1 to x using Gauss's shortcut'''
return (x*(x+1)/2)
def triangle(n):
'''Given an integer n, return a string with all the integers
from 1 to n concatenated. E.g., 15 -> 123456789101112131415'''
result=""
for t in range(1, k+1):
result+=str(t)
return result
import sys
for k in sys.stdin.readlines():
k=int(k)
print ( 'YES' if (k-1)%3 else 'NO', end='')
# If it wouldn't take too long, double check by trying it the hard way
if k<100000:
kstr=triangle(k)
print("\t// %s modulo 3 is %d" % (kstr, int(kstr)%3))
else:
print('\t// 123456789101112131415...%d%d%d modulo 3 is %d' %
tuple([k-2, k-1, k, sumgauss(k)%3]))
Speaking of Gauss's shortcut for summation, this problem seems a lot like a homework assignment. (Gauss invented it as a student when a teacher was trying to get the class out of his hair for a while by making them add up the numbers from 1 to 100.) If this is indeed a class assignment, please make sure the teacher knows to give the A to me and stackoverflow. Thanks!
Sample output:
$ cat data
2
6
15
130000000
130000001
$ ./k3.py < data
YES // 12 modulo 3 is 0
YES // 123456 modulo 3 is 0
YES // 123456789101112131415 modulo 3 is 0
NO // 123456789101112131415...129999998129999999130000000 modulo 3 is 1
YES // 123456789101112131415...129999999130000000130000001 modulo 3 is 0
The first 32 triangular numbers:
$ seq 32 | ./k3.py
NO // 1 modulo 3 is 1
YES // 12 modulo 3 is 0
YES // 123 modulo 3 is 0
NO // 1234 modulo 3 is 1
YES // 12345 modulo 3 is 0
YES // 123456 modulo 3 is 0
NO // 1234567 modulo 3 is 1
YES // 12345678 modulo 3 is 0
YES // 123456789 modulo 3 is 0
NO // 12345678910 modulo 3 is 1
YES // 1234567891011 modulo 3 is 0
YES // 123456789101112 modulo 3 is 0
NO // 12345678910111213 modulo 3 is 1
YES // 1234567891011121314 modulo 3 is 0
YES // 123456789101112131415 modulo 3 is 0
NO // 12345678910111213141516 modulo 3 is 1
YES // 1234567891011121314151617 modulo 3 is 0
YES // 123456789101112131415161718 modulo 3 is 0
NO // 12345678910111213141516171819 modulo 3 is 1
YES // 1234567891011121314151617181920 modulo 3 is 0
YES // 123456789101112131415161718192021 modulo 3 is 0
NO // 12345678910111213141516171819202122 modulo 3 is 1
YES // 1234567891011121314151617181920212223 modulo 3 is 0
YES // 123456789101112131415161718192021222324 modulo 3 is 0
NO // 12345678910111213141516171819202122232425 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526 modulo 3 is 0
YES // 123456789101112131415161718192021222324252627 modulo 3 is 0
NO // 12345678910111213141516171819202122232425262728 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526272829 modulo 3 is 0
YES // 123456789101112131415161718192021222324252627282930 modulo 3 is 0
NO // 12345678910111213141516171819202122232425262728293031 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526272829303132 modulo 3 is 0
Actually the answer is pretty straight forward, if the sum of the digits divisible by three then the number is also divisible by 3.
string ans=(((1 + num) * num) / 2) % 3 == 0 ? "YES" : "NO";
according to the problem sum of digit can be considered as sum of numbers from 1 to n, sum=(n*(n+1))/2
*Make sure you divide the whole thing by 2
Another approach:
string ans=n % 3 !=1 ? "YES" : "NO";
You can prove that if n or n-2 is divisible by 3, then the sum up to n is divisible by 3 (e.g., in your case sum(1...8), sum(1..9), sum(1..11), etc.).

Why does recursive fibonacci work?

I was looking at the following code:
function _fibonacci(n) {
if (n < 2){
return 1;
}else{
return _fibonacci(n-2) + _fibonacci(n-1);
}
}
console.log(_fibonacci(5))
I understand HOW this works, but I do not understand WHY this works. Can someone explain to me why this works?
It's quite simple, the fibonacci answer for both location 0 and 1 are both 1 (the sequence looks like 1 1 2 3 5 8 etc...) so when it enters the function with n being 0 or 1 (which can happen for both the n-2 recursive call and the n-1 recursive call), the result is 1. For all other values it just keeps adding the numbers.
(Note that the values for the first 2 in the sequence can be 0 1 or 1 1, depending on your definition of the sequence. For this one it's apparently assumed the first 2 are both 1.)

Recursively Find A Path

I have a series of numbers ranging from 0-9. Each number represents a position with an x and y co-ordinate. So, position 0 could represent (5, 5) or something similar, always (x, y). Now what I need to do is recursively bash each possible route using 5 positions to get the position given by a user. So for example:
Input = (1, 2) //This is the co-ordinate the user gives.
Now given this input it should take every possible path and find the shortest one. Some paths could be:
start 0 1 2 3 4 input
start 0 1 2 3 5 input
start 0 1 2 3 6 input
start 0 1 2 3 7 input
start 0 1 2 4 3 input
start 1 0 2 3 5 input
and so on....
It could be any combination of 5 numbers from the 0-9. It must end at the input destination and begin at start destination. Numbers cannot be reused. So I need to recursively add all the distances for a given course (ex. start 0 1 2 3 4 input) and find the shortest possible course while going through those 5 points.
Question: What would the base and recursive case be?
Basically what you want to do is generate all combinations of size k (the length of the path) from the set {1,..,n}, and then calculate the value of the path for it.
Here's a C# code sample:
void OPTPathForKSteps(List<int> currentPath, List<int> remainingPositions, int remainingSteps)
{
if (remainingSteps == 0)
{
// currentPath now contains a combination of k positions
// do something with currentPath...
}
else
{
for (int i = 0; i < remainingPositions.Count; i++)
{
int TempPositionIndex = remainingPositions[i];
currentPath.Add(TempPositionIndex);
remainingPositions.RemoveAt(i);
OPTPathForKSteps(currentPath, remainingPositions, remainingSteps - 1);
remainingPositions.Insert(i, TempPositionIndex);
currentPath.RemoveAt(currentPath.Count - 1);
}
}
}
This is the initial call for the function (assume Positions is an integer list of 0...n positions, and k is the length of the path):
OPTPathForKSteps(new List<int>(), Positions, K);
You can change the function and add arguments so it will return the optimal path and minimal value.
There are other (maybe shorter) ways to create these combinations, the good thing about my implementation is that it is light on the memory, and doesn't require storing all the possible combinations.

Repeat a loop until it satisfies a specific condition

Anybody can help me on this? Suppose the "p" is totally exogenous and following a uniform distribution. Then I want to generate "z", which is a TRUE(=1) or FALSE(=0) dummy, and has the property that the summation of each three elements (1-3, 4-6, 7-9,..., 58-60) in "z" should be greater than 0.
For example, if I get a "z" like {1 0 0 1 1 0 0 0 0 0 1 0...}, I hope to repeat the loop again ( since sum(z[7:9])=0 ) to draw a different "error" until I get a new "z" like {1 1 0 0 0 1 0 1 0 1 0 0...} where all summations for each three elements are greater than 0. The code I use is as follows. Where am I wrong?
set.seed(005)
p<-runif(60, 0, 1)
for (i in 1:20) {
repeat {
error= -0.2*log((1/runif(60, 0, 1))-1) # a random component
z=(p<0.5+error) # TRUE/FALSE condition
z=replace(z, z==TRUE, 1) # replace z to 1 if z is true, else z=0
if (sum(z[(3*i-2):(3*i)])>0) {break}
}
}
Your for loop generates a new z for every i. I don't think that's what you're trying to do. From what I can understand, you're trying to generate a new z and then use a for loop with the counter i to check for sums of three consecutive elements. If so, then you need to have one loop to generate new zs, and then another one inside this loop which checks for the sum of three consecutive elements.
I think this does what you want. But when I run it it seems unlikely that you will get a satisfactory z soon.
set.seed(005)
p<-runif(60, 0, 1)
invalidentriesexist =1
while(invalidentriesexist == 1) {
error = -0.2*log((1/runif(60, 0, 1))-1) # a random component
z=(p<0.5+error) # TRUE/FALSE condition
z=replace(z, z==TRUE, 1) # replace z to 1 if z is true, else z=0
z=replace(z, z==FALSE, 0) # replace z to 1 if z is true, else z=0
invalidentriesexist = 0
i = 1
while ( i <=20 & invalidentriesexist == 0 ) {
invalidentriesexist = 0
if (sum(z[((3*i)-2):(3*i)])==0) {invalidentriesexist = 1}
cat(i,'\n')
cat(invalidentriesexist,'\n')
cat(paste(z,collapse = ","),'\n')
cat(z[((3*i)-2):(3*i)],'\n\n')
i = i + 1
}
}

Resources