Compare 4 variables to find the lowest C++ - c++

I want to find the lowest number of the four, but this looks kinda wierd , isnt there a smarter and shorter way to do it?
That is what I have:
int findlowest(int one, int two, int three, int four) {
int output = one //as of now , we will be outputting one , except if we find a lower score.
if(output > two) { out = two;} // if output is proven to be bigger than two, two is our new output.
if(output > three){ output = three;} //same operation with three
if(output > four){ output = four;} // same operation with four
return output;
}

std::min(a, std::min(b, std::min(c, d)));
Include <algorithm>.

c++11:
int minimum = std::min( { 1,2,3,4,5 } );

min_int = min(min(one, two), min(three, four));

int a[] = {1,2,3,4,5};
int minimum = *std::min_element(a, a+5);

Lots of answers saying to use the Standard library facilities - they're right, it covers this case! But, for the educational value, here's a slightly more concise way to do what you were doing:
int findlowest(int a, int b, int c, int d)
{
int of_a_b = a < b ? a : b;
int of_c_d = c < d ? c : d;
return of_a_b < of_c_d ? of_a_b : of_c_d;
}
Easily generalised for different types (though C++03 doesn't make it easy to generalise for arbitrary numbers of arguments):
template <typename T>
T findlowest(const T& a, const T& b, const T& c, const T& d)
{
const T& of_a_b = a < b ? a : b;
const T& of_c_d = c < d ? c : d;
return of_a_b < of_c_d ? of_a_b : of_c_d;
}

Related

Storing all vector values in a data type

I have a vector declared containing n integers.
vector <int> tostore[n];
I want to store all the numbers in the vector inside a string in the format of their subscripts, like 12345..n
Example:
vector <int> store_vec{1,2,3,4,5};
int store_str; //to store the digits in order from vector store_vec
cout<<store_str;
Desired Output:
12345
How do I store it in store_str without printing it?
Instead of using an integer, which if it is 32 bits wide will only be able to store 8-9 digits, you could instead build a string that has all of the elements combined like
vector <int> store_vec{1,2,3,4,5};
std::string merged;
merged.reserve(store_vec.size());
for (auto num : store_vec)
merged += '0' + num;
// now merged is "12345"
One way would be to just multiply by 10 each iteration
int result = 0;
for (auto it : tostore)
{
result = result * 10 + it;
}
As mentioned in comments, a more robust approach would be concatenating to an actual string, or at least using a 64-bit integer.
Since you confirmed that store_vec only contains single digit numbers, a simple way of doing this would be :
std::vector<uint8_t> store_vec = {1,2,3,4,5};
std::string str = std::accumulate(store_vec.begin(), store_vec.end(), std::string{},
[](const std::string& res, uint8_t num){ return res + char('0' + num); });
int resnum = atoi(str.c_str());
or basically use the str resulting with accumulate since it already represent the sequence.
Since you know that each value in tostore will only be a single digit, you could use int_8 or uint8_t data types to store the values instead. This way you can still perform arithmetic on the values within the vectors (so long as the result of the arithmetic falls within the range of -128 to 127 or 0 to 255 respectively, see integer types for more details). These data types have the advantage of being only a single byte long, allowing your vector to potentially be more densely packed and faster to traverse. You can then use std::cout << unsigned(tostore[n]) to cast the integer into a character for display. The whole thing would look something like this
#include <iostream>
#include <type_traits>
#include <vector>
int main()
{
std::vector<uint8_t> tostore;
tostore.reserve(32);
for(int i = 0; i < 32; ++i) {
tostore.push_back(i % 10);
}
for(uint i = 0; i < tostore.size(); ++i) {
std::cout << unsigned(tostore[i]);
}
}
Alternatively, if you know that your digit will always be positive it opens a whole new range of possibilities. When converting an integer to a list of characters a program needs to break the integer into its individual digits and then add 48 to that digits value to find its ascii character code equivalent (see asciiTable for more details). The process of splitting the integer into its base 10 digits may be too cumbersome (you decide) if you plan to display these characters often or perform only a few arithmetic operations on the data. In this case you could create a struct that stores the value of the integer as a char data type but performs arithmetic with the data as if it were an integer. This way, when printing the values no operations need to be performed to format the data properly and the only operations that need to be done to format the data for arithmetic operations are simple subtractions by 48 which are very fast. Such a struct could look something like this:
#include <iostream>
#include <type_traits>
#include <vector>
struct notANumber {
char data;
notANumber() {}
notANumber(const int& a) : data(a + 48) {}
notANumber(const char& a) : data(a) {}
notANumber operator+(const notANumber& b) {
notANumber c;
c.data = b.data + c.data - 48;
return c;
}
notANumber operator-(const notANumber& b) {
notANumber c;
c.data = b.data - c.data + 48;
return c;
}
notANumber operator*(const notANumber& b) {
notANumber c;
c.data = (b.data - 48) * (c.data - 48) + 48;
return c;
}
notANumber operator/(const notANumber& b) {
notANumber c;
c.data = (b.data - 48) / (c.data - 48) + 48;
return c;
}
};
int operator+(const int& a, const notANumber& b) {
int c;
c = a + b.data - 48;
return c;
}
int operator-(const int& a, const notANumber& b) {
int c;
c = a - b.data + 48;
return c;
}
int operator*(const int& a, const notANumber& b) {
int c;
c = a * (b.data - 48);
return c;
}
int operator/(const int& a, const notANumber& b) {
int c;
c = a / (b.data - 48);
return c;
}
int main()
{
std::vector<notANumber> tostore;
tostore.reserve(32);
for(int i = 0; i < 32; ++i) {
tostore.push_back(i % 10);
}
std::cout.write(reinterpret_cast<char*>(tostore.data()), tostore.size());
}
Now this might not be what you are looking for, but I hope that it does showcase an important aspect of programming which is "the more you know about the data you are working with, the more you can optimize the program" so make sure you have a good feel for the range of the data you are working with and what operations you are going to be doing with it most often (arithmetic or printing for example) and the cost of those operations.

How to put min and max inside a function

I'd like to do this piece of code
auto f = player == color ? max : min;
Where player and color are booleans and min and max are standard functions from C++ library.
But I get this error : error: overloaded function with no contextual type information
How do I tell the compiler I want to load min and max that compares integers?
Here's how to reproduce the error :
1) create a file toto.cpp
2) paste this :
int main() {
bool one = 1;
bool zero = 0;
auto f = one == zero ? std::min : std::max;
return 0;
}
3) compile it g++ toto.cpp
4) run it ./a.out
5) observe the same error as above
Something like this?
#include <algorithm>
int main()
{
auto Max = [](int a, int b){return std::max(a, b);};
auto Min = [](int a, int b){return std::min(a, b);};
bool one = 1;
bool zero = 0;
auto f = one == zero ? Min : Max;
return 0;
}
I think the compiler is simply not able to deduce the template parameter(s) for std::max and std::min when you write it like:
auto f = one == zero ? std::min : std::max;

