Friday, 23 January 2015

Dracula Untold

A thrilling origins story that would make for a great video game.




Vlad is a Prince whose family is threatened by the Turks. In order to save his family and the people of his country, he must seek a power much greater than any human can have. But with that power comes a price much greater than a human should bear. He must struggle to keep his humanity and save his people.

Personally, I loved the story, but felt that the ending was such a huge cliff-hanger, it deserves a sequel. If there were to be a sequel, it will definitely be one that surpasses Dracula Untold. With amazing acting by every member of the cast, combined with a well written origin story (though hardcore Count Dracula fans would dismiss it), topped off with good directing and visual effects, this movie is definitely one to watch.

Some criticism is required however. A lot of the story line was given away in the trailer itself, so if you've seen the trailer in advance (as I did), you'll find that the movie only does some filling in of details (and the bad ass ending, which I have been going on about). This movie is not one to be seen multiple times. Also, it does feel like the movie could've been an awesome game instead. Imagine doing the bat changing thing! If a sequel were to be made however, which continued right where this one ended, I would definitely want to watch it in theaters.

So, what did you think of this movie? Leave your comments below.

PS: Turns out that a sequel might actually be done (executive producer Alissa Phillips revealed so).

Monday, 5 January 2015

Writeup for n00b15CTF

This is a collection of hints for all the problems in the recently conducted Capture The Flag (CTF) contest conducted by SDSLabs as a way to get n00bs (beginners) to have a taste of the beautiful world of hacking. It was a pretty fun contest even though it was quite easy.

Test


Use a SHA256 tool. My favourite is to just search for "SHA256 STRING_TO_BE_SHA256" on my default search engine (www.duckduckgo.com)

Location-51


There is a redirect occuring here from http://hack.bckdr.in/LOCATION-51/index.html to http://hack.bckdr.in/LOCATION-51/trap.html Stop this redirect, and read the source of index.html The javascript there gives away the flag

Hidden flag - Easy


Using the file linux command, we find out that it is an ELF binary, but running it gives nothing. However, running strings on it gives away the flag.

Search


The zip file contains a .txt file which does not seem normal text, so we run a file on it. This says that it is jpeg, so change it to .jpg and open it. It is a QR code. Decode this using some online tool (just search for "QR code decode online" for a large number of free tools) and get a link. The link has the flag.

Lost


The message says Console, so open up console in Firefox. The message then tells you to POST data to a link. Going to this link directly does nothing, but sending it any random POST data (using HackBar addon in Firefox for example) gives the flag.

Hidden flag - Medium


Analyzing the file with IDA Pro shows that there is a function called print_flags() which is not called inside main(). Running this function should print the flag. We can do this by attaching gdb to the binary, breaking the execution and running the print_flags() function.

Clutter


Extracting the file and analyzing with Wireshark shows that there is too much to work with. But exporting all the files and then running strings on it would probably work. However, filtering this is a pain, so I just ran a grep for flag and the answer will be visible near a pastebin title.

No - Signal


Use GIMP or Photoshop to add the images. The flag should be obvious then.

Sound


Slow down and reverse the sound wave using Audacity. Listen to it and it should be obvious what the flag is.

Sequel


Looking at the code, it seems like a SQL injection can be done here. Downloading the database.sdb file and rewriting the source code to start throwing data from database, you realize that there is no user sdslabs in the database. This makes it obvious that you need to add the user. The following username virtually that: ' UNION SELECT 'sdslabs','sdslabs','sdslabs','sdslabs','0c4ea8f5b344600f78516334254e9e085f2225a42a0bb18fa8bd774589f1ca19' UNION SELECT * FROM users WHERE '0'='1. Note that this query will not work directly, the password will have to be set accordingly.

Undisputed


