Final version of solution. Some minimal optimization included.