One Dimensional Game of Life - algorithm

The problem is based on a spin-off of the Conway's game of life.
Click here
Based on the solution provided by the author
`#include <cstdio>
#include <cstring>
int N;
long long rot(long long x, int amt){
return ((x<<amt)|(x>>(N-amt)))&((1ll<<N)-1);
}
int main(){
char in[51];
int T;
scanf("%d", &T);
while(T--){
scanf("%s", in);
N=strlen(in);
long long cur=0, orig=0;
for(int i=0; i<N; i++)
cur|=(long long)(in[i]-'0')<<i;
for(int i=0; i<N; i++)
if((i%3)!=(2*N%3))
orig^=rot(cur, i);
if((N%3)==0){
if(orig==0)
puts("Multiple solutions");
else
puts("No solution");
}else{
for(int i=0; i<N; i++)
putchar('0'+((orig>>i)&1));
putchar('\n');
}
}
return 0;
}
`
Can you explain what the "if" condition if((i%3)!=(2*N%3)) helps to achieve.
Also can you elaborate the second solution provided in the editorial [https://discuss.codechef.com/questions/4202/life-editorial?sort=oldest] because the simulation step (A<<<1)^A^(A>>>1) does not satisfy any of the test cases.

Related

Hello, I try to run my c code in dev-c++ and get this : [Error] 'for' loop initial declarations are only allowed in C99 or C11 mode

#include <stdio.h>
int main ()
{
printf("Hello \n");
for(int i=0; i<6; i++){
for(int j=0; j<30; j++)
printf("%c", (char)179);
printf("\n");
}
printf("\n");
printf("what\ up \n ");
for(int i=0; i<6; i++){
for(int j=0; j<30; j++)
printf("%c", (char)179);
printf("\n");
}
printf("\n");
printf("Are you enjoying programming \n");
for(int i=0; i<6; i++){
for(int j=0; j<30; j++)
printf("%c", (char)179);
printf("\n");
}
printf("\n");
return 0;
}
If I remember correctly, initial declaration of the loop counter needs to be outside the loop, ie:
int i;
for (i = 0; i < 5; i++) {
//do stuff here
}
In-loop initial declaration, as your error message suggests, can be used only in C99 or C11 standard (which is C standard published in 1999 and 2011).

Geeksforgeeks is showing my code as runtime error after submission

This is my code
#include <bits/stdc++.h>
using namespace std;
int srch(vector<int> arr, int ln, int fn)
{
for (int i = 1; i <= ln; i++)
{
if (arr[i] == fn)
return i;
}
return -1;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, k;
scanf("%d%d", &n, &k);
vector<int> a(n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
printf("%d\n", srch(a, n, k));
}
return 0;
}
I am not understanding where is the problem. Here is the problem link Click here.
Please help me solving this problem. I am not understanding why geeksforgeeks is showing runtime error for this code.
Note that your loops use n-th entry of vector, but
vector< int> a(n);
has indexes from 0 to n-1
Notice that the first element has a position of 0 (not 1).

Weighted Activity Selection

I am stuck with this problem for a few days-
Consider a modification to the activity-selection problem in which each activity ai has, in addition to a start and finish time, a value vi. The objective is no longer to maximize the number of activities scheduled, but instead to maximize the total value of the activities scheduled. That is, we wish to choose a set A of compatible activities such that summation of their corresponding values is maximized. Give a polynomial-time algorithm for
this problem.
I know this question has been answered here & I have devised a DP approach to find out the summation of the values. But can you print the activities that were selected?
The C++ code is given below. Hope you can easily translate it to any other language.
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 1000
struct activity
{
int start;
int finish;
int weight;
};
bool comp(activity m, activity n)
{
return m.finish>n.finish;
}
int dp[N];
int main()
{
int n, maxi=-1;
int DP[N];
activity a[N];
scanf("%d", &n);
for(int i=0;i<n;i++)
{
scanf("%d %d %d", &a[i].start, &a[i].finish, &a[i].weight);
a[i].pos=i+1;
}
sort(a, a+n, comp);
for(int i=0; i<n; i++)
dp[i]=a[i].weight;
for(int i=1; i<n; i++)
{
for(int j=0; j<i; j++)
{
if(a[j].finish<=a[i].start)
dp[i]=max(dp[i], dp[j]+a[i].weight);
maxi=max(dp[i], maxi);
}
}
printf("%d\n", maxi);
int act[N];
int k=0;
for(int i=n-1;i>=0;i--)
{
if(dp[i]==maxi)
{
maxi-=a[i].weight;
act[k++]=a[i].pos;
}
}
for(int i=k-1;i>=0;i--)
printf("%d ", act[i]);
return 0;
}

Why am I getting a SIGABRT here?

I am getting a SIGABRT error here. I don't understand why. Please help me out with this. It runs fine on my computer but on submitting it, it gives a SIGABRT on the very first test case. The memory alloted is to the order of 10^5 only and I have used vectors, instead of arrays, even then it gives this error.
#include <bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d", &T);
while(T--){
string s;
cin>>s;
int N;
string str;
scanf("%d", &N);
vector <string> f;
for (int i=0; i<N; i++){
cin>>str;
f.push_back(str);
}
vector<int> op;
op.resize(10, 0);
for (int i=0; i<N; i++){
for (int j=0;j <10; j++){
op[i] *= 2;
op[i] += ((f[i][j] == '+')? 1: 0);
}
}
int sint=0;
for (int i=0; i<10; i++){
sint*=2;
sint += ((s[i] == 'b')? 1: 0);
}
int allb = 1023;
int tgt = allb ^ sint;
vector <long long int> prev, curr;
prev.resize(1027, 0);
curr.resize(1027, 0);
prev[op[0]] = 1;
prev[0] = 1;
curr[0] = 1;
curr[op[0]] = 1;
if (op[0] == 0){
curr[op[0]]++;
prev[op[0]]++;
}
for (int i=1; i<N; i++){
for (int j=0; j<=1023; j++){
curr[j] = (prev[j] + prev[j ^ op[i]])%1000000007;
}
for (int j=0; j<=1023; j++)
prev[j] = curr[j];
}
cout<<curr[tgt]<<endl;
}
}

