Is there a way to manipulate function arguments by their position number? - c++

I wish to be able to manipulate function arguments by the order in which they are given. So,
void sum(int a, int b, int c)
std::cout<< arguments[0]+arguments[1];
sum(1,1,4);
should print 2. This feature is in JavaScript.
I need it to implement a numerical scheme. I'd create a function that takes 4 corner values and tangential direction as input. Then, using the tangential direction, it decides which corners to use. I wish to avoid an 'if' condition as this function would be called several times.
EDIT - The reason why I do not wish to use an array as input is for potential optimization and readability reasons. I would explain my situation a bit more. solution is a 2D array. We would be running this double for loop several times
for (int i = 0;i<N_x;i++)
for (int j = 0;j<N_y;j++)
update_solution(solution[i,j],solution[i+1,j],solution[i-1,j],...);
Optimization: N_x,N_y are large enough for me to be concerned about whether or not adding a step like variables_used = {solution(i,j),solution(i+1,j),...} in every single loop will increase the cost.
Readability The arguments of update_solution indicate which indices were used to update the solution. Putting that in the previous line is slightly non-standard, judging by the codes I have read.

Related

How to find a better algorithm taking less Execution Time?

#include <iostream>
using namespace std;
int main() {
int n;
cin>>n;
int *arr=new int [n];
for(int k=0;n>k;k++)
{
cin>>*(arr+k);
}
long long sum1=0,sum2=0,sum3=0;
for(int k=0;n>k;k++)
{
sum1=sum1+*(arr+k);
if(*(arr+k)%2==0)
sum2++;
else
sum3++;
}
cout<<sum1<<" ";
cout<<sum3<<" ";
cout<<sum2;
return 0;
}
You're given a sequence of N integers, your task is to print sum of them, number of odd integers, and number of even integers respectively.
Input
The first line of input contains an integer N (1≤N≤10⁵).
The second line of input contains N integers separated by a single space (1≤Ai≤10⁵).
Output
Print the sum of them, number of odd integers, and number of even integers respectively, separated by a space.
Examples
input
5
1 2 3 4 5
output
15 3 2
Is there a better algorithm for this code? I need it to take less Execution Time.
Where can I find better algorithms for any code?
Unless you need to re-use the N integers that you have stored in the array, there's no point in storing them. You can get the sum as well as number of odd/even integers as you input them.
Additionally, you don't need long long as the input will never get that big, unless you mean 10^5?
Further, whenever you are thinking about improving performance you should take a look at the big O which in this case is O(N) where N is the number of integers that you have. From an algorithm point of view with N input there's generally very little that you can do to improve this. Maybe if we're talking streams, you can do some statistics but otherwise this implementation is as good as it gets. In some other situations, while the worst case can't be improved, we can improve the average case, which I don't think is applicable here.
Then you should look at profiling the code. That way you have a clear understanding of where bottlenecks are. For your code, there's probably not too much that can be done reasonably.
If we're trying to squeeze every ounce of performance possible, adjusting the compiler flags can bring some performance gains. You should research these but I would not prioritize this over the above.
I would also improve how you name your variables, but this has no impact on performance.
Actually C++ by default synchronizes cin/cout with C way of doing I/O - printf/scanf, which slows down I/O by quite a lot.
Switching to printf/scanf or adding something like ios::sync_with_stdio(0); at the start of main should speed this up a few times.

How to speed up program execution