The file is a ext4 filesystem (use file command if you don't trust the extension). Mount this in linux using the mount command (read man mount to know how) and then open the file inside to see the flag.



Did you find any other cool/new ways of solving any of these tasks? If so, leave a comment below.

Link to writeup for n00b16ctf

Sunday, 14 December 2014

How to Start Competitive Programming

If you've ever thought about competitive coding, all you've got to do is start now. Doesn't matter which class or branch you are in. Everyone can code and everyone can be competitive. Basically, all you've got to have is the right mindset and the right skill set.

Let's talk about the mindset first. Competitive programming requires a drastically different mindset when compared to "normal" (or developmental) programming. While in developmental programming you have to concentrate on writing quality code that is manageable, competitive programming generally involves writing code that "just works". This is because you'll probably never even look at your code again, once you get an AC (accepted) result from the grader. This does not mean that you should write sloppy code since that would just make it hard to debug (and this can be a real pain in the a** in a competitive setting, with the added pressure of time running out). All it means is that the code need not have extensive documentation (just some inter-spread comments to help out when debugging are enough) or modularity/objects/classes (just write it in logically separate functions to make life easier).

What about the skill set? Basically, the only requirement is that you should be able to write in the language that the grader accepts without having to look at the documentation for the basics. Since almost all graders support C++ (I haven't found any that don't, except in some "special language contests" etc), and C++ has a massively powerful library called STL (standard template library), C++ is the natural choice for most competitive coders. However, if Java is your mother tongue, a fairly large number of graders accept this as well, but do note that Java is known to be slightly slower and more cumbersome to write in a pressured setting. Java does have one major advantage over C++ and this lies in its BigInteger library. However, this is so rarely used that it isn't worth the hassle of doing everything in Java just for this. Most coders use C++ for everything except for when the question requires large integers (larger than 10^18 or so).

I've put together a small set of FAQs below and this should help. If you do have any more questions, do ask in the comments below.

Q: Which language should I use?
A: C++ (Read above for why)

Q: How should I learn C++?
A: The tutorials on cplusplus.com are extremely useful (http://www.cplusplus.com/doc/tutorial/). Not to mention, their documentation is in depth and is useful later on also, when learning things like STL.

Q: Any specifics of the language that are more useful?
A: C++ is a very powerful language with a gazillion features (and more added with C++11), but a whole large chunk of them are not necessary whatsoever for competitive programming. Basically, you should be comfortable with variable types, I/O (using cin, cout - there are faster ways but those are usually not necessary unless a 0.001 second improvement is the only thing that's causing a TLE - usually, the algorithm can be improved instead), control statements (if, ?: operator), looping (for and while, break and continue), functions (call by reference and call by value), arrays, strings (as character arrays), struct. Once you're comfortable with these, learn how to use basics of STL (vector, sort() are most useful). Pointers and dynamic memory is usually a larger headache than anything in the pressures of a contest. See a further question for more. Also, classes and objects will usually not be used since your code usually depends heavily on algorithms and does not usually break down into a object-oriented way.

Q: What do I do for unknown sizes of memory? Is int x[n]; OK? Can I use pointers for this (using int *x = new int[n];)?
A: NO!!! int x[n]; is NOT OK. Arrays need to have a compile time constant size. n is not a constant at compile time. Pointers and dynamic memory is too much of a headache. Just declare an array that is of the size that is max allowed (based on question). If question says n is less than 10^6, then just declare int x[1000010];. The extra 10 is just to be safe :P. Oh, and put large arrays in global scope (declare outside the function) so that it doesn't cause stack overflow problems (can cause SIGSEGV on graders). And don't forget to initialize them using loops whenever necessary. If you really need a truly dynamic sized array, don't use pointers, use std::vector (http://www.cplusplus.com/reference/vector/vector/).

Q: Where do I learn algorithms from?
A: Best place I've found is the MIT OpenCoursware. It is a BTech level course (but usually understandable by most Indian school students too). Link: http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/

Q: What if I prefer books instead of videos?
A: You might've heard of the book we fondly call "murder-weapon" due to it's size. CLRS (Introduction to Algorithms by Cormen, Leiserson, Rivest, Stein) is like the bible of algorithms. If you have the guts to read this huge book, by all means, please do. However, if you want something smaller and more manageable, try the book by Skiena (The Algorithm Design Manual).

Q: Which sites should I practice on?
A: SPOJ has the largest collection of problems. CodeChef has a very nice classification of Easy, Medium, Hard problems. UVa has a large number of problems suitable for ICPC training. CodeForces holds extremely regular contests (and editorials are also regular). TopCoder has regular SRMs but has a very messy arena applet that you have to get used to (but tutorials on TopCoder are great). HackerRank has a nice set of problems divided by difficulty and topic. Finally, it is up to you. I currently use UVa and CodeForces the most, but would suggest CodeChef for beginners due to its classification.

Q: What to do if I get a TLE (Time Limit Exceeded)?
A: Usually your algorithm might not be good enough. Check if the number of elemental operations (like single element access or write or operation etc) totally stays bounded by 10^6 or 10^7. If so, it should run within a second. Otherwise, you're in trouble. Even an algorithm that takes 10^8 operations would be too slow. For example, on an array of size 10^5, a sort using bubble sort (requiring quadratic time) is too slow, but merge sort (requiring N log N time) runs within a second.

Q: What to do if I get a MLE (Memory Limit Exceeded)?
A: You really need to cut down on what memory you are using. Reuse memory space if possible. Usually this verdict from a grader is very very rare. I've got it only once or twice totally in my whole experience until now, and it was fixed by rethinking the usage of memory. A million sized array if integers takes up 4 MB of space, and million 'long long's take up 8 MB space, so this is usually not a problem at all.

Q: What to do if I get a WA (Wrong Answer)?
A: Check if you are missing any \n while outputting your answer. This is a common mistake that might happen even if code and algo is correct otherwise. If that isn't the problem, try running the algo on paper and see that it matches for all cases you can throw at it. If it still works, you haven't tried some corner cases (n=0,1, or very very large). Also, are you sure you are using the right data type? int stores max of ~10^9, long long stores ~10^18. Use it instead. Remember, intermediate calculations also should fit within the limit. If all else fails, try rethinking the algorithm.

Q: I cannot figure out the algorithm. What should I do?
A: If this is in a contest, there is usually not much you can do other than just think or move onto another question. However, if this is when practicing, try working out the example on paper first to make sure you've understood the question. If nothing yet, don't give up (or check online yet). Mentally take note of the question and go on with other work. The answer will strike at the most random time (in the shower for instance). If you still get nothing (after a few days/weeks/months depending on difficulty of question), search for an editorial for the question, or ask someone who's solved it. If it involves a new concept, learn it (don't just copy code without understanding). If it did not require anything new, then re learn whatever was needed. After that, try coding it in and getting an AC. Search for related concepts and questions and solve them.

Q: I know the algo, but cannot code it in. What should I do?
A: Isn't this obvious? Relearn the topics needed.

Q: Can you see my code for problem XXX from site YYY?
A: Nope. I do not have the time to do this individually. Also, competitive code is usually hard to read and difficult to find mistakes in. I usually cannot understand my own (competitive) code after a few days (developmental code is understandable even after years however, since it is written that way). You're on your own. However, if you write the algo in simple English (or pseudo code) then it might help for you to figure out what is wrong by yourself. Also online forums exist just for this. If nothing else, if you can find me a great question, I might just write an editorial on it (see example here).

Q: My question is not in this FAQ.
A: Write it in the comments below.

Wednesday, 3 December 2014

1000 Week Mark

Turns out, I was born exactly 1000 weeks before today. Next such round number happens in 2018 when I'd have lived for 200,000 hours on this hunk of rock that we call Earth. All this cool calculation is done very nicely using the Special Age Calculator on the website timeanddate.com.

Wednesday, 26 November 2014

Debugging code in a competitive setting, Part 1


Writing code in a competitive setting is an especially tiring and frustrating task, for a multitude of reasons. The rush of wanting to code fast prevents one from applying good coding standards and leads to trivial errors. Also, there is no time to set up a testing framework etc. How do you prevent (or at least find and correct) any errors in the code you write?

What I personally do is to use a combination of gdb and a custom debug message function.

The first part of this series of posts will explain the function

First, I always put the following code at the start of my programs:

#ifdef DEBUGIT
  #define DEBUG(X) cerr << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << X << endl
#else
  #define DEBUG(X) (void)0
#endif

Now, whenever there is a need to check the value of a variable (or expression), all that is left to be done is to call the DEBUG() function like so:

DEBUG(x); // debugging variable x
DEBUG((a<<3)+2); // debugging an expression

The way that the "function" (or macro, to be precise) is defined, whenever DEBUGIT is defined at compilation, debug statements are shown, and otherwise, they are just skipped.

Hence, whenever you want to look at the debug statements, use g++ -DDEBUGIT to compile instead of just g++.

Here's an example program and its output:

#include <iostream>

using namespace std;

#ifdef DEBUGIT
  #define DEBUG(X) cerr << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << X << endl
#else
  #define DEBUG(X) (void)0
#endif

int main() {
  int x = 5, y = 10;
  DEBUG(x);
  DEBUG(y);
  ++x += y++;
  DEBUG(y+1);
  cout << x << endl;
}

Output:

>>> DEBUG(13) x = 5
>>> DEBUG(14) y = 10
>>> DEBUG(16) y+1 = 12
16

The advantage with the DEBUGIT technique is that you can directly submit code (without any modifications) and the grader will not run the DEBUG statements at all.

I have added the following line to my .bashrc file:

alias d++='g++ -DDEBUGIT'

Hence, I can directly run d++ for compiling with the debug statements.

In my next post, I will explain how to use gdb to further make life easier.

Monday, 24 November 2014

Terminal based Spell Check

Here's a cool little script I wrote (added to my .bashrc) file in order to test spellings, or to generate them when I don't remember them.

function spelling {
if [ $((`grep -c "^$1$" /usr/share/dict/american-english`)) -gt 0 ]; then
   echo -e "Spelling of\e[1;32m" `grep -m 1 "^$1$" \
    /usr/share/dict/american-english` "\e[0mseems fine"
else 
   echo -e "\e[1;31mThere seems to be a mistake in spelling\e[0m"
fi
}

The script is run quite simply by saying "spelling word-to-be-checked". For example,
spelling look
would say
Spelling of look seems fine
but
spelling louk
would say
There seems to be a mistake in spelling

Where this is extremely useful is when you cannot remember some part of the spelling of a word. For example allitaration or alliteration. Here, I can just use a regex.

Running
spelling allit.ration
would say
Spelling of alliteration seems fine
thereby giving the right spelling.

Wednesday, 29 October 2014

Editorial for Blitzkreig "Lost Zucky"

A nice problem based on choosing a proper method to denote state and then implementing it correctly and efficiently.

Let's first look at the question:

  Problem Statement:

  Zucky wants to find his way out of a maze in minimum possible steps. 
  Zucky knows that he can get lost in the maze if he can't find the exit so 
  he decides to find a way by writing the code first. Now, he knows that 
  there are doors, keys and walls in the maze. Doors and keys can be of four 
  colors Red, Blue, Green, Yellow (RBGY) and red, blue, green, yellow (rbgy) 
  respectively. (Capital letters represent doors, lower case letters 
  represent keys). Every key can open the door of same color as its own. For 
  eg. r can open R, g can open G, etc. No one can get through the walls. 
  Now, being a busy person he can't write all the code. So, he turns to you 
  for help. Your task is to find minimum number of steps in which he can get 
  out of the maze.
  Note: Zucky can move only in horizontal and vertical direction.

  Input:
  The first line contains t, the number of test cases (1 ≤ t ≤ 5).
  The second line contanis two integers R, C (1 ≤ R, C ≤ 100)
  Then R lines follow. Every line contains C characters, which can be
  1) R, B, G, Y - doors,
  2) r, b, g, y - keys,
  3) # - wall,
  4) . - free space,
  5) * - start point,
  6) X - exit

  Output:
  Each line should contain number of steps required if a path exists and 
  "Trapped!" if there is no path.

  Example:

  Input:
  2
  1 10
  *...rRG..X

  2 5
  *gr##
  RG..X

  Output:
  Trapped!
  5

  Please note that there can be multiple exits, multiple keys/doors of the 
  same color, multiple walls, but only one start point. A key once collected 
  can be used to open as many number of doors.