shell sort in openmp

Is anyone familiar with openmp, I don't get a sorted list. what am I doing wrong. I am using critical at the end so only one thread can access that section when it's been sorted. I guess my private values are not correct. Should they even be there or am I better off with just #pragma omp for.
void shellsort(int a[])
{
int i, j, k, m, temp;
omp_set_num_threads(10);
for(m = 2; m > 0; m = m/2)
{
#pragma omp parallel for private (j, m)
for(j = m; j < 100; j++)
{
#pragma omp critical
for(i = j-m; i >= 0; i = i-m)
{
if(a[i+m] >= a[i])
break;
else
{
temp = a[i];
a[i] = a[i+m];
a[i+m] = temp;
}
}
}
}
}
So there's a number of issues here.
So first, as has been pointed out, i and j (and temp) need to be private; m and a need to be shared. A useful thing to do with openmp is to use default(none), that way you are forced to think through what each variable you use in the parallel section does, and what it needs to be. So this
#pragma omp parallel for private (i,j,temp) shared(a,m) default(none)
is a good start. Making m private in particular is a bit of a disaster, because it means that m is undefined inside the parallel region. The loop, by the way, should start with m = n/2, not m=2.
In addition, you don't need the critical region -- or you shouldn't, for a shell sort. The issue, we'll see in a second, is not so much multiple threads working on the same elements. So if you get rid of those things, you end up with something that almost works, but not always. And that brings us to the more fundamental problem.
The way a shell sort works is, basically, you break the array up into many (here, m) subarrays, and insertion-sort them (very fast for small arrays), and then reassemble; then continue by breaking them up into fewer and fewer subarrays and insertion sort (very fast, because they're partly sorted). Sorting those many subarrays is somethign that can be done in parallel. (In practice, memory contention will be a problem with this simple approach, but still).
Now, the code you've got does that in serial, but it can't be counted on to work if you just wrap the j loop in an omp parallel for. The reason is that each iteration through the j loop does one step of one of the insertion sorts. The j+m'th loop iteration does the next step. But there's no guarantee that they're done by the same thread, or in order! If another thread has already done the j+m'th iteration before the first does the j'th, then the insertion sort is messed up and the sort fails.
So the way to make this work is to rewrite the shell sort to make the parallelism more explicit - to not break up the insertion sort into a bunch of serial steps.
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
void insertionsort(int a[], int n, int stride) {
for (int j=stride; j<n; j+=stride) {
int key = a[j];
int i = j - stride;
while (i >= 0 && a[i] > key) {
a[i+stride] = a[i];
i-=stride;
}
a[i+stride] = key;
}
}
void shellsort(int a[], int n)
{
int i, m;
for(m = n/2; m > 0; m /= 2)
{
#pragma omp parallel for shared(a,m,n) private (i) default(none)
for(i = 0; i < m; i++)
insertionsort(&(a[i]), n-i, m);
}
}
void printlist(char *s, int a[], int n) {
printf("%s\n",s);
for (int i=0; i<n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int checklist(int a[], int n) {
int result = 0;
for (int i=0; i<n; i++) {
if (a[i] != i) {
result++;
}
}
return result;
}
void seedprng() {
struct timeval t;
/* seed prng */
gettimeofday(&t, NULL);
srand((unsigned int)(1000000*(t.tv_sec)+t.tv_usec));
}
int main(int argc, char **argv) {
const int n=100;
int *data;
int missorted;
data = (int *)malloc(n*sizeof(int));
for (int i=0; i<n; i++)
data[i] = i;
seedprng();
/* shuffle */
for (int i=0; i<n; i++) {
int i1 = rand() % n;
int i2 = rand() % n;
int tmp = data[i1];
data[i1] = data[i2];
data[i2] = tmp;
}
printlist("Unsorted List:",data,n);
shellsort2(data,n);
printlist("Sorted List:",data,n);
missorted = checklist(data,n);
if (missorted != 0) printf("%d missorted nubmers\n",missorted);
return 0;
}
Variables "j" and "i" need to be declared private on the parallel region. As it is now, I am surprised anything is happening, because "m" can not be private. The critical region is allowing it to work for the "i" loop, but the critical region should be able to be reduced - though I haven't done a shell sort in a while.

Resources