Thursday, February 9, 2012

Algorithm: Convert large integer from any base to any base.


// Written by Kevin C. Wong
// @JEngineTeam 2/9/2012


// 2-64 Base conversion: from any to any.
// You can increase the base more than 64 by appending m
// ore various characters to the lookup string


#include <iostream>
#include <vector>


#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i--)


using namespace std;


string lookup="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@_";


string convert(string s,int x, int y)
{
    if(x<=1||x>64)return "error";
    if(y<=1||y>64)return "error";
    if(s.compare("0")==0)return"0";
    int l=s.length();
    if(l==0)return"";    
    int ca=(int)lookup.find(s[l-1]);
    string b=convert(s.substr(0,l-1),x,y);
    int i=b.length()-1;
    
    string t;
    while(i>=0||ca>0)
    {
        int v=ca;
        if(i>=0)
        {
            v+=lookup.find(b.at(i))*x;
        }
        t=lookup[v%y]+t;
        ca=(int)(v/y);
        i--;
    }
  return t;   
}


int main(int argc, char** arg)
{
    cout<<convert("1A5A7A902342734022348904583904829045760724907593",12,12)<<endl;
    cout<<convert("1A5A7A902342734022348904583904829045760724907593",12,5)<<endl;
    cout<<convert("4312311240132203424023310434144444444224420004343440124243024330432321104",5,5)<<endl;
    cout<<convert("4312311240132203424023310434144444444224420004343440124243024330432321104",5,12)<<endl;
    cout<<convert("1",7,19)<<endl;
    cout<<convert("2",10,2)<<endl;
    cout<<convert("0000000",7,19)<<endl;
    cout<<convert("5",7,1)<<endl;
    return 0;
}

Sunday, February 5, 2012

My Solution to Top Coder SRM 531 : Non RepeatPlayList


Problem:
There are two rules for a valid playlist
1 - At least M songs have to be played between any two occurrences of the same song. 
2 - Every songs at least played once.

Firstly, let us just consider the first rule.

1. If we list out all invalid and valid arrangements, they can be show in a big searching tree:

    

2. If the parent break the 1st rule, so as its children.

3. If a i-th layer node has more than M-1 ancestors, a valid node just can have N-M choices in next branch, so it will have N-M children.

Algorithm
Let us define DP[i] as following
DP[i]=numbers of leaves(playlists) in i-th layer.
DP[0]=1;
==>DP[i+1]=  DP[i]*(N-i) where i < M 
                 DP[i]*(N-M)     where i>=M
==>DP[i+1]=  DP[i]*(max(N-i,N-M)) 
==>DP[i]=  DP[i-1]*(max(N-i+1,N-M)) 
where 1<M<N<P<=100

====================================================
Now, let us consider the problem with both first and second rules.

1. Define rule2(N) = it is true when all songs 1....N have been played once.

2. If the parent meets rule2(N), so as its children.
    i.e. If a playlist uses N songs, it will be the same as it is longer.

3. If a playlist meets rule2(N-1), it must not meet rule2(N)

    i.e. If a playlist just uses N-1 songs, this playlist cannot use other songs.

4. If the parent meets rule2(j), only (N-j) choice of its children meet rule2(j+1).
    i.e. If a playlist is using j songs, the only way to make this playlist using j+1 songs is:
         Add a new song which is not belong to 1...j.
         And you can have N-j choices in this case.


Let us define DP[i][j] as following
DP[i][j] = # of playlist in ith layer (play list length=i), if we just consider j songs (1....j)
                  and the playlist meet the rules 1(non-repeat in last m song) 
                                                         and rule2(j)=(Just j songs are picked). 


DP[i][j] in i-th layer is contributed by the values of two types of playlist in its upper layer, (i-1)th layer.

Type 1 : Playlists has been counted in DP[i-1][N-1] but not counted in DP[i-1][N]


- This playlist meet Rule2(N-1), but must not meet Rule2(N).
   so, no playlist exist in both DP[i-1][N] and DP[i-1][N-1]

