Algorithm that displays all the even numbers between 0 and 1000 - algorithm

This is how I did it and I think it's wrong
Step 1: Start
Step 2: I = 0
Step 3: Input number
Step 4:
while(i <= 1000)
if(number % 2 == 0)
display the number
Step 5: End

Increase i with each iteration in loop

Related

Need to set the limits of input data

Needing some help please with a project for a course that requires us to create a python program that has the user input 5 numbers (between 0 and 100), displays those numbers on the screen, then calculates and displays the sum of the numbers and average of those numbers. I have done pretty much everything except for having the program determine if the number is between 0 and 100 and if it isn't, prompt the user for a number within the range. Can anyone please help me with this last part. Here is the code I have at present.
print("please enter your 5 marks below")
#read 5 inputs
mark1 = int(input("enter mark 1: "))
mark2 = int(input("enter mark 2: "))
mark3 = int(input("enter mark 3: "))
mark4 = int(input("enter mark 4: "))
mark5 = int(input("enter mark 5: "))
#create array/list with five marks
marksList = [mark1, mark2, mark3, mark4, mark5]
#print the array/list
print(marksList)
#calculate the sum and average
sumOfMarks = sum(marksList)
averageOfMarks = sum(marksList)/5
#display results
print("The sum of your marks is: "+str(sumOfMarks))
print("The average of your marks is: "+str(averageOfMarks))
UPDATE: I have managed to figure it out using WHILE loops as below, however I am sure there is a much more efficient way of doing it by having just 1 input statement with a variable (say 'n') which loops through the numbers 1-5....any ideas on how to do that??
while True:
mark1 = int(input("enter mark 1: "))
if 0 < mark1 <100:
break
print('Please enter a number between 0 and 100')
while True:
mark2 = int(input("enter mark 2: "))
if 0 < mark2 <100:
break
print('Please enter a number between 0 and 100')
while True:
mark3 = int(input("enter mark 3: "))
if 0 < mark3 <100:
break
print('Please enter a number between 0 and 100')
while True:
mark4 = int(input("enter mark 4: "))
if 0 < mark4 <100:
break
print('Please enter a number between 0 and 100')
while True:
mark5 = int(input("enter mark 5: "))
if 0 < mark5 <100:
break
print('Please enter a number between 0 and 100')

How do I find the number of ways to place blocks of length 1 and 3, in a walkway, using recursion?

I have been given the following problem. Given a walkway of length n, design a recursive algorithm that tells the number of ways to place blocks of size 1 and size 3 on the walkway. I understand the strategy to apply recursion to this problem -
Put in base cases for cases where the walkway is of lengths 1, 2, and 3.
Assume that you already have figured out the number of ways to place blocks of length 1 on the walkway
Assume that you already have figured out the number of ways to place blocks of length 3 on the walkway
Add 2) and 3)
My problem is that I don't know how to code 2) and 3). Here's my code below -
def countPatterns(n):
if(n==1 or n==2):
return 1
elif(n==3):
return 2
elif(n<1):
return 0
else:
# return 2) and 3)
This problem is the same as given the target sum and you need to count number of ways that you can get that target sum just by adding numbers 1 and 3.
Example:
sum = 4
ways:
1: 1 + 1 + 1 + 1
2: 1 + 3
3: 3 + 1
So your function for sum = 4 should return 3.
I think your approach is wrong. Here is my solution:
def numWays(tSum):
if tSum < 0:
return 0
if tSum <= 2:
return 1
return numWays(tSum - 1) + numWays(tSum - 3)

Why in this factorial code (no recursion) the step is -1 instead of +1?