This is a very simple question, but unfortunately, I am stuck and do not know what to do. My program is a simple program that keeps on accepting 3 numbers and outputs the largest of the 3. The program keeps on running until the user inputs a character.
As the tittle says, my question is how I can make this execute faster ( There will be a large amount of input data ). Any sort of help which may include using a different algorithm or using different functions or changing the entire code is accepted.
I'm not very experienced in C++ Standard, and thus do not know about all the different functions available in the different libraries, so please do explain your reasons and if you're too busy, at least try and provide a link.
Here is my code
#include<stdio.h>
int main()
{
int a,b,c;
while(scanf("%d %d %d",&a,&b,&c))
{
if(a>=b && a>=c)
printf("%d\n",a);
else if(b>=a && b>=c)
printf("%d\n",b);
else
printf("%d\n",c);
}
return 0;
}
It's working is very simple. The while loop will continue to execute until the user inputs a character. As I've explained earlier, the program accepts 3 numbers and outputs the largest. There is no other part of this code, this is all. I've tried to explain it as much as I can. If you need anything more from my side, please ask, ( I'll try as much as I can ).
I am compiling on an internet platform using CPP 4.9.2 ( That's what is said over there )
Any sort of help will be highly appreciated. Thanks in advance
EDIT
The input is made by a computer, so there is no delay in input.
Also, I will accept answers in c and c++.
UPDATE
I would also like to ask if there are any general library functions or algorithms, or any other sort of advise ( certain things we must do and what we must not do ) to follow to speed up execution ( Not just for this code, but in general ). Any help would be appreciated. ( and sorry for asking such an awkward question without giving any reference material )
Your "algorithm" is very simple and I would write it with the use of the max() function, just because it is better style.
But anyway...
What will take the most time is the scanf. This is your bottleneck. You should write your own read function which reads a huge block with fread and processes it. You may consider doing this asynchronously - but I wouldn't recommend this as a first step (some async implementations are indeed slower than the synchronous implementations).
So basically you do the following:
Read a huge block from file into memory (this is disk IO, so this is the bottleneck)
Parse that block and find your three integers (watch out for the block borders! the first two integers may lie within one block and the third lies in the next - or the block border splits your integer in the middle, so let your parser just catch those things)
Do your comparisions - that runs as hell compared to the disk IO, so no need to improve that
Unless you have a guarantee that the three input numbers are all different, I'd worry about making the program get the correct output. As noted, there's almost nothing to speed up, other than input and output buffering, and maybe speeding up decimal conversions by using custom parsing and formatting code, instead of the general-purpose scanf and printf.
Right now if you receive input values a=5, b=5, c=1, your code will report that 1 is the largest of those three values. Change the > comparisons to >= to fix that.
You can minimize the number of comparisons by remembering previous results. You can do this with:
int d;
if (a >= b)
if (a >= c)
d = a;
else
d = c;
else
if (b >= c)
d = b;
else
d = c;
[then output d as your maximum]
That does exactly 2 comparisons to find a value for d as max(a,b,c).
Your code uses at least two and maybe up to 4.

Is adding 1 to a number repeatedly slower than adding everything at the same time in C++? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
If I have a number a, would it be slower to add 1 to it b times rather than simply adding a + b?
a += b;
or
for (int i = 0; i < b; i++) {
a += 1;
}
I realize that the second example seems kind of silly, but I have a situation where coding would actually be easier that way, and I am wondering if that would impact performance.
EDIT: Thank you for all your answers. It looks like some posters would like to know what situation I have. I am trying to write a function to shift an inputted character a certain number of characters over (ie. a cipher) if it is a letter. So, I want to say that one char += the number of shifts, but I also need to account for the jumps between the lowercase characters and uppercase characters on the ascii table, and also wrapping from z back to A. So, while it is doable in another way, I thought it would be easiest to keep adding one until I get to the end of a block of letter characters, then jump to the next one and keep going.
If your loop is really that simple, I don't see any reason why a compiler couldn't optimize it. I have no idea if any actually would, though. If your compiler doesn't the single addition will be much faster than the loop.
The language C++ does not describe how long either of those operations take. Compilers are free to turn your first statement into the second, and that is a legal way to compile it.
In practice, many compilers would treat those two subexpressions as the same expression, assuming everything is of type int. The second, however, would be fragile in that seemingly innocuous changes would cause massive performance degradation. Small changes in type that 'should not matter', extra statements nearby, etc.
It would be extremely rare for the first to be slower than the second, but if the type of a was such that += b was a much slower operation than calling += 1 a bunch of times, it could be. For example;
struct A {
std::vector<int> v;
void operator+=( int x ) {
// optimize for common case:
if (x==1 && v.size()==v.capacity()) v.reserve( v.size()*2 );
// grow the buffer:
for (int i = 0; i < x; ++i)
v.reserve( v.size()+1 );
v.resize( v.size()+1 );
}
}
};
then A a; int b = 100000; a+=b; would take much longer than the loop construct.
But I had to work at it.
The overhead (CPU instructions) on having a variable being incremented in a loop is likely to be insignificant compared to the total number of instructions in that loop (unless the only thing you are doing in the loop is incrementing). Loop variables are likely to remain in the low levels of the CPU cache (if not in CPU registries) and is very fast to increment as in doesn't need to read from the RAM via the FSB. Anyway, if in doubt just make a quick profile and you'll know if it makes sense to sacrifice code readability for speed.
Yes, absolutely slower. The second example is beyond silly. I highly doubt you have a situation where it would make sense to do it that way.
Lets say 'b' is 500,000... most computers can add that in a single operation, why do 500,000 operations (not including the loop overhead).
If the processor has an increment instruction, the compiler will usually translate the "add one" operation into an increment instruction.
Some processors may have an optimized increment instructions to help speed up things like loops. Other processors can combine an increment operation with a load or store instruction.
There is a possibility that a small loop containing only an increment instruction could be replaced by a multiply and add. The compiler is allowed to do so, if and only if the functionality is the same.
This kind of operation, generally produces negligible results. However, for large data sets and performance critical applications, this kind of operation may be necessary and the time gained would be significant.
Edit 1:
For adding values other than 1, the compiler would emit processor instructions to use the best addition operations.
The add operation is optimized in hardware as a different animal than incrementing. Arithmetic Logic Units (ALU) have been around for a long time. The basic addition operation is very optimized and a lot faster than incrementing in a loop.