Okay, now, how do we go about solving this?

Firstly, we notice that if we get rid of the RGBYrgby stuff, then all we have is a simple maze to solve (use a BFS on the implicit graph).
However, one can then notice that the coloured keys create nothing new, other than to multiply a factor of 2^4=16 to the number of states (i.e. for each key, whether it is picked up or not also needs to be added to the state). Noticing this, we have a very clear idea of how to implement a BFS on the implicit graph that is formed here. Each node in the graph is a state which contains row number, column number, and which keys have been picked up.

Putting all of this in a pair<pair<int,int>,pair<pair<bool,bool>,pair<bool,bool>>> might be fun to some, but to me, that's just taking it too far.
What I did instead is made a struct that stores the values and wrote hash, unhash functions in order to convert this struct to and from a long long. This makes it easier to use with STL map which I used to store which vertices were already visited.

Here's the state struct and hash,unhash functions:

  typedef long long ll;

  struct state {
    int row, col, r,g,b,y;
  };

  const ll MULT_BASE = 101;

  ll hash(const state &s) {
    ll ret = 0;
    ret *= MULT_BASE; ret += s.row;
    ret *= MULT_BASE; ret += s.col;
    ret *= MULT_BASE; ret += s.r;
    ret *= MULT_BASE; ret += s.g;
    ret *= MULT_BASE; ret += s.b;
    ret *= MULT_BASE; ret += s.y;
    return ret;
  }

  state unhash(ll h) {
    state ret;
    ret.y = h % MULT_BASE; h /= MULT_BASE;
    ret.b = h % MULT_BASE; h /= MULT_BASE;
    ret.g = h % MULT_BASE; h /= MULT_BASE;
    ret.r = h % MULT_BASE; h /= MULT_BASE;
    ret.col = h % MULT_BASE; h /= MULT_BASE;
    ret.row = h % MULT_BASE; h /= MULT_BASE;
    return ret;
  }


