compiling in GPU using thrust (prime numbers) - c++

I have a code written in thrust in C language, but i am not able to compile it since i dont have a GPU. My code is supposed to calculate the first 1000 prime numbers. That's it. But the problem is
1 - i can not compile it since i do not have a GPU.
2 - Since i can not compile it, i can not know if it really calculates prime numbers.
Here is my code:
`struct prime{
_host_ _device_
void operator()(long& x){
bool result = true;
long stop = ceil(sqrt((float)x));
if(x%2!=0){
for(int i = 3;i<stop;i+=2){
if(x%i==0){
result = false;
break;
};
}
}else{
result = false;
}
if(!result)
x = -1;
}
};
void doTest(long gen){
using namespace thrust;
device_vector<long> tNum(gen);
thrust::sequence(tNum.begin(),tNum.end());
}
int main(){
doTest(1000);
return 0;
}`
Could someone help me compile my code and display the result, and if not working correctly, then help me fix it?

If you don't have a GPU, then use thrust::host_vector instead of thrust::device_vector.
I've cleaned up your code, and it's running on the CPU like this:
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sequence.h>
#include <iostream>
int main()
{
thrust::host_vector<long> tNum(1000);
thrust::sequence(std::begin(tNum), std::end(tNum));
thrust::transform(std::cbegin(tNum), std::cend(tNum), std::begin(tNum), [](long x)
{
bool result = true;
long stop = (long)std::ceil(std::sqrt((float)x));
if (x % 2 != 0) {
for (long i = 3; i < stop; i += 2) {
if (x % i == 0) {
result = false;
break;
};
}
} else {
result = false;
}
if (!result) x = -1;
return x;
});
for (const auto& element : tNum) if (element>0) std::cout << element << ", ";
std::cout << std::endl;
std::cin.ignore();
return 0;
}

Related

Code ends before it actually should, I'm using std::time()

I'm writing a code that tries to paint all dots in graph correctly by randomly giving colors (according to some simple algorithm) while I still have time left. Correctly means that no two dots with same color are adjacent. Also every dot must have color distinct from the initial.
I noticed that in a simple test it gives wrong answer when I set time limit <=3 sec, but it doesn't work 3 seconds, it almost instantly throws "Impossible", here is part of the code (start, end and tl are global):
std::string new_paint;
bool success = false;
while (!success && end - start < tl) {
std::time(&end);
new_paint = TryPaint(edges, paint, success, v);
}
if (success) {
for (int i = 1; i < new_paint.size(); ++i) {
std::cout << new_paint[i];
}
} else {
std::cout << "Impossible";
}
Test is:
3 3
RGB
1 2
2 3
1 3
It means "3 dots with 3 edges, initial color RGB, edges between 1 2, 1 3 and 2 3"
Also I noticed that when i try to cout end - start it gives 6 in this test. I can't understand what is wrong can smn help?
Im using CLion, Cmake looks like this:
cmake_minimum_required(VERSION 3.21)
project(untitled1)
set(CMAKE_CXX_STANDARD 14)
add_executable(untitled1 main.cpp)
Here is full version of code:
#include <chrono>
#include <iostream>
#include <vector>
#include <set>
#include <random>
#include <algorithm>
time_t start, end;
const int tl = 20;
void check(std::vector<bool>& color, const std::string& paint, int n) {
if (paint[n] == 'R') {
color[0] = false;
} else if (paint[n] == 'G') {
color[1] = false;
} else {
color[2] = false;
}
}
std::string available_color(std::vector<bool>& color) {
std::string s;
if (color[0]) {
s += 'R';
}
if (color[1]) {
s += 'G';
}
if (color[2]) {
s += 'B';
}
return s;
}
std::string TryPaint(std::vector<std::set<int>>& edges, std::string paint, bool& success, int v) {
std::vector<bool> was(v + 1);
int count = 0;
std::vector<int> deck;
for (int i = 0; i < v; ++i) {
deck.push_back(i + 1);
}
std::random_shuffle(deck.begin(), deck.end());
while (count != v) {
auto now = deck[count];
std::vector<bool> color = {true, true, true};
check(color, paint, now);
// std::cout << now << '\n';
for (const auto& i : edges[now]) {
std::time(&end);
if (end - start >= tl) {
success = false;
return "";
}
if (was[i]) {
check(color, paint, i);
}
}
std::string choice = available_color(color);
// std::cout << choice << '\n';
if (choice.empty()) {
success = false;
return "";
} else {
++count;
was[now] = true;
char new_color = choice[0];
paint[now] = new_color;
}
}
success = true;
return paint;
}
int main(){
std::time(&start);
std::time(&end);
int v, e;
std::cin >> v >> e;
std::string paint;
std::cin >> paint;
paint = '#' + paint;
std::vector<std::set<int>> edges(v + 1);
for (int i = 0; i < e; ++i) {
int a, b;
std::cin >> a >> b;
edges[a].insert(b);
edges[b].insert(a);
}
std::string new_paint;
bool success = false;
while (!success && end - start < tl) {
std::time(&end);
new_paint = TryPaint(edges, paint, success, v);
// std::cout << "-------------------------------------------------\n";
}
if (success) {
for (int i = 1; i < new_paint.size(); ++i) {
std::cout << new_paint[i];
}
} else {
std::cout << "Impossible";
}
std::cout << '\n';
return 0;
}
Use difftime() to calculate the number of seconds between two time_t variables. The time_t is opaque and can contain different values on different systems according to the doc.

