What means for i=a,1,-1 in pseudocode? - pseudocode

I have a code in pseudocode.
This is a line of code: for i=k1,1,-1 do Ti <- Ti-1 + Ti.
k1 is an integer. Ti is an array.
The question is: what means for i=k1,1,-1? I know what is for but I don't know what is i=k1,1,-1.
Thank you!

Have i assume values from k1 to 1 with steps of -1. Equivalent to C:
for (i = k1; i >= 1; i += -1)
The syntax in your question is basically same as in Fortran, been around for decades:
DO 10,i=k1,1,-1
T(i) = T(i-1) + T(i)
10 CONTINUE

It means the loop is counting downwards (-1) starting at k1, finishing at 1.

It probably means that i starts at k1 and decreases to 1 by steps of -1 , i.e. in C
for (i=k1; i>=1; i--)

Related

Product of consecutive numbers f(n) = n(n-1)(n-2)(n-3)(n- ...) find the value of n

Is there a way to find programmatically the consecutive natural numbers?
On the Internet I found some examples using either factorization or polynomial solving.
Example 1
For n(n−1)(n−2)(n−3) = 840
n = 7, -4, (3+i√111)/2, (3-i√111)/2
Example 2
For n(n−1)(n−2)(n−3) = 1680
n = 8, −5, (3+i√159)/2, (3-i√159)/2
Both of those examples give 4 results (because both are 4th degree equations), but for my use case I'm only interested in the natural value. Also the solution should work for any sequences size of consecutive numbers, in other words, n(n−1)(n−2)(n−3)(n−4)...
The solution can be an algorithm or come from any open math library. The parameters passed to the algorithm will be the product and the degree (sequences size), like for those two examples the product is 840 or 1640 and the degree is 4 for both.
Thank you
If you're interested only in natural "n" solution then this reasoning may help:
Let's say n(n-1)(n-2)(n-3)...(n-k) = A
The solution n=sthen verifies:
remainder of A/s = 0
remainder of A/(s-1) = 0
remainder of A/(s-2) = 0
and so on
Now, we see that s is in the order of t= A^(1/k) : A is similar to s*s*s*s*s... k times. So we can start with v= (t-k) and finish at v= t+1. The solution will be between these two values.
So the algo may be, roughly:
s= 0
t= (int) (A^(1/k)) //this truncation by leave out t= v+1. Fix it in the loop
theLoop:
for (v= t-k to v= t+1, step= +1)
{ i=0
while ( i <= k )
{ if (A % (v - k + i) > 0 ) // % operator to find the reminder
continue at theLoop
i= i+1
}
// All are valid divisors, solution found
s = v
break
}
if (s==0)
not natural solution
Assuming that:
n is an integer, and
n > 0, and
k < n
Then approximately:
n = FLOOR( (product ** (1/(k+1)) + (k+1)/2 )
The only cases I have found where this isn't exactly right is when k is very close to n. You can of course check it by back-calculating the product and see if it matches. If not, it almost certainly is only 1 or 2 in higher than this estimate, so just keep incrementing n until the product matches. (I can write this up in pseudocode if you need it)

What is wrong with the recursive algorithm developed for the below problem?

I have tried to solve an algorithmic problem. I have come up with a recursive algorithm to solve the same. This is the link to the problem:
https://codeforces.com/problemset/problem/1178/B
This problem is not from any contest that is currently going on.
I have coded my algorithm and had run it on a few test cases, it turns out that it is counting more than the correct amount. I went through my thought process again and again but could not find any mistake. I have written my algorithm (not the code, but just the recursive function I have thought of) below. Can I please know where had I gone wrong -- what was the mistake in my thought process?
Let my recursive function be called as count, it takes any of the below three forms as the algorithm proceeds.
count(i,'o',0) = count(i+1,'o',0) [+ count(i+1,'w',1) --> iff (i)th
element of the string is 'o']
count(i,'w',0) = count(i+1,'w',0) [+ count(i+2,'o',0) --> iff (i)th and (i+1)th elements are both equal to 'v']
count(i,'w',1) = count(i+1,'w',1) [+ 1 + count(i+2,'w',0) --> iff (i)th and (i+1)th elements are both equal to 'v']
Note: The recursive function calls present inside the [.] (square brackets) will be called iff the conditions mentioned after the arrows are satisfied.)
Explanation: The main idea behind the recursive function developed is to count the number of occurrences of the given sequence. The count function takes 3 arguments:
argument 1: The index of the string on which we are currently located.
argument 2: The pattern we are looking for (if this argument is 'o' it means that we are looking for the letter 'o' -- i.e. at which index it is there. If it is 'w' it means that we are looking for the pattern 'vv' -- i.e. we are looking for 2 consecutive indices where this pattern occurs.)
argument 3: This can be either 1 or 0. If it is 1 it means that we are looking for the 'vv' pattern, having already found the 'o' i.e. we are looking for the 'vv' pattern shown in bold: vvovv. If it is 0, it means that we are searching for the 'vv' pattern which will be the
beginning of the pattern vvovv (shown in bold.)
I will initiate the algorithm with count(0,'w',0) -- it means, we are at the 0th index of the string, we are looking for the pattern 'vv', and this 'vv' will be the prefix of the 'vvovv' pattern we wish to find.
So, the output of count(0,'w',0) should be my answer. Now comes the trouble, for the following input: "vvovooovovvovoovoovvvvovo" (say input1), my program (which is based on the above algorithm) gives the expected answer(= 50). But, when I just append "vv" to the above input to get a new input: "vvovooovovvovoovoovvvvovovv" (say input2) and run my algorithm again, I get 135 as the answer, while the correct answer is 75 (this is the answer the solution code returns). Why is this happening? Where had I made an error?
Also, one more doubt is if the output for the input1 is 50, then the output for the input2 should be at least twice right -- because all of the subsequences which were present in the input1, will be present in the input2 too and all of those subsequences can also form a new subsequence with the appended 'vv' -- this means we have at least 100 favourable subsequences right?
P.S. This is the link to the solution code https://codeforces.com/blog/entry/68534
This question doesn't need recursion or dynamic programming.
The basic idea is to count how many ws we have before and after each o.
If you have X vs, it means you have X - 1 ws.
Let's use vvvovvv as an example. We know that before and after the o we have 3 vs, which means 2 ws. To evaluate the answer, just multiply 2x2 = 4.
For each o we find, we just need to multiply the ws before and after it, sum it all and this is our answer.
We can find how many ws there are before and after each o in linear time.
#include <iostream>
using namespace std;
int convert_v_to_w(int v_count){
return max(0, v_count - 1);
}
int main(){
string s = "vvovooovovvovoovoovvvvovovvvov";
int n = s.size();
int wBefore[n];
int wAfter[n];
int v_count = 0, wb = 0, wa = 0;
//counting ws before each o
int i = 0;
while(i < n){
v_count = 0;
while(i < n && s[i] == 'v'){
v_count++;
i++;
}
wb += convert_v_to_w(v_count);
if(i < n && s[i] == 'o'){
wBefore[i] = wb;
}
i++;
}
//counting ws after each o
i = n - 1;
while(i >= 0){
v_count = 0;
while(i >= 0 && s[i] == 'v'){
v_count++;
i--;
}
wa += convert_v_to_w(v_count);
if(i >= 0 && s[i] == 'o'){
wAfter[i] = wa;
}
i--;
}
//evaluating answer by multiplying ws before and after each o
int ans = 0;
for(int i = 0; i < n; i++){
if(s[i] == 'o') ans += wBefore[i] * wAfter[i];
}
cout<<ans<<endl;
}
output: 100
complexity: O(n) time and space