The maze itself is quite simply stored in a character array:

  char maze[101][101];
  int R, C;

Now, we have to figure out which states are accessible from where. Also, we want to update the new state if we end up picking up a key.

  bool should_move(const state &o, state &n) {
    if ( n.row < 0 || n.row >= R || n.col < 0 || n.col >= C )
      return false;
    char l = maze[n.row][n.col];
    if ( l == '.' || l == '*' || l == 'X' )
      return true;
    if ( l == '#' )
      return false;
    if ( l == 'r' )
      return (n.r=1,true);
    if ( l == 'g' )
      return (n.g=1,true);
    if ( l == 'b' )
      return (n.b=1,true);
    if ( l == 'y' )
      return (n.y=1,true);
    if ( l == 'R' )
      return (n.r>0);
    if ( l == 'G' )
      return (n.g>0);
    if ( l == 'B' )
      return (n.b>0);
    if ( l == 'Y' )
      return (n.y>0);
  }


Notice the code for picking up the keys. The syntax return (n.y=1,true); uses a very nice but underused feature of C/C++. The comma operator, used in an expression, executes the left side part, followed by the right side part and keeps the right side part for further evaluation. This basically makes the code do n.y=1; return true; but the code is much more cleaner using this comma notation since unnecessary curly braces are removed and also, the code has a smooth uniform look of returns based on conditions.