Can you store arithmetic operators in an array i,e(+, -, *, /) in C++

I want to make a program that takes 4 numbers eg.(a, b, c and d) and checks if using arithmetic operators i can make the first 3 numbers result to the fourth number, like if the input is (3, 4, 5, 23) this will check out true because
3 + 4 * 5 = 23,So i want to make an array that has the operators and use a loop to check every possible combination, Hope i made it clear.
Edit:
Its actually codeforces problem, given 4 numbers. Check whether he could get the fourth number by using the arithmetic operators (+,−,×) between the other three numbers. Knowing that an operator can be used only once. in this format ->(a□b□c=d).My question was if there is a way to make it automatic or do i have to code every possibility manually So sorry for any confusion i may have caused.
You can't store the operators in an array, but you could make wrapper functions for them and store those in an array.
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
int mul(int a, int b) {
return a * b;
}
int div(int a, int b) {
return a / b;
}
typedef int (*funptr)(int, int);
funptr arr[] = { add, sub, mul, div };
You can then call them like:
(arr[1])(2, 1) // call sub(2, 1)
The parentheses around arr[1] aren't needed in this case, but I like to put them for clarity.
No. You'd have to write a program to work this out. You could store something like function pointers to the arithmetic operators in an array, but I don't think that would help solve your problem. You'd still have to write the code to solve your problem.
Adding onto #CoffeeTableEspresso's answer, you can also put those function pointers into a map.
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
int mul(int a, int b) {
return a * b;
}
int div(int a, int b) {
return a / b;
}
typedef int (*funptr)(int, int);
std::map<char,funptr> operators = {
{'+', add},
{'-', sub},
{'*', mul},
{'/', div}};
Then you can do
operators['+'](4,7);
Which might be a bit more readable, and you can iterate through these more easily.
I thought I would submit a compete answer. This works for positive numbers. It may take a bit more work to cover all the possibilities. And it does not answer to CoffeeTableEspresso's question about precedence. But it may help with your last question about if statements.
#include <iostream>
namespace {
auto add = [](int a, int b) {return a + b; };
auto sub = [](int a, int b) {return a - b; };
auto mult = [](int a, int b) {return a * b; };
auto divd = [](int a, int b) {return b ? a / b : -1; };
std::vector<int(*)(int, int)> ops = { add,sub,mult,divd };
}
int check(int* params)
{
for (size_t i = 0; i < 4; ++i)
for (size_t j = 0; j < 4; ++j)
{
auto result = ops[i](params[0], ops[j](params[1], params[2]));
if (params[3] == result)
return result;
else
std::cout << result << std::endl;
}
return -1;
}
int main()
{
int params[] = { 3, 4, 5, 23 };
std::cout << check(params);
}
Operators * / have a higher precedence than + -, so operator[i](A, operator[j](B, C)) solution doesn't really work.
You can write a little string calculator, and cycle through char-operators:
#include <iostream>
#include <sstream>
#include <vector>
#include <cmath>
double calculate(std::string str)
{
// calculator there
return -1;
};
int main()
{
std::vector<char> op = {'+', '-', '*', '/'};
std::vector<int> a = { 96, 3, 10, 42 };
for (auto op1: op)
for (auto op2: op)
{
std::stringstream ss;
ss << a[0] << op1 << a[1] << op2 << a[2];
double result = calculate( ss.str());
if (std::abs(a[3] - result) < 1E-6)
std::cout << ss.str() << " = " << a[3];
else
std::cout << ss.str() << " = " << result << " != " << a[3];
}
}

