Sunday, 16 May 2010

[Almost] Universal Makefile

#compiler
CC=g++
#compiler options
OPTS=-c -Wall
#source files
SOURCES=$(wildcard *.cc SomePath/*.cc )
#object files
OBJECTS=$(SOURCES:.cc=.o)
#sdl-config or any other library here. 
#``- ensures that the command between them is executed, and the result is put into LIBS
LIBS=`sdl-config --cflags --libs`
#executable filename
EXECUTABLE=Main.run
#Special symbols used:
#$^ - is all the dependencies (in this case =$(OBJECTS) )
#$@ - is the result name (in this case =$(EXECUTABLE) )

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
 $(LINK.o) $^ -o $@ $(LIBS)

clean:
 rm $(EXECUTABLE) $(OBJECTS)

It is hard to say why it works, but it works. "Make" uses hidden rules to compile object files from sources.

See there for more (in Russian): http://abuse.edu.ioffe.ru/cluster/makeman or read the manual :)

Friday, 14 May 2010

Sunday, 9 May 2010

Google Code Jam 2010 - Qualification round

Qualification round of Google Code Jam is over, I have managed to get only 53 points of 99 possible. Not a very good start, but nevertheless I proceeded to Round 1. Here is some of my code, that I solved the problems with.

Snapper Chain

It was the easiest problem to solve. (Problem Text) The key to the solution is that the chain shows number of snaps in binary (actually last n bits of it), and light is on when all snappers are in ON state (= the last n bits are all equal to 1).

#include <iostream>
#include <math.h>

using namespace std;

int main(){
  unsigned int t, n, k;
  cin >> t;
  for (unsigned int i=1; i<=t; i++){
    cin >> n >> k;
    unsigned int d = (1U << n ) - 1;

    cout << "Case #" << i << ": " <<
          (  (k & d) == d ? "ON" : "OFF" ) << endl;
  }
}

Provided code was successful with large input too.

Fair Warning

This one was a little bit harder. (Problem Text) The key is that the difference is time between any 2 events stays the same, no matter how big/small number of starboseconds we add to all of them. So we need a greatest common divisor of the differences.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef unsigned int uint;

uint gcd( uint a, uint b ){
  if ( b == 0 ) return a;
  return gcd( b, a % b );
}

uint op_minus( uint a, uint b){
  return a > b ? a - b : b - a;
}

int main(){
  uint c, n, tmp;
  cin >> c;
  for (uint i=1; i<=c; i++){
    cin >> n;
    vector<uint> t;
    for (uint j=0; j<n; j++){
      cin >> tmp;
      t.push_back( tmp );
    }
    //after first transformation t[i] will have the difference 
    //between former t[i] and t[i+1]. 
    //The last member t[n-1] remains - it will be needed at the end 
    //to find the required amount of seconds to add 
    transform( t.begin(), t.end()-1, t.begin()+1, t.begin(), op_minus );
    //after second transformation t[i] will have the gcd of t[i-1] and t[i]
    //I use the following feature of gcd: gcd(a,b,c) == gcd(gcd(a,b), c)
    //every time we are at t[i] there is alreaady a gcd(t[i-2], t[i-1]) in t[i-1]
    transform( t.begin(), t.end()-2, t.begin()+1, t.begin()+1, gcd );
    
    uint remainder =  t.back() % *(t.end()-2);
    cout << "Case #" << i << ": " <<
            (remainder > 0 ?  *(t.end()-2) - remainder : 0 )<< endl;
  }
}

This code does not solve the large input as there are integers up to 1050, and we need to use a bigint class, which I didn't find/write myself.

Theme Park

This is the hardest one to solve, because small input can be solved with straight approach, but the large one needs some different. And I couldn't figure it out. (Problem Text) The code that solves the small input is pretty straightforward. We take the group at the beginning of the queue as soon as it can fit in roller coaster. And don't forget that 1 and the same group cannot be taken twice in 1 run (that may happen if number of seats in roller coaster is more than all the number of people in queue)

#include <iostream>
#include <vector>

using namespace std;

typedef unsigned int uint;

int main(){
  uint t, r, k, n, tmp, sum, total;
  cin >> t;
  for (uint i=1; i<=t; i++){
    cin >> r >> k >> n;
    vector<uint> g;
    total = 0;
    for (uint j=0; j<n; j++){
      cin >> tmp;
      g.push_back( tmp );
    }
    uint a=0;
    for (uint j=0; j<r; j++){
      uint sum = 0;
      for (uint b=0;  b<n && sum + g[a] <= k; a=(a+1)%n, b++ ){
        sum += g[a];
      }
      //cout << "sum: " << sum << " ";
      total += sum;
    }
    cout << "Case #" << i << ": " << total << endl;
  }
}

Pity, the same approach is too slow for large input.

The "official" solutions can be found here.

Tuesday, 4 May 2010

Escaping Curly Bracket in String.Format()

If you need to print a curly bracket in string, when using string format, just put it twice in a row.

string.Format("{{ hello world }}")//{ hello world };
string.Format("{{0}}", 45);//{0}
string.Format("{{{0}}}", 45);//{45}
string.Format("{0:N}", 45);//45.00
string.Format("{{{0:N}}}", 45);//{N}

The last one is not `{45.00}`, because the parser when reading `}}}` first prints the escaped `}`, and only then closes the formatting section. And as `N}` number format does not mean anything to it, it just prints it out.

Tuesday, 13 April 2010

Pointers and Memory Handling In C++

Handling memory resources doesn't need any special knowledge in C++, the memory is freed as soon as the variable is out of scope. Unless you are dealing with pointers. Memory that is addressed by pointer is not freed automatically, even if you are out the scope already. It should be done manually, using delete or some provided special function (If it's some library).

Let's take the following function as an example.

void use_file( const char* fn ){
  FILE* f = fopen( fn, "w" );
  //using f;
  fclose( f );
}

At first sight nothing seems to be wrong here. The memory allocated by fopen is freed at the end of the function with fclose. But what if some exception occurs between those two? Yes, the memory will not be freed. The first attempt to fix this is to add exception handling.

void use_file( const char* fn ){
  FILE* f = fopen( fn, "w" );
  try {
    //using f;
  }
  catch(...){
    fclose( f );
    throw;
  }
  fclose( f );
}

The problem of this solution is that it is too diffusive. Anybody wants to write everywhere try-catch blocks, just to make sure the memory is freed? I am too lazy to do that. There should be a more elegant solution. We can define a class File_ptr, that will behave just like FILE*, but will free resources automatically.

class File_ptr{
  FILE* fp;
public:

  //Constructor that creates File_ptr from FILE*
  File_ptr( FILE* pp ){ fp = pp; }
  
  //Destructor, that closes the file and frees memory
  ~File_ptr(){ if (fp) fclose( fp ) };
  
  //Type conversion operator. It is called every time an object 
  //of File_ptr type needs to be converted to FILE*;
  operator FILE* (){ return fp; }
}

This is a minimum amount of functions that needed for this wrapper class to work. The use_file function then will look like that.

void use_file( const char* fn ){
  File_ptr f = fopen( fn, "w" );
  //using f;
  //file will be closed automatically as soon as f is out of scope
}

But actually it is not all yet. You will also need to define a copy constructor and an assign operator in File_ptr. Here is the good explanation, why.

Thursday, 11 March 2010

Joining a Vector And Splitting String In C++

We need these two opposite operations more or less often. As C++ stl does not provide us these functions, we need to write them ourselves.

template <class T>
string vector_join( const vector<T>& v, const string& token ){
  ostringstream result;
  for (typename vector<T>::const_iterator i = v.begin(); i != v.end(); i++){
    if (i != v.begin()) result << token;
    result << *i;
  }
  return result.str();
}

vector<string> string_split( const string& s, const string& delimiter ){
  vector<string> result;
  string::size_type from = 0;
  string::size_type to = 0;

  while ( to != string::npos ){
    to = s.find( delimiter, from );
    if ( from < s.size() && from != to ){
      result.push_back( s.substr( from, to - from ) );
    }
    from = to + delimiter.size();
  }
  return result;
}

The functions produce the following results:

string ss[] = { "qwerty", "hello", "world" };
vector<string> v( ss, ss+3 );
vector_join( v, ", ") );//"qwerty, hello, world"

int ii[] = { 111, 222, 333 };
vector<int> vi( ii, ii+3 );
vector_join( vi, "; ") );//"111; 222; 333"

string_split( "qwerty, hello, world", ", " );
//results in [ "qwerty", "hello", "world" ]
string_split( ", , wow, , qwerty, hello, world, ", ", " );
//results in [ "wow", "qwerty", "hello", "world" ]

If we have a space as delimiter, we can split string more efficient way and even make use of templates too

template <class T>
vector<T> string_split( const string& s ){
  vector<T> result;
  istringstream ss(s);
  copy( istream_iterator<T>(ss), istream_iterator<T>(), 
        back_inserter( result ) );
  return result;
}

And the tests:

string_split<float>( "11.1 22.2 33.3" );//[ 11.1, 22.2, 33.3 ]
string_split<int>( "111 222 333" );//[ 111, 222, 333 ]

Tuesday, 2 March 2010

Restoring the MSSQL Database

Restoring of the database can be done through the database menu, or [I prefer] like that.

RESTORE DATABASE DatabaseName
FROM DISK = 'C:\Path\To\Backup\File\DatabaseName.bak'
WITH REPLACE

If you get the following error: "Exclusive access could not be obtained because the database is in use", try to get the list of connected users:

EXEC SP_WHO2

Find ones that are connected to DatabaseName and kill them

KILL [SPID]

Saturday, 6 February 2010

How To Get Last Inserted Row ID In PostgreSQL

Imagine we have a test table.

CREATE TABLE test (id SERIAL, name TEXT);

Use the RETURNING statement in the INSERT statement.

INSERT INTO test (name) VALUES ('My Name') RETURNING id;

 id 
----
  1 

INSERT INTO test (name) VALUES ('My Name 1') RETURNING id;

 id 
----
  2 

More info in Postgres manual.

Saturday, 23 January 2010

Remove User List From Ubuntu Karmic Login

As I use Ubuntu on my eeePC, I like better typing than using touchpad.

That would remove user list from login screen and will make you type your username instead of selecting it.

sudo -u gdm gconftool-2 --type bool --set /apps/gdm/simple-greeter/disable_user_list 'true'

Friday, 15 January 2010

Silverlight Cross-Domain Http Request Results Into Security Exception

That is because cross-domain http requests are restricted in Silverlight. One has to add a crossdomain.xml into web service provider root folder with the following lines.

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
 <allow-access-from domain="*" />
</cross-domain-policy>

For more info see Network Security Access Restrictions in Silverlight.