Now, we can just do a BFS starting from the first location. We exit out of the BFS the moment we find any exit; thus guaranteeing shortest path.

The BFS is implemented quite simply as follows:

  int bfs(int startrow, int startcol) {
  // returns -1 if not possible to exit 
    map<ll,int> dist;
    int ans = -1;
    state startstate;
    startstate.row = startrow; startstate.col = startcol;
    startstate.r = 0; startstate.g = 0;
    startstate.b = 0; startstate.y = 0;

    queue<pair<ll,int> > q;

    q.push(make_pair(hash(startstate),0));

    while (!q.empty()){
      ll curhash = q.front().first;
      state curstate = unhash(curhash), newstate;
      int curdist = q.front().second;
      q.pop();

      if ( dist.count(curhash) != 0 )
        continue;

      dist[curhash] = curdist;

      if ( maze[curstate.row][curstate.col] == 'X' ) {
        ans = curdist;
        break;
      }

      newstate = curstate; newstate.row += 1;
      if ( should_move(curstate,newstate) )
        q.push(make_pair(hash(newstate),curdist+1));

      newstate = curstate; newstate.row -= 1;
      if ( should_move(curstate,newstate) )
        q.push(make_pair(hash(newstate),curdist+1));

      newstate = curstate; newstate.col += 1;
      if ( should_move(curstate,newstate) )
        q.push(make_pair(hash(newstate),curdist+1));

      newstate = curstate; newstate.col -= 1;
      if ( should_move(curstate,newstate) )
        q.push(make_pair(hash(newstate),curdist+1));

    }

    return ans; 
 }


Let's take a look at what's happening in this (pretty long) code. We are keeping a list of distances to visited states in the dist map. As is done in a normal BFS, we push the first vertex into a queue and then start a loop. However, in this case, the distances matter, and so we put an integer tagged along with the state too which will store the distance (distance means number of steps needed to reach that state). As long as the queue is not empty, we keep taking off the front element and we put all its neighbours into the queue whenever the neighbours are accessible. As soon as we reach a final destination (exit) however, we break out of the loop and return out of the function.

All that remains now is to implement the necessary I/O routines and to call the right functions; and there it is - AC!!!

Any doubts/suggestions/criticisms? Please leave your comments below.