Dynamic programming - canSum memoization in C++

The objective is to return true if the sum can be made by adding up elements from a given vector. The vector elements maybe used and reused in any order.
Example:
sum = 7, list = [4,5]
return false because you can't use these list elements to make 7
sum = 9 or 5 or 20 or 8, list = [4,5]
return true because 9 = 4+5, 5 is in list already, 20 = 5+5+5+5, 8 = 4 + 4
I do not know why canSum is not returning anything. When targetSum reaches 0, canSum should return true, and then in memo we emplace (remainder, true). However, the program is not returning anything. Why is that?
#include <iostream>
#include <vector>
#include <map>
using namespace std;
bool canSum(int targetSum, vector<int> &vec, map<int, bool> &memo) {
int remainder;
if (memo[targetSum] == true)
return true;
else if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else
for (auto i : vec) {
remainder = targetSum - i;
if (canSum(remainder, vec, memo)) {
memo.emplace(remainder, true);
return true;
}
}
memo.emplace(remainder, false);
return false;
}
int main() {
vector<int> vector1{7, 14};
int sum = 300;
map<int, bool> memo;
if (canSum(sum, vector1, memo))
cout << "true";
else
cout << "false";
}
The problem in your code is the way you handle the storing of sates in your memo table. You store only when the result is desired in the for loop and same problem is while returning using the memo table. So, the states which result in false are not stored in your memo until the complete recursive call ends and you are out of the loop. So, your recursion keeps on calculating the same states again and again. Your logic is correct but dynamic programming integration in recursive code is not proper. Your code will give an output, you just need to wait for a long time even for a small input. Below I have explained the above mentioned problems in detail.
You return from memo only if the result is true i.e. the if condition:
...
if(memo[remainder] == true)
return true;
...
is the problem. We use dynamic programming to save the result of a state that has been calculated so that if we come across the same problem in future, we don't have to recalculate it and we can return its result from saved memo table to avoid going into recursion again. We return the result from memo table irrespective of the result. But here you are returning only if the result was true. You should instead use this:
...
if (memo.find(targetSum)!=memo.end())
return memo[targetSum];
...
This is also the problem while you are storing the results in the memo table in the for loop. The if condition in the for loop:
for (auto i : vec) {
remainder = targetSum - i;
if (canSum(remainder, vec, memo)) {
memo.emplace(remainder, true);
return true;
}
}
is the problem. We store the result in the memo table irrespective of our desired result.
Here is the complete code with both problems fixed.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
bool canSum(int targetSum, vector<int> &vec, map<int, bool> &memo) {
int remainder;
if (memo.find(targetSum)!=memo.end())
return memo[targetSum];
else if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else{
bool ans = false;
for (auto i : vec) {
remainder = targetSum - i;
ans = ans || canSum(remainder, vec, memo);
if (ans) {
memo.emplace(targetSum, true);
return true;
}
}
memo.emplace(targetSum, false);
}
return false;
}
int main() {
vector<int> vector1{7, 14};
int sum = 300;
map<int, bool> memo;
if (canSum(sum, vector1, memo))
cout << "true";
else
cout << "false";
}
This is the answer to your question "I do not know why canSum is not returning anything."
Now, in general one should not use recursive DP as it is too much time consuming and iterative DP is best suited for competitive programming problems.
I think this code is from the freecodecamp video. I have solved the same question like below. Here, 0 means false and 1 means true. I hope you'll understand:
#include<bits/stdc++.h>
using namespace std;
vector<int>memo(1000,10);
bool canSum(int n, vector<int>v){
if(n==0){
return true;
}
if(n<0) return false;
if(memo[n]==1) return true;
if(memo[n]==0) return false;
for(int i = 0; i<v.size(); i++){
int rmndr = n-v[i];
bool x = canSum(rmndr,v);
if(x){
memo[n] = 1;
return true;
}
else{
memo[n] = 0;
}
}
return false;
}
int main() {
int n,x;
cin>>x;
vector<int>v(x);
for(int i = 0; i<v.size(); i++){
cin>>v[i];
}
cin>>n;
if(canSum(n,v)) cout<<"true"<<endl;
else cout<<"false"<<endl;
return 0;
}
This is what you are looking for
#include <vector>
#include <unordered_map>
using namespace std;
bool canSum(int target, vector<int> arr,unordered_map<int,bool> &mp){
if(target == 0)
return true;
if(target < 0)
return false;
if(mp.find(target)!=mp.end())
return mp[target];
for(auto x:arr){
int rem = target - x;
if(canSum(rem,arr,mp) == true){
mp[target] = true;
return true;
}
}
mp[target] = false;
return false;
}
int main(){
int target = 300;
unordered_map<int,bool> mp;
vector <int> arr = {7,14};
cout<<canSum(target,arr,mp);
return 0;
}```
// memoization for the canSum problem
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
bool canSum(int targetSum, vector <int> &numbers, unordered_map <int,int> &memo) {
int key = targetSum;
if(targetSum == 0) return true;
if(targetSum < 0) return false;
if(memo.find(key) != memo.end()) return memo[key]; // to avoid duplicate subtree calculations
else {
for(auto x:numbers) {
int rem = targetSum - x;
if( canSum(rem, numbers, memo) == true) {
memo[key] = true;
return true;
}
}
memo[key] = false;
return false;
}
}
int main() {
unordered_map <int,int> mp1;
unordered_map <int,int> mp2;
unordered_map <int,int> mp3;
unordered_map <int,int> mp4;
unordered_map <int,int> mp5;
vector <int> nums{2,3};
vector <int> nums1{7,14};
vector <int> nums2{5,3,4,7};
vector <int> nums3{2,4};
vector <int> nums4{2,3,5};
cout<<canSum(7,nums,mp1)<<"\n";
cout<<canSum(7,nums2,mp2)<<"\n";
cout<<canSum(7,nums3,mp3)<<"\n";
cout<<canSum(8,nums4,mp4)<<"\n";
cout<<canSum(300,nums1,mp5)<<"\n";
return 0;
}
Output of the code: 1 stands for 'true' and 0 stands for 'false'

Why does my RLE code show std out of range for c++?

Whenever I try to run this program, it always shows me the error message
terminate called after throwing an instance of 'std::out_of_range'
What I figured out, when I try to take input as a string then this problem happens. Hence, my loops do not get executed properly.
I really appreciate if anyone can explain me what's wrong with my code!
#include <iostream>
#include <vector>
#include <stdexcept>
#include <string>
using namespace std;
int main()
{
vector<string> compressed_run_lengths_data;
vector<char> compressed_characters_data;
int i;
int count = 1;
bool can_be_compressed = false;
string data;
try
{
cout << "Enter the data to be compressed: ";
getline(cin, data);
for (i = 0; i < data.size(); ++i)
{
if (!isalpha(data.at(i)))
{
throw runtime_error("error: invalid input");
}
}
if (!data.empty())
{
i = 1;
while (i <= data.size())
{
if (data.at(i - 1) == data.at(i))
{
count++;
if (count > 1)
{
can_be_compressed = true;
}
}
else
{
compressed_characters_data.push_back(data.at(i - 1));
compressed_run_lengths_data.push_back(to_string(count));
count = 1;
}
++i;
}
if (can_be_compressed)
{
for (i = 0; i < compressed_run_lengths_data.size(); ++i)
{
cout << compressed_run_lengths_data.at(i) << compressed_characters_data.at(i);
}
}
else
{
data;
}
}
}
catch (runtime_error &e)
{
cout << e.what();
return 1;
}
return 0;
}
As requested, an elaboration on my comments:
while (i <= data.size()) // <- i runs up to and including data.size ()
{
if (data.at(i - 1) == data.at(i)) // data.at (i) is out of range when i == data.size ()
I have not analysed your algorithm, but you probably want:
while (i < data.size())
instead.

Printing prime numbers by calling a function

How to make a function that calls the next prime number every time I call it?
Here's what I've got:
#include <iostream>
#include <cmath>
void prime();
using namespace std;
int main()
{
void prime();
}
bool isPrime(int integer)
{
int x;
int br = 0;
for (x = 1; x < integer; x++) {
if (integer % x == 0) {
br++;
}
}
if (br == 1) {
cout << " The number " << integer << " is prime " << endl;
}
else if (br > 1) {
cout << " The number " << integer << " is not prime " << endl;
}
}
void prime(){
for (int x = 2;x<1000;x++){
isPrime(x);
}
}
Nothing is displayed when I run it.
Edit: Here I added the main function...
int main()
{
void prime();
}
void prime(); is a function declaration. It has no effect; the function is not called. You must call the function:
int main()
{
prime();
}
And then there's another big problem. Your isPrime function doesn't return anything. Add a return statement to it:
return br == 1;
If you do not intend for the function to return anything (and your code currently doesn't use the returned value, so this may indeed be your intention), then make it a void function.
isPrime is boolean function is expecting to return true or false, there is no return in your code. Make it a void if you just want to "cout" the number on the console.
The main issue with your code is that you are not returning anything from your isPrime function (which should give back a boolean value).
For that you can rewrite your code as:
bool is_prime(int integer) {
if (integer < 2) return true;
auto range = boost::irange(2, integer);
auto pred = [integer](auto i) { return integer % i == 0; };
return find_if(range, pred) == std::end(range);
}
Live demo
Second, your main:
int main()
{
void prime();
}
Is really just declaring the function prime. In order to call it you can write:
void prime();
int main() {
prime();
}

Largest Palindrome 3 digits C++

I cannot figure out why this code isn't working. It doesn't even seem to be going through my for loops and nested loops. I'm very new to programing. I have been trying to answer Euler questions for practice. Sorry if my code is awful.
#include <iostream>
#include <string>
using namespace std;
bool isPalindrome(int x) {
string str = to_string(x);
for(string::reverse_iterator rit=str.rbegin(); rit!=str.rend(); ++rit) {
string pal = to_string(*rit);
if(pal == str) {
return true;
}else {
return false;
}
}
}
int main() {
int max[] = {0, 0};
for(int i=999; i>99; i--) {
for( int j =999; j>99; j--) {
int pal = i*j;
if(isPalindrome(pal) == true) {
max[1] = pal;
if(max[1] > max[0]){
max[0] = pal;
}
}
}
}
cout << max[0];
}
I think you need to return true in isPalindrome after comparing complete string. ie return true; should be outside for loop
And for checking largest 3 digit palindrome why are you passing int pal = i*j; ie for first iteration 999*999. Check this
bool isPalindrome(int x) {
string str = to_string(x);
string pal = str;
std::reverse(pal.begin(),pal.end());
if(pal == str) {
return true;
}else {
return false;
}
}