Sum the odd positioned and the even positioned integers in an array - c++

What is the most elegant way to sum 'each number on odd position' with 'each number on even position multiplied by 3'? I must obide this prototype
int computeCheckSum(const int* d)
My first try was to use this but my idea was flawed. I can't find a way to tell which element is even this way.
int sum=0;
for_each(d,
d+11,
[&sum](const int& i){sum+=(i%2==1)?3*i:i;}
);
example
1 2 3 4 5
1+2*3+3+4*3+5=27

I can't find a way to tell which element is even this way.
If you insist on using for_each (there's no reason to do that here), then you track the index separately:
int computeCheckSum(const int* d, int count)
{
int sum=0;
int pos=1;
std::for_each(d, d+count,
[&sum,&pos](const int& value) { sum += pos++ % 2 ? value : value * 3; } );
return sum;
}
Note I added a count parameter, so the function can work on arrays of any length. If you're feeling really perverse, you can remove that parameter and go back to hardcoding the length so the function only works arrays with 12 elements. But if you hope to be good at this some day, doing that should make you feel gross.

These things rarely become very "elegant" in C++ (it seems C++ is asymptotically approaching Perl on the "line noise" index) but since accumulate is a left fold, you can pass the index "along the fold":
int sum = std::accumulate(d,
d + 11,
std::make_pair(0,0), // (index, result)
[](std::pair<int, int> r, int x) {
r.second += r.first % 2 ? x : 3 * x;
r.first++;
return r;
}).second;

You were right. As Mud said, it was just a terrible function design. This is what I needed.
int computeCheckSum(){
int sum = 0;
bool multiplyBy3 = false;
for (auto i : m_digits){
sum += multiplyBy3 ? 3*i : i;
multiplyBy3 = !multiplyBy3;
}
return sum;
}
Mud's solution is correct using my flawed design. A simple for loop would probably be even a better solution, as everyone said.

Related

How does memoization help here?

I just solved the subset sum problem:
Given an integer array nums of size N. You are also given an integer B, you need to find whether there exists a subset in nums whose sum is B. If there exist a subset then return 1 else return 0.
Constraints are: 1 <= N <= 100; 1 <= nums[i] <= 100; 1 <= B <= 10^5;
The way I solved this problem is as below (0/1 knapsack):
vector<int> n;
int t;
unordered_map<string, long long> m;
int helper(int i, int sum) {
if(i>=n.size()) return sum==t;
string str=to_string(i)+"-"+to_string(sum);
if(m.count(str)) return m[str];
int val=helper(i+1, sum+n[i]);
val=max(val, helper(i+1, sum));
return m[str]=val;
}
int Solution::solve(vector<int> &nums, int B) {
n=nums;
t=B;
m.clear();
return helper(0,0);
}
This gets "Accepted". However, note that all the values in nums are positive; so IMO sum will only remain the same/go on increasing. i goes on increasing, too. So, we will never encounter a value previously stored in the memoization table.
But, if I remove memoization, it results in Wrong Answer for some large test case. What am I missing? Will any recursive call ever encounter a previous state?
You call helper twice, the second time with the lower sum than the first. Therefore a later call to helper could indeed have the same sum as an earlier call.
#user3386109 already gave a concrete set of num that demonstrates this. As for how often, consider the case where nums = [1, 1, ..., 1] 100 times. Then without memoization you'll call helper(100, 50) 100 choose 50 = 100,891,344,545,564,193,334,812,497,256 times. Over 100 octillion calls..takes a while.

c++ Recursion addition, 4*x

I have been trying to understand how to work on a function that returns the sum of a number like this: 1+2+3+4...4n by using recursion
I tried different cases without success and I am wondering if there is any mathematical way to solve it and translate it into code. I know that if I were this function:
int MyFunction(int x)
{
if (x==0)
return 0;
else{
return x+MyFunction(x-1);
}
}
and I used x=3 it would return 1+2+3 which is equal to 6 but in my case, I want to do something similar but up to 4 times the number. For example if x=1 it will return 1+2+3+4 since 4(1)=4. Then what returns is the addition of those numbers which is equal to 10
I tried thinking about simply converting the x to 4*x
int MyFunction(int x)
{
if (x==0)
return 0;
else{
return 4*x+MyFunction(x-1);
}
}
of course this didn't work, I also tried thinking that since everything was the same but by a factor of 4 thus MyFunction(4(x-1)) but obviously I am not thinking of this correctly. I wanted suggestions at least to understand the math behind it and how to relate it to code
nonrecursive solution
The sum of the members of a finite arithmetic progression is called an arithmetic series. For example, consider the sum:
1 + 2 + 3 + ... 4n-1 + 4n
This sum can be found quickly by taking the number of terms being added (here 4n), multiplying by the sum of the first and last number in the progression (here 1 + 4n = 4n+1), and dividing by 2.
The formula you are looking for is:
sum = 2n(4n+1)
A possible implementation can be:
int MyFunction(int n)
{
assert(n>0);
return 2*n*(4*n+1);
}
note: we do not checked a possible overflow
recursive solution
int recursive_sum(int k)
{
return (k>0) ? k+recursive_sum(k-1) : 0;
}
int recursive_MyFunction(int n)
{
assert(n>0);
return recursive_sum(4*n);
}
Check that both approaches give the same result
#include <cassert>
int MyFunction(int n) { ... as before ...}
int recursive_MyFunction(int n) { ... as before ...}
int main()
{
int n = 10; // whatever you want
assert(recursive_MyFunction(n)==MyFunction(n));
}

Is Coin Change Algorithm That Output All Combinations Still Solvable By DP?

For example, total amount should be 5 and I have coins with values of 1 and 2. Then there are 3 ways of combinations:
1 1 1 1 1
1 1 1 2
1 2 2
I've seen some posts about how to calculate total number of combinations with dynamic programming or with recursion, but I want to output all the combinations like my example above. I've come up with a recursive solution below.
It's basically a backtracking algorithm, I start with the smallest coins first and try to get to the total amount, then I remove some coins and try using second smallest coins ... You can run my code below in http://cpp.sh/
The total amount is 10 and the available coin values are 1, 2, 5 in my code.
#include <iostream>
#include <stdlib.h>
#include <iomanip>
#include <cmath>
#include <vector>
using namespace std;
vector<vector<int>> res;
vector<int> values;
int total = 0;
void helper(vector<int>& curCoins, int current, int i){
int old = current;
if(i==values.size())
return;
int val = values[i];
while(current<total){
current += val;
curCoins.push_back(val);
}
if(current==total){
res.push_back(curCoins);
}
while (current>old) {
current -= val;
curCoins.pop_back();
if (current>=0) {
helper(curCoins, current, i+1);
}
}
}
int main(int argc, const char * argv[]) {
total = 10;
values = {1,2,5};
vector<int> chosenCoins;
helper(chosenCoins, 0, 0);
cout<<"number of combinations: "<<res.size()<<endl;
for (int i=0; i<res.size(); i++) {
for (int j=0; j<res[i].size(); j++) {
if(j!=0)
cout<<" ";
cout<<res[i][j];
}
cout<<endl;
}
return 0;
}
Is there a better solution to output all the combinations for this problem? Dynamic programming?
EDIT:
My question is is this problem solvable using dynamic programming?
Thanks for the help. I've implemented the DP version here: Coin Change DP Algorithm Print All Combinations
A DP solution:
We have
{solutions(n)} = Union ({solutions(n - 1) + coin1},
{solutions(n - 2) + coin2},
{solutions(n - 5) + coin5})
So in code:
using combi_set = std::set<std::array<int, 3u>>;
void append(combi_set& res, const combi_set& prev, const std::array<int, 3u>& values)
{
for (const auto& p : prev) {
res.insert({{{p[0] + values[0], p[1] + values[1], p[2] + values[2]}}});
}
}
combi_set computeCombi(int total)
{
std::vector<combi_set> combis(total + 1);
combis[0].insert({{{0, 0, 0}}});
for (int i = 1; i <= total; ++i) {
append(combis[i], combis[i - 1], {{1, 0, 0}});
if (i - 2 >= 0) { append(combis[i], combis[i - 2], {{0, 1, 0}}); }
if (i - 5 >= 0) { append(combis[i], combis[i - 5], {{0, 0, 1}}); }
}
return combis[total];
}
Live Demo.
Exhaustive search is unlikely to be 'better' with dynamic programming, but here's a possible solution:
Start with a 2d array of combination strings, arr[value][index] where value is the total worth of the coins. Let X be target value;
starting from arr[0][0] = "";
for each coin denomination n, from i = 0 to X-n you copy all the strings from arr[i] to arr[i+n] and append n to each of the strings.
for example with n=5 you would end up with
arr[0][0] = "", arr[5][0] = "5" and arr[10][0] = "5 5"
Hope that made sense. Typical DP would just count instead of having strings (you can also replace the strings with int vector to keep count instead)
Assume that you have K the total size of the output your are expecting (the total number of coins in all the combinations). Obviously you can not have a solution that runs faster than O(K), if you actually need to output all them. As K can be very large, this will be a very long running time, and in the worst case you will get little profit from the dynamic programming.
However, you still can do better than your straightforward recursive solution. Namely, you can have a solution running in O(N*S+K), where N is the number of coins you have and S is the total sum. This will not be better than straightforward solution for the worst possible K, but if K is not so big, you will get it running faster than your recursive solution.
This O(N*S+K) solution can be relatively simply coded. First you run the standard DP solution to find out for each sum current and each i whether the sum current can be composed of first i coin types. You do not yet calculate all the solutions, you just find out whether at least one solution exists for each current and i. Then, you write a recursive function similar to what you have already written, but before you try each combination, you check using you DP table whether it is worth trying, that is, whether at least one solution exists. Something like:
void helper(vector<int>& curCoins, int current, int i){
if (!solutionExists[current, i]) return;
// then your code goes
this way each branch of the recursion tree will finish in finding a solution, and therefore the total recursion tree size will be O(K), and the total running time will be O(N*S+K).
Note also that all this is worth only if you really need to output all the combinations. If you need to do something else with the combinations you get, it is very probable that you do not actually need all the combinations and you may adapt the DP solution for that. For example, if you want to print only m-th of all solutions, this can be done in O(N*S).
You just need to make two passes over the data structure (a hash table will work well as long as you've got a relatively small number of coins).
The first one finds all unique sums less than the desired total (actually you could stop perhaps at 1/2 the desired total) and records the simplest way (least additions required) to obtain that sum. This is essentially the same as the DP.
The second pass then goes starts at the desired total and works its way backwards through the data to output all ways that the total can be generated.
This ends up being a two stage approach of what Petr is suggesting.
The actual amount of non distinct valid combinations for amounts {1, 2, 5} and N = 10 is 128, using a pure recursive exhaustive technique (Code below). My question is can an exhaustive search be improved with memoization/dynamic programming. If so, how can I modify the algorithm below to incorporate such techniques.
public class Recursive {
static int[] combo = new int[100];
public static void main(String argv[]) {
int n = 10;
int[] amounts = {1, 2, 5};
ways(n, amounts, combo, 0, 0, 0);
}
public static void ways(int n, int[] amounts, int[] combo, int startIndex, int sum, int index) {
if(sum == n) {
printArray(combo, index);
}
if(sum > n) {
return;
}
for(int i=0;i<amounts.length;i++) {
sum = sum + amounts[i];
combo[index] = amounts[i];
ways(n, amounts, combo, startIndex, sum, index + 1);
sum = sum - amounts[i];
}
}
public static void printArray(int[] combo, int index) {
for(int i=0;i < index; i++) {
System.out.print(combo[i] + " ");
}
System.out.println();
}
}

Get 2 unique numbers in a row?

I want to make sure 'grid' can't return 2 same values, but I'm not sure how. Here's my code:
grid[rnd(2,x-2) * y + rnd(2,y-2)].height = rnd(25,40);
int rnd(int min, int max) {
return min + rand() % (max - min + 1);
}
I also seeded rand() with srand(time(NULL));
I wish I could provide more details or what I tried, but I couldn't quite find anything related to this topic.
EDIT: I could of course do re-randoming, but I feel like it's bad practice :/
If you really need to avoid consecutive repeats,1 all you need to do is pass the previous value into your function, and then generate random numbers in a loop until it is distinct.
Pseudo-code:
int rnd(..., int prev) {
int y;
do {
y = rand() ...;
} while (y == prev);
return y;
}
Note that you could alternatively maintain prev as a static variable inside the function. But this would render it incapable of generating multiple independent streams simultaneously.
1. Which actually makes things less "random", in the sense of becoming more predictable.

Horner's Rule C/C++ Using Recursion

I learned about Horner's Rule here for the first time:
Horner's rule in C++
Since I am learning about recursion ATM, I was wondering if it is possible to implement this algorithm using recursion ?
int HornerR( int a[], int n, int x, int index )
{
if (index==n) return a[n];
else
return x*HornerR(a,n ,x,index+1) + a[index];
}
I think it's only possible with a fourth parameter.
You can do it with pointer arithmetic:
Base Case at the end of array (check n) return constant parameter
Recursive Case return current cell added to variable multiplied recursive call
Recursive Call move the array to next cell and update the counter (n)
Basically this lets you calculate the index variable by moving the array to the next position and sending that (and always using the first cell) instead of sending the whole array every time
You can implement the function as follows with 3 arguments in function, provided, the array pi contains the coefficients from highest degree to 0 from index 0 to degree+1. Ex for 3x^2 + 2x^1 + 1 => pi[3] = { 3,2,1}
int compute_by_horner(int *pi, int degree, int x)
{
int i, j;
if (degree == 0)
{
return pi[0];
}
return compute_by_horner(pi, degree-1, x) * x + pi[degree];
}
Rather than passing an index, think of a as a pointer (since it is). Along with that, you'll want to decrement n, and keep track of whether it's been reduced to zero yet, rather than keeping track of whether index==n.