Unable to understand algorithm

Here is the link of problem
https://www.hackerrank.com/challenges/equal
I read its editorial and unable to understand it. And if you are not make any account on hackerrank then surely you will not see it's editorial so here is some lines of editorial.
This is equivalent to saying, christy can take away the chocolates of
one coworker by 1, 2 or 5 while keeping others' chocolate untouched.
Let's consider decreasing a coworker's chocolate as an operation. To minimize the number of operations, we should try to make the number of chocolates of every coworker equal to the minimum one in the group(min). We have to decrease the number of chocolates the ith person A[i] by (A[i] - min). Let this value be x.
This can be done in k operations.
k = x/5 +(x%5)/2 + (x%5)%2
and from here i unable to understand
Let f(min) be sum of operations performed over all coworkers to reduce
each of their chocolates to min. However, sometimes f(min) might not
always give the correct answer. It can also be a case when
f(min) > f(min-1)
f(min) < f(min-5)
as f(min-5) takes N operations more than f(min) where N is the number
of coworkers. Therefore, if
A = {min,min-1,min-2,min-3,min-4}
then f(A) <= f(min) < f(min-5)
can someone help me to understand why this is necessary to check f(min),f(min-1),...,f(min-4)
Consider the case A = [1,5,5]
As the editorial said, it is intuitive to think it is optimal to change A to [1,1,1] with 4 (2 minus 2) operations, but it is better to change it to [0,0,0] with 3 (1 minus 1, 2 minus 5) operations.
Hence if min = minimum element in array, then change all elements to min may not be optimal.
The part you do not understand is to cater this situation, we know min may not be optimal as min-x maybe better, but how large is x? Well it is 4. The editorial is saying if we know x is at most 4, we can just simply brute force min, min-1...min-4 to see which one is the minimum without thinking too much.
Reasoning (Not proof!) for x <= 4
If x >= 5, then you have to use at least extra N type 3 (minus 5) operations on all elements which is definitely not worth.
Basically it is not a matter of the type of operation, it is because you need to use same operation on ALL elements, after you do that, the problem is not reduced, the relative difference between elements is still the same while you aim to make the relative difference to 0, you cost N operations for nothing.
In other words, if x >= 5, then x-5 must be a more optimal choice of goal, indeed x%5 must be the best goal.
(Below is TL;DR part: Version 2) Jump to the Last Section If You are Not Interested in the proof
In the process of writing the original solution, I suspect x <= 2 indeed, and I have tried to submit a code on HackerRank which only check minimum for f(min-x) where x <= 2, and it got ACed.
More formally, I claim
If 5> (z-min)%5 >= 3 and (z-min')%5==0, then F(min')< F(min)
where min'=min-x for x<=2, F(k) = min # of operation for element z to become k
(Beware the notation, I use F(), it is different meaning from f() in the question)
Here is the proof:
If (z-min)%5 = 1 or 2, then it needs at least (z-min)/5 + 1 operations, while (z-min')%5 == 0 needs (z-min')/5 = (z-min)/5 + 1 operation, means F(min') = F(min)
If(z-min)%5 == 3 or 4, then it needs at least (z-min)/5 + 2 operations, while (z-min')%5 == 0 needs (z-min')/5 = (z-min)/5 + 1 operation, means F(min') < F(min) (or F(min') = F(min)+1)
So we proof
If 5> (z-min)%5 >= 3 and (z-min')%5==0, then F(min')< F(min)
where min'=min-x
Now let's proof the range of x
As we assume (z-min)%5 >= 3 and (z-min')%5 == 0,
so (z-min')%5 = (z-min+x)%5 = ((z-min)%5 + x%5)%5 == 0
Now, if x >= 3, then (z-min)%5 can never be >= 3 in order to make ((z-min)%5 + x%5)%5 == 0
If x = 2, then (z-min)%5 can be 3; if x = 1 then (z-min)%5 can be 4, to meet both conditions: 5> (z-min)%5 >= 3 and (z-min')%5==0
Thus together we show
If 5> (z-min)%5 >= 3 and (z-min')%5==0, then F(min')< F(min)
where min'=min-x for x<=2
Note one can always generate array P, such that f(min') < f(min), as you can always repeat integer which can be improved by such method until it out number those integers cannot. This is because for elements that cannot be improved, they will always need exactly 1 more operations
eg: Let P = [2,2,2,10] f(min) = 0+3 = 3, f(min-2) = 3+2 = 5
Here 10 is the element which can be improved, while 2 cannot, so we can just add more 10 in the array. Each 2 will use 1 more operation to get to min' = min-2, while each 10 will save 1 operation to get min'. So we only have to add more 10 until it out number (compensate) the "waste" of 2:
P = [2,2,2,10,10,10,10,10], then f(min) = 0+15 = 15, f(min-2) = 3+10=13
or simply just
P = [2,10,10], f(min) = 6, f(min-2) = 5
(End of TL;DR part!)
EDITED
OMG THE TEST CASE ON HACKERRANK IS WEAK!
Story is when I arrive my office this morning, I keep thinking this problem a bit, and think that there maybe a problem in my code (which got ACed!)
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int T, n, a[10005], m = 1<<28;
int f(int m){
m = max(0, m);
int cnt = 0;
for(int i=0; i<n;i++){
cnt += (a[i]-m)/5 + (a[i]-m)%5/2 + (a[i]-m)%5%2;
}
return cnt;
}
int main() {
cin >> T;
while(T--){
m = 1<<28;
cin >> n;
for(int i=0; i<n;i++) cin >> a[i], m = min(m,a[i]);
cout << min(min(f(m), f(m-1)),f(m-2)) << endl;
}
return 0;
}
Can you see the problem?
The problem is m = max(0, m); !
It ensure that min-x must be at least 0, but wait, my proof above did not say anything about the range of min-x! It can be negative indeed!
Remember the original question is about "adding", so there is no maximum value of the goal; while we model the question to "subtracting", there is no minimum value of the goal as well (but I set it to 0!)
Try this test case with the code above:
1
3
0 3 3
It forces min-x = 0, so it gives 4 as output, but the answer should be 3
(If we use "adding" model, the goal should be 10, with +5 on a[0],a[2], +5 on a[0],a[1], +2 on a[1], a[2])
So everything finally got right (I think...) when I remove the line m = max(0, m);, it allows min-x to get negative and give 3 as a correct output, and of course the new code get ACed as well...

Ruby challenge: experienced developers opinions

I'm working on some ruby problems geared towards new developers, but I would like the opinions of experienced developers on this. Sorry for the long post, and I really appreciate your time and opinions.
Problem Question
Write a function, nearest_larger(arr, i) which takes an array and an
index. The function should return another index, j: this should
satisfy:
(a) arr[i] < arr[j], AND
(b) there is no j2 closer to i than j where arr[i] < arr[j].
In case of ties (see example below), choose the earliest (left-most)
of the two indices. If no number in arr is larger than arr[i],
return nil.
Difficulty: 2/5
Rspec Test
describe "#nearest_larger" do
it "handles a simple case to the right" do
nearest_larger([2,3,4,8], 2).should == 3
end
it "handles a simple case to the left" do
nearest_larger([2,8,4,3], 2).should == 1
end
it "treats any two larger numbers like a tie" do
nearest_larger([2,6,4,8], 2).should == 1
end
it "should choose the left case in a tie" do
nearest_larger([2,6,4,6], 2).should == 1
end
it "handles a case with an answer > 1 distance to the left" do
nearest_larger([8,2,4,3], 2).should == 0
end
it "handles a case with an answer > 1 distance to the right" do
nearest_larger([2,4,3,8], 1).should == 3
end
it "should return nil if no larger number is found" do
nearest_larger( [2, 6, 4, 8], 3).should == nil
end
end
Solution
def nearest_larger arr, idx
diff = 1
loop do
l = idx - diff
r = idx + diff
return l if (l >= 0) && (arr[l] > arr[idx])
return r if (r < arr.length) && (arr[r] > arr[idx])
return nil if (l < 0) && (r >= arr.length)
diff += 1
end
end
Feedback
How would you go about working towards a solution for this problem? (what's your process?)
In your opinion do find the Problem Question clear and easy to understand?
How long should it take you to solve this problem? (10min, 20min, ...?)
Do agree with the level of difficulty? (Keep in mind this is geared towards new developers)
If willing: please post your own solution, showcasing your style of solving this problem.
I decided to post this question because I know how easy it can be for new developer to get stuck on a problem and not know what to write first. I'm hoping your responses will give an insight on how you would work through a problem that you perceive as a challenge.
I have not an experienced developer, or even an inexperienced one, but I will give you my thoughts anyway.
1 How would you go about working towards a solution for this problem? (what's your process?)
I would look to break into pieces, but surely everyone does that. For example, here the values in the array are only used to pull out the indices of elements that are larger, so I'd see the first problem as pulling out the indices and the second problem as dealing with the indices alone. I'd further simplify the latter by subtracting i from each index so that j and be compared to k like so: if j.abs < k.abs ..., rather than if (j-i).abs < (k-i).abs.... In choosing among different approaches, I tend to look for the one that is most easily understood ("reads best").
2. In your opinion do find the Problem Question clear and easy to understand?
Yes.
3. How long should it take you to solve this problem?
I refuse to answer on the grounds that it would surely incriminate me.
4. Do you agree with the level of difficulty?
It seems about right. It would be a "beginner" problem at rubeque.com.
5. If willing: please post your own solution, showcasing your style of solving this problem.
Sure.
def nearest_larger(arr, i)
ret = nearest_to_zero( arr.each_with_index
.select { |e,j| e > arr[i] }
.map { |_,j| j-i } )
ret ? ret + i : nil
end
I looked at two ways of writing nearest_to_zero(). The first is short, direct and clear, but inefficient, using sort!:
def nearest_to_zero(a)
a.sort! { |j,k| (j.abs == k.abs) ? j <=> k : j.abs <=> k.abs }
a.any? ? a.first : nil
end
More efficient, but not as pretty:
def nearest_to_zero(a)
neg, pos = a.partition { |e| e < 0 }
case
when neg.empty?
pos.empty? ? nil : pos.first
when pos.empty?
neg.last
else
pos.last.abs < neg.last.abs ? pos.first : neg.last
end
end
For arr = [2,5,4,8,10], i = 2, the following steps are performed by nearest_larger():
a = arr.each_with_index.select { |e,j| e > arr[i] } # => [[5,1],[8,3],[10,4]]
b = a.map { |_,j| j-i } # => [-1,1,2]
ret = nearest_to_zero(b) # => -1
ret ? ret + i : nil # => 1
In the first nearest_to_zero(), if two indices have equal absolute value (meaning they are equally close to i before the transformation), the tie goes to the index with the lower vlaue; else it is the index with the smaller absolute value.
In the second nearest_to_zero():
neg, pos = [-1,1,2].partition {|e| e < 0} # => [[-1],[1,2]]
The rest should be self-explanatory.
I had read about rspec, but had not used it before. It was about time that it did. My code passed.
How would you go about working towards a solution for this problem? (what's your process?)
Start with a simple example, e.g. one of the tests. It is discovered that if the array element arr[i-1] is greater than arr[i] then you can immediately return i-1 as the answer. So you can just check in succession: i-1, i+1, i-2, i+2, i-3, i+3 etc. and return the first index that satisfies the inequality.
In your opinion do find the Problem Question clear and easy to understand?
Yes; the tests help but it only confirmed my understanding from the worded problem.
How long should it take you to solve this problem? (10min, 20min, ...?)
For a student in a test/classroom environment, no more than 10min. Depending on how much preparatory material they have had before this, maybe even less.
Do agree with the level of difficulty? (Keep in mind this is geared towards new developers)
Yes, 2/5 seems right.
If willing: please post your own solution, showcasing your style of solving this problem.
def nearest_larger( a, i )
2.upto([i,a.length-i].max << 1) do |k|
j = (k&1).zero? ? i - (k>>1) : i + (k>>1)
return j if 0 <= j && j < a.length && a[i] < a[j]
end
return nil
end
Addendum: Thinking in Bits
This addendum will go through in greater detail the problem solving that went into the above solution for the benefit of new programmers.
As was mentioned in the answer to Question #1 above, the return value of nearest_larger is the first index j for which a[i] < a[j] as j iterates through the sequence
i-1, i+1, i-2, i+2, i-3, i+3, ...
This opens the way to a sub-problem, which is how to generate this sequence of numbers. When actually writing the program, I used comments as a "scratch pad", and in the code had something like this:
# -1, 1, -2, 2, -3, 3, ... (Sequence G)
from which the prior sequence is constructed by just adding i to each term. Call this Sequence G. Now this is where a "binary intuition" would come into play. Consider a simple sequence of binary numbers that increases by one after each term, shown in Column A, and the familiar decimal representation is shown in Column B:
A B C D E F
----------------------------
0000 0 000 0 0 0
0001 1 000 1 0 0
0010 2 001 0 1 -1
0011 3 001 1 1 1
0100 4 010 0 2 -2
0101 5 010 1 2 2
0110 6 011 0 3 -3
0111 7 011 1 3 3
Now split the bits in each number into two groups: all the bits other than bit 0 (the right-most bit) as shown in Column C, and bit 0 shown in Column D. In other words, concatenate C and D to get A. The decimal representation of C is in column E. Notice that column D conveniently flips between 0 and 1, just as in Sequence G the numbers flip between negative and positive. We will use this to construct column F, which is the same as E, except when D is 0 make F negative. Finally, if we just start in the above table at A=0010 (or B=2) then Column F gives us the above Sequence G.
So now how do we get Column F from A in code? This is where bit operations come in to play.
C = A >> 1 - The >> right-shift operator shifts the bits on the LHS (left-hand side) by RHS (right-hand side). In this case, each value A is shifted to the right one place. The right-most bit is lost. Mathematically, it is the same as dividing by 2 and dropping the remainder in this case (B/2 == E with remainder dropped.)
D = A & 1 - The & is the bitwise AND operator. By "anding" A with 1, we select only bit 0; see the link in the prior sentence for more detail. This gives us Column D.
Putting this together in the code, we'll have k be the iteration variable that starts at 2 and increments by 1 each time. Then the above analysis gives us j:
j = (k&1).zero? ? i - (k>>1) : i + (k>>1)
The first value for j which is both in bounds and for which a[i] < a[j] holds is automatically the answer, so it can be returned immediately:
return j if 0 <= j && j < a.length && a[i] < a[j]
Finally, if there are no valid values for j then return nil. Other than calculating a lower upper-bound for k, which is left as a homework problem, that is the entirety of the nearest_larger function.
In actual practice, for a problem like this, a readable solution as posed in the OP is preferable since it is more clear and accessible to a wider group of programmers. This present approach was motivated by an opportunity to demonstrate the use of bit operations.

algorithm to simulate multiplication by addition (pseudo code)

I'm trying to design an algorithm to simulate multiplication by addition. The input has to be, which can be zero, positive or negative.
if "a" & "b" are two numbers
than
if (a)(b)=ab or 2*4=8
than a+a+a+a = ab or 2+2+2+2 =8
I have been given a question to solve and i cant figure it out yet. I've designed the following algorithm/pseudo-code:
if C is a place where we have to store after addition and initially C=0
add C into "a" and store in C (0+2=2)
subtract 1 from "b" and store in "b". (4-1=3)
if "b=0" STOP. otherwise goto step 2.
While this algorithm work when b > 0, it fails if b equals -1 or zero. The algorithm keeps running without ever stopping.
How can I fix my algorithm so it works for negative numbers?
Here’s the simplest approach:
int x = 5;
int y = -10;
int mul = 0;
if (x > 0)
for (int i=0; i<x; i++)
mul += y;
else
for (int i=0; i>x; i--)
mul -= y;
// mul now x*y;
Here are two simple hints for you.
Check for b=0 before adding the c and a, and replace the conditionnal goto statement at step 4 with an uncoditionnal goto.
Remember that 2*-4 = -(2*4). Therefore, you may check if b is negative very early in your code, and set a variable to -1 if it negative, or +1 if it is positive or null. Then set b to the absolute of itself, and let the code continue just as you wrote it. Then at the very last moment, multiply the sum by that temporary variable. Then you have the correct answer.
I won't give you the resulting pseudo-code, as this really is something you have to do yourself ;) Good luck.

Resources