Orienteering map game using C++

I solved a programming puzzle using a brute force method and without dynamic programming, and it worked fine. Here is the puzzle:
An orienteering map is to be given in the following format.
" ##### "
" #...# "
" #S#G# "
" ##### "
Calculate the minimum distance from the start to the goal with passing all the checkpoints.
A map consists of 5 characters as following. You can assume that the map does not contain any invalid characters and the map has exactly one start symbol 'S' and exactly one goal symbol 'G'.
'S' means the orienteering start.
'G' means the orienteering goal.
'#' means an orienteering checkpoint.
'.' means an opened-block that players can pass.
'#' means a closed-block that players cannot pass.
It is allowed to move only by one step vertically or horizontally (up, down, left, or right) to the next block. Other types of movements, such as moving diagonally (left up, right up, left down and right down) and skipping one or more blocks, are NOT permitted.
You MUST NOT get out of the map.
Distance is to be defined as the number of movements to the different blocks.
You CAN pass opened-blocks, checkpoints, the start, and the goal more than once if necessary.
You can assume that parameters satisfy following conditions.
1 <= width <= 100
1 <= height <= 100
The maximum number of checkpoints is 18.
Then I found a much faster solution, which I don't understand some things about:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cstdlib>
#include<ctime>
#include<set>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e2+ 10;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
std::vector<int>path;
const int INF=1<<20;
struct Point
{
int x,y;
bool operator < (const Point &a)const
{
return x<a.x||(x==a.x)&&y<a.y;
}
};
std::vector<Point>P;
char mat[maxn][maxn];
int vis[maxn][maxn];
int w,h,s,e;
int d[1<<20][20];
int dx[]={-1,0,0,1};
int dy[]={0,-1,1,0};
int dist[25][25];
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
while(cin>>w>>h){
map<Point,int>id;
P.clear();
path.clear();
memset(d,100,sizeof d);
memset(dist,100,sizeof dist);
for(int i=0;i<h;i++){
scanf("%s",mat[i]);
for(int j=0;mat[i][j];++j){
char &c=mat[i][j];
if(c=='S'||c=='G'||c=='#'){
P.pb((Point){i,j});
int sz=P.size();
id[P[sz-1]]=sz;
if(c=='S')s=sz-1;
else if(c=='G')e=sz-1;
path.pb(sz-1);
}
}
}
for(int i=0;i<path.size();i++){
Point now=P[path[i]];
int x=path[i];
//out<<"x "<<x<<endl;
dist[x][x]=0;
memset(vis,0,sizeof vis);
vis[now.x][now.y]=1;
queue<Point>q;
q.push(now);
//cout<<"Bfs"<<endl;
while(!q.empty()){
now=q.front();q.pop();
for(int i=0;i<4;i++){
int nx=now.x+dx[i],ny=now.y+dy[i];
if(nx>=0&&nx<h&&ny>=0&&ny<w&&mat[nx][ny]!='#'&&!vis[nx][ny]){
Point tp=(Point){nx,ny};
q.push(tp);
vis[nx][ny]=vis[now.x][now.y]+1;
if(id[tp]){
dist[x][id[tp]-1]=vis[now.x][now.y];
}
}
}
}
}
d[1<<s][s]=0;
int M=path.size();
for(int i=0;i<(1<<M);++i){
for(int j=0;j<M;j++){
int p=path[j];
for(int k=0;1<<k<=i;k++){
if(i&(1<<k)){
d[i|(1<<p)][p]=min(d[i|(1<<p)][p],d[i][k]+dist[k][p]);
}
}
}
}
cout<<d[(1<<M)-1][e]<<endl;
}
return 0;
}
Here are 3 specific questions I have about it:
What is the use of the constant INF? It isn’t used anywhere in the program. I understand that programmers very often leave some things in their programs which may not seem to be of any use presently, but would be useful for any future modifications. Does INF serve that same purpose? If any kind of modification is performed to make the program more efficient or to use a different method, INF is used?
The use of the left-shift operator inside the array dimensions. For example, int d[1<<20][20]. What purpose does the let-shift operator accomplish with regard to this program? There are various other instances where the let shift operator has been used inside array dimensions, and I can’t understand why.
The overloading of the less-than operator. In the Point structure, the less-than operator is overloaded. But I can't seem to find out where in the program it has been called. It needs a Point object to call it, but I can’t find any place where any Point object calls that member function.
Your questions aren't invalid, but do not need all the context to ask them. They could each be separate questions, and I've provided a link for each showing that the essence of the question has been asked before more succinctly. If you isolate your questions and separate them out of the specific body of code you are looking at, that's better--they can be triaged more easily as duplicates.
What is the use of the constant INF?It isn’t used anywhere in the program. I understand that programmers very often leave some things in their programs which may not seem to be of any use presently, but would be useful for any future modifications. Does INF serve that same purpose? If any kind of modification is performed to make the program more efficient or to use a different method, INF is used?
If you delete the line declaring INF, does it still compile and work? Does it get slower? If so, it is a magic incantation that makes programs faster, known only in C++ secret societies. :-) If not, it's just a leftover definition as you suspect...perhaps used at some time, or perhaps never was.
See:
How do I detect unused macro definitions & typedefs?
The use of the left-shift operator inside the array dimensions. For example, int d[1<<20][20]. What purpose does the let-shift operator accomplish with regard to this program? There are various other instances where the let shift operator has been used inside array dimensions, and I can’t understand why.
In binary math, shifting 1 some number of bits left is the same as raising 2 to that power. So 1 << 20 is 2^20, or 1048576. It's faster to bit shift than to call a power function, although with an optimized enough power function that can special case when the base is 2...how much faster may not be that much:
are 2^n exponent calculations really less efficient than bit-shifts?
The overloading of the less-than operator. In the Point structure, the less-than operator is overloaded. But I can’t seem to find out where in the program it has been called. It needs a Point object to call it, but I can’t find any place where any Point object calls that member function.
One might think that if you want to test if a method is ever called or a definition used, you can delete it and see if it still compiles. But in C++ that doesn't always work; some definitions are overloads. If you delete them, the program still compiles but just falls through to more basic behavior. Even preprocessor macros can be funny because one file might detect if it had been defined elsewhere, and do something different if not...
There are other approaches, like just throwing an exception or asserting if it's ever called in the course of running. People offer some other thoughts here:
Find out if a function is called within a C++ project?
As #BrianSchlenker points out, the less than operator is definitely used despite the lack of explicit calls in the code shown. It's used to order the elements of map<Point,int> id;. The C++ std::map type imposes ordering on its contents, and defaults to using operator< to achieve this ordering...though you may override this. If you print something out inside the less than function, you'll see it called every time the id map is interacted with.
(Note: If you want an unordered map you have to use std::unordered_map, but that requires your datatype to have a different ability to calculate its std::hash...as well as a test for equality.)
In general: this code is not stylized in a maintainable or readable manner. I'd suggest that if you want to learn methods for increasing C++ program performance, you avoid the tarpit of reading any piece of obfuscated code you find...just because it happened to catch your attention.
Can you learn from it? I guess, but de-obfuscating it and commenting it will be your first step. Not a great idea, especially if you have to go asking others to help you do it, because even if they know how...they probably don't want to. Better would be to work through steps to improve your own implementation in a stable logical way, where you don't step too far outside of your sphere of understanding in any one step.
(Though if you can find the original author of such things, you might be able to engage them in a conversation about it and comment it for you. If they don't have the interest, why would random people on the Internet?)

How does this C++ function use memoization?

#include <vector>
std::vector<long int> as;
long int a(size_t n){
if(n==1) return 1;
if(n==2) return -2;
if(as.size()<n+1)
as.resize(n+1);
if(as[n]<=0)
{
as[n]=-4*a(n-1)-4*a(n-2);
}
return mod(as[n], 65535);
}
The above code sample using memoization to calculate a recursive formula based on some input n. I know that this uses memoization, because I have written a purely recursive function that uses the same formula, but this one much, much faster for much larger values of n. I've never used vectors before, but I've done some research and I understand the concept of them. I understand that memoization is supposed to store each calculated value, so that instead of performing the same calculations over again, it can simply retrieve ones that have already been calculated.
My question is: how is this memoization, and how does it work? I can't seem to see in the code at which point it checks to see if a value for n already exists. Also, I don't understand the purpose of the if(as[n]<=0). This formula can yield positive and negative values, so I'm not sure what this check is looking for.
Thank you, I think I'm close to understanding how this works, it's actually a bit more simple than I was thinking it was.
I do not think the values in the sequence can ever be 0, so this should work for me, as I think n has to start at 1.
However, if zero was a viable number in my sequence, what is another way I could solve it? For example, what if five could never appear? Would I just need to fill my vector with fives?
Edit: Wow, I got a lot of other responses while checking code and typing this one. Thanks for the help everyone, I think I understand it now.
if (as[n] <= 0) is the check. If valid values can be negative like you say, then you need a different sentinel to check against. Can valid values ever be zero? If not, then just make the test if (as[n] == 0). This makes your code easier to write, because by default vectors of ints are filled with zeroes.
The code appears to be incorrectly checking is (as[n] <= 0), and recalculates the negative values of the function(which appear to be approximately every other value). This makes the work scale linearly with n instead of 2^n with the recursive solution, so it runs a lot faster.
Still, a better check would be to test if (as[n] == 0), which appears to run 3x faster on my system. Even if the function can return 0, a 0 value just means it will take slightly longer to compute (although if 0 is a frequent return value, you might want to consider a separate vector that flags whether the value has been computed or not instead of using a single vector to store the function's value and whether it has been computed)
If the formula can yield both positive and negative values then this function has a serious bug. The check if(as[n]<=0) is supposed to be checking if it had already cached this value of computation. But if the formula can be negative this function recalculates this cached value alot...
What it really probably wanted was a vector<pair<bool, unsigned> >, where the bool says if the value has been calculated or not.
The code, as posted, only memoizes about 40% of the time (precisely when the remembered value is positive). As Chris Jester-Young pointed out, a correct implementation would instead check if(as[n]==0). Alternatively, one can change the memoization code itself to read as[n]=mod(-4*a(n-1)-4*a(n-2),65535);
(Even the ==0 check would spend effort when the memoized value was 0. Luckily, in your case, this never happens!)
There's a bug in this code. It will continue to recalculate the values of as[n] for as[n] <= 0. It will memoize the values of a that turn out to be positive. It works a lot faster than code without the memoization because there are enough positive values of as[] so that the recursion is terminated quickly. You could improve this by using a value of greater than 65535 as a sentinal. The new values of the vector are initialized to zero when the vector expands.