Program to calculate the sum of terms? c++ - c++

So im trying to write a program that will calculate the sum of terms but each term is 3 times the previous term minus the second previous term so it looks like this 0, 1, 3, 8, 21, 55 and so on. For example if the user wants 4 terms then the program should output 21. The part im having problems with is setting up the variables to store the previous number and the second previous number. This is what i have so far.
#include <iostream>
using namespace std;
int main(){
int num;
int last;
int last2;
int current;
cout << "Number of terms to be shown: ";
cin >> num;
for(int i = 0; i < num; i++){
for(int term; term <= i; i++){
//THIS IS WHERE IM STUCK
}
}
}
The way i see it is the first for loop will tell the nested for loop how many times to run. In the nested for loop i think is where the math should go (current = (last * 3) - last2) while updating the last and last2 variables to keep the term list going. And then outside the loop i would cout << current so it would display the term. Like always, any help is appreciated!

There is an Undefined Behavior in your code in:
for(int i = 0; i < num; i++){
for(int term; term <= i; i++){ // term not initiaized. and the loop is infinte
//THIS IS WHERE IM STUCK
}
}
You are using term without being intialized. Also you are stuck in the inner loop because you should increment term not i in the inner loop.
So you can make it this way:
for(int i = 0; i < num; ++i){
for(int term = 0; term <= i; ++term){
// now rock here
}
}

You would typically remember the last two values, and simply go on computing the next one:
#include <iostream>
using namespace std;
int main()
{
int num;
cout << "Number of terms to be shown: ";
cin >> num;
int p1 = 1;
int p2 = 0;
cout << p2 << " " << p1 << " ";
num -= 2;
while (num > 0)
{
int current = 3 * p1 - p2;
cout << current << " ";
p2 = p1;
p1 = current;
num--;
}
}

This is the algorithm as I see it in my head when I read your question:
unsigned term(unsigned num) {
// the previous term*3 minus the second previous term
if(num > 1) return term(num - 1) * 3 - term(num - 2);
return num; // 0 or 1
}
It uses recursion to call itself, which is a great way to visualize what needs to be done for problems like this. The function works as-is but only for small nums, or else you'll get a stack overflow. It's also rather time consuming since it's doing function calls and calculates all terms many, many times.

Related

Trying to make a program that automatically sorts an array before using binary searching

I'm trying to make a program that asks the user to input a set of 10 numbers before asking them to select a number from the list. it would first automatically sort the ten numbers before being placed in a binary searching function.
Here's the code I wrote.
#include <iostream>
using namespace std;
int searchbinary(int arr[], int left, int right, int x){
while (left <= right){
int mid = left+(right-left)/2;
if (arr[mid]==x){
return mid;
}
else if (arr[mid]<1){
left = mid + 1;
}
else{
right = mid -1;
}
}
return -1;
}
int main(){
int num;
int darr[10];
int output;
int temp;
cout << "Enter 10 Numbers: " << endl;
for (int i=0; i<10; i++){
cin >> darr[i];
}
for (int i=0;i<10;i++){
for (int j=i+1;j<10;j++){
if (darr[i]>darr[j]){
temp = darr[i];
darr[i] = darr[j];
darr[j] = temp;
}
}
}
cout << "Enter a number from list: ";
cin >> num;
output = searchbinary(darr, 0, 9, num);
if (output ==-1){
cout << "Match not Found";
}
else {
cout << "Match Found in Position " << output;
}
return 0;
}
It works fine when I do it separately, but combining the two seems to cause an issue. Any suggestions?
Well, there seems to be a problem with your Binary Search. In the else if condition you wrote arr[mid] < 1 whereas it should have been arr[mid] < x because you are trying to find x not 1. Bellow is the code that should work:
#include <iostream>
using namespace std;
//binary search
int searchbinary(int arr[], int left, int right, int x){
while (left <= right){
int mid = (right+left)/2;//this formula is better than the one you used, it has the same results though
if (arr[mid] == x){
return mid;
}
else if (arr[mid] < x) {//here was your mistake,it is x not 1
left = mid + 1;
}
else{
right = mid -1;
}
}
return -1;
}
int main(){
int num;
int darr[10];
int output;
int temp;
cout << "Enter 10 Numbers: " << endl;
//input
for (int i=0; i<10; i++){
cin >> darr[i];
}
//sorting
for (int i=0;i<10;i++) {
for (int j=i+1;j<10;j++) {
if (darr[i]>darr[j]) {
temp = darr[i];
darr[i] = darr[j];
darr[j] = temp;
}
}
}
cout << "Enter a number from list: ";
cin >> num;
output = searchbinary(darr, 0, 9, num);//searching
//output
if (output == -1){
cout << "Match not Found";
}
else {
cout << "Match Found in Position " << output;
}
return 0;
}
If you fix that issue then your code should work but I would like to point some things out:
It is better not to hardcode numbers, like when you write 10 as a limit to all for loops. It would be better to save 10 in a variable or use darr.length().
Instead of using your own Sort you could have used the built-in sort that the algorithm library provides like this sort(darr, darr+10). In this case it was only with 10 elements but bear in mind that if you ever find yourself trying to solve the same problem with array sizes up to a million or more, the sort you implemented(it is called Bubble sort), would take up to much time, whereas std::sort would be able to do it faster as it has been optimised.
In this problem first sorting the array and then using Binary Search on top of it takes more time than performing Linear Search on the unsorted array. Generally, when searching once for a value on an unsorted array, first sorting it and then using Binary Search takes up more time than just doing Linear Search no matter the size of the array. However, if you wanted to to use the array in the future multiple times then your approach could prove to be faster.
These are all small improvements that you could make to your code but I am guessing this is done for educational purposes that is why you didn't do some of them.