- If we want next level playlist meet Rule2(N),  there are only (1) choice on the song.
   That mean only one child for this node in layer (i-1)th.

- In general, there will be N-(j-1) choices for a new song in order to make this playlist meet rule2(j) .
==> DP[i][j] +=  DP[i-1][j-1]*(N-j+1)




Type 2 : Playlists were counted in DP[i-1][N]
All playlists have been counted in DP[i-1][N] meet rule 1 and 2.

5. If the parent meet the 2nd rule, so as its children.

6. If the parent break the 1st rule, so as its children.
==> If the parent keep the 1st rule, there should be N-M choices for a child to pick a new song  in order to keep rule1.
In general, there should be j-M choices for a playlist in D[i-1][j]


But please also notice that if(j<M), this playlist will fail to meet rule 2(M). (j songs are not enough.) 

==> DP[i][j] +=  DP[i-1][j]*(max(j-M,0))

Examples
N=50,M=5,P=100
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,2450,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,117600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(i<j zero area)0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,5527200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,254251200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,417372479,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,252117430,947016478,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,921607339,682098833,774691803,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,260587143,675411789,746917981,762363706,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,938546765,231482425,354966845,435455513,494548030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
(j<M zero area)
0,0,0,0,0,0,441303923,294465995,51957883,142129153,730918098,385508560,287373037,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,6304462,817911350,750747684,481885700,549775063,46444980,920175336,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,429981403,724825902,355267177,190083313,574078224,766342170,126311865,46487194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,441303923,277335278,663677895,863756375,516370717,47801787,753445737,131497170,91923716,673538977,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
... <truncated> 



Hence, the C++ code will be:




#define rep(i,a,b) for(int i=a;i<=b;i++)
#define MOD 1000000007
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))


#include <iostream>
using namespace std;


class NoRepeatPlaylist
{
  public:
  int numPlaylists(int n,int m,int p)
  {
  ll dp[102][102];
  rep(i,0,101)rep(j,0,101)dp[i][j]=0;
dp[0][0]=1;
rep(i,1,p)
{
          rep(j,1,n)
 {
   dp[i][j]=(dp[i-1][j]*max(j-m,0)+dp[i-1][j-1]*(n-j+1))%MOD;
   }
  }
  return (int)dp[p][n];
  };
};

Sunday, January 29, 2012

My Facebook Hacker Cup 2012 Round 1 - Squished Status answer (Java)


import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Scanner;


public class C {


    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(new File("input.txt"));
        PrintWriter out = new PrintWriter(new File("output.txt"));
        int T = in.nextInt();
        for (int i = 0; i < T; i++) {
            String s = new C().solve(in,i+1);
            out.println(s);
            System.out.println(s);
        }
        out.close();
    }


    HashMap<Integer,Long> hash1=new HashMap<Integer,Long>();
    HashMap<Integer,Long> hash2=new HashMap<Integer,Long>();
    
    private void printDebug(HashMap<Integer,Long> hash1)
    {
    for(Entry<Integer,Long> e:hash1.entrySet())
    {
    System.err.println(e.getKey()+","+e.getValue());
    }
    }
    
    synchronized private String solve(Scanner in, int caseid) {
        int m = in.nextInt();
        String s = in.next();
    int i=0;
   
//        System.err.println("m="+m+",s="+s);
   
    hash1.clear();
    int c=(int)s.charAt(0)-48;
    if(c>0)
    hash1.put(c, 1l);
   
        for(i=1;i<s.length();i++)
        {
        c=(int)s.charAt(i)-48;
//            System.err.println("c="+c);


            hash2.clear();


            for(Entry<Integer,Long> e:hash1.entrySet())
            {
            int s0=e.getKey();
            int s1=s0*10+c;
            int s2=c;            
            long c0=(hash1.get(s0)!=null)?hash1.get(s0).intValue():0;
            long c1=(hash2.get(s1)!=null)?hash2.get(s1).intValue():0;
            long c2=(hash2.get(s2)!=null)?hash2.get(s2).intValue():0;
            hash2.put(s1,(c1+c0)%0xfaceb00c);            
            hash2.put(s2,(c2+c0)%0xfaceb00c);            
            if(s1<=0||s1>m)
                hash2.put(s1,0l);
            if(s2<=0||s2>m)
                hash2.put(s2,0l);
            }
            
            hash1.clear();
            for(Entry<Integer,Long> e:hash2.entrySet())
            {
            if(e.getValue()>0)
            {
            hash1.put(e.getKey(), e.getValue());
            }
            }
            
//            printDebug(hash1);
        }        
        long res=0;
        for(Entry<Integer,Long> e:hash1.entrySet())
        {
        res=(res+e.getValue())%0xfaceb00c;
        }
        
    return "Case #"+caseid+": "+res;
    }


}