Why in this code for calculating factorial the step is -1, not +1?
How it calculates n = 0, if in the program we have only n < 0 and n > 0?
def factorial(n)
if n < 0
return nil
end
result = 1
while n > 0
result = result * n
n -= 1
end
return result
end
It calculates n=0 because result is set to 1 by default. When n is 0, the loop will not run (because n is not > 0), so the default value of result (which is 1) will be returned.
It subtracts one each time so that it can count downward over all the numbers, so
5! = 5 * 4 * 3 * 2 * 1
If it added one each time it would be
5! = 5 * 6 * 7 * 8...
and so on. So not only would it be wrong but it would also be an infinite loop.
The step is -1 so that you multiply together all the values of n * (n -1) * (n - 2) * ... * 1. Since the multiplication starts at n and goes down, you want the step to be negative. (Alternatively, you could start at 1 and go up to n. In that case you would want the step to be +1. That's just not how this implementation works.)
The program still works for an input of 0 because the default is set to result = 1 before the while loop. The body of the loop is skipped in that case.
1 * 2 * 3 == 3 * 2 * 1, so arithmetically it doesn't matter whether you work your way up or down. However, decrementing the argument n allows it to be used directly in calculating result, as opposed to basing the calculation on an additional separate variable which gets incremented until it hits n.
That said, it's still not a very ruby way of doing things. I'd probably go with something like:
def factorial(n)
n == 0 ? 1 : (1..n).inject(:*)
end
You also asked how your implementation calculates factorial(0) as 1. If n == 0 the while n > 0 loop is never activated, so from your initialization result = 1 you skip down to the return statement.
The reason the step is -1 and not +1 is because the while loop is going while n > 0. So if you were to do n += 1, you would have an infinite loop on your hands.
If you were to set up a for loop with an iterator, you could start the iterator and go until iterator <= n. In that case, you would want to do iterator += 1. But in this situation, we just need to multiply all the values from 1-n together, which is not sensitive to order. Because of that, it is simpler and less code to start at n and decrement it until it reaches zero. That is the reason for n -= 1.

Running time/time complexity for while loop with square root

This question looks relatively simple, but I can't seem to find the running time in terms of n.
Here is the problem:
j = n;
while(j >= 2) {
j = j^(1/2)
}
I don't really need the total running time, I just need to know how to calculate the amount of times the second and third lines are hit (they should be the same). I'd like to know if there is some sort of formula for finding this, as well. I can see that the above is the equivalent of:
for(j = n; n >= 2; j = j^(1/2)
Please note that the type of operation doesn't matter, each time a line is executed, it counts as 1 time unit. So line 1 would just be 1 time unit, line 2 would be:
0 time units if n were 1,
1 time unit if n were 2,
2 time units if n were 4,
3 time units if n were 16, etc.
Thanks in advance to anyone who offers help! It is very much appreciated!
Work backwards to get the number of time units for line 2:
time
n n log_2(n) units
1 1 0 0
2 2 1 1
4 4 2 2
16 16 4 3
16^2 256 8 4
(16^2)^2 65536 16 5
((16^2)^2)^2) ... 32 6
In other words, for the number of time units t, n is 2^(2^(t-1)) except for the case t = 0 in which case n = 1.
To reverse this, you have
t = 0 when n < 2
t = log2(log2(n)) + 1 when n >= 2
where log2(x) is known as the binary logarithm of x.

Finding maximum size sub-matrix of all 1's in a matrix having 1's and 0's

Suppose you are given an mXn bitmap, represented by an array M[1..m,1.. n] whose entries are all 0 or 1. A all-one block is a subarray of the form M[i .. i0, j .. j0] in which every bit is equal to 1. Describe and analyze an efficient algorithm to find an all-one block in M with maximum area
I am trying to make a dynamic programming solution. But my recursive algorithm runs in O(n^n) time, and even after memoization I cannot think of bringing it down below O(n^4). Can someone help me find a more efficient solution?
An O(N) (number of elements) solution:
A
1 1 0 0 1 0
0 1 1 1 1 1
1 1 1 1 1 0
0 0 1 1 0 0
Generate an array C where each element represents the number of 1s above and including it, up until the first 0.
C
1 1 0 0 1 0
0 2 1 1 2 1
1 3 2 2 3 0
0 0 3 3 0 0
We want to find the row R, and left, right indices l , r that maximizes (r-l+1)*min(C[R][l..r]). Here is an algorithm to inspect each row in O(cols) time:
Maintain a stack of pairs (h, i), where C[R][i-1] < h ≤ C[R][i]. At any position cur, we should have h=min(C[R][i..cur]) for all pairs (h, i) on the stack.
For each element:
If h_cur>h_top
Push (h, i).
Else:
While h_cur<h_top:
Pop the top of the stack.
Check whether it would make a new best, i.e. (i_cur-i_pop)*h_pop > best.
If h_cur>h_top
Push (h, i_lastpopped).
An example of this in execution for the third row in our example:
i =0 1 2 3 4 5
C[i]=1 3 2 2 3 0
(3, 4)
S= (3, 1) (2, 1) (2, 1) (2, 1)
(1, 0) (1, 0) (1, 0) (1, 0) (1, 0)
(0,-1) (0,-1) (0,-1) (0,-1) (0,-1) (0,-1)
i=0, C[i]=1) Push (1, 0).
i=1, C[i]=3) Push (3, 1).
i=2, C[i]=2) Pop (3, 1). Check whether (2-1)*3=3 is a new best.
        The last i popped was 1, so push (2, 1).
