some algorithmic puzzles, tutorials, interview questions... and stuff...

Tuesday, November 02, 2010

Forex trading

Hi everyone!!! Sorry for the lack of posts, I know it looks like this blog was abandoned, but it's not (not completely :) ).

I've been busy with trying out some online Forex trading with some degree of success.
If anyone out there is interested, please make sure to check out this awesome MetaTrader 4 indicator that I wrote (using my full expertise as a software developer):

I took these algorithms to the next level by using neural networks to build the ultimate indicator which tells you if the price goes up or down.

Good luck and have fun!

Saturday, March 13, 2010

How to print a spiral of numbers 1 through N

Printing the numbers 1 through N in a spiral is asked on interviews sometimes and is a interesting puzzle to solve. The reverse process is also simple but I will not write it here.

The code here is quite simple, but it does not print the numbers thorough N in a spiral, instead it prints a matrix with size N in which numbers are arranged into a spiral. Assuming N is given (16 for example), identifying the matrix size is simply of matter of finding sqrt(n). The idea is to print the outer layer and move inward progressively until reaching the most inner layer.

   1:  #define N 4
   2:  int mat[N][N];
   4:  void fillSpiral() {
   5:      int start = 0;
   6:      int end = N;
   7:      int k = 0;
   8:      while (end - start >= 1) {
   9:          for (int i = start; i < end; i++) {
  10:              mat[start][i] = k;
  11:              ++k;
  12:          }
  13:          for (int i = start + 1; i < end; i++) {
  14:              mat[i][end - 1] = k;
  15:              ++k;
  16:          }
  17:          for (int i = end - 2; i >= start; i--) {
  18:              mat[end - 1][i] = k;
  19:              ++k;
  20:          }
  21:          for (int i = end - 2; i >= start + 1; i--) {
  22:              mat[i][start] = k;
  23:              ++k;
  24:          }
  25:          ++start;
  26:          --end;
  27:      }
  28:  }
  31:  int main() {
  32:      memset(mat, 0, sizeof(mat));
  33:      fillSpiral();
  34:      for (int i = 0; i < N; i++) {
  35:          for (int j = 0; j < N; j++) {
  36:              cout << mat[i][j] << "\t";
  37:          }
  38:          cout << endl;
  39:      }
  40:      cout << endl << endl;
  41:      return 0;
  42:  }

And the result is something like this (notice the spiral):

0       1       2       3
11      12      13      4
10      15      14      5
9       8       7       6

Saturday, February 27, 2010

Data structures

What is a linked list?
What is the structure like?
See my first post.

What is the complexity of finding a specific element in a linked list?
Hint: It's O(n).
• An excellent answer will discuss implementation, structure, operational complexity of common operations, and examples of usage.
• A good answer will discuss an example implementation or usage, but will fail to include internal details or complexity analysis.
• A poor answer would be not knowing about linked lists or confusing them with another data structure.

Compare a linked-list to a vector.
Hint: A vector is a single contiguous memory block containing all the elements whereas a linked list is made up of several memory blocks (elements) linked together through the "next" pointer. Access to an element of the array can be made directly in O(1) but in a list, to find the nth element, you must iterate over the previous n elements, therefore the complexity is O(n). An array is fixed in size so to extend it you must reallocate a different memory block and copy all the existing data to the new allocated block; in a linked list you can simply add a new element which is linked to the last element, so it's much faster.
• An excellent answer will discuss the implementation differences, different pattern of memory usage and access, and mention some use cases where one is more appropriate than the other.
• A good answer will discuss the implementation differences and elaborate on some examples.
• An acceptable answer will merely mention the access time differences.
• A poor answer will make a technical mistake or not know one or both data structures.

What is a hash table? What is it used for?
Hint: The following description applies for all questions about maps. A hash table is a structure which uses hash functions to store and read items. When a key-value pair is inserted, the key is transformed through a hash function into an integer which represents the index in an array where the key-value pair will be stored. Because of this hash function, the insertion and deletions are O(1) in complexity. Therefore, most hash tables are implemented using an array. Hash tables are particularly efficient when the maximum number of entries can be predicted in advance, so that the array can be allocated once with the optimum size and never resized. If hash collisions occur, one usual solution is to store a list of items at each index in the array. This list will contains key-value pairs for which all the keys have the same hash value.
• An excellent answer will describe an O(1) read and write data structure with scaling memory usage and give several examples of where it is useful (e.g. caching, lookup tables with irregular keys).
• A good answer will describe an O(1) read and write data structure and give an example of where it is useful.
• An acceptable answer will mention constant-time access.
• A poor answer will give the access time as something other than constant-time, or confuse it with a tree or other structure.