My Facebook Hacker Cup 2012 Round 1 - Checkpoint answer (Java)



import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;


public class C {

    static int nCrMax=10000000;
    static long _nCr[]=new long[nCrMax+1];
    static long _tmpnCr[]=new long[nCrMax+1];
    static int _n[]=new int[nCrMax+1];
    static int _r[]=new int[nCrMax+1];


    private static void init()
    {
    for(int i=1;i<=nCrMax;i++)
    {
    _n[i]=i;
    _r[i]=1;
    }
   
    _n[0]=0;_r[0]=0; //Not use    
    _nCr[0]=1;
    _nCr[1]=1;
    int thisRowEnd=0,r=0;
    for(int n=2;n<=nCrMax;n++)
    {
    for(r=1;r<=((int)(n/2));r++)
    {
    if(r==((int)(n/2))&&n%2==0)
    _tmpnCr[r]=(_nCr[r-1]*2);    
    else
    _tmpnCr[r]=(_nCr[r]+_nCr[(r-1)]);
   
    if(_tmpnCr[r]>nCrMax)
    {
    break;
    }
    }
    thisRowEnd=r-1;
    for(r=1;r<=thisRowEnd;r++)
    {
    _nCr[r]=_tmpnCr[r];
        int ncr=(int)_nCr[r];
        if((_n[ncr]+_r[ncr])>(n+r))
        {
        _n[ncr]=n;
        _r[ncr]=r;
        }
    }
    }
    }


    public static void main(String[] args) throws FileNotFoundException {
    init();
        Scanner in = new Scanner(new File("input.txt"));
        PrintWriter out = new PrintWriter(new File("output.txt"));
        int T = in.nextInt();
        for (int i = 0; i < T; i++) {
            String s = new C().solve(in,i+1);
            out.println(s);
            System.out.println(s);
        }
        out.close();
    }
             
    synchronized private String solve(Scanner in, int caseid) {
        int s = in.nextInt();
    int i;
    int res=Integer.MAX_VALUE;
        
    if(s==1)
    {
    res=_n[1]+_n[1];
    }
    else
    {
    for(i=1;i*i<=s;i++)
    {
    if(s%i==0)
      {
    int s1=i;
        int s2=s/i;
if(res>(_n[s1]+_n[s2]))
res=_n[s1]+_n[s2];
      }
    }
    }


    return "Case #"+caseid+": "+res;
    }


}

Tuesday, January 24, 2012

2012 Facebook Hacker Cup Auction Question


You have encountered a new fancy online auction that offers lots of products. You are only interested in their price and weight. We shall say that product A is strictly preferred over product B if A costs less than B and is not heavier (they may be of equal weight) or if A weighs less and is not more expensive (they can have equal price).
We shall call a product A a bargain if there is no product B such that B is better than A. Similarly, we shall call a product C a terrible deal if there exists no product D such that C is better than D. Note that according to our definitions, the same product may be both a bargain and a terrible deal! Only wacky auctioneers sell such products though.
One day you wonder how many terrible deals and bargains are offered. The number of products, N, is too large for your human-sized brain though. Fortunately, you discovered that the auction manager is terribly lazy and decided to sell the products based on a very simple pseudo-random number generator.
If product i has price Pi and weight Wi, then the following holds for product i+1:
  • Pi = ((A*Pi-1 + B) mod M) + 1 (for all i = 2..N)
  • Wi = ((C*Wi-1 + D) mod K) + 1 (for all i = 2..N)
