Sunday 22 February 2015

TopCoder Dynamic Programming Bad Neighbours Donation Collection Problem


TopCoder Dynamic Programming Bad Neighbours Donation Collection Problem


Problem 

The old song declares "Go ahead and hate your neighbor", and the residents of Onetinville have taken those words to heart. Every resident hates his next-door neighbors on both sides. Nobody is willing to live farther away from the town's well than his neighbors, so the town has been arranged in a big circle around the well. Unfortunately, the town's well is in disrepair and needs to be restored. You have been hired to collect donations for the Save Our Well fund.

Each of the town's residents is willing to donate a certain amount, as specified in the int[] donations, which is listed in clockwise order around the well. However, nobody is willing to contribute to a fund to which his neighbor has also contributed. Next-door neighbors are always listed consecutively in donations, except that the first and last entries in donations are also for next-door neighbors. You must calculate and return the maximum amount of donations that can be collected.

Constraints
- donations contains between 2 and 40 elements, inclusive.
- Each element in donations is between 1 and 1000, inclusive.

Examples
   
 { 10, 3, 2, 5, 7, 8 }
Returns: 19
The maximum donation is 19, achieved by 10+2+7. It would be better to take 10+5+8 except that the 10 and 8 donations are from neighbors.
   
{ 11, 15 }
Returns: 15
   
{ 7, 7, 7, 7, 7, 7, 7 }

Returns: 21

Solution

int badNeighbours(int *a, int size) {

 if(size == 2) {
   int sum = findMax(a[0], a[1]);
   return sum;
 }

 int i, j;
 int *s = (int *)malloc(sizeof(int)*size);
 int *b = (int *)malloc(sizeof(int)*size);
 s[0]=a[0];
 s[1]=a[1];
 b[0]=1;
 b[1]=0;
 for(i=2;i<size;i++) {
    s[i]=0;
    b[i]=0;
 }

 for(i=2;i<size;i++) {
    for(j=0;j<i-1;j++) {
       if(s[i]<s[j]+a[i]) {
        s[i]=s[j]+a[i];
        b[i]=b[j];
       }
    }
 }

 if(b[size-1]==0) {
   return s[size-1];
 } else {
   int min = findMin(a[0], a[size-1]);
   int sum = findMax(s[size-2], s[size-1]-min);
   return sum;
 }
 return 0;
}



Saturday 21 February 2015

TopCoder Dynamic Programming Longest Zig Zag Sequence Problem


Dynamic Programming - Longest Zig Zag Sequence


Problem 

ZigZag - 2003 TCCC Semifinals 3

A sequence of numbers is called a zig-zag sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a zig-zag sequence.

For example, 1,7,4,9,2,5 is a zig-zag sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, 1,4,7,2,5 and 1,7,4,5,5 are not zig-zag sequences, the first because its first two differences are positive and the second because its last difference is zero.

Given a sequence of integers, sequence, return the length of the longest subsequence of sequence that is a zig-zag sequence. A subsequence is obtained by deleting some number of elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.

Constraints
- sequence contains between 1 and 50 elements, inclusive.
- Each element of sequence is between 1 and 1000, inclusive.

Examples
   
{ 1, 7, 4, 9, 2, 5 }
Returns: 6
The entire sequence is a zig-zag sequence.
   
{ 1, 17, 5, 10, 13, 15, 10, 5, 16, 8 }
Returns: 7
There are several subsequences that achieve this length. One is 1,17,10,13,10,16,8.

Solution

int findLongZigZag(int *a, int size) {

  if(size<=2) {
        printf("%d\n", size);
        return;
  }

  // to track alternate positive and negative sequence.
  int *b = (int *)malloc(sizeof(int)*size);
  // to track length of longest sequence till ith index. 
  int *s = (int *)malloc(sizeof(int)*size));
  int i,j;

  s[0]=1;
  b[0]=a[0];
  b[1]=a[1]-a[0];
  s[1]=2;
  for(i=2;i<size;i++) {
        s[i]=2;
        b[i]=0;
  }

  for(i=2;i<size;i++) {
     for(j=1;j<i;j++) {
        if(b[j]<0) {
           if(a[i] > a[j] && s[i]<=s[j]+1) {
                s[i]=s[j]+1;
                b[i]=a[i]-a[j];
           }
        } else {
          if(a[i] < a[j] && s[i]<=s[j]+1) {
                s[i]=s[j]+1;
                b[i]=a[i]-a[j];
          }
        }
     }
     if(b[i]==0) {
        b[i]=a[i]-a[i-1];
     }
  }

  return s[size-1];
}

Wednesday 11 February 2015

Goldbach's conjecture


Goldbach's Conjecture

 

Problem

Goldbach's conjecture : Every even integer greater than 2 can be expressed as the sum of two primes.
Write a function which takes a number as input, verify if is an even number greater than 2 and also print atleast one pair of prime numbers.

Approach

1) Assume the two numbers are equal to half of the given number.
2) Choose two numbers as half of numbers.
3) increment first by one and decrement second by 1.
4) if the current pair is prime no print it.
5) Else start from step 3 again.

Solution

#include<stdio.h>

int isPrime(int no) {
 int i;
 if (no <= 1) return 0; // 0 and 1 are not prime.
 for (i=2; i*i <= no; i++) {
     if(no % i == 0) return 0;
 }
 return 1;
}

int main()
{
 int a, b, c, i;
 printf("Enter the even no to find out two prime no whose sum is no - ");
 scanf("%d", &a);
 if (a%2 != 0) {
    printf("Please enter even no only\n");
    return 0;
 }
 b = a/2-1;
 c = a/2+1;
 while (1) {
   if (isPrime(b) && isPrime(c)) {
        printf("b %d and c %d are the primes you were looking for.\n", b, c);
        break;
   }
   else {
        b--;
        c++;
   }
 }

}