How can a Map data structure be implemented? (By following the question regarding hash tables, this should be a gimme.)
• An excellent answer will cite at least the hash table-backed and the tree-backed implementations and note the different performance characteristics of each, possibly mentioning that the tree-backed implementation can provide some features not available in a hash-backed implementation (e.g. sorting).
• A good answer will cite both hash table and tree implementations.
• An acceptable answer will cite either the hash table or tree implementation.
• Being unable to answer this question is unacceptable.

What is a binary tree?(This question follows the Map question to allow people who forgot non-hash table solutions to realize and revise their omission. It is good for candidates who only mentioned the hash table implementation of a map to point out that a tree is also an alternative implementation after this question is asked.)
• An excellent answer will describe a binary tree as distinct from a ternary or general tree, and will note that a binary search tree or balanced tree are distinct sub-categories of the generic binary tree.
• A good answer will describe a generic tree where every node has no more than two children and will cite the O(log N) access time where N is the depth/height of the tree.
• An acceptable answer will describe a tree where every node has no more than two children.
• A poor answer will respond by describing a binary search tree or a non-binary tree, and will not respond to gentle hinting or prodding back to the specific question that was asked.

What is the operational complexity of inserting an element into a hash table?
• An excellent answer will correctly cite O(1) complexity and then consider details include about cases in which a collision occurs and common methodologies for resolving hash collisions (i.e. chaining, linear or quadratic probing, secondary hash functions, etc.) are needed.
• A good answer will cite O(1) complexity but will not include collision considerations.
• A poor answer will be incorrect.

How is a hash table implemented?
• An excellent answer will discuss selecting a hashing algorithm, dividing the address space into buckets and tuning the number of buckets to the use-case, hash collisions and bucket overflow/conflict resolution (possibly mentioning several strategies for dealing with collisions), dynamic resizing of the hash table, and might even discuss performance optimizations and interactions with hardware caching.
• A good answer will note the use of a hashing algorithm on the keys and an array or vector of buckets, and will identify hash collisions as a problem and may cite at least one method of dealing with them. The candidate will be able to answer a follow-up about dynamic resizing.
• An acceptable answer will mention an array of buckets and using a hashing function on the key to index into the array.
• A poor answer will be technically incorrect or impossible, or will be for a different data structure than a hash table.
What is the operational complexity of (various operations) on a binary tree?If the candidate already answered this as part of the first phone screen, this question may be skipped. It may also be asked to ensure the candidate is consistent in responding correctly.

What is operational complexity?
Hint: These notations describe different kinds of bounds on asymptotic growth rates. Search the web. You really should know what they all mean, if you want to work at GOOGLE.
• An excellent answer will distinguish between Big Oh, Big Omega, and Big Theta notations and describe each in detail, including how they relate to measures of run-time and space trade-offs.
• A good answer will describe Big Oh notation and how it relates to run-time of algorithms and common operations of abstract data types (ADTs).
• A poor answer will include vague or incorrect ideas regarding Big Oh notation and usage.

What is the operational complexity of inserting an element into a linked list? (Asking a clarifying question about singly-linked lists versus doubly-linked lists is unnecessary in this case, but clarifying requirements is always a good thing.)
• An excellent answer will correctly cite O(N) and note the edge cases such as empty lists and the beginning/ending of the list.
• An acceptable answer will correctly cite O(N).
• A poor answer will be incorrect.

Friday, February 26, 2010

Verbal communication tips

Why are you leaving your current position?
• A good answer will be generally positive, seeking better challenges or goals. Contract expirations and familial obligations are also common.
• A poor answer would be ranting against the current employer or generally being negative. Honesty is not necessarily negativity. The key is how they view their departure, whether they seek self-improvement whatever the situation.
Why do you want to work for GOOGLE?
• An excellent answer will be enthusiastic about GOOGLE and its business and problem space, demonstrating knowledge of our sites and familiarity with its use.
• A good answer will be enthusiastic about GOOGLE and show a desire to work in this environment and on our sorts of problems.
• A mediocre answer will demonstrate a lack of knowledge of our site and operations
Tell me about a recent project that you have worked on.
• An excellent answer will discuss an in-depth project involving a complicated problem, have a clear description of the problem that explains why it was difficult, describe the solution chosen, and reference how the candidate was involved in the entire process and implementation.
• A good answer may involve a small project that was well-executed, or a large project working on a simple problem, or a complex problem for which a sub-optimal solution was chosen.
• An acceptable answer will describe a project in detail from problem to implementation.
• A poor answer will not give a clear explanation of what the purpose of the project was, or will neglect to mention a solution at all, or will say the candidate was not actually involved in the project being described.