You carefully calculated the parameters for the generator (P1, W1, M, K, A, B, C and D). Now you want to calculate the number of terrible deals and bargains on the site.

Input

The first line of the input file contains a single integer T: the number of test cases. T lines follow, each representing a single test case with 9 space-separated integers: N, P1, W1, M, K, A, B, C and D.

Output

Output T lines, one for each test case. For each case, output "Case #t: a b", where t is the test case number (starting from 1), a is the number of terrible deals and b is the number of bargains.

Constraints

  • 1 ≤ T ≤ 20
  • 1 ≤ N ≤ 1018
  • 1 ≤ M, K ≤ 107
  • 1 ≤ P1 ≤ M
  • 1 ≤ W_1 ≤ K
  • 0 ≤ A,B,C,D ≤ 109

Example Input
5
5 1 4 5 7 1 0 1 2
3 1 3 3 3 1 0 1 1
8 1 3 3 3 1 0 1 2
13 5 7 5 9 1 3 2 5
11 2 3 5 7 11 13 17 19

Example Output
Case #1: 3 3
Case #2: 3 3
Case #3: 2 3
Case #4: 2 2
Case #5: 3 1

Monday, January 23, 2012

My Alphabet Soup Solution


import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

public class C {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(new File("input.txt"));
        PrintWriter out = new PrintWriter(new File("output.txt"));
        int T = in.nextInt();
        for (int i = 0; i < T; i++) {
            String s = new C().solve(in,i+1);
            out.println(s);
            System.out.println(s);
        }
        out.close();
    }

    private String solve(Scanner in,int caseid) {
//        long n = in.nextLong();
//        long k = in.nextLong();
     int h=0,a=0,c=0,k=0,e=0,r=0,u=0,p=0;
     int stats[]={0,0,0,0,0,0,0,0};
     String s;
     do{
     s = in.nextLine();
     }while(s.length()<=0);
   
     for(int ii=0;ii<s.length();ii++)
     {
     char cc=s.charAt(ii);
     if(cc=='H'){ h++;stats[0]++;}
     if(cc=='A'){ a++;stats[1]++;}
     if(cc=='C'){ c++;stats[2]++;}
     if(cc=='K'){ k++;stats[3]++;}
     if(cc=='E'){ e++;stats[4]++;}
     if(cc=='R'){ r++;stats[5]++;}
     if(cc=='U'){ u++;stats[6]++;}
     if(cc=='P'){ p++;stats[7]++;}
     }
     stats[2]=(int)(stats[2]/2);
   
   
     int res=stats[0];
     int ri=0;
     for(int i=1;i<8;i++)
     {
     if(stats[i]<res)
     {
     res=stats[i];
     ri=i;
     }
     }
   
     return "Case #"+(caseid)+": "+res;
    }

}

Friday, January 20, 2012

Hacker Cup 2012 - 3 problems solved.

I just solved 3 questions. Here are some of my comments:

1. Alphabet Soup
Just use 8 counters to count the numbers of the key letters. The solution can be easily deduced by those values.

2. Auction
My approach is trying to construct a directed graph based on the 'better' relation. This graph constructed should be acyclic. Every root you found should be Bargain product. And every leaves should be Terrible Deal product. To save the computation time, I just used an ArrayList to model the computation mentioned above.

3. Billboards 
I just use brute force method for this problem. The fontsize are reducing during the iteration.
To make the verification easier, I assume there is a cursor in the billboard. When I insert a word to the billboard, the cursor move. If the cursor goes outside of the billboard, I reset and try another iteration with a smaller fontsize.