i=3, C[i]=2) h_cur=h_top so do nothing.
i=4, C[i]=3) Push (3, 4).
i=5, C[i]=0) Pop (3, 4). Check whether (5-4)*3=3 is a new best.
        Pop (2, 1). Check whether (5-1)*2=8 is a new best.
        Pop (1, 0). Check whether (5-0)*1=5 is a new best.
        End. (Okay, we should probably add an extra term C[cols]=0 on the end for good measure).
Here's an O(numCols*numLines^2) algorithm. Let S[i][j] = sum of the first i elements of column j.
I will work the algorithm on this example:
M
1 1 0 0 1 0
0 1 1 1 0 1
1 1 1 1 0 0
0 0 1 1 0 0
We have:
S
1 1 0 0 1 0
1 2 1 1 1 1
2 3 2 2 1 1
2 3 3 3 1 1
Now consider the problem of finding the maximum subarray of all ones in a one-dimensional array. This can be solved using this simple algorithm:
append 0 to the end of your array
max = 0, temp = 0
for i = 1 to array.size do
if array[i] = 1 then
++temp
else
if temp > max then
max = temp
temp = 0
For example, if you have this 1d array:
1 2 3 4 5 6
1 1 0 1 1 1
you'd do this:
First append a 0:
1 2 3 4 5 6 7
1 1 0 1 1 1 0
Now, notice that whenever you hit a 0, you know where a sequence of contiguous ones ends. Therefore, if you keep a running total (temp variable) of the current number of ones, you can compare that total with the maximum so far (max variable) when you hit a zero, and then reset the running total. This will give you the maximum length of a contiguous sequence of ones in the variable max.
Now you can use this subalgorithm to find the solution for your problem. First of all append a 0 column to your matrix. Then compute S.
Then:
max = 0
for i = 1 to M.numLines do
for j = i to M.numLines do
temp = 0
for k = 1 to M.numCols do
if S[j][k] - S[i-1][k] = j - i + 1 then
temp += j - i + 1
else
if temp > max then
max = temp
temp = 0
Basically, for each possible height of a subarray (there are O(numLines^2) possible heights), you find the one with maximum area having that height by applying the algorithm for the one-dimensional array (in O(numCols)).
Consider the following "picture":
M
1 1 0 0 1 0 0
i 0 1 1 1 0 1 0
j 1 1 1 1 0 0 0
0 0 1 1 0 0 0
This means that we have the height j - i + 1 fixed. Now, take all the elements of the matrix that are between i and j inclusively:
0 1 1 1 0 1 0
1 1 1 1 0 0 0
Notice that this resembles the one-dimensional problem. Let's sum the columns and see what we get:
1 2 2 2 0 1 0
Now, the problem is reduced to the one-dimensional case, with the exception that we must find a subsequence of contiguous j - i + 1 (which is 2 in this case) values. This means that each column in our j - i + 1 "window" must be full of ones. We can check for this efficiently by using the S matrix.
To understand how S works, consider a one-dimensional case again: let s[i] = sum of the first i elements of the vector a. Then what is the sum of the subsequence a[i..j]? It's the sum of all the elements up to and including a[j], minus the sum of all those up to and including a[i-1], meaning s[j] - s[i-1]. The 2d case works the same, except we have an s for each column.
I hope this is clear, if you have any more questions please ask.
I don't know if this fits your needs, but I think there's also an O(numLines*numCols) algorithm, based on dynamic programming. I can't figure it out yet, except for the case where the subarray you're after is square. Someone might have better insight however, so wait a bit more.
Define a new matrix A wich will store in A[i,j] two values: the width and the height of the largest submatrix with the left upper corner at i,j, fill this matrix starting from the bottom right corner, by rows bottom to top. You'll find four cases:
Perform these cases when given matrix at [i,j]=1
case 1: none of the right or bottom neighbour elements in the original matrix are equal to the current one, i.e: M[i,j] != M[i+1,j] and M[i,j] != M[i,j+1] being M the original matrix, in this case, the value of A[i,j] is 1x1
case 2: the neighbour element to the right is equal to the current one but the bottom one is different, the value of A[i,j].width is A[i+1,j].width+1 and A[i,j].height=1
case 3: the neighbour element to the bottom is equal but the right one is different, A[i,j].width=1, A[i,j].height=A[i,j+1].height+1
case 4: both neighbours are equal:
Three rectangles are considered:
A[i,j].width=A[i,j+1].width+1; A[i,j].height=1;
A[i,j].height=A[i+1,j].height+1; a[i,j].width=1;
A[i,j].width = min(A[i+1,j].width+1,A[i,j+1].width) and A[i,j].height = min(A[i,j+1]+1,A[i+1,j])
The one with the max area in the above three cases will be considered to represent the rectangle at this position.
The size of the largest matrix that has the upper left corner at i,j is A[i,j].width*A[i,j].height so you can update the max value found while calculating the A[i,j]
the bottom row and the rightmost column elements are treated as if their neighbours to the bottom and to the right respectively are different.
Here is a O(N) implementation in C#.
The idea is to use a dynamic programming to build an accumulated Matrix that has the size of the biggest submatrix including the current cell itself.
public static int LargestSquareMatrixOfOne(int[,] original_mat)
{
int[,] AccumulatedMatrix = new int[original_mat.GetLength(0), original_mat.GetLength(1)];
AccumulatedMatrix[0, 0] = original_mat[0, 0];
int biggestSize = 1;
for (int i = 0; i < original_mat.GetLength(0); i++)
{
for (int j = 0; j < original_mat.GetLength(1); j++)
{
if (i > 0 && j > 0)
{
if (original_mat[i, j] == 1)
{
AccumulatedMatrix[i, j] = Math.Min(AccumulatedMatrix[i - 1, j - 1], (Math.Min(AccumulatedMatrix[i - 1, j], AccumulatedMatrix[i, j - 1]))) + 1;
if (AccumulatedMatrix[i, j] > biggestSize)
{
biggestSize = AccumulatedMatrix[i, j];
}
}
else
{
AccumulatedMatrix[i, j] = 0;
}
}
else if ( (i > 0 && j == 0) || (j > 0 && i == 0))
{
if (original_mat[i, j] == 1) { AccumulatedMatrix[i, j] = 1; }
else { AccumulatedMatrix[i, j] = 0; }
}
}
}
return biggestSize;
}

Resources