Binary tree and Processors (C++ Codeforces Problem)

As the title says, I am trying to solve this problem which I couldn't find a solution on Youtube or somewhere else...
So here is the problem statement:
Eonathan Eostar decided to learn the magic of multiprocessor systems. He has a full binary tree of tasks with height h. In the beginning, there is only one ready task in the tree — the task in the root. At each moment of time, p processes choose at most p ready tasks and perform them. After that, tasks whose parents were performed become ready for the next moment of time. Once the task becomes ready, it stays ready until it is performed.
You shall calculate the smallest number of time moments the system needs to perform all the tasks.
Input:
The first line of the input contains the number of tests t (1≤t≤5⋅105). Each of the next t lines contains the description of a test. A test is described by two integers h (1≤h≤50) and p (1≤p≤104) — the height of the full binary tree and the number of processes. It is guaranteed that all the tests are different.
Output:
For each test output one integer on a separate line — the smallest number of time moments the system needs to perform all the tasks
Example:
input:
3
3 1
3 2
10 6
output:
7
4
173
I am a new C++ learner, so I thought of this way to solve this question:
I count all the nodes (pow(2,height)-1)
For each row I count the available nodes and put an if statement which says: If the available nodes at this row are smaller than the processors number then count++, else while the available nodes are bigger than zero (node_at_m -= m[i])
[node_at_m = Nodes available at this row; m[i] = processors number given in the question]
It gives correct answer for the first 2 cases which is (3 1) and (3 2) but it gives me wrong answer on the third case (10 6), so here is my code:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int t, node,nodeatm, count;
cin >> t;
int n[t], m[t];
for (int i = 0; i < t; i++)
{
cin >> n[i];
cin >> m[i];
node = pow(2,n[i])-1;
count = 0;
for(int q = 0; q < n[i]; q++)
{
nodeatm = pow(2,q);
if(nodeatm <= m[i])
{
count++;
}
else
while(nodeatm > 0)
{
nodeatm -= m[i];
count++;
}
}
cout << count << endl;
}
return 0;
}
I am really not a big fan of posting Codeforces questions on here, but I couldn't find any resource for this question on the Internet...
Waiting your answers, thanks.
The problem with above code is that you are incorrectly handling the case when some of the tasks are remaining from previous level. You are assuming that all tasks must finished from one level before we move to another level.
Following is corrected code. You can see it working here:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int t, node,nodeatm, count;
cin >> t;
int n[t], m[t];
for (int i = 0; i < t; i++)
{
cin >> n[i];
cin >> m[i];
node = pow(2,n[i])-1;
count = 0;
int rem = 0;
for(int q = 0; q < n[i]; q++)
{
nodeatm = pow(2,q) + rem ;
if(nodeatm <= m[i])
{
count++;
rem = 0;
}
else
{
while(nodeatm >= m[i])
{
nodeatm -= m[i];
count++;
}
rem = nodeatm;
}
}
if( rem )
{
count++;
}
cout << count << endl;
}
return 0;
}
Following is a bit simplified code. You can see it working here:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int t;
cin >> t;
for (int i = 0; i < t; i++)
{
int rem = 0, n, m, count = 0;
cin >> n >> m;
for(int q = 0; q < n; q++)
{
int nodeatm = pow(2,q) + rem;
if( nodeatm < m)
{
count++;
rem = 0;
}
else
{
count += ( nodeatm/ m );
rem = ( nodeatm % m );
}
}
if( rem )
count++;
cout << count << endl;
}
return 0;
}