D-lang being faster than C++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
So I was practising for an upcoming programming contest on algorithms, and I stumbled upon a problem from the previous year.
I pretty much solved it(in C++), but i was getting some timeouts, so i took a look at the official solution and it was written in Dlang.
I then tried to imitate what the official answer did in D, but I was still getting timeouts( > 4 seconds on a single input). Afaik, C++ is supposed to be faster than D, but D solves the same input in a split second and C++ takes more than 5 seconds for it
Here is the D answer code
import std.stdio;
import std.algorithm;
struct edge {
int src, des, w, o;
int opCmp (ref const edge e) const {
if(w != e.w) return w - e.w;
else return o - e.o;
}
};
const int MAXN = 100004, MAXM = 200004;
int N, M, D, ee, weight, days;
int[MAXN] ds;
edge[] edges;
void init() {
for(int i=1;i<=N;i++) ds[i] = i;
}
int find(int x) {
return ds[x] = (x == ds[x] ? x: find(ds[x]));
}
bool connected(int x, int y) {
return find(x) == find(y);
}
bool merge(int x, int y) {
int xr = find(x), yr = find(y);
if(xr ^ yr) {
ds[xr] = yr;
return 1;
}
return 0;
}
void main() {
scanf("%d%d%d", &N, &M, &D);
for(int i=1, a, b, c;i<=M;i++) {
scanf("%d%d%d", &a, &b, &c);
if(i < N)
edges ~= edge(a, b, c, 0);
else
edges ~= edge(a, b, c, 1);
}
edges.sort();
init();
int i, maxe=0;
for(i=0;i<edges.length;i++) {
auto e = edges[i];
if(merge(e.src, e.des)) {
if(e.o)
days ++;
}
}
printf("%d", days);
}
And then here is what I wrote in C++ as the answer code
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
struct Edge{
long long source, end, weight, old;
Edge(long long _s, long long _e, long long _w, long long _o):source(_s), end(_e), weight(_w), old(_o){}
};
int parents[100004];
vector<Edge>edges;
bool inc(Edge a, Edge b)
{
if(a.weight == b.weight)return a.old > b.old;
return a.weight < b.weight;
}
long long find(long long node)
{
if(parents[node] == node)return node;
else return find(parents[node]);
}
void init(long long M)
{
for(long long i = 0; i < M; ++i)parents[i] = i;
}
bool connect(long long x, long long y)
{
long long fx = find(x);
long long fy = find(y);
if(fx == fy)return false;
parents[fx] = fy;
return true;
}
long long noOfDays()
{
long long days = 0;
for(auto edge : edges){
if(connect(edge.source, edge.end)){
if(!edge.old)++days;
}
}
return days;
}
int main()
{
ios::sync_with_stdio(false);
long long N, M , D;
cin >> N >> M >> D;
N--;
for(long long i = 0; i < M; ++i){
long long a,b,c;
cin >> a >> b >> c;
if(i < N){
edges.push_back(Edge(a,b,c,1));
}else{
edges.push_back(Edge(a,b,c,0));
}
}
sort(edges.begin(), edges.end(), inc);
init(N+2);
cout << noOfDays() << endl;
}
The input which takes more than 5 seconds on C++, and a split second on D can be found here "http://ddl3.data.hu/get/356808/10699419/s4.24.in"
Here is the question I was actually trying to solve "https://dmoj.ca/problem/ccc17s4"(I am only doing the 11 point part).
Is there any way I can make my C++ code as fast as the D code? and why exactly isn't my C++ code running as fast as the D code?
EDIT: For all clarifications, g++ was used for the C++ without any optimizations, and 'dmd' for the Dlang, without any optimizations either
find() seems to be heavily used and they are very different in D and C++ implementations:
int find(int x) {
return ds[x] = (x == ds[x] ? x: find(ds[x]));
}
vs:
long long find(long long node)
{
if(parents[node] == node)return node;
else return find(parents[node]);
}
find() in D modifies array (looks like some kind of dynamic programming, were you cash previous result) while in C++ you always do full lookup. You should compare apples to apples, especially this code could be written exactly the same way in C++.
Out of curiosity, I tried running OPs code, and also the version below, which I created by minimally tweaking the 'D' code so that it would compile under C++. OPs C++ version took around 12 seconds to run. The version below took around 0.25 seconds to run.
My conclusion, in answer to the question is that the difference in run time seen by the OP is likely due to differences in implementation as described in some of the other answers, as opposed to poor performance of C++.
#include <cstdio>
#include <vector>
#include <algorithm>
struct edge {
edge(int src, int des, int w, int o) : src(src), des(des), w(w), o(o) {}
int src, des, w, o;
int opCmp(const edge& e) const {
if (w != e.w) return w - e.w;
else return o - e.o;
}
};
const int MAXN = 100004, MAXM = 200004;
int N, M, D, ee, weight, days;
int ds[MAXN];
std::vector<edge> edges;
void init() {
for (int i = 1; i <= N; i++) ds[i] = i;
}
int find(int x) {
return ds[x] = (x == ds[x] ? x : find(ds[x]));
}
bool connected(int x, int y) {
return find(x) == find(y);
}
bool merge(int x, int y) {
int xr = find(x), yr = find(y);
if (xr ^ yr) {
ds[xr] = yr;
return 1;
}
return 0;
}
void main() {
std::scanf("%d%d%d", &N, &M, &D);
for (int i = 1, a, b, c; i <= M; i++) {
scanf("%d%d%d", &a, &b, &c);
if (i < N)
edges.push_back(edge(a, b, c, 0));
else
edges.push_back(edge(a, b, c, 1));
}
std::sort(edges.begin(), edges.end(), [](const edge& lhs, const edge& rhs) { return lhs.opCmp(rhs) < 0; });
init();
int i, maxe = 0;
for (i = 0; i<edges.size(); i++) {
auto e = edges[i];
if (merge(e.src, e.des)) {
if (e.o)
days++;
}
}
printf("%d", days);
}
One possible contributor to the slow performance of the C++ version is the 'inc' function. It receives 2 'Edge' structs by value, which in C++ will mean copying of the structs for every comparison during the sort call towards the end of main().
Try changing the signature of 'inc' to accept 'const Edge&' instead of 'Edge'. This will cause the struct values to be passed by reference and so avoid the extra copying.
Also, if you run a profiler you should be able to find where the majority of the time is being spent. This is the 'right' way to approach optimization: measure to find where you have a performance bottleneck, address the bottleneck and measure again to confirm you have indeed improved the performance.

Appending a number to a number?

How cold I do the following:
say I have the number 10 and would like to append the number 317 to it. The resulting integer would be 10317. How can this be done. Also, once I have this number, how could I then for example remove the 17 off the end. Without using strings, and without obvious solving and adding.
Thanks
This will append both numbers
int append_a_and_b_as_int(int a, int b)
{
for(int tmp = b; tmp > 0; tmp % 10)
{
a *= 10;
}
return a + b;
}
This will get rid of the last n numbers
int remove_n_numbers_from_a(int n, int a)
{
for(int i = 0; i < n; i++)
{
a /= 10;
}
return a;
}
Appending :
int foo(int a, int b)
{
return a*pow(10, floor(log10(b))+1)+b;
}
Removing :
int bar(int a, int b)
{
return a/pow(10, floor(log10(b))+1);
}
For the first one:
int a = 10;
int b = 317;
int result = a * 1000 + b;
For the second:
int result2 = result / 100;
If this is something you need to do in your workplace I'd advise quitting.
You can treat your two numbers as numeric data and solve the question, or you can treat them as strings and use an append.