The following code giving answer 21. I am not understanding how the operators are working - operator-precedence

#include<stdio.h>
int main()
{
int i = 10;
int d = ++i + i--;
printf ("d = %d\n",d);
return 0;
}
This code printing d = 21. The order of evaluation is taken right to left and left to right, but still the answer is not evaluating to 21.

Related

Implementing Dijkstra's algorithm with C++ STL

I have implemented the Dijkstra's algorithm as follows
#include <iostream>
#include <bits/stdc++.h>
#include<cstdio>
#define ll long long int
#define mod 1000000007
#define pi 3.141592653589793
#define f first
#define s second
#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define vfor(e, a) for (vector<ll> :: iterator e = a.begin(); e != a.end(); e++)
#define vfind(a, e) find(a.begin(), a.end(), e)
#define forr(i, n) for (ll i = 0; i < n; i++)
#define rfor(i, n) for (ll i = n - 1; i >= 0; i--)
#define fors(i, b, e, steps) for(ll i = b; i < e; i += steps)
#define rfors(i, e, b, steps) for(ll i = e; i > b; i -= steps)
#define mp make_pair
using namespace std;
void up(pair<ll, ll> a[], ll n, ll i, ll indArray[]) {
ll ind = (i - 1) / 2;
while (ind >= 0 && a[ind].s > a[i].s) {
swap(a[ind], a[i]);
indArray[a[ind].f] = ind;
indArray[a[i].f] = i;
i = ind;
ind = (i - 1) / 2;
}
}
void down(pair<ll, ll> a[], ll n, ll i, ll indArray[]) {
ll left = 2 * i + 1;
ll right = 2 * i + 2;
ll m = a[i].s;
ll ind = i;
if (left < n && a[left].s < m) {
ind = left;
m = a[left].s;
}
if (right < n && a[right].s < m) {
ind = right;
}
if (ind != i) {
swap(a[i], a[ind]);
indArray[a[i].f] = i;
indArray[a[ind].f] = ind;
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// cout << setprecision(10);
ll n, m;
cin >> n >> m;
vector<pair<ll, ll>> a[n];
forr(i, m) {
ll u, v, w;
cin >> u >> v >> w;
a[u].pb(mp(v, w));
a[v].pb(mp(u, w));
}
ll parent[n];
parent[0] = -1;
pair<ll, ll> dist[n];
forr(i, n) {
dist[i] = mp(i, INT_MAX);
}
dist[0].s = 0;
ll ind[n];
iota(ind, ind + n, 0);
ll ans[n];
ans[0] = 0;
bool visited[n];
fill(visited, visited + n, false);
ll size = n;
forr(i, n) {
ll u = dist[0].f;
visited[u] = true;
ll d1 = dist[0].s;
ans[u] = dist[0].s;
swap(dist[0], dist[size - 1]);
size--;
down(dist, size, 0, ind);
for (auto e : a[u]) {
if (visited[e.f]){
continue;
}
ll v = e.f;
ll j = ind[v];
if (dist[j].s > d1 + e.s) {
dist[j].s = d1 + e.s;
up(dist, size, j, ind);
parent[v] = u;
}
}
}
stack<ll> st;
forr(i, n) {
ll j = i;
while (j != -1) {
st.push(j);
j = parent[j];
}
while (!st.empty()) {
cout << st.top() << "->";
st.pop();
}
cout << " Path length is " << ans[i];
cout << '\n';
}
}
This implementation is correct and giving correct output.
As it can be seen every time I select the node with lowest key value(distance from source) and then I update the keys on all the adjacent nodes of the selected node. After updating the keys of the adjacent nodes I am calling the 'up' function as to maintain the min heap properties. But priority queue is present in the c++ stl. How can I use them to avoid the functions up and down.
The thing is I need to be able to find the index of the node-key pair in the mean heap whose key needs to be updated. Here in this code I have used a seperate ind array which is updated every time the min heap is updated.
But how to make use of c++ stl
Like you implied, we cannot random-access efficiently with std::priority_queue. For this case I would suggest that you use std::set. It is not actually a heap but a balanced binary search tree. However it works the desired way you wanted. find, insert and erase methods are all O(log n) so you can insert/erase/update a value with desired time since update can be done with erase-then-insert. And accessing minimum is O(1).
You may refer to this reference implementation like the exact way I mentioned. With your adjacency list, the time complexity is O(E log V) where E is number of edges, V is number of vertices.
And please note that
With default comparator, std::set::begin() method returns the min element if non-empty
In this code, it puts the distance as first and index as second. By doing so, the set elements are sorted with distance in ascending order
% I did not look into the implementation of up and down of your code in detail.

Optimizing code for reading some VLVs in a file?

I'm trying to read some variable-length-values from a file I created.
The file contains the following:
81 7F 81 01 2F F3 FF
There are two VLVs there, 81 7F and 81 01 which are 255 and 129 in decimal.
I also created some file-reader functions that go like this:
void read_byte_from_file_to(std::fstream& file, uint8_t& to) {
file.read((char*)&to, 1);
}
unsigned long readVLV(std::fstream& t_midi_file) {
unsigned long result = 0;
static unsigned long sum = 0, depth = 0, count = 0;
uint8_t c;
read_byte_from_file_to(t_midi_file, c);
++count;
if (c & 0x80) {
readVLV(t_midi_file);
}
sum += (c & 0x7F) << (7 * depth++);
if (count == depth) {
result = sum;
sum = 0;
depth = 0;
count = 0;
}
return result;
};
While running readVLV n times gives correct answers for the first n VLVs when reading from a file, I absolutely hate how I wrote it, which so much statics parameters and that ugly parameter reset. SO if someone could head me in the right direction I'd be very pleased.
A basic _readVLV which takes the positional state of the function could be done by writing
unsigned long _readVLV(
std::fstream& t_midi_file,
unsigned long sum,
unsigned long depth) {
uint8_t c;
read_byte_from_file_to(t_midi_file, c);
if (c & 0x80) {
sum += _readVLV(t_midi_file, sum, depth);
++depth;
}
return (c & 0x7F) << (7 * depth);
}
and creating a global readVLV function that takes the positional information and the file like so
unsigned long readVLV(std::fstream& t_midi_file) {
unsigned long sum = 0, depth = 0, count = 0;
return _readVLV(t_midi_file, sum, depth, count);
}

50 error: invalid operands to binary % (have' int ' and ' *int ')

I get this error at line 50.I dont know what to use instead of (*p).
I am learning how to use pointers and trying to use pointers in a function passing arguments by reference.
I've been staring at it for some time now.
# include "stdio.h"
int odd (int (*), int );
main(){
int i,n;
int size;
int main(){
int v[i];
int *p;
p = &v[0];
printf("Write the quantity of integers you want to ingress");
scanf("%d",&size);
for(i=0;i<size;i++){
printf("write a number");
scanf("%d",&n);
v[i]= n;
p = &v[i];
odd(&v[i],size);
printf("The value number %d is: %d \n",i,*p);
}
return 0;
}
int odd(int *p,int siz){
int i;
int counter = 0;
for(i=0;i<siz;i++){
/*50*/ if(*p % 2 = 0){ }
else counter++ ;
return counter;
}
}
You are confusing assignment (=) with testing for equality (==). Change:
if(*p % 2 = 0)
to:
if(*p % 2 == 0)
Also your prototype for odd is wrong - change:
int odd (int (*), int );
to:
int odd (int *, int );

Rearranging an array in CUDA

I have the following problem that I want to implement on CUDA:
I want to read an array (say "flag[20]"), and based on a certain condition, write indices of this array to another array (say "pindex[]")
Simple code implementation in C can be:
int N = 20;
int flag[N];
int pindex[N];
for(int i=0;i<N;i++)
flag[i] = -1;
for(int i=0;i<N;i+=2)
flag[i] = 0;
for(int i=0;i<N;i++)
pindex[i] = 0;
//operation: count # of times flag != -1 and write those indices in a different array
int pcount1 = 0;
for(int i=0;i<N;i++)
{
if(flag[i] != -1)
{
pindex[pcount1] = i;
++pcount1;
}
}
How will I implement this in CUDA?
I can use atomicAdd() to calculate total number of times my condition is satisfied. But, how do I write indices in a different array. For example, I tried the following:
__global__ void kernel_tryatomic(int N,int* pcount,int* flag, int* pindex)
{
int tId=threadIdx.x;
int n=(blockIdx.x*2+blockIdx.y)*BlockSize+tId;
if(n > N-1) return;
if(flag[n] != -1)
{
atomicAdd(pcount,1);
atomicExch(&pindex[*pcount],n);
//pindex[*pcount] = n;
}
}
This code calculates "pcount" correctly, but does not update "pindex" array.
I need help to do this operation on GPUs.
Thanks
Since your condition (flag) is conceptually a binary, you can use binary prefix sum (thoroughly explained here) to determine which place the thread with a positive flag should write.
For example if N is 20, with the help of below __device__ functions:
__device__ int lanemask_lt(int lane) {
return (1 << (lane)) − 1;
}
__device__ int warp_prefix_sums(int lane, int p) {
const int mask = lanemask_lt( lane );
int b = __ballot( p );
return __popc( b & mask );
}
your __global__ function can simply be written like below:
__global__ void kernel_scan(int N,int* pcount,int* flag, int* pindex)
{
int tId=threadIdx.x;
if(tId >= N)
return;
int threadFlag = ( flag[tId] == -1 ) ? 0 : 1;
int position_to_write = warp_prefix_sum( tId & (warpSize-1), threadFlag );
if( threadFlag )
pindex[ position_to_write ] = tId;
}
If N is bigger than the warp size (32), you can use intra-block binary prefix sum that is explained in the provided link.

Compound assignment operators, what happens if the value is modified (in the meanwhile)?

Consider the following pseudocode (language agnostic):
int f(reference int y) {
y++;
return 2;
}
int v = 1;
v += f(v);
When the function f changes y (that is v) while evaluating v += f(v), is the original value of v "frozen" and changes to v "lost"?
v += f(v); // Compute the address of v (l-value)
// Evaluate v (1)
// Execute f(v), which returns 2
// Store 1 + 2
printf(v); // 3
In most languages += operator (as well as any other compound assignment operator, as well as simple assignment operator) has right-to-left associativity. That means f(v) value will be evaluated first, then its result will be added to the current value of v.
So in your example it should be 4, not 3:
C++: (demo)
int f(int& v) {
v++;
return 2;
}
int main() {
int v = 1;
v += f(v);
cout << v; // 4
}
Perl: (demo)
sub f {
$_[0]++;
return 2;
}
my $v = 1;
$v += f($v);
print $v; # 4