Right way of using max function and/or alternatives

So, here is my homework problem. It states "Enter five numbers five times. Every time, the program chooses the biggest number you enter, and it returns the arithmetic mean of those five largest numbers." Now, what I've done is use max function, however, I learned that it isn't useable in this way. Here is what I've tried:
#include <iostream>
using namespace std;
int main() {
int zbir = 0;
for (int i = 1; i < 6; i++) {
int a, b, c, d, e;
for (int j = 1; j < 6; j++) {
cin >> a >> b >> c >> d >> e;
}
int maks = max(a, b, c, d, e);
zbir = zbir + maks;
}
cout << zbir / 5;
}
There are two versions of max: the two-argument version, and the initializer list version. In this case, you have five arguments, so use the initializer list version:
std::max({a, b, c, d, e})
(You need to #include <algorithm> to use std::max.)
Within your code you do not need to have an inner for-loop because you are already collecting all 5 of the user numbers with the cin >> a >> b >> c >> d >> e; statement. Having a second for loop around it will cause you to collect 5 numbers from the user 25 times total.
This is an example of the alternative to using the max function in which case a single number is collected 5 times making use of an inner for-loop:
int main()
{
int sumOfMaxNums = 0;
int userNum = 0;
int maxNum = 0;
// it is a good practice to have a const that will bound the loop
// this way you can change it from here
// in other cases you can have two different const bounds, one for the inner loop and
// one for the outer loop because they may differ
const int NUM_ITERS = 5;
// This will handle asking the user to enter the numbers 5 times
for(int i = 0; i < NUM_ITERS; ++i)
{
// this loop will asks the user to enter a number 5 times and keep track of the max
for(int j = 0; j < NUM_ITERS; ++j)
{
cin >> userNum;
// here we want to set the maxNum to be the very first number that the user enters
// or we could set it to smallest negative number
if(j == 0)
{
maxNum = userNum;
}
else if(userNum > maxNum)
{
maxNum = userNum;
}
} // end of inner for-loop
sumOfMaxNums += maxNum;
} // end of outer for-loop
cout << sumOfMaxNums / static_cast<float>(NUM_ITERS) << "\n";
} // end of main
You probably want to calculate the mean as a float rather than an int, otherwise the program will round the final answer down to the nearest whole number. Also, you really don't need to use five variables to store each cycle's inputs, since you can ignore any inputs that are less than the running maximum for that cycle. This means you don't need to use std::max at all.
#include<iostream>
int main()
{
float running_total = 0;
for (int cycle = 1; cycle < 6; ++cycle)
{
float cycle_max;
for (int entry = 1; entry < 6; ++entry)
{
float input = 0;
std::cin >> input;
if (entry == 1 || input > cycle_max) cycle_max = input;
}
running_total += cycle_max;
}
std::cout << running_total / 5 << std::endl;
}

Words of length k generation from a DFA

Good day,
I'm having a serious problem into generating a list with all the words of length k (the generate function is the function intended to generate all the words of length k, the other function is used to find out if a word is accepted or not) from a DFA just by using the DFS algorithm, here's my attempt:
#include<vector>
#include<iostream>
#include<fstream>
#include<string.h>
using namespace std;
vector < pair <int,char> > a[100];
int viz[100], v[100];
char s1[100];
void accepted (int q, char c, char s[100], int x) {
c = s[x];
viz[q] = 1;
cout << q;
for (int i = 0; i < a[q].size(); i++)
if (a[q][i].second == c) {
x++;
accepted (a[q][i].first, a[q][i+1].second, s, x);
}
}
void generate (int q, int k) {
int x = 0;
v[q] = 1;
while (x < k) {
cout << a[q][0].second;
for (int i = 0; i < a[q].size(); i++)
if (v[a[q][i].first] == 0)
{
cout << a[q][i].second;
generate(a[q][i].first, k);
}
x++;
}
}
int main() {
ifstream f ("input.txt");
int n, m, x, y, i, j, k;
char c;
char s[100];
f >> n >> m;
for (i = 0; i < m; i++) {
f >> x >> y;
f >> c;
a[x].push_back (make_pair(y,c));
}
for (i = 0; i < n; i++) {
cout << i << ": ";
for (j = 0; j < a[i].size(); j++)
cout << a[i][j].first << a[i][j].second << " ";
cout << endl;
}
cout << endl << "Fiite states: 2, 3" << endl << endl;
cin.get (s,100);
accepted(0, s[0], s, 0);
if (viz[2] == 1) cout << endl << "Accepted";
cout << endl;
cin >> k;
generate (0, k);
cout << endl;
return 0;
}
Also here's how my input looks like:
4 6
0 0 a
0 1 b
1 2 c
2 2 a
2 3 c
3 3 c
Here's how the DFA and the output would look like:
The serious problem I'm facing is that I can't find a way to ouput properly all the obtained words to the screen by calling the generate function.
I changed your generate function as below. Following that is an explanation as to what I thought and how I changed it.
void generate (int q, int k, string &s) {
if (k > 0) {
for (int i = 0; i < a[q].size(); i++)
{
s += a[q][i].second;
generate(a[q][i].first, k-1, s);
s.pop_back();
}
}
else {
cout << s << endl;
}
}
First and foremost, you were attempting a mixture of recursive and repetitive version of DFS, but you had no structure for keeping the stack if you were, and I doubt, going for a repetitive version using an explicit stack. Basically, your outer while loop was wrong, as the depth should increase as you recursively traverse the graph and not repetitively at a single level of recursion using a while loop as you did. You could also, as I mentioned, have a repetitive approach and use an explicitly defined stack other than the one implicitly used by memory when you implement DFS recursively. But it was easier and more intuitive to get a grasp of DFS with its recursive implementation, so I left out the outer loop.
Secondly, keeping a list of visited nodes is not a good idea as you want to list all k-length strings and your DFA is not a simple graph. (i.e. there may exist edges from node u to node u) So I removed the if statement inside the for loop as you could visit the sane node multiple times. Your approach is exponential based on the branching factor of the DFA, but if your k is small enough, it should work regardless of that. And the approach being exponential is not the problem to the solution of which you are looking with this question.
Thirdly, probably due to your usage of while loop, there was a mixup with printing a single character at each level, which is incorrect. Remember, at every node of depth k, you have to print all the characters you encountered starting from the root of the tree. That is why I added a string as the third parameter to your function. Don't worry, though, it's passed by reference and it will only cause an addition of O(k) space complexity to your algorithm, which should be negligible.
If in your main function you start traversing using the call below, you will find that it works properly.
string S;
generate(0, k, S);

Calculating a conditional probability that is similar to a binomial sum

I am considering a society where there are an arbitrary number of people. Each person has just two choices. Either he or she stays with her current choice or she switches. In the code that I want to write, the probability that the person switches is inputted by the user.
To make clear what I am trying to do, suppose that the user tells the computer that there are 3 people in the society where the probabilities that each person chooses to switch is given by (p1,p2,p3). Consider person 1. He has probability of p1 of switching. Using him as a base for our calculation, the probability given person 1 as a base, that exactly no one in the society chooses to switch is given by
P_{1}(0)=(1-p2)*(1-p3)
and the probability using person 1 as a base, that exactly one person in the society chooses to switch is given by
P_{1}(1)=p2*(1-p3)+(1-p2)*p3.
I can't figure out how to write this probability function in C++ without writing out every term in the sum. I considered using the binomial coefficient but I can't figure out a closed form expression for the sum since depending on user input, there are arbitrarily many probabilities that need to be considered.
I have attached what I have. The probability function is only a part of what I am trying to do but it is also the hardest part. I named the probability function probab and what I have in the for loop within the function is obviously wrong.
EDIT: Basically I want to calculate the probability of choosing a subset where each element in that subset has a different probability of being chosen.
I would appreciate any tips on how to go about this. Note that I am a beginner at C++ so any tips on improving my programming skills is also appreciated.
#include <iostream>
#include <vector>
using namespace std;
unsigned int factorial(unsigned int n);
unsigned int binomial(unsigned int bin, unsigned int cho);
double probab(int numOfPeople, vector<double> probs, int p, int num);
int main() {
char correctness;
int numOfPeople = 0;
cout << "Enter the # of people: ";
cin >> numOfPeople;
vector<double> probs(numOfPeople); // Create a vector of size numOfPeople;
for (int i = 1; i < numOfPeople+1; i++) {
cout << "Enter the probability of person "<< i << " will accept change: ";
cin >> probs[i-1];
}
cout << "You have entered the following probabilities of accepting change: (";
for (int i = 1; i < numOfPeople+1; i++) {
cout << probs[i-1];
if (i == numOfPeople) {
cout << ")";
}
else {
cout << ",";
}
}
cout << endl;
cout << "Is this correct? (Enter y for yes, n for no): ";
cin >> correctness;
if (correctness == 'n') {
return 0;
}
return 0;
}
unsigned int factorial(unsigned int n){ // Factorial function
unsigned int ret = 1;
for(unsigned int i = 1; i <= n; ++i) {
ret *= i;
}
return ret;
}
unsigned int binomial(unsigned int totl, unsigned int choose) { // Binomial function
unsigned int bin = 0;
bin = factorial(totl)/(factorial(choose)*factorial(totl-choose));
return bin;
}
double probab(int numOfPeople, vector<double> probs, int p, int num) { // Probability function
double prob = 0;
for (int i = 1; i < numOfPeople; i++) {
prob += binomial(numOfPeople, i-1)/probs[p]*probs[i-1];
}
return prob;
}
For future reference, for anybody attempting to do this, the probability function will look something like:
double probability (vector<double> &yesprobabilities, unsigned int numOfPeople, unsigned int yesNumber, unsigned int startIndex) {
double kprobability = 0;
// Not enough people!
if (numOfPeople-1 < yesNumber) {
kprobability = 0;
}
// n == k, the only way k people will say yes is if all the remaining people say yes.
else if (numOfPeople-1 == yesNumber) {
kprobability = 1;
for (int i = startIndex; i < numOfPeople-1; ++i) {
kprobability = kprobability * yesprobabilities[i];
}
}
else if (yesprobabilities[startIndex] == 1) {
kprobability += probability(yesprobabilities,numOfPeople-1,yesNumber-1,startIndex+1);
}
else {
// The first person says yes, k - 1 of the other persons have to say yes.
kprobability += yesprobabilities[startIndex] * probability(yesprobabilities,numOfPeople-1,yesNumber-1,startIndex+1);
// The first person says no, k of the other persons have to say yes.
kprobability += (1 - yesprobabilities[startIndex]) * probability(yesprobabilities,numOfPeople-1,yesNumber,startIndex+1);
}
return probability;
}
Something called a recursive function is used here. This is completely new to me and very illuminating. I credit this to Calle from Math stack exchange. I modified his version slightly to take vectors instead of arrays with some help.